jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/345607 )
Change subject: MWSaveDialog: Run links through a render function for preview & visual diff ...................................................................... MWSaveDialog: Run links through a render function for preview & visual diff Provide a utility funcition in ve.init.mw.LinkCache to do this. Also use this in ve.ce.MWTransclusionNode/ve.ui.MWPreviewElement, and introduce to ve.ce.MWExtenionNode Bug: T73900 Bug: T153535 Change-Id: Ieb9a0274b8c5ae1932c431546f09d18000fa6dd9 --- M modules/ve-mw/ce/nodes/ve.ce.MWExtensionNode.js M modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js M modules/ve-mw/init/ve.init.mw.ArticleTarget.js M modules/ve-mw/init/ve.init.mw.LinkCache.js M modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js M modules/ve-mw/ui/elements/ve.ui.MWPreviewElement.js 6 files changed, 108 insertions(+), 36 deletions(-) Approvals: Esanders: Looks good to me, but someone else must approve jenkins-bot: Verified Jforrester: Looks good to me, approved diff --git a/modules/ve-mw/ce/nodes/ve.ce.MWExtensionNode.js b/modules/ve-mw/ce/nodes/ve.ce.MWExtensionNode.js index 2c9df42..6386da7 100644 --- a/modules/ve-mw/ce/nodes/ve.ce.MWExtensionNode.js +++ b/modules/ve-mw/ce/nodes/ve.ce.MWExtensionNode.js @@ -86,6 +86,22 @@ }; /** + * @inheritdoc + */ +ve.ce.MWExtensionNode.prototype.getRenderedDomElements = function () { + // Parent method + var elements = ve.ce.GeneratedContentNode.prototype.getRenderedDomElements.apply( this, arguments ); + + if ( this.getModelHtmlDocument() ) { + ve.init.platform.linkCache.styleParsoidElements( + $( elements ), + this.getModelHtmlDocument() + ); + } + return elements; +}; + +/** * Handle a successful response from the parser for the wikitext fragment. * * @param {jQuery.Deferred} deferred The Deferred object created by generateContents diff --git a/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js b/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js index 2450d9a..816bf46 100644 --- a/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js +++ b/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js @@ -191,24 +191,17 @@ /** * @inheritdoc */ -ve.ce.MWTransclusionNode.prototype.getRenderedDomElements = function ( domElements ) { - var $elements = $( ve.ce.GeneratedContentNode.prototype.getRenderedDomElements.call( this, domElements ) ), - transclusionNode = this; +ve.ce.MWTransclusionNode.prototype.getRenderedDomElements = function () { + // Parent method + var elements = ve.ce.GeneratedContentNode.prototype.getRenderedDomElements.apply( this, arguments ); + if ( this.getModelHtmlDocument() ) { - $elements - .find( 'a[href][rel="mw:WikiLink"]' ).addBack( 'a[href][rel="mw:WikiLink"]' ) - .each( function () { - var targetData = ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref( - this.href, transclusionNode.getModelHtmlDocument() - ), - normalisedHref = targetData.title; - if ( mw.Title.newFromText( normalisedHref ) ) { - normalisedHref = mw.Title.newFromText( normalisedHref ).getPrefixedText(); - } - ve.init.platform.linkCache.styleElement( normalisedHref, $( this ) ); - } ); + ve.init.platform.linkCache.styleParsoidElements( + $( elements ), + this.getModelHtmlDocument() + ); } - return $elements.toArray(); + return elements; }; /** diff --git a/modules/ve-mw/init/ve.init.mw.ArticleTarget.js b/modules/ve-mw/init/ve.init.mw.ArticleTarget.js index d158fe2..53c67a9 100644 --- a/modules/ve-mw/init/ve.init.mw.ArticleTarget.js +++ b/modules/ve-mw/init/ve.init.mw.ArticleTarget.js @@ -744,7 +744,11 @@ this.getSurface().getModel().getDocument().once( 'transact', this.saveDialog.clearDiff.bind( this.saveDialog ) ); - this.saveDialog.setDiffAndReview( diffHtml, this.getVisualDiff() ); + this.saveDialog.setDiffAndReview( + diffHtml, + this.getVisualDiff(), + this.getSurface().getModel().getDocument().getHtmlDocument() + ); }; /** @@ -1091,6 +1095,7 @@ ve.init.mw.ArticleTarget.prototype.onSaveDialogPreview = function () { var wikitext, target = this; + if ( !this.saveDialog.$previewViewer.children().length ) { this.emit( 'savePreview' ); this.saveDialog.getActions().setAbilities( { approve: false } ); @@ -1108,7 +1113,9 @@ wikitext: wikitext, pst: true } ).always( function ( response, details ) { - var doc, body; + var doc, body, + baseDoc = target.getSurface().getModel().getDocument().getHtmlDocument(); + if ( ve.getProp( response, 'visualeditor', 'result' ) === 'success' ) { doc = target.parseDocument( response.visualeditor.content, 'visual' ); body = doc.body; @@ -1117,11 +1124,16 @@ // TODO: This code is very similar to ve.ui.PreviewElement ve.resolveAttributes( body, doc, ve.dm.Converter.static.computedAttributes ); ve.targetLinksToNewWindow( body ); - target.saveDialog.showPreview( $( body ).contents() ); + target.saveDialog.showPreview( $( body ).contents(), baseDoc ); + } else { - target.saveDialog.showPreview( $( '<em>' ).text( - ve.msg( 'visualeditor-loaderror-message', ve.getProp( details, 'error', 'info' ) || 'Failed to connect' ) - ) ); + target.saveDialog.showPreview( + $( '<em>' ).text( ve.msg( + 'visualeditor-loaderror-message', + ve.getProp( details, 'error', 'info' ) || 'Failed to connect' + ) ), + baseDoc + ); } target.bindSaveDialogClearDiff(); } ); @@ -1151,7 +1163,11 @@ */ ve.init.mw.ArticleTarget.prototype.onSaveDialogReviewComplete = function ( wikitext ) { this.bindSaveDialogClearDiff(); - this.saveDialog.setDiffAndReview( $( '<pre>' ).text( wikitext ), this.getVisualDiff() ); + this.saveDialog.setDiffAndReview( + $( '<pre>' ).text( wikitext ), + this.getVisualDiff(), + this.getSurface().getModel().getDocument().getHtmlDocument() + ); }; /** diff --git a/modules/ve-mw/init/ve.init.mw.LinkCache.js b/modules/ve-mw/init/ve.init.mw.LinkCache.js index 8e66490..772193d 100644 --- a/modules/ve-mw/init/ve.init.mw.LinkCache.js +++ b/modules/ve-mw/init/ve.init.mw.LinkCache.js @@ -100,6 +100,43 @@ }; /** + * Given a chunk of Parsoid HTML, requests information about each link's title, then adds classes + * to each such element as appropriate. + * + * TODO: Most/all of this code should be done upstream, either by Parsoid itself or by an + * intermediary service – see T64803 and others. + * + * @chainable + * @param {jQuery} $element Elements to style + * @param {HTMLDocument} doc Base document to use for normalisation + * @return {jQuery} The elements, now styled + */ +ve.init.mw.LinkCache.prototype.styleParsoidElements = function ( $elements, doc ) { + // TODO: Remove when fixed upstream in Parsoid (T58756) + $elements + .find( 'a[rel="mw:ExtLink"]' ).addBack( 'a[rel="mw:ExtLink"]' ) + .addClass( 'external' ); + + // TODO: Remove when moved upstream into Parsoid or another service (T64803) + // If the element isn't attached, doc will be null, so we don't know how to normalise titles + if ( doc ) { + $elements + .find( 'a[rel="mw:WikiLink"]' ).addBack( 'a[rel="mw:WikiLink"]' ) + .each( function () { + var title, + href = this.href || mw.config.get( 'wgArticlePath' ); + + title = ve.init.platform.linkCache.constructor.static.normalizeTitle( + ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref( href, doc ).title + ); + ve.init.platform.linkCache.styleElement( title, $( this ) ); + } ); + } + + return $elements; +}; + +/** * Enable or disable automatic assumption of existence. * * While enabled, any get() for a title that's not already in the cache will return diff --git a/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js b/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js index 249b223..ef5816b 100644 --- a/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js +++ b/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js @@ -120,15 +120,25 @@ * * @param {string} wikitextDiff Diff HTML or wikitext * @param {ve.dm.VisualDiff} [visualDiff] Visual diff + * @param {HTMLDocument} [baseDoc] Base document against which to normalise links when rendering visualDiff */ -ve.ui.MWSaveDialog.prototype.setDiffAndReview = function ( wikitextDiff, visualDiff ) { +ve.ui.MWSaveDialog.prototype.setDiffAndReview = function ( wikitextDiff, visualDiff, baseDoc ) { this.$reviewVisualDiff.empty(); if ( visualDiff ) { if ( this.diffElement ) { this.diffElement.destroy(); this.diffElement = null; } + // Don't generate the DiffElement until the tab is switched to + this.deferredDiffElement = function () { + var diffElement = new ve.ui.DiffElement( this.visualDiff ); + diffElement.$document.addClass( 'mw-body-content' ); + // Run styles so links render with their appropriate classes + ve.init.platform.linkCache.styleParsoidElements( diffElement.$document, baseDoc ); + return diffElement; + }; this.visualDiff = visualDiff; + this.baseDoc = baseDoc; this.reviewModeButtonSelect.getItemFromData( 'visual' ).setDisabled( false ); } else { // TODO: Support visual diffs in source mode (epic) @@ -147,12 +157,14 @@ * Set preview content and show preview panel. * * @param {jQuery} content Preview content + * @param {HTMLDocument} baseDoc Base document against which to normalise links */ -ve.ui.MWSaveDialog.prototype.showPreview = function ( content ) { +ve.ui.MWSaveDialog.prototype.showPreview = function ( content, baseDoc ) { this.$previewViewer.empty().append( content ); + // Run styles so links render with their appropriate classes + ve.init.platform.linkCache.styleParsoidElements( this.$previewViewer, baseDoc ); + // Run hooks so other things can alter the document mw.hook( 'wikipage.content' ).fire( this.$previewViewer ); - // TODO: Remove when fixed upstream in Parsoid (T58756) - this.$previewViewer.find( 'a[rel="mw:ExtLink"]' ).addClass( 'external' ); this.actions.setAbilities( { approve: true } ); this.popPending(); this.swapPanel( 'preview' ); @@ -596,17 +608,12 @@ this.$reviewWikitextDiff.toggleClass( 'oo-ui-element-hidden', isVisual ); if ( isVisual ) { if ( !this.diffElement ) { - this.diffElement = new ve.ui.DiffElement( this.visualDiff ); - this.diffElement.$document.addClass( 'mw-body-content' ); - // TODO: Remove when fixed upstream in Parsoid (T58756) - this.diffElement.$element.find( 'a[rel="mw:ExtLink"]' ).addClass( 'external' ); + this.diffElement = this.deferredDiffElement(); this.$reviewVisualDiff.append( this.diffElement.$element ); } this.diffElement.positionDescriptions(); - this.updateSize(); - } else { - this.updateSize(); } + this.updateSize(); }; /** diff --git a/modules/ve-mw/ui/elements/ve.ui.MWPreviewElement.js b/modules/ve-mw/ui/elements/ve.ui.MWPreviewElement.js index 6d39533..35bba67 100644 --- a/modules/ve-mw/ui/elements/ve.ui.MWPreviewElement.js +++ b/modules/ve-mw/ui/elements/ve.ui.MWPreviewElement.js @@ -36,6 +36,9 @@ // Parent method ve.ui.MWPreviewElement.super.prototype.replaceWithModelDom.apply( this, arguments ); - // TODO: Remove when fixed upstream in Parsoid (T58756) - this.$element.find( 'a[rel="mw:ExtLink"]' ).addClass( 'external' ); + ve.init.platform.linkCache.styleParsoidElements( + this.$element, + // The DM node should be attached, but check just in case. + this.model.getDocument() && this.model.getDocument().getHtmlDocument() + ); }; -- To view, visit https://gerrit.wikimedia.org/r/345607 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ieb9a0274b8c5ae1932c431546f09d18000fa6dd9 Gerrit-PatchSet: 4 Gerrit-Project: mediawiki/extensions/VisualEditor Gerrit-Branch: master Gerrit-Owner: Jforrester <jforres...@wikimedia.org> Gerrit-Reviewer: Bartosz Dziewoński <matma....@gmail.com> Gerrit-Reviewer: Esanders <esand...@wikimedia.org> Gerrit-Reviewer: Jforrester <jforres...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits