Esanders has uploaded a new change for review.
https://gerrit.wikimedia.org/r/207815
Change subject: Remote unless, and almost-useless closures in response cache
......................................................................
Remote unless, and almost-useless closures in response cache
Change-Id: Ie02caefe3d8c43b6b1e6b523fb07042f5ae6db37
---
M modules/ve-mw/init/ve.init.mw.ApiResponseCache.js
M modules/ve-mw/init/ve.init.mw.ImageInfoCache.js
M modules/ve-mw/init/ve.init.mw.LinkCache.js
3 files changed, 302 insertions(+), 309 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/15/207815/1
diff --git a/modules/ve-mw/init/ve.init.mw.ApiResponseCache.js
b/modules/ve-mw/init/ve.init.mw.ApiResponseCache.js
index 084a668..636cf1d 100644
--- a/modules/ve-mw/init/ve.init.mw.ApiResponseCache.js
+++ b/modules/ve-mw/init/ve.init.mw.ApiResponseCache.js
@@ -4,188 +4,185 @@
* @copyright 2011-2015 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function () {
- var hasOwn = Object.prototype.hasOwnProperty;
- /**
- * MediaWiki API batch queue.
- *
- * Used to queue up lists of items centrally to get information about
in batches
- * of requests.
- *
- * @class
- * @extends OO.EventEmitter
- * @constructor
- */
- ve.init.mw.ApiResponseCache = function VeInitMwApiResponseCache() {
- // Mixin constructor
- OO.EventEmitter.call( this );
+/**
+ * MediaWiki API batch queue.
+ *
+ * Used to queue up lists of items centrally to get information about in
batches
+ * of requests.
+ *
+ * @class
+ * @extends OO.EventEmitter
+ * @constructor
+ */
+ve.init.mw.ApiResponseCache = function VeInitMwApiResponseCache() {
+ // Mixin constructor
+ OO.EventEmitter.call( this );
- // Keys are titles, values are deferreds
- this.deferreds = {};
+ // Keys are titles, values are deferreds
+ this.deferreds = {};
- // Keys are page names, values are link data objects
- // This is kept for synchronous retrieval of cached values via
#getCached
- this.cacheValues = {};
+ // Keys are page names, values are link data objects
+ // This is kept for synchronous retrieval of cached values via
#getCached
+ this.cacheValues = {};
- // Array of page titles queued to be looked up
- this.queue = [];
+ // Array of page titles queued to be looked up
+ this.queue = [];
- this.schedule = ve.debounce( this.processQueue.bind( this ), 0
);
- };
+ this.schedule = ve.debounce( this.processQueue.bind( this ), 0 );
+};
- /* Inheritance */
+/* Inheritance */
- OO.mixinClass( ve.init.mw.ApiResponseCache, OO.EventEmitter );
+OO.mixinClass( ve.init.mw.ApiResponseCache, OO.EventEmitter );
- /* Static methods */
+/* Static methods */
- /**
- * Process each page in the response of an API request
- *
- * @abstract
- * @static
- * @method
- * @param {Object} page The page object
- * @return {Object|undefined} Any relevant info that we want to cache
and return.
- */
- ve.init.mw.ApiResponseCache.static.processPage = null;
+/**
+ * Process each page in the response of an API request
+ *
+ * @abstract
+ * @static
+ * @method
+ * @param {Object} page The page object
+ * @return {Object|undefined} Any relevant info that we want to cache and
return.
+ */
+ve.init.mw.ApiResponseCache.static.processPage = null;
- /**
- * Normalize the title of the response
- *
- * @param {string} title Title
- * @return {string} Normalized title
- */
- ve.init.mw.ApiResponseCache.static.normalizeTitle = function ( title ) {
- var titleObj = mw.Title.newFromText( title );
- if ( !titleObj ) {
- return title;
- }
- return titleObj.getPrefixedText();
- };
+/**
+ * Normalize the title of the response
+ *
+ * @param {string} title Title
+ * @return {string} Normalized title
+ */
+ve.init.mw.ApiResponseCache.static.normalizeTitle = function ( title ) {
+ var titleObj = mw.Title.newFromText( title );
+ if ( !titleObj ) {
+ return title;
+ }
+ return titleObj.getPrefixedText();
+};
- /* Methods */
+/* Methods */
- /**
- * Look up data about a title. If the data about this title is already
in the cache, this
- * returns an already-resolved promise. Otherwise, it returns a pending
promise and schedules
- * an request to retrieve the data.
- * @param {string} title Title
- * @returns {jQuery.Promise} Promise that will be resolved with the
data once it's available
- */
- ve.init.mw.ApiResponseCache.prototype.get = function ( title ) {
- if ( typeof title !== 'string' ) {
- // Don't bother letting things like undefined or null
make it all the way through,
- // just reject them here. Otherwise they'll cause
problems or exceptions at random
- // other points in this file.
- return $.Deferred().reject().promise();
- }
- title = this.constructor.static.normalizeTitle( title );
- if ( !hasOwn.call( this.deferreds, title ) ) {
- this.deferreds[title] = $.Deferred();
- this.queue.push( title );
- this.schedule();
- }
- return this.deferreds[title].promise();
- };
+/**
+ * Look up data about a title. If the data about this title is already in the
cache, this
+ * returns an already-resolved promise. Otherwise, it returns a pending
promise and schedules
+ * an request to retrieve the data.
+ * @param {string} title Title
+ * @returns {jQuery.Promise} Promise that will be resolved with the data once
it's available
+ */
+ve.init.mw.ApiResponseCache.prototype.get = function ( title ) {
+ if ( typeof title !== 'string' ) {
+ // Don't bother letting things like undefined or null make it
all the way through,
+ // just reject them here. Otherwise they'll cause problems or
exceptions at random
+ // other points in this file.
+ return $.Deferred().reject().promise();
+ }
+ title = this.constructor.static.normalizeTitle( title );
+ if ( !Object.prototype.hasOwnProperty.call( this.deferreds, title ) ) {
+ this.deferreds[title] = $.Deferred();
+ this.queue.push( title );
+ this.schedule();
+ }
+ return this.deferreds[title].promise();
+};
- /**
- * Look up data about a page in the cache. If the data about this page
is already in the cache,
- * this returns that data. Otherwise, it returns undefined.
- *
- * @param {string} name Normalized page title
- * @returns {Object|undefined} Cache data for this name.
- */
- ve.init.mw.ApiResponseCache.prototype.getCached = function ( name ) {
+/**
+ * Look up data about a page in the cache. If the data about this page is
already in the cache,
+ * this returns that data. Otherwise, it returns undefined.
+ *
+ * @param {string} name Normalized page title
+ * @returns {Object|undefined} Cache data for this name.
+ */
+ve.init.mw.ApiResponseCache.prototype.getCached = function ( name ) {
+ if ( Object.prototype.hasOwnProperty.call( this.cacheValues, name ) ) {
+ return this.cacheValues[name];
+ }
+};
+
+/**
+ * Fired when a new entry is added to the cache.
+ *
+ * @event add
+ * @param {Object} entries Cache entries that were added. Object mapping names
to data objects.
+ */
+
+/**
+ * Add entries to the cache.
+ *
+ * @param {Object} entries Object keyed by page title, with the values being
data objects
+ * @fires add
+ */
+ve.init.mw.ApiResponseCache.prototype.set = function ( entries ) {
+ var name, hasOwn = Object.prototype.hasOwnProperty;
+ for ( name in entries ) {
if ( hasOwn.call( this.cacheValues, name ) ) {
- return this.cacheValues[name];
+ continue;
}
- };
-
- /**
- * Fired when a new entry is added to the cache.
- *
- * @event add
- * @param {Object} entries Cache entries that were added. Object
mapping names to data objects.
- */
-
- /**
- * Add entries to the cache.
- *
- * @param {Object} entries Object keyed by page title, with the values
being data objects
- * @fires add
- */
- ve.init.mw.ApiResponseCache.prototype.set = function ( entries ) {
- var name;
- for ( name in entries ) {
- if ( hasOwn.call( this.cacheValues, name ) ) {
- continue;
- }
- if ( !hasOwn.call( this.deferreds, name ) ) {
- this.deferreds[name] = $.Deferred();
- }
- this.deferreds[name].resolve( entries[name] );
- this.cacheValues[name] = entries[name];
+ if ( !hasOwn.call( this.deferreds, name ) ) {
+ this.deferreds[name] = $.Deferred();
}
- this.emit( 'add', Object.keys( entries ) );
- };
+ this.deferreds[name].resolve( entries[name] );
+ this.cacheValues[name] = entries[name];
+ }
+ this.emit( 'add', Object.keys( entries ) );
+};
- /**
- * Get an API request promise to deal with a list of titles
- *
- * @abstract
- * @method
- * @param subqueue
- * @return {jQuery.Promise}
- */
- ve.init.mw.ApiResponseCache.prototype.getRequestPromise = null;
+/**
+ * Get an API request promise to deal with a list of titles
+ *
+ * @abstract
+ * @method
+ * @param subqueue
+ * @return {jQuery.Promise}
+ */
+ve.init.mw.ApiResponseCache.prototype.getRequestPromise = null;
- /**
- * Perform any scheduled API requests.
- *
- * @private
- * @fires add
- */
- ve.init.mw.ApiResponseCache.prototype.processQueue = function () {
- var subqueue, queue,
- cache = this;
+/**
+ * Perform any scheduled API requests.
+ *
+ * @private
+ * @fires add
+ */
+ve.init.mw.ApiResponseCache.prototype.processQueue = function () {
+ var subqueue, queue,
+ cache = this;
- function rejectSubqueue( rejectQueue ) {
- var i, len;
- for ( i = 0, len = rejectQueue.length; i < len; i++ ) {
- cache.deferreds[rejectQueue[i]].reject();
- }
+ function rejectSubqueue( rejectQueue ) {
+ var i, len;
+ for ( i = 0, len = rejectQueue.length; i < len; i++ ) {
+ cache.deferreds[rejectQueue[i]].reject();
}
+ }
- function processResult( data ) {
- var pageid, page, processedPage,
- pages = ( data.query && data.query.pages ) ||
data.pages,
- processed = {};
+ function processResult( data ) {
+ var pageid, page, processedPage,
+ pages = ( data.query && data.query.pages ) ||
data.pages,
+ processed = {};
- if ( pages ) {
- for ( pageid in pages ) {
- page = pages[pageid];
- processedPage =
cache.constructor.static.processPage( page );
- if ( processedPage !== undefined ) {
- processed[page.title] =
processedPage;
- }
+ if ( pages ) {
+ for ( pageid in pages ) {
+ page = pages[pageid];
+ processedPage =
cache.constructor.static.processPage( page );
+ if ( processedPage !== undefined ) {
+ processed[page.title] = processedPage;
}
- cache.set( processed );
}
+ cache.set( processed );
}
+ }
- queue = this.queue;
- this.queue = [];
- while ( queue.length ) {
- subqueue = queue.splice( 0, 50 ).map(
this.constructor.static.normalizeTitle );
- this.getRequestPromise( subqueue )
- .then( processResult )
+ queue = this.queue;
+ this.queue = [];
+ while ( queue.length ) {
+ subqueue = queue.splice( 0, 50 ).map(
this.constructor.static.normalizeTitle );
+ this.getRequestPromise( subqueue )
+ .then( processResult )
- // Reject everything in subqueue; this will
only reject the ones
- // that weren't already resolved above, because
.reject() on an
- // already resolved Deferred is a no-op.
- .then( rejectSubqueue.bind( null, subqueue ) );
- }
- };
-}() );
+ // Reject everything in subqueue; this will only reject
the ones
+ // that weren't already resolved above, because
.reject() on an
+ // already resolved Deferred is a no-op.
+ .then( rejectSubqueue.bind( null, subqueue ) );
+ }
+};
diff --git a/modules/ve-mw/init/ve.init.mw.ImageInfoCache.js
b/modules/ve-mw/init/ve.init.mw.ImageInfoCache.js
index d224592..036be4b 100644
--- a/modules/ve-mw/init/ve.init.mw.ImageInfoCache.js
+++ b/modules/ve-mw/init/ve.init.mw.ImageInfoCache.js
@@ -4,48 +4,46 @@
* @copyright 2011-2015 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function () {
- /**
- * Get information about images.
- * @class
- * @extends ve.init.mw.ApiResponseCache
- * @constructor
- */
- ve.init.mw.ImageInfoCache = function VeInitMwImageInfoCache() {
- ve.init.mw.ImageInfoCache.super.call( this );
- };
- /* Inheritance */
+/**
+ * Get information about images.
+ * @class
+ * @extends ve.init.mw.ApiResponseCache
+ * @constructor
+ */
+ve.init.mw.ImageInfoCache = function VeInitMwImageInfoCache() {
+ ve.init.mw.ImageInfoCache.super.call( this );
+};
- OO.inheritClass( ve.init.mw.ImageInfoCache, ve.init.mw.ApiResponseCache
);
+/* Inheritance */
- /* Static methods */
+OO.inheritClass( ve.init.mw.ImageInfoCache, ve.init.mw.ApiResponseCache );
- /**
- * @inheritdoc
- */
- ve.init.mw.ImageInfoCache.static.processPage = function ( page ) {
- if ( page.imageinfo ) {
- return page.imageinfo[0];
- }
- };
+/* Static methods */
- /* Methods */
+/**
+ * @inheritdoc
+ */
+ve.init.mw.ImageInfoCache.static.processPage = function ( page ) {
+ if ( page.imageinfo ) {
+ return page.imageinfo[0];
+ }
+};
- /**
- * @inheritdoc
- */
- ve.init.mw.ImageInfoCache.prototype.getRequestPromise = function (
subqueue ) {
- return new mw.Api().get(
- {
- action: 'query',
- prop: 'imageinfo',
- indexpageids: '1',
- iiprop: 'size|mediatype',
- titles: subqueue.join( '|' )
- },
- { type: 'POST' }
- );
- };
+/* Methods */
-}() );
+/**
+ * @inheritdoc
+ */
+ve.init.mw.ImageInfoCache.prototype.getRequestPromise = function ( subqueue ) {
+ return new mw.Api().get(
+ {
+ action: 'query',
+ prop: 'imageinfo',
+ indexpageids: '1',
+ iiprop: 'size|mediatype',
+ titles: subqueue.join( '|' )
+ },
+ { type: 'POST' }
+ );
+};
diff --git a/modules/ve-mw/init/ve.init.mw.LinkCache.js
b/modules/ve-mw/init/ve.init.mw.LinkCache.js
index 95b589f..a4af640 100644
--- a/modules/ve-mw/init/ve.init.mw.LinkCache.js
+++ b/modules/ve-mw/init/ve.init.mw.LinkCache.js
@@ -4,125 +4,123 @@
* @copyright 2011-2015 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
-( function () {
- /**
- * Caches information about titles.
- * @class
- * @extends ve.init.mw.ApiResponseCache
- * @constructor
- */
- ve.init.mw.LinkCache = function VeInitMwLinkCache() {
- ve.init.mw.LinkCache.super.call( this );
- // Keys are page names, values are link data objects
- // This is kept for synchronous retrieval of cached values via
#getCached
- this.cacheValues = {};
+/**
+ * Caches information about titles.
+ * @class
+ * @extends ve.init.mw.ApiResponseCache
+ * @constructor
+ */
+ve.init.mw.LinkCache = function VeInitMwLinkCache() {
+ ve.init.mw.LinkCache.super.call( this );
+
+ // Keys are page names, values are link data objects
+ // This is kept for synchronous retrieval of cached values via
#getCached
+ this.cacheValues = {};
+};
+
+/* Inheritance */
+
+OO.inheritClass( ve.init.mw.LinkCache, ve.init.mw.ApiResponseCache );
+
+/* Static methods */
+
+/**
+ * Get the icon name to use for a particular link type
+ *
+ * @param {Object} linkData Link data
+ * @return {string} Icon name
+ */
+ve.init.mw.LinkCache.static.getIconForLink = function ( linkData ) {
+ if ( linkData.missing ) {
+ return 'page-not-found';
+ }
+ if ( linkData.redirect ) {
+ return 'page-redirect';
+ }
+ if ( linkData.disambiguation ) {
+ return 'page-disambiguation';
+ }
+ return 'page-existing';
+};
+
+/**
+ * @inheritdoc
+ */
+ve.init.mw.LinkCache.static.processPage = function ( page ) {
+ return {
+ missing: page.missing !== undefined,
+ redirect: page.redirect !== undefined,
+ disambiguation: ve.getProp( page, 'pageprops', 'disambiguation'
) !== undefined,
+ imageUrl: ve.getProp( page, 'thumbnail', 'source' ),
+ description: ve.getProp( page, 'terms', 'description' )
};
+};
- /* Inheritance */
+/* Methods */
- OO.inheritClass( ve.init.mw.LinkCache, ve.init.mw.ApiResponseCache );
-
- /* Static methods */
-
- /**
- * Get the icon name to use for a particular link type
- *
- * @param {Object} linkData Link data
- * @return {string} Icon name
- */
- ve.init.mw.LinkCache.static.getIconForLink = function ( linkData ) {
- if ( linkData.missing ) {
- return 'page-not-found';
- }
- if ( linkData.redirect ) {
- return 'page-redirect';
- }
- if ( linkData.disambiguation ) {
- return 'page-disambiguation';
- }
- return 'page-existing';
- };
-
- /**
- * @inheritdoc
- */
- ve.init.mw.LinkCache.static.processPage = function ( page ) {
- return {
- missing: page.missing !== undefined,
- redirect: page.redirect !== undefined,
- disambiguation: ve.getProp( page, 'pageprops',
'disambiguation' ) !== undefined,
- imageUrl: ve.getProp( page, 'thumbnail', 'source' ),
- description: ve.getProp( page, 'terms', 'description' )
- };
- };
-
- /* Methods */
-
- /**
- * Requests information about the title, then adds classes to the
provided element as appropriate.
- *
- * @param {string} title
- * @param {jQuery} $element Element to style
- */
- ve.init.mw.LinkCache.prototype.styleElement = function ( title,
$element ) {
- this.get( title ).done( function ( data ) {
- if ( data.missing ) {
- $element.addClass( 'new' );
- } else {
- // Provided by core MediaWiki, no styles by
default.
- if ( data.redirect ) {
- $element.addClass( 'mw-redirect' );
- }
- // Should be provided by the Disambiguator
extension, but no one has yet written a suitably
- // performant patch to do it. It is instead
implemented in JavaScript in on-wiki gadgets.
- if ( data.disambiguation ) {
- $element.addClass( 'mw-disambig' );
- }
+/**
+ * Requests information about the title, then adds classes to the provided
element as appropriate.
+ *
+ * @param {string} title
+ * @param {jQuery} $element Element to style
+ */
+ve.init.mw.LinkCache.prototype.styleElement = function ( title, $element ) {
+ this.get( title ).done( function ( data ) {
+ if ( data.missing ) {
+ $element.addClass( 'new' );
+ } else {
+ // Provided by core MediaWiki, no styles by default.
+ if ( data.redirect ) {
+ $element.addClass( 'mw-redirect' );
}
- } );
- };
-
- /**
- * Enable or disable automatic assumption of existence.
- *
- * While enabled, any get() for a title that's not already in the cache
will return
- * { missing: false } and write that to the cache.
- *
- * @param {boolean} assume Assume all uncached titles exist
- */
- ve.init.mw.LinkCache.prototype.setAssumeExistence = function ( assume )
{
- this.assumeExistence = !!assume;
- };
-
- /**
- * @inheritdoc
- */
- ve.init.mw.LinkCache.prototype.get = function ( title ) {
- var data = {};
- if ( this.assumeExistence ) {
- data[this.constructor.static.normalizeTitle( title )] =
{ missing: false };
- this.set( data );
+ // Should be provided by the Disambiguator extension,
but no one has yet written a suitably
+ // performant patch to do it. It is instead implemented
in JavaScript in on-wiki gadgets.
+ if ( data.disambiguation ) {
+ $element.addClass( 'mw-disambig' );
+ }
}
+ } );
+};
- // Parent method
- return ve.init.mw.LinkCache.super.prototype.get.call( this,
title );
- };
+/**
+ * Enable or disable automatic assumption of existence.
+ *
+ * While enabled, any get() for a title that's not already in the cache will
return
+ * { missing: false } and write that to the cache.
+ *
+ * @param {boolean} assume Assume all uncached titles exist
+ */
+ve.init.mw.LinkCache.prototype.setAssumeExistence = function ( assume ) {
+ this.assumeExistence = !!assume;
+};
- /**
- * @inheritdoc
- */
- ve.init.mw.LinkCache.prototype.getRequestPromise = function ( subqueue
) {
- return new mw.Api().get( {
- action: 'query',
- gpslimit: 10,
- prop: 'info|pageprops|pageimages|pageterms',
- pithumbsize: 80,
- pilimit: 10,
- wbptterms: 'description',
- ppprop: 'disambiguation',
- titles: subqueue.join( '|' )
- } );
- };
+/**
+ * @inheritdoc
+ */
+ve.init.mw.LinkCache.prototype.get = function ( title ) {
+ var data = {};
+ if ( this.assumeExistence ) {
+ data[this.constructor.static.normalizeTitle( title )] = {
missing: false };
+ this.set( data );
+ }
-}() );
+ // Parent method
+ return ve.init.mw.LinkCache.super.prototype.get.call( this, title );
+};
+
+/**
+ * @inheritdoc
+ */
+ve.init.mw.LinkCache.prototype.getRequestPromise = function ( subqueue ) {
+ return new mw.Api().get( {
+ action: 'query',
+ gpslimit: 10,
+ prop: 'info|pageprops|pageimages|pageterms',
+ pithumbsize: 80,
+ pilimit: 10,
+ wbptterms: 'description',
+ ppprop: 'disambiguation',
+ titles: subqueue.join( '|' )
+ } );
+};
--
To view, visit https://gerrit.wikimedia.org/r/207815
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie02caefe3d8c43b6b1e6b523fb07042f5ae6db37
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits