Trevor Parscal has uploaded a new change for review.
https://gerrit.wikimedia.org/r/71132
Change subject: Use template data for new templates
......................................................................
Use template data for new templates
Objectives:
* Use template data for templates added to a transclusion using the list
controls
* Cache template data between dialog openings
* Allow placeholders to be replaced with templates asynchronously
Bug: 49778
Change-Id: I391e51cb900ef5560455d6f3d4d2a8b99ed2b034
---
M modules/ve/dm/models/ve.dm.MWTemplateSpecModel.js
M modules/ve/dm/models/ve.dm.MWTransclusionModel.js
M modules/ve/ui/dialogs/ve.ui.MWTransclusionDialog.js
3 files changed, 91 insertions(+), 30 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/32/71132/1
diff --git a/modules/ve/dm/models/ve.dm.MWTemplateSpecModel.js
b/modules/ve/dm/models/ve.dm.MWTemplateSpecModel.js
index 9823a92..06a2d88 100644
--- a/modules/ve/dm/models/ve.dm.MWTemplateSpecModel.js
+++ b/modules/ve/dm/models/ve.dm.MWTemplateSpecModel.js
@@ -80,17 +80,15 @@
this.getDefaultParameterSpec( key ),
paramObj
);
+ // Add aliased references
if ( paramObj.aliases.length ) {
for ( i = 0, len = paramObj.aliases.length; i <
len; i++ ) {
this.params[ paramObj.aliases[i] ] =
paramObj;
}
}
- delete paramObj.aliases;
}
}
- if ( data.sets ) {
- this.sets = data.sets;
- }
+ this.sets = data.sets;
};
/**
@@ -126,6 +124,7 @@
'default': '',
'type': 'string',
'aliases': [],
+ 'origin': name,
'required': false,
'deprecated': false
};
@@ -225,6 +224,19 @@
};
/**
+ * Get the parameter origin, which is the parameter this is an alias of.
+ *
+ * If a parameter is not an alias of another, its origin and name will be the
same.
+ *
+ * @method
+ * @param {string} name Parameter name
+ * @returns {string} Origin parameter name
+ */
+ve.dm.MWTemplateSpecModel.prototype.getParameterOrigin = function ( name ) {
+ return this.params[name].origin;
+};
+
+/**
* Check if parameter is required.
*
* @method
diff --git a/modules/ve/dm/models/ve.dm.MWTransclusionModel.js
b/modules/ve/dm/models/ve.dm.MWTransclusionModel.js
index 595c3e2..9204e21 100644
--- a/modules/ve/dm/models/ve.dm.MWTransclusionModel.js
+++ b/modules/ve/dm/models/ve.dm.MWTransclusionModel.js
@@ -8,7 +8,13 @@
/*global mw */
( function () {
-var hasOwn = Object.hasOwnProperty;
+var hasOwn = Object.hasOwnProperty,
+ /**
+ * @property {Object} Template spec cache
+ * @static
+ * @private
+ */
+ specCache = {};
/**
* MediaWiki transclusion model.
@@ -24,8 +30,8 @@
// Properties
this.parts = [];
- this.specs = {};
this.uid = 0;
+ this.requests = [];
};
/* Inheritance */
@@ -81,7 +87,7 @@
}
// Add fetched specs to #specs store when the promise is resolved
return this.fetchSpecs( templates ).done( function ( specs ) {
- ve.extendObject( this.specs, specs );
+ ve.extendObject( specCache, specs );
} );
};
@@ -92,15 +98,16 @@
* @returns {jQuery.Promise} Promise, resolved when spec is loaded
*/
ve.dm.MWTransclusionModel.prototype.fetchSpecs = function ( templates ) {
- var i, len, title,
+ var i, len, title, request,
+ requests = this.requests,
deferred = $.Deferred(),
specs = {},
titles = [];
- // Get unique list of titles
+ // Get unique list of titles that aren't already loaded
for ( i = 0, len = templates.length; i < len; i++ ) {
title = templates[i].getTitle();
- if ( ve.indexOf( title, titles ) === -1 ) {
+ if ( !specCache[title] && ve.indexOf( title, titles ) === -1 ) {
titles.push( title );
}
}
@@ -112,7 +119,7 @@
}
// Request template specs from server
- $.ajax( {
+ request = $.ajax( {
'url': mw.util.wikiScript( 'api' ),
'dataType': 'json',
'data': {
@@ -153,9 +160,31 @@
} )
.fail( function () {
deferred.reject( 'http', arguments );
+ } )
+ .always( function () {
+ // Prune requests when complete
+ var index = requests.indexOf( request );
+ if ( index !== -1 ) {
+ requests.splice( index, 1 );
+ }
} );
+ requests.push( request );
return deferred.promise();
+};
+
+/**
+ * Abort any pending requests.
+ *
+ * @method
+ */
+ve.dm.MWTransclusionModel.prototype.abortRequests = function () {
+ var i, len;
+
+ for ( i = 0, len = this.requests.length; i < len; i++ ) {
+ this.requests[i].abort();
+ }
+ this.requests.length = 0;
};
/**
@@ -224,22 +253,32 @@
/**
* Add template part.
*
+ * Templates are added asynchronously.
+ *
* @method
* @param {Object} target Template target
* @param {string} target.wt Original wikitext of target
* @param {string} [target.href] Hypertext reference to target
* @param {number} [index] Specific index to add template at
- * @returns {ve.dm.MWTransclusionModel} Added template part
+ * @returns {ve.dm.MWTemplateModel} Added template part
* @emits add
*/
ve.dm.MWTransclusionModel.prototype.addTemplate = function ( target, index ) {
var part = new ve.dm.MWTemplateModel( this, target ),
- title = part.getTitle();
+ title = part.getTitle(),
+ finish = ve.bind( this.addPart, this, part, index );
- if ( hasOwn.call( this.specs, title ) ) {
- part.getSpec().extend( this.specs[title] );
+ if ( hasOwn.call( specCache, title ) ) {
+ part.getSpec().extend( specCache[title] );
+ setTimeout( finish );
+ } else {
+ // Add fetched specs to #specs store when the promise is
resolved
+ this.fetchSpecs( [ part ] )
+ .done( function ( specs ) {
+ ve.extendObject( specCache, specs );
+ } )
+ .always( finish );
}
- this.addPart( part, index );
return part;
};
@@ -317,17 +356,6 @@
}
}
return null;
-};
-
-/**
- * Get a template specification.
- *
- * @method
- * @param {string} name Template name
- * @returns {ve.dm.MWTemplateSpecModel} Template spec
- */
-ve.dm.MWTransclusionModel.prototype.getTemplateSpec = function ( name ) {
- return this.specs[name];
};
}() );
diff --git a/modules/ve/ui/dialogs/ve.ui.MWTransclusionDialog.js
b/modules/ve/ui/dialogs/ve.ui.MWTransclusionDialog.js
index 5d2c773..1583a78 100644
--- a/modules/ve/ui/dialogs/ve.ui.MWTransclusionDialog.js
+++ b/modules/ve/ui/dialogs/ve.ui.MWTransclusionDialog.js
@@ -44,6 +44,7 @@
// Properties
this.node = null;
this.transclusion = null;
+ this.pending = [];
};
/* Inheritance */
@@ -117,6 +118,9 @@
}
}
+ this.transclusion.disconnect( this );
+ this.transclusion.abortRequests();
+ this.transclusion = null;
this.clearPages();
this.node = null;
this.content = null;
@@ -129,7 +133,7 @@
* @param {ve.dm.MWTransclusionPartModel} part Added part
*/
ve.ui.MWTransclusionDialog.prototype.onAddPart = function ( part ) {
- var i, len, page, params, param, names;
+ var i, len, page, params, param, names, pending, item;
if ( part instanceof ve.dm.MWTemplateModel ) {
page = this.getTemplatePage( part );
@@ -151,6 +155,21 @@
this.addPage( param.getId(), page );
}
part.connect( this, { 'add': 'onAddParameter',
'remove': 'onRemoveParameter' } );
+ }
+ }
+ // Resolve pending placeholder
+ for ( i = 0, len = this.pending.length; i < len; i++ ) {
+ pending = this.pending[i];
+ if ( pending.part === part ) {
+ // Auto-select new part if placeholder is still selected
+ item = this.outlineWidget.getSelectedItem();
+ if ( item.getData() === pending.placeholder.getId() ) {
+ this.setPageByName( part.getId() );
+ }
+ // Cleanup
+ pending.placeholder.remove();
+ this.pending.splice( i, 1 );
+ break;
}
}
};
@@ -550,8 +569,10 @@
target = { 'href': new mw.Title( href ).getPrefixedText(),
'wt': value };
part = this.transclusion.addTemplate( target, ve.indexOf(
placeholder, parts ) );
- this.setPageByName( part.getId() );
- placeholder.remove();
+ this.pending.push( { 'part': part, 'placeholder': placeholder }
);
+ addTemplateInput.pushPending();
+ addTemplateButton.setDisabled( true );
+ removeButton.setDisabled( true );
}
addTemplateFieldset = new ve.ui.FieldsetLayout( {
--
To view, visit https://gerrit.wikimedia.org/r/71132
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I391e51cb900ef5560455d6f3d4d2a8b99ed2b034
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Trevor Parscal <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits