jenkins-bot has submitted this change and it was merged. Change subject: ve.ui.MWTemplateDialog: Implement templatedata API fetch ......................................................................
ve.ui.MWTemplateDialog: Implement templatedata API fetch Fetch * Added basic name expansion logic since bug 48663 is not yet resolved in Parsoid. * Fetch info from template data API. Clean up (follows-up 97157a1c, de203cb8, 718db58) * Remove redundant initialize method. * Pass the entire target object to #getTemplateData because `target.wt` is *not* the template name. * Reorganise #createPage to be more logical and rename to #createParamPage. * Add todo comments for things currently missing. * Implement error handling of promise to prevent UI from going stale if the promise is not resolved. * Fix documentation in ve.ui.MWCategoryInputWidget. Change-Id: Ie0114a81eead86d7a3b3e3a7a5b10d25c457b524 --- M modules/ve/ui/dialogs/ve.ui.MWTemplateDialog.js M modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js 2 files changed, 107 insertions(+), 74 deletions(-) Approvals: Catrope: Looks good to me, approved jenkins-bot: Verified diff --git a/modules/ve/ui/dialogs/ve.ui.MWTemplateDialog.js b/modules/ve/ui/dialogs/ve.ui.MWTemplateDialog.js index 3ea15ec..548a962 100644 --- a/modules/ve/ui/dialogs/ve.ui.MWTemplateDialog.js +++ b/modules/ve/ui/dialogs/ve.ui.MWTemplateDialog.js @@ -5,8 +5,13 @@ * @license The MIT License (MIT); see LICENSE.txt */ +/*global mw */ + /** * Document dialog. + * + * See https://raw.github.com/wikimedia/mediawiki-extensions-TemplateData/master/spec.templatedata.json + * for the latest version of the TemplateData specification. * * @class * @extends ve.ui.PagedDialog @@ -35,68 +40,90 @@ /** * Handle frame ready events. - * - * @method - */ -ve.ui.MWTemplateDialog.prototype.initialize = function () { - // Call parent method - ve.ui.PagedDialog.prototype.initialize.call( this ); -}; - -/** - * Handle frame ready events. - * - * @method */ ve.ui.MWTemplateDialog.prototype.onOpen = function () { - var mwAttr = this.surface.view.focusedNode.model.getAttribute( 'mw' ); - this.getTemplateData( mwAttr.target.wt ).done( ve.bind( function( templateData ) { - var param; - this.paramsKeys = []; - this.paramsToInputs = {}; + var self = this, + mwAttr = this.surface.view.focusedNode.model.getAttribute( 'mw' ); + + function handle( templateData ) { + var param, + paramsData = templateData && templateData.params; + self.paramsKeys = []; + self.paramsToInputs = {}; // Parent method - ve.ui.PagedDialog.prototype.onOpen.call( this ); + ve.ui.PagedDialog.prototype.onOpen.call( self ); // Add template page - this.addPage( 'template', mwAttr.target.wt, 'template' ); + self.addPage( 'template', mwAttr.target.wt, 'template' ); // Loop through parameters for ( param in mwAttr.params ) { - this.createPage( + self.createParamPage( param, mwAttr.params[param], - templateData && templateData.params[param] + paramsData && paramsData[param] ); } - }, this ) ); + + // TODO: Ability to remove parameters + // TODO: Ability to add other parameters in paramsData + // Also account for paramsData#aliases + // TODO: Ability to add arbitrary parameters + // TODO: Use templateData.sets + } + + this.getTemplateData( mwAttr.target ) + .done( handle ) + .fail( function ( errorCode, details ) { + mw.log( 'TemplateData unavailable: ' + errorCode, mwAttr.target, details ); + handle(); + } ); }; /** * Handle creating page for single parameter. * - * @method + * @param {string} key Template parameter name + * @param {Object} value Value container with `wt` property + * @param {Object} paramData Param object from TemplateData */ -ve.ui.MWTemplateDialog.prototype.createPage = function( key, value, singleTemplateData ) { - var pageName = 'parameter_' + key, - label = singleTemplateData ? singleTemplateData.label.en : key, - fieldset, textInput, inputLabel; +ve.ui.MWTemplateDialog.prototype.createParamPage = function ( key, value, paramData ) { + var fieldset, textInput, inputLabel, + pageName = 'parameter_' + key, + label = paramData && paramData.label ? paramData.label.en : key, + description = paramData && paramData.description && paramData.description.en; - fieldset = new ve.ui.FieldsetLayout( { '$$': this.$$, 'label': label, 'icon': 'parameter' } ); - textInput = new ve.ui.TextInputWidget( { '$$': this.$$, 'multiline': true } ); - textInput.$input.css('height', 100); + // Label + fieldset = new ve.ui.FieldsetLayout( { + '$$': this.$$, + 'label': label, + 'icon': 'parameter' + } ); - if ( singleTemplateData ) { + textInput = new ve.ui.TextInputWidget( { + '$$': this.$$, + 'multiline': true + } ); + textInput.$input.css( 'height', 100 ); + textInput.setValue( value.wt ); + + // TODO: Use paramData.requred + // TODO: Use paramData.deprecation + // TODO: Use paramData.default + // TODO: Use paramData.type + + if ( description ) { inputLabel = new ve.ui.InputLabelWidget( { '$$': this.$$, 'input': textInput, - 'label': singleTemplateData.description.en + 'label': description } ); fieldset.$.append( inputLabel.$ ); } fieldset.$.append( textInput.$ ); - textInput.setValue( value.wt ); + this.addPage( pageName, label, 'parameter', 1 ); this.pages[pageName].$.append( fieldset.$ ); @@ -104,53 +131,58 @@ this.paramsToInputs[key] = textInput; }; -ve.ui.MWTemplateDialog.prototype.getTemplateData = function ( /*templateName*/ ) { - var promise = $.Deferred(), - templateData = { - 'title': 'Template:Unsigned', - 'params': { - 'user': { - 'label': { - 'en': 'User' - }, - 'description': { - 'en': 'Name or IP of user who left the comment' - }, - 'required': true, - 'type': 'string/wiki-user-name', - 'aliases': [ - '1' - ], - 'deprecated': false, - 'default': '' - }, - 'param1': { - 'label': { - 'en': 'Time stamp' - }, - 'description': { - 'en': 'datestamp from edit history (remember to label it UTC)' - }, - 'aliases': [ - '2' - ], - 'required': false, - 'deprecated': false, - 'default': '', - 'type': 'unknown' +/** + * @param {Object} template Information about the template target from Parsoid. + * Contains a `wt` property containing the wikitext of the invocation target. + * This is unprocessed so it can start with : and/or lack the proper namespace + * prefix for templates in the Template namespace. + * @return {jQuery.Promise} Template data blob on success, or an error code on failure. + */ +ve.ui.MWTemplateDialog.prototype.getTemplateData = function ( template ) { + var title, + d = $.Deferred(); + if ( !template.wt || template.wt.indexOf( '{' ) !== -1 ) { + // Name contains wikitext, need Parsoid to provide name (bug 48663) + d.reject( 'complicated' ); + } + // In sample cases we'll handle the namespace fallback (should ultimately + // be done by Parsoid, bug 48663). If the title has no namespace prefix, + // assume NS_TEMPLATE namespace (like MediaWiki does) + title = new mw.Title( template.wt ); + if ( title.getNamespaceId() === 0 && title.toString()[0] !== ':' ) { + title = new mw.Title( template.wt, mw.config.get( 'wgNamespaceIds' ).template ); + } + title = title.toString(); + $.ajax( { + 'url': mw.util.wikiScript( 'api' ), + 'dataType': 'json', + 'data': { + 'format': 'json', + 'action': 'templatedata', + 'titles': title + } + } ).done( function ( data ) { + var pageid, page; + if ( data && data.pages ) { + for ( pageid in data.pages ) { + page = data.pages[pageid]; + if ( page.title === title ) { + d.resolve( page ); + return; } } - }; - setTimeout( function() { - promise.resolve( templateData ); - }, 500 ); - return promise; + } + d.reject( 'unavailable', arguments ); + } ).fail( function () { + d.reject( 'http', arguments ); + } ); + + return d.promise(); }; /** * Handle frame ready events. * - * @method * @param {string} action Action that caused the window to be closed */ ve.ui.MWTemplateDialog.prototype.onClose = function ( action ) { diff --git a/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js b/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js index e7cbbf5..3c0ccd1 100644 --- a/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js +++ b/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js @@ -5,7 +5,7 @@ * @license The MIT License (MIT); see LICENSE.txt */ -/*global mw*/ +/*global mw */ /** * Creates an ve.ui.MWCategoryInputWidget object. @@ -16,6 +16,7 @@ * @mixins ve.ui.LookupInputWidget * * @constructor + * @param {ve.ui.MWCategoryWidget} categoryWidget * @param {Object} [config] Config options */ ve.ui.MWCategoryInputWidget = function VeUiMWCategoryInputWidget( categoryWidget, config ) { -- To view, visit https://gerrit.wikimedia.org/r/64651 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie0114a81eead86d7a3b3e3a7a5b10d25c457b524 Gerrit-PatchSet: 2 Gerrit-Project: mediawiki/extensions/VisualEditor Gerrit-Branch: master Gerrit-Owner: Krinkle <krinklem...@gmail.com> Gerrit-Reviewer: Catrope <roan.katt...@gmail.com> Gerrit-Reviewer: Christian <christ...@wikia-inc.com> Gerrit-Reviewer: Inez <i...@wikia-inc.com> Gerrit-Reviewer: Jforrester <jforres...@wikimedia.org> Gerrit-Reviewer: Trevor Parscal <tpars...@wikimedia.org> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits