Merge "MWSaveDialog: Run links through a render function for preview & visual diff"

This commit is contained in:
jenkins-bot 2017-04-01 15:22:08 +00:00 committed by Gerrit Code Review
commit c599a82fe8
6 changed files with 108 additions and 36 deletions

View file

@ -85,6 +85,22 @@ ve.ce.MWExtensionNode.prototype.generateContents = function ( config ) {
}
};
/**
* @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.
*

View file

@ -191,24 +191,17 @@ ve.ce.MWTransclusionNode.prototype.onSetup = function () {
/**
* @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;
};
/**

View file

@ -744,7 +744,11 @@ ve.init.mw.ArticleTarget.prototype.showChangesDiff = function ( diffHtml ) {
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.onSaveDialogReview = function () {
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 @@ ve.init.mw.ArticleTarget.prototype.onSaveDialogPreview = function () {
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 @@ ve.init.mw.ArticleTarget.prototype.onSaveDialogPreview = function () {
// 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.bindSaveDialogClearDiff = function () {
*/
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()
);
};
/**

View file

@ -99,6 +99,43 @@ ve.init.mw.LinkCache.prototype.styleElement = function ( title, $element ) {
} );
};
/**
* 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.
*

View file

@ -120,15 +120,25 @@ ve.ui.MWSaveDialog.static.actions = [
*
* @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 @@ ve.ui.MWSaveDialog.prototype.setDiffAndReview = function ( wikitextDiff, visualD
* 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 @@ ve.ui.MWSaveDialog.prototype.updateReviewMode = function () {
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();
};
/**

View file

@ -36,6 +36,9 @@ ve.ui.MWPreviewElement.prototype.replaceWithModelDom = function () {
// 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()
);
};