eslint: Enforce no-var

Change-Id: Iadb18597cacaa2849b65c32afb54ec3b15fe09dc
This commit is contained in:
Ed Sanders 2024-09-16 16:00:27 +01:00
parent 4ab9e38274
commit 7b3ee1d90b
13 changed files with 376 additions and 386 deletions

View file

@ -9,7 +9,6 @@
"wikimedia/mediawiki" "wikimedia/mediawiki"
], ],
"rules": { "rules": {
"max-len": "off", "max-len": "off"
"no-var": "off"
} }
} }

View file

@ -106,7 +106,7 @@ Model.static.translateObsoleteParamTypes = function ( paramType ) {
* definition data * definition data
*/ */
Model.static.getAllProperties = function ( getFullData ) { Model.static.getAllProperties = function ( getFullData ) {
var properties = { const properties = {
name: { name: {
type: 'string', type: 'string',
// Validation regex // Validation regex
@ -197,10 +197,10 @@ Model.static.getAllProperties = function ( getFullData ) {
* @return {string[]} Property names * @return {string[]} Property names
*/ */
Model.static.getPropertiesWithLanguage = function () { Model.static.getPropertiesWithLanguage = function () {
var result = [], const result = [],
propDefinitions = this.getAllProperties( true ); propDefinitions = this.getAllProperties( true );
for ( var prop in propDefinitions ) { for ( const prop in propDefinitions ) {
if ( propDefinitions[ prop ].allowLanguages ) { if ( propDefinitions[ prop ].allowLanguages ) {
result.push( prop ); result.push( prop );
} }
@ -218,9 +218,9 @@ Model.static.getPropertiesWithLanguage = function () {
Model.static.splitAndTrimArray = function ( str, delim ) { Model.static.splitAndTrimArray = function ( str, delim ) {
delim = delim || mw.msg( 'comma-separator' ); delim = delim || mw.msg( 'comma-separator' );
var arr = []; const arr = [];
str.split( delim ).forEach( ( part ) => { str.split( delim ).forEach( ( part ) => {
var trimmed = part.trim(); const trimmed = part.trim();
if ( trimmed ) { if ( trimmed ) {
arr.push( trimmed ); arr.push( trimmed );
} }
@ -237,7 +237,7 @@ Model.static.splitAndTrimArray = function ( str, delim ) {
* @return {Array} Union of the arrays * @return {Array} Union of the arrays
*/ */
Model.static.arrayUnionWithoutEmpty = function () { Model.static.arrayUnionWithoutEmpty = function () {
var result = OO.simpleArrayUnion.apply( this, arguments ); const result = OO.simpleArrayUnion.apply( this, arguments );
// Trim and filter empty strings // Trim and filter empty strings
return result.filter( ( i ) => i.trim() ); return result.filter( ( i ) => i.trim() );
@ -251,7 +251,7 @@ Model.static.arrayUnionWithoutEmpty = function () {
* @return {Model} New model * @return {Model} New model
*/ */
Model.static.newFromObject = function ( tdObject, paramsInSource ) { Model.static.newFromObject = function ( tdObject, paramsInSource ) {
var model = new Model(); const model = new Model();
model.setSourceCodeParameters( paramsInSource || [] ); model.setSourceCodeParameters( paramsInSource || [] );
@ -265,7 +265,7 @@ Model.static.newFromObject = function ( tdObject, paramsInSource ) {
// Add params // Add params
if ( tdObject.params ) { if ( tdObject.params ) {
for ( var param in tdObject.params ) { for ( const param in tdObject.params ) {
model.addParam( param, tdObject.params[ param ] ); model.addParam( param, tdObject.params[ param ] );
} }
} }
@ -300,7 +300,7 @@ Model.static.newFromObject = function ( tdObject, paramsInSource ) {
* the model * the model
*/ */
Model.prototype.getMissingParams = function () { Model.prototype.getMissingParams = function () {
var allParamNames = this.getAllParamNames(), const allParamNames = this.getAllParamNames(),
sourceCodeParameters = this.sourceCodeParameters; sourceCodeParameters = this.sourceCodeParameters;
return sourceCodeParameters.filter( ( sourceCodeParameter ) => allParamNames.indexOf( sourceCodeParameter ) === -1 ); return sourceCodeParameters.filter( ( sourceCodeParameter ) => allParamNames.indexOf( sourceCodeParameter ) === -1 );
@ -312,7 +312,7 @@ Model.prototype.getMissingParams = function () {
* @return {Object} Parameters added. -1 for failure. * @return {Object} Parameters added. -1 for failure.
*/ */
Model.prototype.importSourceCodeParameters = function () { Model.prototype.importSourceCodeParameters = function () {
var model = this, const model = this,
allParamNames = this.getAllParamNames(), allParamNames = this.getAllParamNames(),
existingArray = [], existingArray = [],
importedArray = [], importedArray = [],
@ -348,18 +348,18 @@ Model.prototype.importSourceCodeParameters = function () {
* @return {string[]} Language codes in use * @return {string[]} Language codes in use
*/ */
Model.prototype.getExistingLanguageCodes = function () { Model.prototype.getExistingLanguageCodes = function () {
var result = []; let result = [];
// Take languages from the template description // Take languages from the template description
if ( $.isPlainObject( this.description ) ) { if ( $.isPlainObject( this.description ) ) {
result = Object.keys( this.description ); result = Object.keys( this.description );
} }
var languageProps = this.constructor.static.getPropertiesWithLanguage(); const languageProps = this.constructor.static.getPropertiesWithLanguage();
// Go over the parameters // Go over the parameters
for ( var param in this.params ) { for ( const param in this.params ) {
// Go over the properties // Go over the properties
for ( var prop in this.params[ param ] ) { for ( const prop in this.params[ param ] ) {
if ( languageProps.indexOf( prop ) !== -1 ) { if ( languageProps.indexOf( prop ) !== -1 ) {
result = this.constructor.static.arrayUnionWithoutEmpty( result, Object.keys( this.params[ param ][ prop ] ) ); result = this.constructor.static.arrayUnionWithoutEmpty( result, Object.keys( this.params[ param ][ prop ] ) );
} }
@ -378,8 +378,8 @@ Model.prototype.getExistingLanguageCodes = function () {
* @fires change * @fires change
*/ */
Model.prototype.addParam = function ( name, paramData ) { Model.prototype.addParam = function ( name, paramData ) {
var data = $.extend( true, {}, paramData ); const data = $.extend( true, {}, paramData );
var key = this.getNewValidParameterKey( name ); const key = this.getNewValidParameterKey( name );
// Initialize // Initialize
this.params[ key ] = { name: name }; this.params[ key ] = { name: name };
@ -402,11 +402,11 @@ Model.prototype.addParam = function ( name, paramData ) {
// Go over the rest of the data // Go over the rest of the data
if ( data ) { if ( data ) {
var language = this.getDefaultLanguage(); const language = this.getDefaultLanguage();
var propertiesWithLanguage = this.constructor.static.getPropertiesWithLanguage(); const propertiesWithLanguage = this.constructor.static.getPropertiesWithLanguage();
var allProps = this.constructor.static.getAllProperties( true ); const allProps = this.constructor.static.getAllProperties( true );
for ( var prop in data ) { for ( const prop in data ) {
var propToSet = prop; let propToSet = prop;
if ( if (
// This is to make sure that forwards compatibility is achieved // This is to make sure that forwards compatibility is achieved
// and the code doesn't die on properties that aren't valid // and the code doesn't die on properties that aren't valid
@ -432,7 +432,7 @@ Model.prototype.addParam = function ( name, paramData ) {
$.isPlainObject( data[ prop ] ) $.isPlainObject( data[ prop ] )
) { ) {
// Add all language properties // Add all language properties
for ( var lang in data[ prop ] ) { for ( const lang in data[ prop ] ) {
this.setParamProperty( key, propToSet, data[ prop ], lang ); this.setParamProperty( key, propToSet, data[ prop ], lang );
} }
} else { } else {
@ -456,9 +456,9 @@ Model.prototype.addParam = function ( name, paramData ) {
* @return {string[]} Used parameter names * @return {string[]} Used parameter names
*/ */
Model.prototype.getAllParamNames = function () { Model.prototype.getAllParamNames = function () {
var result = []; let result = [];
for ( var key in this.params ) { for ( const key in this.params ) {
var param = this.params[ key ]; const param = this.params[ key ];
result.push( param.name ); result.push( param.name );
if ( param.aliases ) { if ( param.aliases ) {
result = result.concat( param.aliases ); result = result.concat( param.aliases );
@ -618,7 +618,7 @@ Model.prototype.addKeyTemplateParamOrder = function ( key ) {
* @fires change * @fires change
*/ */
Model.prototype.reorderParamOrderKey = function ( key, newIndex ) { Model.prototype.reorderParamOrderKey = function ( key, newIndex ) {
var keyIndex = this.paramOrder.indexOf( key ); const keyIndex = this.paramOrder.indexOf( key );
// Move the parameter, account for left shift if moving forwards // Move the parameter, account for left shift if moving forwards
this.paramOrder.splice( this.paramOrder.splice(
newIndex - ( newIndex > keyIndex ? 1 : 0 ), newIndex - ( newIndex > keyIndex ? 1 : 0 ),
@ -641,7 +641,7 @@ Model.prototype.reorderParamOrderKey = function ( key, newIndex ) {
* @fires change * @fires change
*/ */
Model.prototype.removeKeyTemplateParamOrder = function ( key ) { Model.prototype.removeKeyTemplateParamOrder = function ( key ) {
var keyPos = this.paramOrder.indexOf( key ); const keyPos = this.paramOrder.indexOf( key );
if ( keyPos > -1 ) { if ( keyPos > -1 ) {
this.paramOrder.splice( keyPos, 1 ); this.paramOrder.splice( keyPos, 1 );
this.emit( 'change-paramOrder', this.paramOrder ); this.emit( 'change-paramOrder', this.paramOrder );
@ -679,8 +679,8 @@ Model.prototype.getTemplateFormat = function () {
* @fires change * @fires change
*/ */
Model.prototype.setParamProperty = function ( paramKey, prop, value, language ) { Model.prototype.setParamProperty = function ( paramKey, prop, value, language ) {
var allProps = this.constructor.static.getAllProperties( true ), const allProps = this.constructor.static.getAllProperties( true );
status = false; let status = false;
language = language || this.getDefaultLanguage(); language = language || this.getDefaultLanguage();
if ( !allProps[ prop ] ) { if ( !allProps[ prop ] ) {
@ -688,7 +688,7 @@ Model.prototype.setParamProperty = function ( paramKey, prop, value, language )
return status; return status;
} }
var propertiesWithLanguage = this.constructor.static.getPropertiesWithLanguage(); const propertiesWithLanguage = this.constructor.static.getPropertiesWithLanguage();
// Check if the property is split by language code // Check if the property is split by language code
if ( propertiesWithLanguage.indexOf( prop ) !== -1 ) { if ( propertiesWithLanguage.indexOf( prop ) !== -1 ) {
// Initialize property if necessary // Initialize property if necessary
@ -706,10 +706,10 @@ Model.prototype.setParamProperty = function ( paramKey, prop, value, language )
} else { } else {
// Compare without language // Compare without language
if ( !this.constructor.static.compare( this.params[ paramKey ][ prop ], value ) ) { if ( !this.constructor.static.compare( this.params[ paramKey ][ prop ], value ) ) {
var oldValue = this.params[ paramKey ][ prop ]; const oldValue = this.params[ paramKey ][ prop ];
this.params[ paramKey ][ prop ] = value; this.params[ paramKey ][ prop ] = value;
var newKey = value; let newKey = value;
if ( prop === 'name' && oldValue !== value ) { if ( prop === 'name' && oldValue !== value ) {
// See if the parameters already has something with this new key // See if the parameters already has something with this new key
if ( this.params[ newKey ] && !this.params[ newKey ].deleted ) { if ( this.params[ newKey ] && !this.params[ newKey ].deleted ) {
@ -886,13 +886,13 @@ Model.prototype.getOriginalTemplateDataObject = function () {
* @return {Object} Templatedata object * @return {Object} Templatedata object
*/ */
Model.prototype.outputTemplateData = function () { Model.prototype.outputTemplateData = function () {
var allProps = this.constructor.static.getAllProperties( true ), const allProps = this.constructor.static.getAllProperties( true ),
original = this.getOriginalTemplateDataObject() || {}; original = this.getOriginalTemplateDataObject() || {};
original.params = original.params || {}; original.params = original.params || {};
var result = $.extend( true, {}, original ), const result = $.extend( true, {}, original ),
defaultLang = this.getDefaultLanguage(); defaultLang = this.getDefaultLanguage();
var normalizedValue; let normalizedValue;
// Template description // Template description
if ( this.description[ defaultLang ] !== undefined ) { if ( this.description[ defaultLang ] !== undefined ) {
normalizedValue = this.propRemoveUnusedLanguages( this.description ); normalizedValue = this.propRemoveUnusedLanguages( this.description );
@ -935,8 +935,8 @@ Model.prototype.outputTemplateData = function () {
} }
// Go over parameters in data // Go over parameters in data
for ( var paramKey in this.params ) { for ( const paramKey in this.params ) {
var key = paramKey; const key = paramKey;
if ( this.params[ key ].deleted ) { if ( this.params[ key ].deleted ) {
delete result.params[ key ]; delete result.params[ key ];
continue; continue;
@ -949,8 +949,8 @@ Model.prototype.outputTemplateData = function () {
} }
// Check if name was changed and change the key accordingly // Check if name was changed and change the key accordingly
var name = this.params[ key ].name; const name = this.params[ key ].name;
var oldKey = key; const oldKey = key;
// Notice for clarity: // Notice for clarity:
// Whether the parameter name was changed or not the following // Whether the parameter name was changed or not the following
@ -966,7 +966,7 @@ Model.prototype.outputTemplateData = function () {
} }
// Go over all properties // Go over all properties
for ( var prop in allProps ) { for ( const prop in allProps ) {
if ( prop === 'status' || prop === 'deprecatedValue' || prop === 'name' ) { if ( prop === 'status' || prop === 'deprecatedValue' || prop === 'name' ) {
continue; continue;
} }
@ -1021,7 +1021,7 @@ Model.prototype.outputTemplateData = function () {
default: default:
// Check if there's a value in the model // Check if there's a value in the model
if ( this.params[ key ][ prop ] !== undefined ) { if ( this.params[ key ][ prop ] !== undefined ) {
var compareOrig = original.params[ oldKey ] && original.params[ oldKey ][ prop ]; const compareOrig = original.params[ oldKey ] && original.params[ oldKey ][ prop ];
if ( allProps[ prop ].allowLanguages ) { if ( allProps[ prop ].allowLanguages ) {
normalizedValue = this.propRemoveUnusedLanguages( this.params[ key ][ prop ] ); normalizedValue = this.propRemoveUnusedLanguages( this.params[ key ][ prop ] );
// Check if this should be displayed with language object or directly as string // Check if this should be displayed with language object or directly as string
@ -1073,9 +1073,9 @@ Model.prototype.getNewValidParameterKey = function ( key ) {
* @return {Object} Property data with only used language keys * @return {Object} Property data with only used language keys
*/ */
Model.prototype.propRemoveUnusedLanguages = function ( propData ) { Model.prototype.propRemoveUnusedLanguages = function ( propData ) {
var result = {}; const result = {};
if ( $.isPlainObject( propData ) ) { if ( $.isPlainObject( propData ) ) {
for ( var key in propData ) { for ( const key in propData ) {
if ( propData[ key ] ) { if ( propData[ key ] ) {
result[ key ] = propData[ key ]; result[ key ] = propData[ key ];
} }

View file

@ -1,4 +1,4 @@
var Model = require( './Model.js' ); const Model = require( './Model.js' );
/** /**
* TemplateData Source Handler * TemplateData Source Handler
@ -43,7 +43,7 @@ OO.mixinClass( SourceHandler, OO.EventEmitter );
* @return {jQuery.Promise} API promise * @return {jQuery.Promise} API promise
*/ */
SourceHandler.prototype.getApi = function ( page, getTemplateData ) { SourceHandler.prototype.getApi = function ( page, getTemplateData ) {
var type = getTemplateData ? 'templatedata' : 'query', const type = getTemplateData ? 'templatedata' : 'query',
api = new mw.Api(), api = new mw.Api(),
baseConfig = { baseConfig = {
action: type, action: type,
@ -51,7 +51,7 @@ SourceHandler.prototype.getApi = function ( page, getTemplateData ) {
redirects: getTemplateData ? 1 : 0 redirects: getTemplateData ? 1 : 0
}; };
var config; let config;
if ( type === 'query' ) { if ( type === 'query' ) {
config = Object.assign( baseConfig, { config = Object.assign( baseConfig, {
prop: 'revisions', prop: 'revisions',
@ -76,9 +76,9 @@ SourceHandler.prototype.getApi = function ( page, getTemplateData ) {
* or is rejected if the model was impossible to create. * or is rejected if the model was impossible to create.
*/ */
SourceHandler.prototype.buildModel = function ( wikitext ) { SourceHandler.prototype.buildModel = function ( wikitext ) {
var tdObject = null, const templateDataString = this.findModelInString( wikitext );
templateDataString = this.findModelInString( wikitext );
let tdObject = null;
if ( templateDataString !== null ) { if ( templateDataString !== null ) {
try { try {
tdObject = JSON.parse( templateDataString ); tdObject = JSON.parse( templateDataString );
@ -114,9 +114,9 @@ SourceHandler.prototype.buildModel = function ( wikitext ) {
* @return {jQuery.Promise} Promise resolving into template parameter array * @return {jQuery.Promise} Promise resolving into template parameter array
*/ */
SourceHandler.prototype.getParametersFromTemplateSource = function ( wikitext ) { SourceHandler.prototype.getParametersFromTemplateSource = function ( wikitext ) {
var params = [], const sourceHandler = this;
sourceHandler = this;
let params = [];
if ( !this.templateSourceCodePromise ) { if ( !this.templateSourceCodePromise ) {
// Check given page text first // Check given page text first
if ( wikitext ) { if ( wikitext ) {
@ -130,7 +130,7 @@ SourceHandler.prototype.getParametersFromTemplateSource = function ( wikitext )
// Get the content of the parent // Get the content of the parent
this.templateSourceCodePromise = this.getApi( this.getParentPage() ).then( this.templateSourceCodePromise = this.getApi( this.getParentPage() ).then(
( resp ) => { ( resp ) => {
var pageContent = ''; let pageContent = '';
// Verify that we have a sane response from the API. // Verify that we have a sane response from the API.
// This is particularly important for unit tests, since the // This is particularly important for unit tests, since the
@ -165,7 +165,7 @@ SourceHandler.prototype.getParametersFromTemplateSource = function ( wikitext )
* @return {string[]} An array of parameters that appear in the template code * @return {string[]} An array of parameters that appear in the template code
*/ */
SourceHandler.prototype.extractParametersFromTemplateCode = function ( templateCode ) { SourceHandler.prototype.extractParametersFromTemplateCode = function ( templateCode ) {
var paramNames = [], const paramNames = [],
normalizedParamNames = [], normalizedParamNames = [],
// This regex matches the one in TemplateDataBlob.php // This regex matches the one in TemplateDataBlob.php
paramExtractor = /{{{+([^\n#={|}]*?)([<|]|}}})/mg; paramExtractor = /{{{+([^\n#={|}]*?)([<|]|}}})/mg;
@ -175,10 +175,10 @@ SourceHandler.prototype.extractParametersFromTemplateCode = function ( templateC
.replace( /<nowiki\s*>[\s\S]*?<\/nowiki\s*>/g, '' ) .replace( /<nowiki\s*>[\s\S]*?<\/nowiki\s*>/g, '' )
.replace( /<pre\s*>[\s\S]*?<\/pre\s*>/g, '' ); .replace( /<pre\s*>[\s\S]*?<\/pre\s*>/g, '' );
var matches; let matches;
while ( ( matches = paramExtractor.exec( templateCode ) ) !== null ) { while ( ( matches = paramExtractor.exec( templateCode ) ) !== null ) {
// This normalization process is repeated in PHP in TemplateDataBlob.php // This normalization process is repeated in PHP in TemplateDataBlob.php
var normalizedParamName = matches[ 1 ].replace( /[-_ ]+/, ' ' ).trim().toLowerCase(); const normalizedParamName = matches[ 1 ].replace( /[-_ ]+/, ' ' ).trim().toLowerCase();
if ( !normalizedParamName || normalizedParamNames.indexOf( normalizedParamName ) !== -1 ) { if ( !normalizedParamName || normalizedParamNames.indexOf( normalizedParamName ) !== -1 ) {
continue; continue;
} }
@ -199,7 +199,7 @@ SourceHandler.prototype.extractParametersFromTemplateCode = function ( templateC
* templatedata string was found. * templatedata string was found.
*/ */
SourceHandler.prototype.findModelInString = function ( templateDataString ) { SourceHandler.prototype.findModelInString = function ( templateDataString ) {
var parts = templateDataString.match( const parts = templateDataString.match(
/<templatedata>([\s\S]*?)<\/templatedata>/i /<templatedata>([\s\S]*?)<\/templatedata>/i
); );

View file

@ -1,4 +1,4 @@
var Model = require( './Model.js' ), const Model = require( './Model.js' ),
SourceHandler = require( './SourceHandler.js' ); SourceHandler = require( './SourceHandler.js' );
module.exports = { module.exports = {

View file

@ -1,4 +1,4 @@
var const
LanguageSearchWidget = require( './widgets/LanguageSearchWidget.js' ), LanguageSearchWidget = require( './widgets/LanguageSearchWidget.js' ),
Metrics = require( './Metrics.js' ), Metrics = require( './Metrics.js' ),
Model = require( 'ext.templateDataGenerator.data' ).Model, Model = require( 'ext.templateDataGenerator.data' ).Model,
@ -131,7 +131,7 @@ Dialog.prototype.initialize = function () {
flags: [ 'progressive', 'primary' ], flags: [ 'progressive', 'primary' ],
disabled: true disabled: true
} ); } );
var addParamFieldlayout = new OO.ui.ActionFieldLayout( const addParamFieldlayout = new OO.ui.ActionFieldLayout(
this.newParamInput, this.newParamInput,
this.addParamButton, this.addParamButton,
{ {
@ -180,27 +180,27 @@ Dialog.prototype.initialize = function () {
this.mapsGroup = new OO.ui.OutlineSelectWidget( { this.mapsGroup = new OO.ui.OutlineSelectWidget( {
classes: [ 'mw-templateData-template-map-group' ] classes: [ 'mw-templateData-template-map-group' ]
} ); } );
var addNewMapButtonPanel = new OO.ui.PanelLayout( { const addNewMapButtonPanel = new OO.ui.PanelLayout( {
classes: [ 'mw-templateData-template-add-map-button-panel' ], classes: [ 'mw-templateData-template-add-map-button-panel' ],
padded: true, padded: true,
expanded: true expanded: true
} ); } );
var mapsListPanel = new OO.ui.PanelLayout( { const mapsListPanel = new OO.ui.PanelLayout( {
expanded: true, expanded: true,
scrollable: true scrollable: true
} ); } );
var mapsListMenuLayout = new OO.ui.MenuLayout( { const mapsListMenuLayout = new OO.ui.MenuLayout( {
classes: [ 'mw-templateData-template-map-list-menu-panel' ], classes: [ 'mw-templateData-template-map-list-menu-panel' ],
menuPosition: 'top', menuPosition: 'top',
expanded: true, expanded: true,
contentPanel: mapsListPanel, contentPanel: mapsListPanel,
menuPanel: addNewMapButtonPanel menuPanel: addNewMapButtonPanel
} ); } );
var mapsContentPanel = new OO.ui.PanelLayout( { const mapsContentPanel = new OO.ui.PanelLayout( {
padded: true, padded: true,
expanded: true expanded: true
} ); } );
var templateMapsMenuLayout = new OO.ui.MenuLayout( { const templateMapsMenuLayout = new OO.ui.MenuLayout( {
contentPanel: mapsContentPanel, contentPanel: mapsContentPanel,
menuPanel: mapsListMenuLayout menuPanel: mapsListMenuLayout
} ); } );
@ -212,7 +212,7 @@ Dialog.prototype.initialize = function () {
flags: [ 'progressive' ] flags: [ 'progressive' ]
} ); } );
var languageActionFieldLayout = new OO.ui.ActionFieldLayout( const languageActionFieldLayout = new OO.ui.ActionFieldLayout(
this.languageDropdownWidget, this.languageDropdownWidget,
this.languagePanelButton, this.languagePanelButton,
{ {
@ -237,7 +237,7 @@ Dialog.prototype.initialize = function () {
this.paramSelect = new ParamSelectWidget(); this.paramSelect = new ParamSelectWidget();
this.paramImport = new ParamImportWidget(); this.paramImport = new ParamImportWidget();
var templateParamsFieldset = new OO.ui.FieldsetLayout( { const templateParamsFieldset = new OO.ui.FieldsetLayout( {
label: mw.msg( 'templatedata-modal-title-templateparams' ), label: mw.msg( 'templatedata-modal-title-templateparams' ),
items: [ this.paramSelect, this.paramImport ] items: [ this.paramSelect, this.paramImport ]
} ); } );
@ -268,7 +268,7 @@ Dialog.prototype.initialize = function () {
placeholder: mw.msg( 'templatedata-modal-format-placeholder' ) placeholder: mw.msg( 'templatedata-modal-format-placeholder' )
} ); } );
var templateFormatFieldSet = new OO.ui.FieldsetLayout( { const templateFormatFieldSet = new OO.ui.FieldsetLayout( {
label: mw.msg( 'templatedata-modal-title-templateformat' ), label: mw.msg( 'templatedata-modal-title-templateformat' ),
items: [ items: [
new OO.ui.FieldLayout( this.templateFormatSelectWidget ), new OO.ui.FieldLayout( this.templateFormatSelectWidget ),
@ -397,7 +397,7 @@ Dialog.prototype.onModelChangeDescription = function ( description ) {
* @param {Object|undefined} map * @param {Object|undefined} map
*/ */
Dialog.prototype.onModelChangeMapInfo = function ( map ) { Dialog.prototype.onModelChangeMapInfo = function ( map ) {
var selectedItem = this.mapsGroup.findSelectedItem(); const selectedItem = this.mapsGroup.findSelectedItem();
map = map || {}; map = map || {};
this.mapsCache = OO.copy( map ); this.mapsCache = OO.copy( map );
if ( selectedItem ) { if ( selectedItem ) {
@ -411,11 +411,11 @@ Dialog.prototype.onModelChangeMapInfo = function ( map ) {
* @param {string} value New parameter name * @param {string} value New parameter name
*/ */
Dialog.prototype.onAddParamInputChange = function ( value ) { Dialog.prototype.onAddParamInputChange = function ( value ) {
var allProps = Model.static.getAllProperties( true ); const allProps = Model.static.getAllProperties( true );
value = value.trim(); value = value.trim();
var invalid = !value || allProps.name.restrict.test( value ); const invalid = !value || allProps.name.restrict.test( value );
var used = this.model.isParamExists( value ) && !this.model.isParamDeleted( value ); const used = this.model.isParamExists( value ) && !this.model.isParamDeleted( value );
this.addParamButton.setDisabled( invalid || used ); this.addParamButton.setDisabled( invalid || used );
}; };
@ -497,9 +497,9 @@ Dialog.prototype.onDescriptionInputChange = function ( value ) {
*/ */
Dialog.prototype.populateMapsItems = function ( mapsObject ) { Dialog.prototype.populateMapsItems = function ( mapsObject ) {
mapsObject = mapsObject || {}; mapsObject = mapsObject || {};
var mapKeysList = Object.keys( mapsObject ); const mapKeysList = Object.keys( mapsObject );
var items = mapKeysList.map( ( mapKey ) => new OO.ui.OutlineOptionWidget( { const items = mapKeysList.map( ( mapKey ) => new OO.ui.OutlineOptionWidget( {
label: mapKey label: mapKey
} ) ); } ) );
@ -516,7 +516,7 @@ Dialog.prototype.populateMapsItems = function ( mapsObject ) {
* @param {string} value map info value * @param {string} value map info value
*/ */
Dialog.prototype.onMapInfoChange = function ( value ) { Dialog.prototype.onMapInfoChange = function ( value ) {
var selectedItem = this.mapsGroup.findSelectedItem(); const selectedItem = this.mapsGroup.findSelectedItem();
// Update map Info // Update map Info
this.model.maps = this.model.getMapInfo() || {}; this.model.maps = this.model.getMapInfo() || {};
if ( selectedItem ) { if ( selectedItem ) {
@ -587,11 +587,11 @@ Dialog.prototype.onCancelAddingMap = function ( highlightNext ) {
* @param {jQuery.Event} response response from Enter action on promptMapName * @param {jQuery.Event} response response from Enter action on promptMapName
*/ */
Dialog.prototype.onEmbedNewMap = function ( response ) { Dialog.prototype.onEmbedNewMap = function ( response ) {
var mapNameValue = response ? response.target.value : this.newMapNameInput.getValue(); const mapNameValue = response ? response.target.value : this.newMapNameInput.getValue();
this.mapsCache = this.mapsCache || {}; this.mapsCache = this.mapsCache || {};
// Create a new empty map in maps object // Create a new empty map in maps object
this.mapsCache[ mapNameValue ] = {}; this.mapsCache[ mapNameValue ] = {};
var newlyAddedMap = new OO.ui.OutlineOptionWidget( { const newlyAddedMap = new OO.ui.OutlineOptionWidget( {
label: mapNameValue label: mapNameValue
} ); } );
// Add the new map item and select it // Add the new map item and select it
@ -607,7 +607,7 @@ Dialog.prototype.onEmbedNewMap = function ( response ) {
* Handle click event for the remove button * Handle click event for the remove button
*/ */
Dialog.prototype.onMapItemRemove = function () { Dialog.prototype.onMapItemRemove = function () {
var item = this.mapsGroup.findSelectedItem(); const item = this.mapsGroup.findSelectedItem();
if ( item ) { if ( item ) {
this.mapsGroup.removeItems( [ item ] ); this.mapsGroup.removeItems( [ item ] );
// Remove the highlighted map from maps object // Remove the highlighted map from maps object
@ -623,7 +623,7 @@ Dialog.prototype.onMapItemRemove = function () {
*/ */
Dialog.prototype.onMapsGroupSelect = function () { Dialog.prototype.onMapsGroupSelect = function () {
// Highlight new item // Highlight new item
var item = this.mapsGroup.findSelectedItem(); const item = this.mapsGroup.findSelectedItem();
if ( !item ) { if ( !item ) {
this.templateMapsInput.setDisabled( true ); this.templateMapsInput.setDisabled( true );
@ -648,7 +648,7 @@ Dialog.prototype.onMapsGroupSelect = function () {
// Populate the mapsContentPanel // Populate the mapsContentPanel
this.mapsCache = this.mapsCache || {}; this.mapsCache = this.mapsCache || {};
var currentMapInfo = this.mapsCache[ item.label ]; const currentMapInfo = this.mapsCache[ item.label ];
this.templateMapsInput.setValue( this.stringifyObject( currentMapInfo ) ); this.templateMapsInput.setValue( this.stringifyObject( currentMapInfo ) );
} }
}; };
@ -676,7 +676,7 @@ Dialog.prototype.onLanguagePanelButton = function () {
* @param {OO.ui.OptionWidget} item Selected item * @param {OO.ui.OptionWidget} item Selected item
*/ */
Dialog.prototype.onLanguageDropdownWidgetSelect = function ( item ) { Dialog.prototype.onLanguageDropdownWidgetSelect = function ( item ) {
var language = item ? item.getData() : this.language; const language = item ? item.getData() : this.language;
// Change current language // Change current language
if ( language !== this.language ) { if ( language !== this.language ) {
@ -705,13 +705,13 @@ Dialog.prototype.onLanguageDropdownWidgetSelect = function ( item ) {
* @param {OO.ui.OptionWidget} item Chosen item * @param {OO.ui.OptionWidget} item Chosen item
*/ */
Dialog.prototype.onNewLanguageSearchResultsChoose = function ( item ) { Dialog.prototype.onNewLanguageSearchResultsChoose = function ( item ) {
var newLanguage = item.getData().code; const newLanguage = item.getData().code;
if ( newLanguage ) { if ( newLanguage ) {
if ( this.availableLanguages.indexOf( newLanguage ) === -1 ) { if ( this.availableLanguages.indexOf( newLanguage ) === -1 ) {
// Add new language // Add new language
this.availableLanguages.push( newLanguage ); this.availableLanguages.push( newLanguage );
var languageButton = new OO.ui.MenuOptionWidget( { const languageButton = new OO.ui.MenuOptionWidget( {
data: newLanguage, data: newLanguage,
label: $.uls.data.getAutonym( newLanguage ) label: $.uls.data.getAutonym( newLanguage )
} ); } );
@ -730,7 +730,7 @@ Dialog.prototype.onNewLanguageSearchResultsChoose = function ( item ) {
* Respond to edit maps button click * Respond to edit maps button click
*/ */
Dialog.prototype.onMapsPanelButton = function () { Dialog.prototype.onMapsPanelButton = function () {
var item = this.mapsGroup.findSelectedItem() || this.mapsGroup.findFirstSelectableItem(); const item = this.mapsGroup.findSelectedItem() || this.mapsGroup.findFirstSelectableItem();
this.switchPanels( this.editMapsPanel ); this.switchPanels( this.editMapsPanel );
// Select first item // Select first item
this.mapsGroup.selectItem( item ); this.mapsGroup.selectItem( item );
@ -744,7 +744,7 @@ Dialog.prototype.onAddParamButtonClick = function () {
return; return;
} }
var newParamKey = this.newParamInput.getValue().trim(); const newParamKey = this.newParamInput.getValue().trim();
if ( this.model.isParamDeleted( newParamKey ) ) { if ( this.model.isParamDeleted( newParamKey ) ) {
this.model.emptyParamData( newParamKey ); this.model.emptyParamData( newParamKey );
} else if ( !this.model.isParamExists( newParamKey ) ) { } else if ( !this.model.isParamExists( newParamKey ) ) {
@ -764,7 +764,7 @@ Dialog.prototype.onAddParamButtonClick = function () {
* @param {OO.ui.OptionWidget} item Parameter item * @param {OO.ui.OptionWidget} item Parameter item
*/ */
Dialog.prototype.onParamSelectChoose = function ( item ) { Dialog.prototype.onParamSelectChoose = function ( item ) {
var paramKey = item.getData(); const paramKey = item.getData();
this.selectedParamKey = paramKey; this.selectedParamKey = paramKey;
@ -781,7 +781,7 @@ Dialog.prototype.onParamSelectChoose = function ( item ) {
* @param {OO.ui.OptionWidget} item Format item * @param {OO.ui.OptionWidget} item Format item
*/ */
Dialog.prototype.onTemplateFormatSelectWidgetChoose = function ( item ) { Dialog.prototype.onTemplateFormatSelectWidgetChoose = function ( item ) {
var format = item.getData(), const format = item.getData(),
shortcuts = { shortcuts = {
inline: '{{_|_=_}}', inline: '{{_|_=_}}',
block: '{{_\n| _ = _\n}}' block: '{{_\n| _ = _\n}}'
@ -817,11 +817,11 @@ Dialog.prototype.displayToFormat = function ( s ) {
* @param {string} value Input widget value * @param {string} value Input widget value
*/ */
Dialog.prototype.onTemplateFormatInputWidgetChange = function ( value ) { Dialog.prototype.onTemplateFormatInputWidgetChange = function ( value ) {
var item = this.templateFormatSelectWidget.findSelectedItem(); const item = this.templateFormatSelectWidget.findSelectedItem();
if ( item.getData() === 'custom' ) { if ( item.getData() === 'custom' ) {
// Convert literal newlines or backslash-n to our fancy character // Convert literal newlines or backslash-n to our fancy character
// replacement. // replacement.
var normalized = this.formatToDisplay( this.displayToFormat( value ) ); const normalized = this.formatToDisplay( this.displayToFormat( value ) );
if ( normalized !== value ) { if ( normalized !== value ) {
this.templateFormatInputWidget.setValue( normalized ); this.templateFormatInputWidget.setValue( normalized );
// Will recurse to actually set value in model. // Will recurse to actually set value in model.
@ -840,12 +840,12 @@ Dialog.prototype.onTemplateFormatInputWidgetEnter = function () {
}; };
Dialog.prototype.onParamPropertyInputChange = function ( propName, value ) { Dialog.prototype.onParamPropertyInputChange = function ( propName, value ) {
var $errors = $( [] ), let $errors = $( [] );
prop = Model.static.getAllProperties( true )[ propName ], const prop = Model.static.getAllProperties( true )[ propName ],
propInput = this.propInputs[ propName ]; propInput = this.propInputs[ propName ];
if ( propName === 'type' ) { if ( propName === 'type' ) {
var selected = propInput.getMenu().findSelectedItem(); const selected = propInput.getMenu().findSelectedItem();
value = selected ? selected.getData() : prop.default; value = selected ? selected.getData() : prop.default;
} else if ( prop.type === 'array' ) { } else if ( prop.type === 'array' ) {
value = propInput.getValue(); value = propInput.getValue();
@ -856,8 +856,8 @@ Dialog.prototype.onParamPropertyInputChange = function ( propName, value ) {
} }
if ( propName === 'name' ) { if ( propName === 'name' ) {
var invalid = !value || prop.restrict.test( value ); const invalid = !value || prop.restrict.test( value );
var changed = value !== this.selectedParamKey; const changed = value !== this.selectedParamKey;
if ( invalid ) { if ( invalid ) {
$errors = $errors.add( $( '<p>' ).text( mw.msg( 'templatedata-modal-errormsg', '|', '=', '}}' ) ) ); $errors = $errors.add( $( '<p>' ).text( mw.msg( 'templatedata-modal-errormsg', '|', '=', '}}' ) ) );
} else if ( changed && this.model.getAllParamNames().indexOf( value ) !== -1 ) { } else if ( changed && this.model.getAllParamNames().indexOf( value ) !== -1 ) {
@ -869,7 +869,7 @@ Dialog.prototype.onParamPropertyInputChange = function ( propName, value ) {
propInput.$element.toggleClass( 'tdg-editscreen-input-error', !!$errors.length ); propInput.$element.toggleClass( 'tdg-editscreen-input-error', !!$errors.length );
// Check if there is a dependent input to activate // Check if there is a dependent input to activate
var dependentField = prop.textValue; const dependentField = prop.textValue;
if ( dependentField && this.propFieldLayout[ dependentField ] ) { if ( dependentField && this.propFieldLayout[ dependentField ] ) {
// The textValue property depends on this property // The textValue property depends on this property
// toggle its view // toggle its view
@ -880,7 +880,7 @@ Dialog.prototype.onParamPropertyInputChange = function ( propName, value ) {
// Validate // Validate
// FIXME: Don't read model information from the DOM // FIXME: Don't read model information from the DOM
// eslint-disable-next-line no-jquery/no-global-selector // eslint-disable-next-line no-jquery/no-global-selector
var anyInputError = !!$( '.tdg-templateDataDialog-paramInput.tdg-editscreen-input-error' ).length; const anyInputError = !!$( '.tdg-templateDataDialog-paramInput.tdg-editscreen-input-error' ).length;
// Disable the 'done' button if there are any errors in the inputs // Disable the 'done' button if there are any errors in the inputs
this.actions.setAbilities( { done: !anyInputError } ); this.actions.setAbilities( { done: !anyInputError } );
@ -904,7 +904,7 @@ Dialog.prototype.onParamPropertyInputChange = function ( propName, value ) {
}; };
Dialog.prototype.toggleSuggestedValues = function ( type ) { Dialog.prototype.toggleSuggestedValues = function ( type ) {
var suggestedValuesAllowedTypes = [ const suggestedValuesAllowedTypes = [
'content', 'content',
'line', 'line',
'number', 'number',
@ -926,12 +926,12 @@ Dialog.prototype.toggleSuggestedValues = function ( type ) {
* @param {string} paramKey * @param {string} paramKey
*/ */
Dialog.prototype.getParameterDetails = function ( paramKey ) { Dialog.prototype.getParameterDetails = function ( paramKey ) {
var paramData = this.model.getParamData( paramKey ); const paramData = this.model.getParamData( paramKey );
var allProps = Model.static.getAllProperties( true ); const allProps = Model.static.getAllProperties( true );
this.stopParameterInputTracking(); this.stopParameterInputTracking();
for ( var prop in this.propInputs ) { for ( const prop in this.propInputs ) {
this.changeParamPropertyInput( paramKey, prop, paramData[ prop ], this.language ); this.changeParamPropertyInput( paramKey, prop, paramData[ prop ], this.language );
// Show/hide dependents // Show/hide dependents
if ( allProps[ prop ].textValue ) { if ( allProps[ prop ].textValue ) {
@ -941,7 +941,7 @@ Dialog.prototype.getParameterDetails = function ( paramKey ) {
// Update suggested values field visibility // Update suggested values field visibility
this.toggleSuggestedValues( paramData.type || allProps.type.default ); this.toggleSuggestedValues( paramData.type || allProps.type.default );
var status; let status;
// This accepts one of the three booleans only if the other two are false // This accepts one of the three booleans only if the other two are false
if ( paramData.deprecated ) { if ( paramData.deprecated ) {
status = !paramData.required && !paramData.suggested && 'deprecated'; status = !paramData.required && !paramData.suggested && 'deprecated';
@ -964,7 +964,7 @@ Dialog.prototype.getParameterDetails = function ( paramKey ) {
this.changeParamPropertyInput( paramKey, 'status', status ); this.changeParamPropertyInput( paramKey, 'status', status );
this.propInputs.status.getMenu().connect( this, { this.propInputs.status.getMenu().connect( this, {
choose: function ( item ) { choose: function ( item ) {
var selected = item.getData(); const selected = item.getData();
// Forward selection from the dropdown to the hidden checkboxes, these get saved // Forward selection from the dropdown to the hidden checkboxes, these get saved
this.propInputs.deprecated.setSelected( selected === 'deprecated' ); this.propInputs.deprecated.setSelected( selected === 'deprecated' );
this.propInputs.required.setSelected( selected === 'required' ); this.propInputs.required.setSelected( selected === 'required' );
@ -987,7 +987,7 @@ Dialog.prototype.stopParameterInputTracking = function () {
*/ */
Dialog.prototype.startParameterInputTracking = function ( paramValues ) { Dialog.prototype.startParameterInputTracking = function ( paramValues ) {
this.paramPropertyChangeTracking = {}; this.paramPropertyChangeTracking = {};
for ( var prop in this.propInputs ) { for ( const prop in this.propInputs ) {
// Set to true, unless one of the exceptions applies. // Set to true, unless one of the exceptions applies.
this.paramPropertyChangeTracking[ prop ] = !( this.paramPropertyChangeTracking[ prop ] = !(
// Setting type when we already have a specific type. // Setting type when we already have a specific type.
@ -1004,7 +1004,7 @@ Dialog.prototype.startParameterInputTracking = function ( paramValues ) {
}; };
Dialog.prototype.trackPropertyChange = function ( property ) { Dialog.prototype.trackPropertyChange = function ( property ) {
var eventKey = ( property === 'required' || property === 'suggested' || property === 'deprecated' ) ? const eventKey = ( property === 'required' || property === 'suggested' || property === 'deprecated' ) ?
'parameter-priority-change' : 'parameter-' + property + '-change'; 'parameter-priority-change' : 'parameter-' + property + '-change';
if ( this.paramPropertyChangeTracking[ property ] ) { if ( this.paramPropertyChangeTracking[ property ] ) {
@ -1044,14 +1044,14 @@ Dialog.prototype.repopulateParamSelectWidget = function () {
return; return;
} }
var paramList = this.model.getParams(), const paramList = this.model.getParams(),
paramOrder = this.model.getTemplateParamOrder(); paramOrder = this.model.getTemplateParamOrder();
this.paramSelect.clearItems(); this.paramSelect.clearItems();
// Update all param descriptions in the param select widget // Update all param descriptions in the param select widget
for ( var i in paramOrder ) { for ( const i in paramOrder ) {
var paramKey = paramList[ paramOrder[ i ] ]; const paramKey = paramList[ paramOrder[ i ] ];
if ( paramKey && !paramKey.deleted ) { if ( paramKey && !paramKey.deleted ) {
this.addParamToSelectWidget( paramOrder[ i ] ); this.addParamToSelectWidget( paramOrder[ i ] );
} }
@ -1059,7 +1059,7 @@ Dialog.prototype.repopulateParamSelectWidget = function () {
// Check if there are potential parameters to add // Check if there are potential parameters to add
// from the template source code // from the template source code
var missingParams = this.model.getMissingParams(); const missingParams = this.model.getMissingParams();
this.paramImport this.paramImport
.toggle( !!missingParams.length ) .toggle( !!missingParams.length )
.buildParamLabel( missingParams ); .buildParamLabel( missingParams );
@ -1074,8 +1074,8 @@ Dialog.prototype.repopulateParamSelectWidget = function () {
* @param {string} [lang] Language * @param {string} [lang] Language
*/ */
Dialog.prototype.changeParamPropertyInput = function ( paramKey, propName, value, lang ) { Dialog.prototype.changeParamPropertyInput = function ( paramKey, propName, value, lang ) {
var prop = Model.static.getAllProperties( true )[ propName ], const prop = Model.static.getAllProperties( true )[ propName ];
propInput = this.propInputs[ propName ]; let propInput = this.propInputs[ propName ];
switch ( prop.type ) { switch ( prop.type ) {
case 'select': case 'select':
@ -1106,7 +1106,7 @@ Dialog.prototype.changeParamPropertyInput = function ( paramKey, propName, value
* @param {string} paramKey Parameter key in the model * @param {string} paramKey Parameter key in the model
*/ */
Dialog.prototype.addParamToSelectWidget = function ( paramKey ) { Dialog.prototype.addParamToSelectWidget = function ( paramKey ) {
var data = this.model.getParamData( paramKey ); const data = this.model.getParamData( paramKey );
this.paramSelect.addItems( [ new ParamWidget( { this.paramSelect.addItems( [ new ParamWidget( {
key: paramKey, key: paramKey,
label: this.model.getParamValue( paramKey, 'label', this.language ), label: this.model.getParamValue( paramKey, 'label', this.language ),
@ -1124,21 +1124,21 @@ Dialog.prototype.addParamToSelectWidget = function ( paramKey ) {
* @return {jQuery} Editable details page for the parameter * @return {jQuery} Editable details page for the parameter
*/ */
Dialog.prototype.createParamDetails = function () { Dialog.prototype.createParamDetails = function () {
var paramProperties = Model.static.getAllProperties( true ); const paramProperties = Model.static.getAllProperties( true );
// Fieldset // Fieldset
var paramFieldset = new OO.ui.FieldsetLayout(); const paramFieldset = new OO.ui.FieldsetLayout();
for ( var propName in paramProperties ) { for ( const propName in paramProperties ) {
var prop = paramProperties[ propName ]; const prop = paramProperties[ propName ];
var propInput; const config = {};
var config = {}; let propInput;
// Create the property inputs // Create the property inputs
switch ( prop.type ) { switch ( prop.type ) {
case 'select': case 'select': {
propInput = new OO.ui.DropdownWidget( config ); propInput = new OO.ui.DropdownWidget( config );
var items = []; const items = [];
for ( var i in prop.children ) { for ( const i in prop.children ) {
items.push( new OO.ui.MenuOptionWidget( { items.push( new OO.ui.MenuOptionWidget( {
data: prop.children[ i ], data: prop.children[ i ],
@ -1159,6 +1159,7 @@ Dialog.prototype.createParamDetails = function () {
} }
propInput.getMenu().addItems( items ); propInput.getMenu().addItems( items );
break; break;
}
case 'boolean': case 'boolean':
propInput = new OO.ui.CheckboxInputWidget( config ); propInput = new OO.ui.CheckboxInputWidget( config );
break; break;
@ -1232,10 +1233,10 @@ Dialog.prototype.createParamDetails = function () {
* they show the currently used language. * they show the currently used language.
*/ */
Dialog.prototype.updateParamDetailsLanguage = function () { Dialog.prototype.updateParamDetailsLanguage = function () {
var languageProps = Model.static.getPropertiesWithLanguage(); const languageProps = Model.static.getPropertiesWithLanguage();
for ( var i = 0; i < languageProps.length; i++ ) { for ( let i = 0; i < languageProps.length; i++ ) {
var prop = languageProps[ i ]; const prop = languageProps[ i ];
// The following messages are used here: // The following messages are used here:
// * templatedata-modal-table-param-aliases // * templatedata-modal-table-param-aliases
// * templatedata-modal-table-param-autovalue // * templatedata-modal-table-param-autovalue
@ -1250,7 +1251,7 @@ Dialog.prototype.updateParamDetailsLanguage = function () {
// * templatedata-modal-table-param-suggested // * templatedata-modal-table-param-suggested
// * templatedata-modal-table-param-suggestedvalues // * templatedata-modal-table-param-suggestedvalues
// * templatedata-modal-table-param-type // * templatedata-modal-table-param-type
var label = mw.msg( 'templatedata-modal-table-param-' + prop, this.language ); const label = mw.msg( 'templatedata-modal-table-param-' + prop, this.language );
this.propFieldLayout[ prop ].setLabel( label ); this.propFieldLayout[ prop ].setLabel( label );
this.propInputs[ prop ] this.propInputs[ prop ]
.$input.attr( { lang: mw.language.bcp47( this.language ), dir: 'auto' } ); .$input.attr( { lang: mw.language.bcp47( this.language ), dir: 'auto' } );
@ -1284,7 +1285,7 @@ Dialog.prototype.toggleNoticeMessage = function ( type, isShowing, noticeMessage
if ( noticeMessageLabel ) { if ( noticeMessageLabel ) {
// See which error to display // See which error to display
var noticeReference; let noticeReference;
if ( type === 'global' ) { if ( type === 'global' ) {
noticeReference = this.noticeMessage; noticeReference = this.noticeMessage;
} else if ( type === 'edit' ) { } else if ( type === 'edit' ) {
@ -1306,12 +1307,12 @@ Dialog.prototype.toggleNoticeMessage = function ( type, isShowing, noticeMessage
* Import parameters from the source code. * Import parameters from the source code.
*/ */
Dialog.prototype.importParametersFromTemplateCode = function () { Dialog.prototype.importParametersFromTemplateCode = function () {
var $message = $( [] ), const response = this.model.importSourceCodeParameters();
state = 'success',
response = this.model.importSourceCodeParameters();
// Repopulate the list // Repopulate the list
this.repopulateParamSelectWidget(); this.repopulateParamSelectWidget();
let $message = $( [] ),
state = 'success';
if ( response.imported.length === 0 ) { if ( response.imported.length === 0 ) {
$message = $( '<p>' ).text( mw.msg( 'templatedata-modal-errormsg-import-noparams' ) ); $message = $( '<p>' ).text( mw.msg( 'templatedata-modal-errormsg-import-noparams' ) );
state = 'error'; state = 'error';
@ -1374,11 +1375,11 @@ Dialog.prototype.getSetupProcess = function ( data ) {
); );
this.availableLanguages = this.model.getExistingLanguageCodes().slice(); this.availableLanguages = this.model.getExistingLanguageCodes().slice();
var defaultLanguage = this.model.getDefaultLanguage(); const defaultLanguage = this.model.getDefaultLanguage();
if ( this.availableLanguages.indexOf( defaultLanguage ) === -1 ) { if ( this.availableLanguages.indexOf( defaultLanguage ) === -1 ) {
this.availableLanguages.unshift( defaultLanguage ); this.availableLanguages.unshift( defaultLanguage );
} }
var items = this.availableLanguages.map( ( lang ) => new OO.ui.MenuOptionWidget( { const items = this.availableLanguages.map( ( lang ) => new OO.ui.MenuOptionWidget( {
data: lang, data: lang,
label: $.uls.data.getAutonym( lang ) label: $.uls.data.getAutonym( lang )
} ) ); } ) );
@ -1412,7 +1413,7 @@ Dialog.prototype.setupDetailsFromModel = function () {
this.mapsCache = OO.copy( this.model.getMapInfo() ); this.mapsCache = OO.copy( this.model.getMapInfo() );
this.onMapsGroupSelect(); this.onMapsGroupSelect();
if ( this.model.getMapInfo() !== undefined ) { if ( this.model.getMapInfo() !== undefined ) {
var firstMapItem = Object.keys( this.model.getMapInfo() )[ 0 ]; const firstMapItem = Object.keys( this.model.getMapInfo() )[ 0 ];
this.templateMapsInput.setValue( this.stringifyObject( this.model.getMapInfo()[ firstMapItem ] ) ); this.templateMapsInput.setValue( this.stringifyObject( this.model.getMapInfo()[ firstMapItem ] ) );
} else { } else {
this.templateMapsInput.setValue( '' ); this.templateMapsInput.setValue( '' );
@ -1420,7 +1421,7 @@ Dialog.prototype.setupDetailsFromModel = function () {
} }
// Set up format // Set up format
var format = this.model.getTemplateFormat(); const format = this.model.getTemplateFormat();
if ( format === 'inline' || format === 'block' || format === null ) { if ( format === 'inline' || format === 'block' || format === null ) {
this.templateFormatSelectWidget.selectItemByData( format ); this.templateFormatSelectWidget.selectItemByData( format );
this.templateFormatInputWidget.setDisabled( true ); this.templateFormatInputWidget.setDisabled( true );
@ -1541,7 +1542,7 @@ Dialog.prototype.getActionProcess = function ( action ) {
} }
if ( !action && this.modified ) { if ( !action && this.modified ) {
return new OO.ui.Process( function () { return new OO.ui.Process( function () {
var dialog = this; const dialog = this;
return OO.ui.confirm( mw.msg( 'templatedata-modal-confirmcancel' ) ) return OO.ui.confirm( mw.msg( 'templatedata-modal-confirmcancel' ) )
.then( ( result ) => { .then( ( result ) => {
if ( result ) { if ( result ) {

View file

@ -1,6 +1,6 @@
function logEvent( eventName ) { function logEvent( eventName ) {
/* eslint-disable camelcase */ /* eslint-disable camelcase */
var event = { const event = {
action: eventName, action: eventName,
page_id: mw.config.get( 'wgArticleId' ), page_id: mw.config.get( 'wgArticleId' ),
page_title: mw.config.get( 'wgTitle' ), page_title: mw.config.get( 'wgTitle' ),
@ -10,7 +10,7 @@ function logEvent( eventName ) {
user_id: mw.user.isNamed() ? mw.user.getId() : 0 user_id: mw.user.isNamed() ? mw.user.getId() : 0
}; };
var editCountBucket = mw.config.get( 'wgUserEditCountBucket' ); const editCountBucket = mw.config.get( 'wgUserEditCountBucket' );
if ( editCountBucket !== null ) { if ( editCountBucket !== null ) {
event.user_edit_count_bucket = editCountBucket; event.user_edit_count_bucket = editCountBucket;
} }

View file

@ -1,4 +1,4 @@
var Dialog = require( './Dialog.js' ), const Dialog = require( './Dialog.js' ),
DataModule = require( 'ext.templateDataGenerator.data' ), DataModule = require( 'ext.templateDataGenerator.data' ),
Model = DataModule.Model, Model = DataModule.Model,
SourceHandler = DataModule.SourceHandler; SourceHandler = DataModule.SourceHandler;
@ -15,7 +15,7 @@ var Dialog = require( './Dialog.js' ),
* @param {Object} config * @param {Object} config
*/ */
function Target( $textarea, config ) { function Target( $textarea, config ) {
var target = this; const target = this;
// Parent constructor // Parent constructor
Target.super.call( this, config ); Target.super.call( this, config );
@ -39,7 +39,7 @@ function Target( $textarea, config ) {
} ) } )
.toggle( false ); .toggle( false );
var $helpLink = $( '<a>' ) const $helpLink = $( '<a>' )
.attr( { .attr( {
href: mw.msg( 'templatedata-helplink-target' ), href: mw.msg( 'templatedata-helplink-target' ),
target: '_blank' target: '_blank'
@ -63,24 +63,24 @@ function Target( $textarea, config ) {
} ); } );
// Check if there's already a templatedata in a related page // Check if there's already a templatedata in a related page
var relatedPage = this.isDocPage ? this.parentPage : this.pageName + '/' + this.docSubpage; const relatedPage = this.isDocPage ? this.parentPage : this.pageName + '/' + this.docSubpage;
this.sourceHandler.getApi( relatedPage ) this.sourceHandler.getApi( relatedPage )
.then( ( result ) => { .then( ( result ) => {
var response = result.query.pages[ result.query.pageids[ 0 ] ]; const response = result.query.pages[ result.query.pageids[ 0 ] ];
// HACK: When checking whether a related page (parent for /doc page or // HACK: When checking whether a related page (parent for /doc page or
// vice versa) already has a templatedata string, we shouldn't // vice versa) already has a templatedata string, we shouldn't
// ask for the 'templatedata' action but rather the actual content // ask for the 'templatedata' action but rather the actual content
// of the related page, otherwise we get embedded templatedata and // of the related page, otherwise we get embedded templatedata and
// wrong information is presented. // wrong information is presented.
if ( response.missing === undefined ) { if ( response.missing === undefined ) {
var content = response.revisions[ 0 ][ '*' ]; const content = response.revisions[ 0 ][ '*' ];
// There's a templatedata string // There's a templatedata string
if ( /<templatedata>/i.test( content ) ) { if ( /<templatedata>/i.test( content ) ) {
// HACK: Setting a link in the messages doesn't work. The bug report offers // HACK: Setting a link in the messages doesn't work. The bug report offers
// a somewhat hacky work around that includes setting a separate message // a somewhat hacky work around that includes setting a separate message
// to be parsed. // to be parsed.
// https://phabricator.wikimedia.org/T49395#490610 // https://phabricator.wikimedia.org/T49395#490610
var msg = mw.message( 'templatedata-exists-on-related-page', relatedPage ).plain(); let msg = mw.message( 'templatedata-exists-on-related-page', relatedPage ).plain();
mw.messages.set( { 'templatedata-string-exists-hack-message': msg } ); mw.messages.set( { 'templatedata-string-exists-hack-message': msg } );
msg = new OO.ui.HtmlSnippet( msg = new OO.ui.HtmlSnippet(
mw.message( 'templatedata-string-exists-hack-message' ).parse() mw.message( 'templatedata-string-exists-hack-message' ).parse()
@ -154,7 +154,7 @@ Target.prototype.openEditDialog = function ( dataModel ) {
* @method onEditOpenDialogButton * @method onEditOpenDialogButton
*/ */
Target.prototype.onEditOpenDialogButton = function () { Target.prototype.onEditOpenDialogButton = function () {
var target = this; const target = this;
this.originalWikitext = this.$textarea.textSelection( 'getContents' ); this.originalWikitext = this.$textarea.textSelection( 'getContents' );
@ -187,7 +187,7 @@ Target.prototype.onEditOpenDialogButton = function () {
} ).closed.then( ( data ) => { } ).closed.then( ( data ) => {
if ( data && data.action === 'accept' ) { if ( data && data.action === 'accept' ) {
// Open the dialog with an empty model // Open the dialog with an empty model
var model = Model.static.newFromObject( const model = Model.static.newFromObject(
null, null,
target.sourceHandler.getTemplateSourceCodeParams() target.sourceHandler.getTemplateSourceCodeParams()
); );
@ -206,10 +206,10 @@ Target.prototype.onEditOpenDialogButton = function () {
* @param {Object} newTemplateData New templatedata * @param {Object} newTemplateData New templatedata
*/ */
Target.prototype.replaceTemplateData = function ( newTemplateData ) { Target.prototype.replaceTemplateData = function ( newTemplateData ) {
var templateDataJSON = JSON.stringify( newTemplateData, null, '\t' ), const templateDataJSON = JSON.stringify( newTemplateData, null, '\t' ),
templatedataPattern = /(<templatedata>\s*)([\s\S]*?)\s*<\/templatedata>/i; templatedataPattern = /(<templatedata>\s*)([\s\S]*?)\s*<\/templatedata>/i;
var matches, templateDataOutput; let matches, templateDataOutput;
if ( ( matches = this.originalWikitext.match( templatedataPattern ) ) ) { if ( ( matches = this.originalWikitext.match( templatedataPattern ) ) ) {
// Move cursor to select withing existing <templatedata> and whitespace // Move cursor to select withing existing <templatedata> and whitespace
this.$textarea.textSelection( 'setSelection', { this.$textarea.textSelection( 'setSelection', {
@ -246,7 +246,7 @@ Target.prototype.replaceTemplateData = function ( newTemplateData ) {
* @param {Object} templateData New templatedata * @param {Object} templateData New templatedata
*/ */
Target.prototype.onDialogApply = function ( templateData ) { Target.prototype.onDialogApply = function ( templateData ) {
var target = this; const target = this;
if ( if (
Object.keys( templateData ).length > 1 || Object.keys( templateData ).length > 1 ||

View file

@ -11,20 +11,16 @@
'use strict'; 'use strict';
new mw.Api().loadMessages( 'templatedata-doc-subpage', { amlang: mw.config.get( 'wgContentLanguage' ) } ).then( () => { new mw.Api().loadMessages( 'templatedata-doc-subpage', { amlang: mw.config.get( 'wgContentLanguage' ) } ).then( () => {
var Target = require( './Target.js' ), const Target = require( './Target.js' ),
pageName = mw.config.get( 'wgPageName' ), pageName = mw.config.get( 'wgPageName' ),
docSubpage = mw.msg( 'templatedata-doc-subpage' ), docSubpage = mw.msg( 'templatedata-doc-subpage' );
config = { let $textbox = $( '#wpTextbox1' );
pageName: pageName,
isPageSubLevel: false
},
$textbox = $( '#wpTextbox1' );
var pieces = pageName.split( '/' ); const pieces = pageName.split( '/' );
var isDocPage = pieces.length > 1 && pieces[ pieces.length - 1 ] === docSubpage; const isDocPage = pieces.length > 1 && pieces[ pieces.length - 1 ] === docSubpage;
var openTDG = new URL( location.href ).searchParams.get( 'templatedata' ) === 'edit'; const openTDG = new URL( location.href ).searchParams.get( 'templatedata' ) === 'edit';
config = { const config = {
pageName: pageName, pageName: pageName,
isPageSubLevel: pieces.length > 1, isPageSubLevel: pieces.length > 1,
parentPage: pageName, parentPage: pageName,
@ -42,16 +38,16 @@ new mw.Api().loadMessages( 'templatedata-doc-subpage', { amlang: mw.config.get(
// Textbox wikitext editor // Textbox wikitext editor
if ( $textbox.length ) { if ( $textbox.length ) {
// Prepare the editor // Prepare the editor
var wtTarget = new Target( $textbox, config ); const wtTarget = new Target( $textbox, config );
$( '.tdg-editscreen-placeholder' ).replaceWith( wtTarget.$element ); $( '.tdg-editscreen-placeholder' ).replaceWith( wtTarget.$element );
if ( openTDG ) { if ( openTDG ) {
wtTarget.onEditOpenDialogButton(); wtTarget.onEditOpenDialogButton();
} }
} }
var veTarget; let veTarget;
// Visual editor source mode // Visual editor source mode
mw.hook( 've.activationComplete' ).add( () => { mw.hook( 've.activationComplete' ).add( () => {
var surface = ve.init.target.getSurface(); const surface = ve.init.target.getSurface();
if ( surface.getMode() === 'source' ) { if ( surface.getMode() === 'source' ) {
// Source mode will have created a dummy textbox // Source mode will have created a dummy textbox
$textbox = $( '#wpTextbox1' ); $textbox = $( '#wpTextbox1' );

View file

@ -52,7 +52,7 @@ LanguageResultWidget.prototype.onKeyDown = function ( e ) {
* @chainable * @chainable
*/ */
LanguageResultWidget.prototype.updateLabel = function ( query, matchedProperty ) { LanguageResultWidget.prototype.updateLabel = function ( query, matchedProperty ) {
var data = this.getData(); const data = this.getData();
// Reset text // Reset text
this.$name.text( data.name ); this.$name.text( data.name );
@ -60,7 +60,7 @@ LanguageResultWidget.prototype.updateLabel = function ( query, matchedProperty )
// Highlight where applicable // Highlight where applicable
if ( matchedProperty ) { if ( matchedProperty ) {
var $highlighted = this.constructor.static.highlightQuery( data[ matchedProperty ], query ); const $highlighted = this.constructor.static.highlightQuery( data[ matchedProperty ], query );
if ( matchedProperty === 'name' ) { if ( matchedProperty === 'name' ) {
this.$name.empty().append( $highlighted ); this.$name.empty().append( $highlighted );
} else { } else {
@ -81,7 +81,7 @@ LanguageResultWidget.prototype.updateLabel = function ( query, matchedProperty )
* @return {jQuery} Text with query substring wrapped in highlighted span * @return {jQuery} Text with query substring wrapped in highlighted span
*/ */
LanguageResultWidget.static.highlightQuery = function ( text, query ) { LanguageResultWidget.static.highlightQuery = function ( text, query ) {
var $result = $( '<span>' ), const $result = $( '<span>' ),
offset = text.toLowerCase().indexOf( query.toLowerCase() ); offset = text.toLowerCase().indexOf( query.toLowerCase() );
if ( !query.length || offset === -1 ) { if ( !query.length || offset === -1 ) {

View file

@ -1,4 +1,4 @@
var LanguageResultWidget = require( './LanguageResultWidget.js' ); const LanguageResultWidget = require( './LanguageResultWidget.js' );
/** /**
* Creates a TemplateDataLanguageSearchWidget object. * Creates a TemplateDataLanguageSearchWidget object.
@ -21,7 +21,7 @@ function LanguageSearchWidget( config ) {
// Properties // Properties
this.filteredLanguageResultWidgets = []; this.filteredLanguageResultWidgets = [];
var languageCodes = Object.keys( $.uls.data.getAutonyms() ).sort(); const languageCodes = Object.keys( $.uls.data.getAutonyms() ).sort();
this.languageResultWidgets = languageCodes.map( ( languageCode ) => new LanguageResultWidget( { this.languageResultWidgets = languageCodes.map( ( languageCode ) => new LanguageResultWidget( {
data: { data: {
code: languageCode, code: languageCode,
@ -64,7 +64,7 @@ LanguageSearchWidget.prototype.setAvailableLanguages = function ( availableLangu
} }
this.filteredLanguageResultWidgets = this.languageResultWidgets.map( ( languageResult ) => { this.filteredLanguageResultWidgets = this.languageResultWidgets.map( ( languageResult ) => {
var data = languageResult.getData(); const data = languageResult.getData();
if ( availableLanguages.indexOf( data.code ) !== -1 ) { if ( availableLanguages.indexOf( data.code ) !== -1 ) {
return languageResult; return languageResult;
} }
@ -76,7 +76,7 @@ LanguageSearchWidget.prototype.setAvailableLanguages = function ( availableLangu
* Update search results from current query * Update search results from current query
*/ */
LanguageSearchWidget.prototype.addResults = function () { LanguageSearchWidget.prototype.addResults = function () {
var matchProperties = [ 'name', 'autonym', 'code' ], const matchProperties = [ 'name', 'autonym', 'code' ],
query = this.query.getValue().trim(), query = this.query.getValue().trim(),
compare = window.Intl && Intl.Collator ? compare = window.Intl && Intl.Collator ?
new Intl.Collator( this.lang, { sensitivity: 'base' } ).compare : new Intl.Collator( this.lang, { sensitivity: 'base' } ).compare :
@ -86,12 +86,12 @@ LanguageSearchWidget.prototype.addResults = function () {
hasQuery = !!query.length, hasQuery = !!query.length,
items = []; items = [];
var results = this.getResults(); const results = this.getResults();
results.clearItems(); results.clearItems();
this.filteredLanguageResultWidgets.forEach( ( languageResult ) => { this.filteredLanguageResultWidgets.forEach( ( languageResult ) => {
var data = languageResult.getData(); const data = languageResult.getData();
var matchedProperty = null; let matchedProperty = null;
matchProperties.some( ( prop ) => { matchProperties.some( ( prop ) => {
if ( data[ prop ] && compare( data[ prop ].slice( 0, query.length ), query ) === 0 ) { if ( data[ prop ] && compare( data[ prop ].slice( 0, query.length ), query ) === 0 ) {

View file

@ -27,7 +27,7 @@ OO.inheritClass( ParamImportWidget, OO.ui.ButtonWidget );
* @param {string[]} params Param names * @param {string[]} params Param names
*/ */
ParamImportWidget.prototype.buildParamLabel = function ( params ) { ParamImportWidget.prototype.buildParamLabel = function ( params ) {
var paramNames = params.slice( 0, 9 ).join( mw.msg( 'comma-separator' ) ); const paramNames = params.slice( 0, 9 ).join( mw.msg( 'comma-separator' ) );
this.setLabel( $( '<div>' ) this.setLabel( $( '<div>' )
.addClass( 'tdg-templateDataParamWidget-param-name' ) .addClass( 'tdg-templateDataParamWidget-param-name' )
.text( mw.msg( 'templatedata-modal-table-param-importoption', params.length ) ) .text( mw.msg( 'templatedata-modal-table-param-importoption', params.length ) )

View file

@ -52,7 +52,7 @@ ParamWidget.prototype.onKeyDown = function ( e ) {
* Build the parameter label in the parameter select widget * Build the parameter label in the parameter select widget
*/ */
ParamWidget.prototype.buildParamLabel = function () { ParamWidget.prototype.buildParamLabel = function () {
var keys = this.aliases.slice(), const keys = this.aliases.slice(),
$paramLabel = $( '<div>' ) $paramLabel = $( '<div>' )
.addClass( 'tdg-templateDataParamWidget-param-name' ), .addClass( 'tdg-templateDataParamWidget-param-name' ),
$aliases = $( '<div>' ) $aliases = $( '<div>' )

View file

@ -3,19 +3,16 @@
*/ */
'use strict'; 'use strict';
var finalJsonParams, finalJson, const DataModule = require( 'ext.templateDataGenerator.data' ),
resultDescCurrLang, resultDescMockLang, resultDescBothLang, currLanguage, originalWikitext,
DataModule = require( 'ext.templateDataGenerator.data' ),
Model = DataModule.Model, Model = DataModule.Model,
SourceHandler = DataModule.SourceHandler; SourceHandler = DataModule.SourceHandler;
QUnit.module( 'ext.templateData', QUnit.newMwEnvironment() ); QUnit.module( 'ext.templateData', QUnit.newMwEnvironment() );
resultDescCurrLang = {}; const resultDescCurrLang = {};
resultDescMockLang = {}; const resultDescMockLang = {};
resultDescBothLang = {}; const currLanguage = mw.config.get( 'wgContentLanguage' ) || 'en';
currLanguage = mw.config.get( 'wgContentLanguage' ) || 'en'; const originalWikitext = 'Some text here that is not templatedata information.' +
originalWikitext = 'Some text here that is not templatedata information.' +
'<templatedata>' + '<templatedata>' +
'{' + '{' +
'"description": {\n' + '"description": {\n' +
@ -68,8 +65,8 @@ originalWikitext = 'Some text here that is not templatedata information.' +
// Prepare description language objects // Prepare description language objects
resultDescCurrLang[ currLanguage ] = 'Some string here in ' + currLanguage + ' language.'; resultDescCurrLang[ currLanguage ] = 'Some string here in ' + currLanguage + ' language.';
resultDescMockLang.blah = 'Some string here in blah language.'; resultDescMockLang.blah = 'Some string here in blah language.';
resultDescBothLang = Object.assign( {}, resultDescCurrLang, resultDescMockLang ); const resultDescBothLang = Object.assign( {}, resultDescCurrLang, resultDescMockLang );
finalJsonParams = { const finalJsonParams = {
user: { user: {
label: 'Username', label: 'Username',
type: 'wiki-user-name', type: 'wiki-user-name',
@ -131,7 +128,7 @@ finalJsonParams.date.description[ currLanguage ] = 'Timestamp of when the commen
finalJsonParams.newParam1.description[ currLanguage ] = 'Some string here in ' + currLanguage + ' language.'; finalJsonParams.newParam1.description[ currLanguage ] = 'Some string here in ' + currLanguage + ' language.';
finalJsonParams.newParam4.description[ currLanguage ] = resultDescBothLang[ currLanguage ]; finalJsonParams.newParam4.description[ currLanguage ] = resultDescBothLang[ currLanguage ];
finalJson = { const finalJson = {
description: { description: {
blah: 'Template description in some blah language.' blah: 'Template description in some blah language.'
}, },
@ -152,200 +149,199 @@ finalJson.description[ currLanguage ] = 'Label unsigned comments in a conversati
// Test validation tools // Test validation tools
QUnit.test( 'Validation tools', ( assert ) => { QUnit.test( 'Validation tools', ( assert ) => {
var i, testVars, const tests = {
tests = { compare: [
compare: [ {
{ obj1: null,
obj1: null, obj2: undefined,
obj2: undefined, result: false,
result: false, msg: 'Compare: null vs undefined'
msg: 'Compare: null vs undefined' },
}, {
{ obj1: 'string',
obj1: 'string', obj2: undefined,
obj2: undefined, result: false,
result: false, msg: 'Compare: string vs undefined'
msg: 'Compare: string vs undefined' },
}, {
{ obj1: undefined,
obj1: undefined, obj2: undefined,
obj2: undefined, result: true,
result: true, msg: 'Compare: undefined vs undefined'
msg: 'Compare: undefined vs undefined' },
}, {
{ obj1: null,
obj1: null, obj2: null,
obj2: null, result: true,
result: true, msg: 'Compare: null vs null'
msg: 'Compare: null vs null' },
}, {
{ obj1: 'A proper string.',
obj1: 'A proper string.', obj2: 'A proper string.',
obj2: 'A proper string.', result: true,
result: true, msg: 'Compare: strings'
msg: 'Compare: strings' },
}, {
{ obj1: true,
obj1: true, obj2: true,
obj2: true, result: true,
result: true, msg: 'Compare: booleans'
msg: 'Compare: booleans' },
}, {
{ obj1: { 1: 'string', 2: 'another', 4: 'and another' },
obj1: { 1: 'string', 2: 'another', 4: 'and another' }, obj2: { 1: 'string', 2: 'another', 4: 'and another' },
obj2: { 1: 'string', 2: 'another', 4: 'and another' }, result: true,
result: true, allowSubset: true,
allowSubset: true, msg: 'Compare: plain object full equality'
msg: 'Compare: plain object full equality' },
}, {
{ obj1: { 1: 'string', 2: 'another', 4: 'and another' },
obj1: { 1: 'string', 2: 'another', 4: 'and another' }, obj2: { 1: 'another', 2: 'and another', 4: 'string' },
obj2: { 1: 'another', 2: 'and another', 4: 'string' }, result: false,
result: false, allowSubset: true,
allowSubset: true, msg: 'Compare: plain object full inequality'
msg: 'Compare: plain object full inequality' },
}, {
{ obj1: { 1: 'string', 2: 'another', 4: 'and another' },
obj1: { 1: 'string', 2: 'another', 4: 'and another' }, obj2: { 4: 'and another' },
obj2: { 4: 'and another' }, result: true,
result: true, allowSubset: true,
allowSubset: true, msg: 'Compare: plain object subset equality'
msg: 'Compare: plain object subset equality' },
}, {
{ obj1: [ 'val1', 'val2', 'val3' ],
obj1: [ 'val1', 'val2', 'val3' ], obj2: [ 'val1', 'val2', 'val3' ],
obj2: [ 'val1', 'val2', 'val3' ], result: true,
result: true, msg: 'Compare: arrays'
msg: 'Compare: arrays' },
}, {
{ obj1: [ 'val1', 'val2', 'val3' ],
obj1: [ 'val1', 'val2', 'val3' ], obj2: [ 'val1' ],
obj2: [ 'val1' ], result: true,
result: true, allowSubset: true,
allowSubset: true, msg: 'Compare: array subset: true'
msg: 'Compare: array subset: true' },
}, {
{ obj1: [ 'val1', 'val2', 'val3' ],
obj1: [ 'val1', 'val2', 'val3' ], obj2: [ 'val1' ],
obj2: [ 'val1' ], result: false,
result: false, allowSubset: false,
allowSubset: false, msg: 'Compare: array subset: false'
msg: 'Compare: array subset: false' },
}, {
{ obj1: {
obj1: { param1: {
param1: { type: 'unknown',
type: 'unknown', aliases: [ 'alias2', 'alias1', 'alias3' ],
aliases: [ 'alias2', 'alias1', 'alias3' ], description: 'Some description',
description: 'Some description', required: true,
required: true, suggested: false
suggested: false
},
param2: {
required: true
}
}, },
obj2: { param2: {
param1: { required: true
type: 'unknown', }
aliases: [ 'alias2', 'alias1', 'alias3' ], },
description: 'Some description', obj2: {
required: true, param1: {
suggested: false type: 'unknown',
}, aliases: [ 'alias2', 'alias1', 'alias3' ],
param2: { description: 'Some description',
required: true required: true,
} suggested: false
}, },
result: true, param2: {
allowSubset: true, required: true
msg: 'Compare: complex objects' }
}, },
{ result: true,
obj1: { allowSubset: true,
param1: { msg: 'Compare: complex objects'
type: 'unknown', },
aliases: [ 'alias1', 'alias2', 'alias3' ], {
description: 'Some description', obj1: {
required: true, param1: {
suggested: false type: 'unknown',
}, aliases: [ 'alias1', 'alias2', 'alias3' ],
param2: { description: 'Some description',
required: true required: true,
} suggested: false
}, },
obj2: { param2: {
param1: { required: true
aliases: [ 'alias1', 'alias2', 'alias3' ], }
suggested: false
}
},
result: true,
allowSubset: true,
msg: 'Compare: complex objects subset'
}
],
splitAndTrimArray: [
{
string: 'str1 , str2 ',
delim: ',',
result: [ 'str1', 'str2' ],
msg: 'splitAndTrimArray: split and trim'
}, },
{ obj2: {
string: 'str1, str2, , , , str3', param1: {
delim: ',', aliases: [ 'alias1', 'alias2', 'alias3' ],
result: [ 'str1', 'str2', 'str3' ], suggested: false
msg: 'splitAndTrimArray: remove empty values' }
}, },
{ result: true,
string: 'str1|str2|str3', allowSubset: true,
delim: '|', msg: 'Compare: complex objects subset'
result: [ 'str1', 'str2', 'str3' ],
msg: 'splitAndTrimArray: different delimeter'
}
],
arrayUnionWithoutEmpty: [
{
arrays: [ [ 'en', 'he', '' ], [ 'he', 'de', '' ], [ 'en', 'de' ] ],
result: [ 'en', 'he', 'de' ],
msg: 'arrayUnionWithoutEmpty: Remove duplications'
},
{
arrays: [ [ 'en', '', '' ], [ 'he', '', '' ], [ 'de', '' ] ],
result: [ 'en', 'he', 'de' ],
msg: 'arrayUnionWithoutEmpty: Remove empty values'
}
],
props: {
all: [
'name',
'aliases',
'label',
'description',
'example',
'type',
'suggestedvalues',
'default',
'autovalue',
'status',
'deprecated',
'deprecatedValue',
'required',
'suggested'
],
language: [
'label',
'description',
'example',
'default'
]
} }
}; ],
splitAndTrimArray: [
{
string: 'str1 , str2 ',
delim: ',',
result: [ 'str1', 'str2' ],
msg: 'splitAndTrimArray: split and trim'
},
{
string: 'str1, str2, , , , str3',
delim: ',',
result: [ 'str1', 'str2', 'str3' ],
msg: 'splitAndTrimArray: remove empty values'
},
{
string: 'str1|str2|str3',
delim: '|',
result: [ 'str1', 'str2', 'str3' ],
msg: 'splitAndTrimArray: different delimeter'
}
],
arrayUnionWithoutEmpty: [
{
arrays: [ [ 'en', 'he', '' ], [ 'he', 'de', '' ], [ 'en', 'de' ] ],
result: [ 'en', 'he', 'de' ],
msg: 'arrayUnionWithoutEmpty: Remove duplications'
},
{
arrays: [ [ 'en', '', '' ], [ 'he', '', '' ], [ 'de', '' ] ],
result: [ 'en', 'he', 'de' ],
msg: 'arrayUnionWithoutEmpty: Remove empty values'
}
],
props: {
all: [
'name',
'aliases',
'label',
'description',
'example',
'type',
'suggestedvalues',
'default',
'autovalue',
'status',
'deprecated',
'deprecatedValue',
'required',
'suggested'
],
language: [
'label',
'description',
'example',
'default'
]
}
};
// Compare // Compare
for ( i = 0; i < tests.compare.length; i++ ) { for ( let i = 0; i < tests.compare.length; i++ ) {
testVars = tests.compare[ i ]; const testVars = tests.compare[ i ];
assert.strictEqual( assert.strictEqual(
Model.static.compare( testVars.obj1, testVars.obj2, testVars.allowSubset ), Model.static.compare( testVars.obj1, testVars.obj2, testVars.allowSubset ),
testVars.result, testVars.result,
@ -354,8 +350,8 @@ QUnit.test( 'Validation tools', ( assert ) => {
} }
// Split and trim // Split and trim
for ( i = 0; i < tests.splitAndTrimArray.length; i++ ) { for ( let i = 0; i < tests.splitAndTrimArray.length; i++ ) {
testVars = tests.splitAndTrimArray[ i ]; const testVars = tests.splitAndTrimArray[ i ];
assert.deepEqual( assert.deepEqual(
Model.static.splitAndTrimArray( testVars.string, testVars.delim ), Model.static.splitAndTrimArray( testVars.string, testVars.delim ),
testVars.result, testVars.result,
@ -364,8 +360,8 @@ QUnit.test( 'Validation tools', ( assert ) => {
} }
// arrayUnionWithoutEmpty // arrayUnionWithoutEmpty
for ( i = 0; i < tests.arrayUnionWithoutEmpty.length; i++ ) { for ( let i = 0; i < tests.arrayUnionWithoutEmpty.length; i++ ) {
testVars = tests.arrayUnionWithoutEmpty[ i ]; const testVars = tests.arrayUnionWithoutEmpty[ i ];
assert.deepEqual( assert.deepEqual(
Model.static.arrayUnionWithoutEmpty.apply( testVars, testVars.arrays ), Model.static.arrayUnionWithoutEmpty.apply( testVars, testVars.arrays ),
testVars.result, testVars.result,
@ -388,8 +384,7 @@ QUnit.test( 'Validation tools', ( assert ) => {
// Test model load // Test model load
QUnit.test( 'TemplateData model', ( assert ) => { QUnit.test( 'TemplateData model', ( assert ) => {
var i, testVars, const sourceHandler = new SourceHandler(),
sourceHandler = new SourceHandler(),
paramAddTest = [ paramAddTest = [
{ {
key: 'newParam1', key: 'newParam1',
@ -513,7 +508,7 @@ QUnit.test( 'TemplateData model', ( assert ) => {
'Parameters retention.' 'Parameters retention.'
); );
for ( i = 0; i < paramAddTest.length; i++ ) { for ( let i = 0; i < paramAddTest.length; i++ ) {
// Add parameter // Add parameter
model.addParam( paramAddTest[ i ].key, paramAddTest[ i ].data ); model.addParam( paramAddTest[ i ].key, paramAddTest[ i ].data );
@ -533,8 +528,8 @@ QUnit.test( 'TemplateData model', ( assert ) => {
} }
// Change parameter properties // Change parameter properties
for ( i = 0; i < paramChangeTest.length; i++ ) { for ( let i = 0; i < paramChangeTest.length; i++ ) {
testVars = paramChangeTest[ i ]; const testVars = paramChangeTest[ i ];
model.setParamProperty( testVars.key, testVars.property, testVars.value, testVars.language ); model.setParamProperty( testVars.key, testVars.property, testVars.value, testVars.language );
assert.deepEqual( assert.deepEqual(
model.getParamData( testVars.key ), model.getParamData( testVars.key ),
@ -596,7 +591,7 @@ QUnit.test( 'TemplateData model', ( assert ) => {
// Test model with maps in wikitext // Test model with maps in wikitext
QUnit.test( 'TemplateData sourceHandler with maps', ( assert ) => { QUnit.test( 'TemplateData sourceHandler with maps', ( assert ) => {
var sourceHandler = new SourceHandler(), const sourceHandler = new SourceHandler(),
wikitextWithMaps = 'Some text here that is not templatedata information.' + wikitextWithMaps = 'Some text here that is not templatedata information.' +
'<templatedata>' + '<templatedata>' +
'{' + '{' +
@ -719,7 +714,7 @@ QUnit.test( 'TemplateData sourceHandler with maps', ( assert ) => {
// Test model fail // Test model fail
QUnit.test( 'TemplateData sourceHandler failure', ( assert ) => { QUnit.test( 'TemplateData sourceHandler failure', ( assert ) => {
var sourceHandler = new SourceHandler(), const sourceHandler = new SourceHandler(),
erronousString = '<templatedata>{\n' + erronousString = '<templatedata>{\n' +
'"params": {\n' + '"params": {\n' +
// Open quote // Open quote
@ -742,10 +737,9 @@ QUnit.test( 'TemplateData sourceHandler failure', ( assert ) => {
'}\n' + '}\n' +
'}\n' + '}\n' +
'}</templatedata>', '}</templatedata>',
done = assert.async(), done = assert.async();
promise;
promise = sourceHandler.buildModel( erronousString ); const promise = sourceHandler.buildModel( erronousString );
promise.always( () => { promise.always( () => {
assert.strictEqual( promise.state(), 'rejected', 'Promise rejected on erronous json string.' ); assert.strictEqual( promise.state(), 'rejected', 'Promise rejected on erronous json string.' );
done(); done();
@ -754,7 +748,7 @@ QUnit.test( 'TemplateData sourceHandler failure', ( assert ) => {
// Test model gets default format // Test model gets default format
QUnit.test( 'TemplateData sourceHandler adding default format', ( assert ) => { QUnit.test( 'TemplateData sourceHandler adding default format', ( assert ) => {
var sourceHandler = new SourceHandler(), const sourceHandler = new SourceHandler(),
simpleTemplateDataNoFormat = '<templatedata>{\n' + simpleTemplateDataNoFormat = '<templatedata>{\n' +
'"params": {}\n' + '"params": {}\n' +
'}</templatedata>', '}</templatedata>',
@ -773,7 +767,7 @@ QUnit.test( 'TemplateData sourceHandler adding default format', ( assert ) => {
} ); } );
QUnit.test( 'Duplicate parameter names', ( assert ) => { QUnit.test( 'Duplicate parameter names', ( assert ) => {
var model = new Model(); const model = new Model();
model.addParam( 'color' ); model.addParam( 'color' );
assert.deepEqual( model.getParams(), { assert.deepEqual( model.getParams(), {
color: { name: 'color' } color: { name: 'color' }
@ -804,7 +798,7 @@ QUnit.test( 'Duplicate parameter names', ( assert ) => {
} ); } );
QUnit.test( 'safesubst: hack with an unnamed parameter', ( assert ) => { QUnit.test( 'safesubst: hack with an unnamed parameter', ( assert ) => {
var handler = new SourceHandler(), const handler = new SourceHandler(),
wikitext = '{{ {{{|safesubst:}}}#invoke:…|{{{1}}}|{{{ 1 }}}}}'; wikitext = '{{ {{{|safesubst:}}}#invoke:…|{{{1}}}|{{{ 1 }}}}}';
assert.deepEqual( assert.deepEqual(