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

Reply via email to