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

Reply via email to