From 30b0f10c2791bf6fafc3afdf777b84465904b19a Mon Sep 17 00:00:00 2001 From: Ed Sanders Date: Mon, 20 Feb 2023 15:33:52 +0000 Subject: [PATCH] Template context: Link to source templates in "Generated from:" list Bug: T328021 Change-Id: I0960f4033f99813ac761daf69abf437b00e7d3f0 --- .../ce/nodes/ve.ce.MWTransclusionNode.js | 38 +++++++++++++++++++ .../ve.ui.MWTransclusionContextItem.js | 13 +++++++ 2 files changed, 51 insertions(+) diff --git a/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js b/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js index 52408847e3..3e1af6a2d0 100644 --- a/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js +++ b/modules/ve-mw/ce/nodes/ve.ce.MWTransclusionNode.js @@ -68,6 +68,44 @@ ve.ce.MWTransclusionNode.static.getDescription = function ( model ) { .join( ve.msg( 'comma-separator' ) ); }; +/** + * Get a formatted description of the template parts in a transclusion node, excluding raw wikitext + * snippets. + * + * Like #getDescription, but parts generated from templates are linked to + * those templates + * + * @static + * @param {ve.dm.MWTransclusionNode} model + * @return {HTMLElement} DOM node with comma-separated list of template names + */ +ve.ce.MWTransclusionNode.static.getDescriptionDom = function ( model ) { + var nodes = model.getPartsList() + .map( function ( part ) { + if ( part.templatePage ) { + var title = mw.Title.newFromText( part.templatePage ); + var link = document.createElement( 'a' ); + link.textContent = title.getRelativeText( mw.config.get( 'wgNamespaceIds' ).template ); + link.setAttribute( 'href', title.getUrl() ); + return link; + } + // Not actually a template, but e.g. a parser function + return part.template ? document.createTextNode( part.template ) : null; + } ) + .filter( function ( desc ) { + return desc; + } ); + var span = document.createElement( 'span' ); + nodes.forEach( function ( node, i ) { + if ( i ) { + span.appendChild( document.createTextNode( ve.msg( 'comma-separator' ) ) ); + } + span.appendChild( node ); + } ); + ve.targetLinksToNewWindow( span ); + return span; +}; + /** * Filter rendering to remove auto-generated content and wrappers * diff --git a/modules/ve-mw/ui/contextitems/ve.ui.MWTransclusionContextItem.js b/modules/ve-mw/ui/contextitems/ve.ui.MWTransclusionContextItem.js index f80c1639cb..64260e2cfd 100644 --- a/modules/ve-mw/ui/contextitems/ve.ui.MWTransclusionContextItem.js +++ b/modules/ve-mw/ui/contextitems/ve.ui.MWTransclusionContextItem.js @@ -76,6 +76,19 @@ ve.ui.MWTransclusionContextItem.prototype.getDescription = function () { ); }; +/** + * @inheritdoc + */ +ve.ui.MWTransclusionContextItem.prototype.renderBody = function () { + var nodeClass = ve.ce.nodeFactory.lookup( this.model.constructor.static.name ); + // eslint-disable-next-line no-jquery/no-append-html + this.$body.append( ve.htmlMsg( + 'visualeditor-dialog-transclusion-contextitem-description', + nodeClass.static.getDescriptionDom( this.model ), + this.model.getPartsList().length + ) ); +}; + /** * @param {string} [source] Source for tracking in {@see ve.ui.WindowAction.open} */