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

Reply via email to