Trevor Parscal has uploaded a new change for review. https://gerrit.wikimedia.org/r/73136
Change subject: Auto-add required params for user added templates ...................................................................... Auto-add required params for user added templates Objectives: * Automatically add required parameters to templates that users create using the GUI, without touching existing templates loaded from data * Cleanup some confusing terminology and APIs Changes: ve.ui.MWParameterSearchWidget.js * Remove special logic for skipping aliases, which are no longer included in the list of names given by getParameterNames ve.ui.MWTransclusionDialog.js * Add origin arguments to constructors of transclusion parts * Re-use onAddParameter method during initial construction of parameter pages * Add required template parameters for user created template parts ve.dm.MWTransclusionPartModel.js * Add origin argument/property/getter for tracking where a part came from ve.dm.MWTransclusionContentModel.js, ve.dm.MWTransclusionPlaceholderModel.js, ve.dm.MWTemplateModel.js * Add origin argument pass through ve.dm.MWTranclusionModel.js * Add origin arguments to constructors of transclusion parts ve.dm.MWTemplateSpecModel.js * Rename origin to name - was a bad name to start with and will be even more confusing with the new part origin property * Add isParameterAlias method * Make getParameterNames only return primary names, excluding aliases ve.dm.MWTemplateModel.js * Update use of parameter origin, now called name Change-Id: Ib444f0f5a8168cd59ea52a6000ba5e42ccdc2a24 --- M modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js M modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js M modules/ve-mw/dm/models/ve.dm.MWTemplateSpecModel.js M modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js M modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js M modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js M modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js M modules/ve-mw/ui/widgets/ve.ui.MWParameterSearchWidget.js 8 files changed, 90 insertions(+), 42 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor refs/changes/36/73136/1 diff --git a/modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js b/modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js index 5d49e7a..a0b013a 100644 --- a/modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js +++ b/modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js @@ -16,10 +16,11 @@ * @param {Object} target Template target * @param {string} target.wt Original wikitext of target * @param {string} [target.href] Hypertext reference to target + * @param {string} [origin] Origin of part, e.g. 'data' or 'user' */ -ve.dm.MWTemplateModel = function VeDmMWTemplateModel( transclusion, target ) { +ve.dm.MWTemplateModel = function VeDmMWTemplateModel( transclusion, target, origin ) { // Parent constructor - ve.dm.MWTransclusionPartModel.call( this, transclusion ); + ve.dm.MWTransclusionPartModel.call( this, transclusion, origin ); // Properties this.target = target; @@ -106,7 +107,7 @@ * @returns {boolean} Parameter exists */ ve.dm.MWTemplateModel.prototype.hasParameter = function ( name ) { - var i, len, origin, names; + var i, len, primaryName, names; // Check if name (which may be an alias) is present in the template if ( this.params[name] ) { @@ -115,13 +116,13 @@ // Check if the name is known at all if ( this.spec.isParameterKnown( name ) ) { - origin = this.spec.getParameterOrigin( name ); - // Check for origin name (may be the same as name) - if ( this.params[origin] ) { + primaryName = this.spec.getParameterName( name ); + // Check for primary name (may be the same as name) + if ( this.params[primaryName] ) { return true; } // Check for other aliases (may include name) - names = this.spec.getParameterAliases( origin ); + names = this.spec.getParameterAliases( primaryName ); for ( i = 0, len = names.length; i < len; i++ ) { if ( this.params[names[i]] ) { return true; diff --git a/modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js b/modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js index 4f3250c..e54d7ba 100644 --- a/modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js +++ b/modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js @@ -13,10 +13,11 @@ * * @constructor * @param {ve.dm.MWTransclusionModel} transclusion Transclusion + * @param {string} [origin] Origin of part, e.g. 'data' or 'user' */ -ve.dm.MWTemplatePlaceholderModel = function VeDmMWTemplatePlaceholderModel( transclusion ) { +ve.dm.MWTemplatePlaceholderModel = function VeDmMWTemplatePlaceholderModel( transclusion, origin ) { // Parent constructor - ve.dm.MWTransclusionPartModel.call( this, transclusion ); + ve.dm.MWTransclusionPartModel.call( this, transclusion, origin ); }; /* Inheritance */ diff --git a/modules/ve-mw/dm/models/ve.dm.MWTemplateSpecModel.js b/modules/ve-mw/dm/models/ve.dm.MWTemplateSpecModel.js index adf6e0e..884b31c 100644 --- a/modules/ve-mw/dm/models/ve.dm.MWTemplateSpecModel.js +++ b/modules/ve-mw/dm/models/ve.dm.MWTemplateSpecModel.js @@ -128,7 +128,7 @@ 'default': '', 'type': 'string', 'aliases': [], - 'origin': name, + 'name': name, 'required': false, 'deprecated': false }; @@ -173,14 +173,27 @@ }; /** - * Check if a parameter is known. + * Check if a parameter name is known. + * + * Could be a primary name or alias. * * @method * @param {string} name Parameter name - * @returns {boolean} Parameter is known + * @returns {boolean} Parameter name is known */ ve.dm.MWTemplateSpecModel.prototype.isParameterKnown = function ( name ) { return this.params[name] !== undefined; +}; + +/** + * Check if a parameter name is an alias. + * + * @method + * @param {string} name Parameter name + * @returns {boolean} Parameter name is an alias + */ +ve.dm.MWTemplateSpecModel.prototype.isParameterAlias = function ( name ) { + return this.params[name] !== undefined && this.params[name].name !== name; }; /** @@ -239,16 +252,16 @@ }; /** - * Get the parameter origin, which is the parameter this is an alias of. + * Get the parameter name, resolving an alias. * - * If a parameter is not an alias of another, its origin and name will be the same. + * If a parameter is not an alias of another, the output will be the same as the input. * * @method - * @param {string} name Parameter name - * @returns {string} Origin parameter name + * @param {string} name Parameter alias + * @returns {string} Parameter name */ -ve.dm.MWTemplateSpecModel.prototype.getParameterOrigin = function ( name ) { - return this.params[name].origin; +ve.dm.MWTemplateSpecModel.prototype.getParameterName = function ( name ) { + return this.params[name].name; }; /** @@ -285,13 +298,22 @@ }; /** - * Get all parameter specifications. + * Get all primary parameter names. * * @method * @returns {string[]} Parameter names */ ve.dm.MWTemplateSpecModel.prototype.getParameterNames = function () { - return ve.getObjectKeys( this.params ); + var name, + names = []; + + for ( name in this.params ) { + if ( this.params[name].name === name ) { + names.push( name ); + } + } + + return names; }; /** diff --git a/modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js b/modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js index a850ccd..f8b8240 100644 --- a/modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js +++ b/modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js @@ -14,10 +14,12 @@ * @constructor * @param {ve.dm.MWTransclusionModel} transclusion Transclusion * @param {string} [value] Content value + * @param {string} [origin] Origin of part, e.g. 'data' or 'user' */ -ve.dm.MWTransclusionContentModel = function VeDmMWTransclusionContentModel( transclusion, value ) { +ve.dm.MWTransclusionContentModel = + function VeDmMWTransclusionContentModel( transclusion, value, origin ) { // Parent constructor - ve.dm.MWTransclusionPartModel.call( this, transclusion ); + ve.dm.MWTransclusionPartModel.call( this, transclusion, origin ); // Properties this.value = value || ''; diff --git a/modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js b/modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js index 82ac39c..9c82ee7 100644 --- a/modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js +++ b/modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js @@ -67,17 +67,19 @@ for ( i = 0, len = data.parts.length; i < len; i++ ) { part = data.parts[i]; if ( part.template ) { - template = new ve.dm.MWTemplateModel( this, part.template.target ); + template = new ve.dm.MWTemplateModel( this, part.template.target, 'data' ); for ( key in part.template.params ) { template.addParameter( new ve.dm.MWTemplateParameterModel( - template, key, part.template.params[key].wt + template, key, part.template.params[key].wt, 'data' ) ); } this.queue.push( { 'part': template } ); } else if ( typeof part === 'string' ) { - this.queue.push( { 'part': new ve.dm.MWTransclusionContentModel( this, part ) } ); + this.queue.push( { + 'part': new ve.dm.MWTransclusionContentModel( this, part, 'data' ) + } ); } } setTimeout( ve.bind( this.fetch, this ) ); diff --git a/modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js b/modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js index 6c640c8..d03fb55 100644 --- a/modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js +++ b/modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js @@ -13,13 +13,15 @@ * * @constructor * @param {ve.dm.MWTransclusionModel} transclusion Transclusion + * @param {string} [origin] Origin of part, e.g. 'data' or 'user' */ -ve.dm.MWTransclusionPartModel = function VeDmMWTransclusionPartModel( transclusion ) { +ve.dm.MWTransclusionPartModel = function VeDmMWTransclusionPartModel( transclusion, origin ) { // Mixin constructors ve.EventEmitter.call( this ); // Properties this.transclusion = transclusion; + this.origin = origin; this.id = 'part_' + this.transclusion.getUniquePartId(); }; @@ -40,9 +42,18 @@ }; /** + * Get part origin. + * + * @returns {string} Origin + */ +ve.dm.MWTransclusionPartModel.prototype.getOrigin = function () { + return this.origin; +}; + +/** * Get a unique part ID within the transclusion. * - * @returns {string} Unique ID. + * @returns {string} Unique ID */ ve.dm.MWTransclusionPartModel.prototype.getId = function () { return this.id; diff --git a/modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js b/modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js index 9237428..caa28d4 100644 --- a/modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js +++ b/modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js @@ -96,7 +96,9 @@ if ( this.node instanceof ve.ce.MWTransclusionNode ) { this.transclusion.load( ve.copyObject( this.node.getModel().getAttribute( 'mw' ) ) ); } else { - this.transclusion.addPart( new ve.dm.MWTemplatePlaceholderModel( this.transclusion ) ); + this.transclusion.addPart( + new ve.dm.MWTemplatePlaceholderModel( this.transclusion, 'user' ) + ); } }; @@ -143,7 +145,7 @@ * @param {ve.dm.MWTransclusionPartModel} part Added part */ ve.ui.MWTransclusionDialog.prototype.onAddPart = function ( part ) { - var i, len, page, params, param, names, pending, item; + var i, len, page, params, names, pending, item, spec; if ( part instanceof ve.dm.MWTemplateModel ) { page = this.getTemplatePage( part ); @@ -155,18 +157,29 @@ if ( page ) { page.index = this.getPageIndex( part ); this.addPage( part.getId(), page ); + // Add existing params to templates if ( part instanceof ve.dm.MWTemplateModel ) { names = part.getParameterNames(); params = part.getParameters(); for ( i = 0, len = names.length; i < len; i++ ) { - param = params[names[i]]; - page = this.getParameterPage( param ); - page.index = this.getPageIndex( param ); - this.addPage( param.getId(), page ); + this.onAddParameter( params[names[i]] ); } part.connect( this, { 'add': 'onAddParameter', 'remove': 'onRemoveParameter' } ); } } + + // Add required params to user created templates + if ( part instanceof ve.dm.MWTemplateModel && part.getOrigin() === 'user' ) { + spec = part.getSpec(); + names = spec.getParameterNames(); + for ( i = 0, len = names.length; i < len; i++ ) { + // Only add required params + if ( spec.isParameterRequired( names[i] ) ) { + part.addParameter( new ve.dm.MWTemplateParameterModel( part, names[i] ) ); + } + } + } + // Resolve pending placeholder for ( i = 0, len = this.pending.length; i < len; i++ ) { pending = this.pending[i]; @@ -259,12 +272,12 @@ switch ( type ) { case 'content': - part = new ve.dm.MWTransclusionContentModel( this.transclusion, '' ); + part = new ve.dm.MWTransclusionContentModel( this.transclusion, '', 'user' ); this.transclusion.addPart( part, this.getPartInsertionIndex() ); this.setPageByName( part.getId() ); break; case 'template': - part = new ve.dm.MWTemplatePlaceholderModel( this.transclusion ); + part = new ve.dm.MWTemplatePlaceholderModel( this.transclusion, 'user' ); this.transclusion.addPart( part, this.getPartInsertionIndex() ); this.setPageByName( part.getId() ); break; @@ -548,7 +561,7 @@ } target = { 'href': new mw.Title( href ).getPrefixedText(), 'wt': value }; - part = new ve.dm.MWTemplateModel( this.transclusion, target ); + part = new ve.dm.MWTemplateModel( this.transclusion, target, 'user' ); this.transclusion.addPart( part, ve.indexOf( placeholder, parts ) ); this.pending.push( { 'part': part, 'placeholder': placeholder } ); addTemplateInput.pushPending(); diff --git a/modules/ve-mw/ui/widgets/ve.ui.MWParameterSearchWidget.js b/modules/ve-mw/ui/widgets/ve.ui.MWParameterSearchWidget.js index eda0964..042237f 100644 --- a/modules/ve-mw/ui/widgets/ve.ui.MWParameterSearchWidget.js +++ b/modules/ve-mw/ui/widgets/ve.ui.MWParameterSearchWidget.js @@ -87,12 +87,8 @@ this.index.length = 0; for ( i = 0, len = knownParams.length; i < len; i++ ) { name = knownParams[i]; - if ( - // Skip aliases - spec.getParameterOrigin( name ) !== name || - // Skip parameters already in use - this.template.hasParameter( name ) - ) { + // Skip parameters already in use + if ( this.template.hasParameter( name ) ) { continue; } label = spec.getParameterLabel( name ); -- To view, visit https://gerrit.wikimedia.org/r/73136 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib444f0f5a8168cd59ea52a6000ba5e42ccdc2a24 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/VisualEditor Gerrit-Branch: master Gerrit-Owner: Trevor Parscal <tpars...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits