From 12251c76f720dd168dfcc361f0685045e846ab7d Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Wed, 5 Mar 2014 14:25:29 +0100 Subject: [PATCH] mediawiki.api: Use Promise.then instead of manual Deferred wrap This is exactly what Promise.then is built for. As a nice bonus, this way the fail/reject handler is transferred automatically, and we don't need to call resolve() manually since the return value from then(Function done) is the resolved value (or another promise). Minor clean up: * category: Fix type documentation (primitive string instead of String object). * category: Use simple boolean check to assert value is no longer false. * Use String() cast instead of explicitly calling .toString. * parse: Fix bug where in theory the deferred would never be resolved if the condition evaluated to false. * watch: Add missing @static. * watch: Simplify params/$.extend logic. Change-Id: Iedbc70b2573c4f6b0d9e133c6f31e8f0b19c6f5e --- .../mediawiki.api/mediawiki.api.category.js | 88 +++++++++---------- resources/mediawiki.api/mediawiki.api.edit.js | 2 +- resources/mediawiki.api/mediawiki.api.js | 2 +- .../mediawiki.api/mediawiki.api.parse.js | 26 +++--- .../mediawiki.api/mediawiki.api.watch.js | 38 ++++---- 5 files changed, 73 insertions(+), 83 deletions(-) diff --git a/resources/mediawiki.api/mediawiki.api.category.js b/resources/mediawiki.api/mediawiki.api.category.js index 57eda3df99..026052c5d7 100644 --- a/resources/mediawiki.api/mediawiki.api.category.js +++ b/resources/mediawiki.api/mediawiki.api.category.js @@ -15,21 +15,19 @@ * @return {boolean} return.done.isCategory Whether the category exists. */ isCategory: function ( title, ok, err ) { - var d = $.Deferred(), - apiPromise; + var apiPromise = this.get( { + prop: 'categoryinfo', + titles: String( title ) + } ); // Backwards compatibility (< MW 1.20) if ( ok || err ) { mw.track( 'mw.deprecate', 'api.cbParam' ); mw.log.warn( msg ); - d.done( ok ).fail( err ); } - apiPromise = this.get( { - prop: 'categoryinfo', - titles: title.toString() - } ) - .done( function ( data ) { + return apiPromise + .then( function ( data ) { var exists = false; if ( data.query && data.query.pages ) { $.each( data.query.pages, function ( id, page ) { @@ -38,52 +36,52 @@ } } ); } - d.resolve( exists ); + return exists; } ) - .fail( d.reject ); - - return d.promise( { abort: apiPromise.abort } ); + .done( ok ) + .fail( err ) + .promise( { abort: apiPromise.abort } ); }, /** * Get a list of categories that match a certain prefix. - * e.g. given "Foo", return "Food", "Foolish people", "Foosball tables" ... + * + * E.g. given "Foo", return "Food", "Foolish people", "Foosball tables" ... + * * @param {string} prefix Prefix to match. * @param {Function} [ok] Success callback (deprecated) * @param {Function} [err] Error callback (deprecated) * @return {jQuery.Promise} * @return {Function} return.done - * @return {String[]} return.done.categories Matched categories + * @return {string[]} return.done.categories Matched categories */ getCategoriesByPrefix: function ( prefix, ok, err ) { - var d = $.Deferred(), - apiPromise; + // Fetch with allpages to only get categories that have a corresponding description page. + var apiPromise = this.get( { + list: 'allpages', + apprefix: prefix, + apnamespace: mw.config.get( 'wgNamespaceIds' ).category + } ); // Backwards compatibility (< MW 1.20) if ( ok || err ) { mw.track( 'mw.deprecate', 'api.cbParam' ); mw.log.warn( msg ); - d.done( ok ).fail( err ); } - // Fetch with allpages to only get categories that have a corresponding description page. - apiPromise = this.get( { - list: 'allpages', - apprefix: prefix, - apnamespace: mw.config.get( 'wgNamespaceIds' ).category - } ) - .done( function ( data ) { + return apiPromise + .then( function ( data ) { var texts = []; if ( data.query && data.query.allpages ) { $.each( data.query.allpages, function ( i, category ) { texts.push( new mw.Title( category.title ).getNameText() ); } ); } - d.resolve( texts ); + return texts; } ) - .fail( d.reject ); - - return d.promise( { abort: apiPromise.abort } ); + .done( ok ) + .fail( err ) + .promise( { abort: apiPromise.abort } ); }, @@ -99,41 +97,39 @@ * if title was not found. */ getCategories: function ( title, ok, err, async ) { - var d = $.Deferred(), - apiPromise; + var apiPromise = this.get( { + prop: 'categories', + titles: String( title ) + }, { + async: async === undefined ? true : async + } ); // Backwards compatibility (< MW 1.20) if ( ok || err ) { mw.track( 'mw.deprecate', 'api.cbParam' ); mw.log.warn( msg ); - d.done( ok ).fail( err ); } - apiPromise = this.get( { - prop: 'categories', - titles: title.toString() - }, { - async: async === undefined ? true : async - } ) - .done( function ( data ) { - var ret = false; + return apiPromise + .then( function ( data ) { + var titles = false; if ( data.query && data.query.pages ) { $.each( data.query.pages, function ( id, page ) { if ( page.categories ) { - if ( typeof ret !== 'object' ) { - ret = []; + if ( titles === false ) { + titles = []; } $.each( page.categories, function ( i, cat ) { - ret.push( new mw.Title( cat.title ) ); + titles.push( new mw.Title( cat.title ) ); } ); } } ); } - d.resolve( ret ); + return titles; } ) - .fail( d.reject ); - - return d.promise( { abort: apiPromise.abort } ); + .done( ok ) + .fail( err ) + .promise( { abort: apiPromise.abort } ); } } ); diff --git a/resources/mediawiki.api/mediawiki.api.edit.js b/resources/mediawiki.api/mediawiki.api.edit.js index 91d9b8f9fc..edfb34a720 100644 --- a/resources/mediawiki.api/mediawiki.api.edit.js +++ b/resources/mediawiki.api/mediawiki.api.edit.js @@ -60,7 +60,7 @@ action: 'edit', section: 'new', format: 'json', - title: title.toString(), + title: String( title ), summary: header, text: message } ).done( ok ).fail( err ); diff --git a/resources/mediawiki.api/mediawiki.api.js b/resources/mediawiki.api/mediawiki.api.js index 749086218e..914f3ec469 100644 --- a/resources/mediawiki.api/mediawiki.api.js +++ b/resources/mediawiki.api/mediawiki.api.js @@ -49,7 +49,7 @@ options = {}; } - // Force toString if we got a mw.Uri object + // Force a string if we got a mw.Uri object if ( options.ajax && options.ajax.url !== undefined ) { options.ajax.url = String( options.ajax.url ); } diff --git a/resources/mediawiki.api/mediawiki.api.parse.js b/resources/mediawiki.api/mediawiki.api.parse.js index 1c04b178e7..952dea4730 100644 --- a/resources/mediawiki.api/mediawiki.api.parse.js +++ b/resources/mediawiki.api/mediawiki.api.parse.js @@ -15,29 +15,25 @@ * @return {string} return.done.data Parsed HTML of `wikitext`. */ parse: function ( wikitext, ok, err ) { - var d = $.Deferred(), - apiPromise; + var apiPromise = this.get( { + action: 'parse', + contentmodel: 'wikitext', + text: wikitext + } ); // Backwards compatibility (< MW 1.20) if ( ok || err ) { mw.track( 'mw.deprecate', 'api.cbParam' ); mw.log.warn( 'Use of mediawiki.api callback params is deprecated. Use the Promise instead.' ); - d.done( ok ).fail( err ); } - apiPromise = this.get( { - action: 'parse', - contentmodel: 'wikitext', - text: wikitext + return apiPromise + .then( function ( data ) { + return data.parse.text['*']; } ) - .done( function ( data ) { - if ( data.parse && data.parse.text && data.parse.text['*'] ) { - d.resolve( data.parse.text['*'] ); - } - } ) - .fail( d.reject ); - - return d.promise( { abort: apiPromise.abort } ); + .done( ok ) + .fail( err ) + .promise( { abort: apiPromise.abort } ); } } ); diff --git a/resources/mediawiki.api/mediawiki.api.watch.js b/resources/mediawiki.api/mediawiki.api.watch.js index 653c90a4fb..9d65e1f3ed 100644 --- a/resources/mediawiki.api/mediawiki.api.watch.js +++ b/resources/mediawiki.api/mediawiki.api.watch.js @@ -6,6 +6,7 @@ /** * @private + * @static * @context mw.Api * * @param {string|mw.Title|string[]|mw.Title[]} pages Full page name or instance of mw.Title, or an @@ -24,35 +25,32 @@ function doWatchInternal( pages, ok, err, addParams ) { // XXX: Parameter addParams is undocumented because we inherit this // documentation in the public method.. - var params, apiPromise, - d = $.Deferred(); + var apiPromise = this.post( + $.extend( + { + action: 'watch', + titles: $.isArray( pages ) ? pages.join( '|' ) : String( pages ), + token: mw.user.tokens.get( 'watchToken' ), + uselang: mw.config.get( 'wgUserLanguage' ) + }, + addParams + ) + ); // Backwards compatibility (< MW 1.20) if ( ok || err ) { mw.track( 'mw.deprecate', 'api.cbParam' ); mw.log.warn( 'Use of mediawiki.api callback params is deprecated. Use the Promise instead.' ); - d.done( ok ).fail( err ); } - params = { - action: 'watch', - token: mw.user.tokens.get( 'watchToken' ), - uselang: mw.config.get( 'wgUserLanguage' ), - titles: $.isArray( pages ) ? pages.join( '|' ) : String( pages ) - }; - - if ( addParams ) { - $.extend( params, addParams ); - } - - apiPromise = this.post( params ) - .done( function ( data ) { + return apiPromise + .then( function ( data ) { // If a single page was given (not an array) respond with a single item as well. - d.resolve( $.isArray( pages ) ? data.watch : data.watch[0] ); + return $.isArray( pages ) ? data.watch : data.watch[0]; } ) - .fail( d.reject ); - - return d.promise( { abort: apiPromise.abort } ); + .done( ok ) + .fail( err ) + .promise( { abort: apiPromise.abort } ); } $.extend( mw.Api.prototype, { -- 2.20.1