mediawiki-extensions-Visual.../modules/ve-mw/ui/contextitems/ve.ui.MWDefinedTransclusionContextItem.js
Ed Sanders dbc696124f ESLint: Enforce no-var and autofix
Temporarily disable prefer-const as this requires
manual fixing.

Change-Id: I477b69a57e8d33535c6fc71dba196a8605780725
2024-05-21 17:40:52 +01:00

147 lines
4.2 KiB
JavaScript

/*!
* VisualEditor MWDefinedTransclusionContextItem class.
*
* @copyright See AUTHORS.txt
*/
/**
* Context item for a defined MWTransclusion.
*
* Templates are defined on-wiki using the message page
* [[MediaWiki:Visualeditor-template-tools-definition.json]]
*
* Example:
* {
* // This key is the static name of the ve.ui.ContextItem
* "citationNeeded": [
* {
* // Normalized title string, or list of strings (for redirects)
* "title": [ "Citation needed", "cn" ],
* // Extra params. This whole object can be accessed
* // via #getMatchedTool
* "params": {
* "reason": "reason",
* "date": "date"
* }
* },
* {
* "title": "Cite quote",
* "params": {
* "date": "date"
* }
* }
* ]
* }
*
* @class
* @abstract
* @extends ve.ui.MWTransclusionContextItem
*
* @constructor
* @param {ve.ui.LinearContext} context Context the item is in
* @param {ve.dm.Model} model Model the item is related to
* @param {Object} [config]
*/
ve.ui.MWDefinedTransclusionContextItem = function VeUiMWDefinedTransclusionContextItem() {
// Parent constructor
ve.ui.MWDefinedTransclusionContextItem.super.apply( this, arguments );
this.tool = this.constructor.static.getMatchedTool( this.model );
};
/* Inheritance */
OO.inheritClass( ve.ui.MWDefinedTransclusionContextItem, ve.ui.MWTransclusionContextItem );
/* Static Properties */
ve.ui.MWDefinedTransclusionContextItem.static.name = null;
ve.ui.MWDefinedTransclusionContextItem.static.toolDefinitions = ( function () {
let tools;
try {
// Must use mw.message to avoid JSON being parsed as Wikitext
tools = JSON.parse( mw.message( 'visualeditor-template-tools-definition.json' ).plain() );
} catch ( e ) {}
return tools || {};
}() );
/**
* Only display item for single-template transclusions of these templates.
*
* @property {string|string[]|null}
* @static
* @inheritable
*/
ve.ui.MWDefinedTransclusionContextItem.static.template = null;
/* Static Methods */
/**
* @inheritdoc
*/
ve.ui.MWDefinedTransclusionContextItem.static.isCompatibleWith = function ( model ) {
// Parent method
return ve.ui.MWDefinedTransclusionContextItem.super.static.isCompatibleWith.apply( this, arguments ) &&
!!this.getMatchedTool( model );
};
/**
* Get tool definitions, indexed by normalized title
*
* @return {Object} Collection of tool definitions
*/
ve.ui.MWDefinedTransclusionContextItem.static.getToolsByTitle = function () {
if ( !this.toolsByTitle ) {
let toolsByTitle;
this.toolsByTitle = toolsByTitle = {};
( this.toolDefinitions[ this.name ] || [] ).forEach( ( template ) => {
const titles = Array.isArray( template.title ) ? template.title : [ template.title ];
// 'title' can be a single title, or list of titles (including redirects)
titles.forEach( ( title ) => {
toolsByTitle[ mw.Title.newFromText( title, mw.config.get( 'wgNamespaceIds' ).template ).getPrefixedText() ] = template;
} );
} );
}
return this.toolsByTitle;
};
/**
* Get the tool definition that matches a specific model, if any
*
* @param {ve.dm.Model} model
* @return {Object|null} Tool definition, or null if no match
*/
ve.ui.MWDefinedTransclusionContextItem.static.getMatchedTool = function ( model ) {
const resource = ve.getProp( model.getAttribute( 'mw' ), 'parts', 0, 'template', 'target', 'href' );
if ( resource ) {
const title = mw.Title.newFromText( mw.libs.ve.normalizeParsoidResourceName( resource ) ).getPrefixedText();
return this.getToolsByTitle()[ title ] || null;
}
return null;
};
/**
* Get a template param using its canonical name
*
* @param {string} name Canonical parameter name
* @return {string|null} Param wikitext, null if not found
*/
ve.ui.MWDefinedTransclusionContextItem.prototype.getCanonicalParam = function ( name ) {
const params = this.tool.params || {};
if ( Object.prototype.hasOwnProperty.call( params, name ) ) {
const aliases = Array.isArray( params[ name ] ) ? params[ name ] : [ params[ name ] ];
// Find the first non-empty value from the alias list
for ( let i = 0; i < aliases.length; i++ ) {
const value = ve.getProp( this.model.getAttribute( 'mw' ), 'parts', 0, 'template', 'params', aliases[ i ], 'wt' );
if ( value ) {
return value;
}
}
}
return null;
};