Mooeypoo has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/189628

Change subject: [WIP] Generalize ResourceQueue and ResourceProvider and supply 
tests
......................................................................

[WIP] Generalize ResourceQueue and ResourceProvider and supply tests

* Depends on ve-core change I5346081317e *

Change-Id: If34cd99334f4ccb93015c3646f68ae3040b9c5d7
---
M .docs/categories.json
M VisualEditor.hooks.php
M VisualEditor.php
M extension.json
M lib/ve
M modules/ve-mw/dm/models/ve.dm.MWMediaResourceProvider.js
M modules/ve-mw/dm/models/ve.dm.MWMediaResourceQueue.js
7 files changed, 87 insertions(+), 317 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor 
refs/changes/28/189628/1

diff --git a/.docs/categories.json b/.docs/categories.json
index 7ef5618..dcee675 100644
--- a/.docs/categories.json
+++ b/.docs/categories.json
@@ -73,6 +73,8 @@
                                        "ve.dm.DocumentSynchronizer",
                                        "ve.dm.IndexValueStore",
                                        "ve.dm.Scalable",
+                                       "ve.dm.ResourceProvider",
+                                       "ve.dm.ResourceQueue",
                                        "ve.dm.NodeFactory",
                                        "ve.dm.Surface",
                                        "ve.dm.SurfaceFragment",
diff --git a/VisualEditor.hooks.php b/VisualEditor.hooks.php
index 2c23a8b..17ca98b 100644
--- a/VisualEditor.hooks.php
+++ b/VisualEditor.hooks.php
@@ -558,6 +558,7 @@
                                'lib/ve/tests/dm/ve.dm.Transaction.test.js',
                                
'modules/ve-mw/tests/dm/ve.dm.Transaction.test.js',
                                
'lib/ve/tests/dm/ve.dm.TransactionProcessor.test.js',
+                               'lib/ve/tests/dm/ve.dm.ResourceQueue.test.js',
                                'lib/ve/tests/dm/ve.dm.Surface.test.js',
                                'lib/ve/tests/dm/ve.dm.SurfaceFragment.test.js',
                                
'modules/ve-mw/tests/dm/ve.dm.SurfaceFragment.test.js',
diff --git a/VisualEditor.php b/VisualEditor.php
index 0e83b56..d8f77f9 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -372,6 +372,8 @@
                        'lib/ve/src/dm/ve.dm.ClassAttributeNode.js',
                        'lib/ve/src/dm/ve.dm.FocusableNode.js',
                        'lib/ve/src/dm/ve.dm.Scalable.js',
+                       'lib/ve/src/dm/ve.dm.ResourceProvider.js',
+                       'lib/ve/src/dm/ve.dm.ResourceQueue.js',
                        'lib/ve/src/dm/ve.dm.ResizableNode.js',
                        'lib/ve/src/dm/ve.dm.BranchNode.js',
                        'lib/ve/src/dm/ve.dm.LeafNode.js',
diff --git a/extension.json b/extension.json
index c3f1fe6..1b5569d 100644
--- a/extension.json
+++ b/extension.json
@@ -384,6 +384,9 @@
                                "lib/ve/src/dm/ve.dm.ClassAttributeNode.js",
                                "lib/ve/src/dm/ve.dm.FocusableNode.js",
                                "lib/ve/src/dm/ve.dm.Scalable.js",
+                               "lib/ve/src/dm/ve.dm.ResourceProvider.js",
+                               "lib/ve/src/dm/ve.dm.ResourceQueue.js",
+                               "lib/ve/src/dm/ve.dm.Scalable.js",
                                "lib/ve/src/dm/ve.dm.ResizableNode.js",
                                "lib/ve/src/dm/ve.dm.BranchNode.js",
                                "lib/ve/src/dm/ve.dm.LeafNode.js",
diff --git a/lib/ve b/lib/ve
index 55e3589..77e1c7e 160000
--- a/lib/ve
+++ b/lib/ve
-Subproject commit 55e3589e1af26d55e556cef6945dca0e33e768d2
+Subproject commit 77e1c7e14693358e45246f26f62c175995ad934b
diff --git a/modules/ve-mw/dm/models/ve.dm.MWMediaResourceProvider.js 
b/modules/ve-mw/dm/models/ve.dm.MWMediaResourceProvider.js
index 19a013b..536ffb1 100644
--- a/modules/ve-mw/dm/models/ve.dm.MWMediaResourceProvider.js
+++ b/modules/ve-mw/dm/models/ve.dm.MWMediaResourceProvider.js
@@ -14,41 +14,29 @@
  * @constructor
  * @param {Object} [config] Configuration options
  */
-ve.dm.MWMediaResourceProvider = function VeDmMWMediaResourceProvider( config ) 
{
+ve.dm.MWMediaResourceProvider = function VeDmMWMediaResourceProvider( apiurl, 
config ) {
        config = config || {};
 
+       // Parent constructor
+       ve.dm.MWMediaResourceProvider.super.call( this, apiurl, config );
+
        // Source Configuration
-       this.apiurl = this.setAPIurl( config.apiurl );
-       this.name = config.name;
-       this.displayName = config.displayName;
        this.local = config.local;
        this.scriptDirUrl  = config.scriptDirUrl;
 
-       // ajaxOptions configuration
-       this.dataType = config.dataType || 'jsonp';
-       this.cached = config.cached || true;
-
        // Fetching configuration
-       this.fetchLimit = config.limit || 30;
        this.iiprop = config.iiprop || [ 'dimensions', 'url', 'mediatype', 
'extmetadata', 'timestamp' ];
-       this.fetchProp = config.fetchProp || 'imageinfo';
-       this.lang = config.lang || 'en';
 
        this.siteInfoPromise = null;
        this.thumbSizes = [];
        this.imageSizes = [];
-
-       this.depleted = false;
-       this.offset = config.offset || 0;
-       this.setQuery( config.query || '' );
 
        // Mixin constructors
        OO.EventEmitter.call( this );
 };
 
 /* Setup */
-OO.initClass( ve.dm.MWMediaResourceProvider );
-OO.mixinClass( ve.dm.MWMediaResourceProvider, OO.EventEmitter );
+OO.inheritClass( ve.dm.MWMediaResourceProvider, ve.dm.ResourceProvider );
 
 /* Methods */
 
@@ -73,23 +61,27 @@
                                if ( data.error ) {
                                        return $.Deferred().reject();
                                }
-                               provider.setImageSizes( ve.getProp( data, 
'query', 'general', 'imagelimits' ) || [] );
-                               provider.setThumbSizes( ve.getProp( data, 
'query', 'general', 'thumblimits' ) || [] );
+                               provider.setImageSizes( 
data.query.general.imagelimits || [] );
+                               provider.setThumbSizes( 
data.query.general.thumblimits || [] );
                        } );
        }
        return this.siteInfoPromise;
 };
 
 /**
- * Get results from the source
+ * Override parent method and get results from the source
  *
+ * @param {Obhect} [config] Configuration object
  * @return {jQuery.Promise} Promise that is resolved into an array
  * of available results, or is rejected if no results are available.
  */
-ve.dm.MWMediaResourceProvider.prototype.getResults = function ( howMany ) {
-       var xhr,
+ve.dm.MWMediaResourceProvider.prototype.getResults = function ( config ) {
+       var xhr, howMany,
                aborted = false,
                provider = this;
+
+       config = config || {};
+       howMany = config.howMany || 10;
 
        return this.loadSiteInfo()
                .then( function () {
@@ -139,7 +131,7 @@
                        gsrnamespace: 6,
                        continue: '',
                        gsroffset: this.getOffset(),
-                       prop: this.getFetchProp(),
+                       prop: 'imageinfo',
                        // Language of the extmetadata details
                        iiextmetadatalanguage: this.getLang(),
                        iiprop: this.getIiProp().join( '|' ),
@@ -148,51 +140,42 @@
                        iiurlwidth: this.getStandardWidth()
                };
 
-       howMany = howMany || 20;
-       // Initial number of images
-       apiCallConfig.gsrlimit = howMany;
+       // Number of images
+       apiCallConfig.gsrlimit = howMany || this.getDefaultFetchLimit();
 
        if ( this.isValid() ) {
-               if ( this.isLocal() ) {
-                       ajaxOptions = {
-                               url: mw.util.wikiScript( 'api' ),
-                               // If the url is local use json
-                               dataType: 'json'
-                       };
-               } else {
-                       ajaxOptions = {
-                               // If 'apiurl' is set, use that. Otherwise, 
build the url
-                               // from scriptDirUrl and /api.php suffix
-                               url: this.apiurl || ( this.scriptDirUrl + 
'/api.php' ),
-                               // If the url is not the same origin use jsonp
-                               dataType: 'jsonp',
-                               // JSON-P requests are not cached by default 
and get a &_=random trail.
-                               // While setting cache=true will still bypass 
cache in most case due to the
-                               // callback parameter, at least drop the 
&_=random trail which triggers
-                               // an API warning (invalid parameter).
-                               cache: true
-                       };
-               }
+               ajaxOptions = this.getAjaxSettings();
 
                xhr = ve.init.target.constructor.static.apiRequest( 
apiCallConfig, ajaxOptions );
                return xhr
                        .then( function ( data ) {
-                               var page, newObj,
-                                       results = [],
-                                       raw = ve.getProp( data, 'query', 
'pages' );
+                               var page, newObj, raw,
+                                       results = [];
+
+                               if ( data.error ) {
+                                       provider.toggleDepleted( true );
+                                       return [];
+                               }
+
                                if ( data[ 'continue' ] ) {
                                        // Update the offset for next time
                                        provider.setOffset( data[ 'continue' 
].gsroffset );
                                } else {
-                                       // This is the last available set of 
result. Mark as depleted!
+                                       // This is the last available set of 
results. Mark as depleted!
                                        provider.toggleDepleted( true );
                                }
-                               if ( raw ) {
-                                       // Strip away the page ids
-                                       for ( page in raw ) {
-                                               newObj = raw[page].imageinfo[0];
-                                               newObj.title = raw[page].title;
-                                               results.push( newObj );
+
+                               // If the source returned no results, it will 
not have a
+                               // query property
+                               if ( data.query ) {
+                                       raw = data.query.pages;
+                                       if ( raw ) {
+                                               // Strip away the page ids
+                                               for ( page in raw ) {
+                                                       newObj = 
raw[page].imageinfo[0];
+                                                       newObj.title = 
raw[page].title;
+                                                       results.push( newObj );
+                                               }
                                        }
                                }
                                return results;
@@ -202,44 +185,31 @@
 };
 
 /**
- * Get search query
+ * Override parent method to retrieve default ajax settings.
  *
- * @return {string} search query
+ * @return {Object} Ajax settings
  */
-ve.dm.MWMediaResourceProvider.prototype.getQuery = function () {
-       return this.query;
-};
-
-/**
- * Set search query
- *
- * @param {string} value
- */
-ve.dm.MWMediaResourceProvider.prototype.setQuery = function ( value ) {
-       if ( this.query !== value ) {
-               this.query = value;
-               // Reset offset
-               this.setOffset( 0 );
-               // Reset depleted status
-               this.toggleDepleted( false );
+ve.dm.MWMediaResourceProvider.prototype.getAjaxSettings = function () {
+       if ( this.isLocal() ) {
+               return {
+                       url: mw.util.wikiScript( 'api' ),
+                       // If the url is local use json
+                       dataType: 'json'
+               };
+       } else {
+               return {
+                       // If 'apiurl' is set, use that. Otherwise, build the 
url
+                       // from scriptDirUrl and /api.php suffix
+                       url: this.apiurl || ( this.scriptDirUrl + '/api.php' ),
+                       // If the url is not the same origin use jsonp
+                       dataType: 'jsonp',
+                       // JSON-P requests are not cached by default and get a 
&_=random trail.
+                       // While setting cache=true will still bypass cache in 
most case due to the
+                       // callback parameter, at least drop the &_=random 
trail which triggers
+                       // an API warning (invalid parameter).
+                       cache: true
+               };
        }
-};
-/**
- * Set api url
- *
- * @param {string} API url
- */
-ve.dm.MWMediaResourceProvider.prototype.setAPIurl = function ( url ) {
-       this.apiurl = url;
-};
-
-/**
- * Set api url
- *
- * @return {string} API url
- */
-ve.dm.MWMediaResourceProvider.prototype.getAPIurl = function () {
-       return this.apiurl;
 };
 
 /**
@@ -258,24 +228,6 @@
  */
 ve.dm.MWMediaResourceProvider.prototype.getName = function () {
        return this.name;
-};
-
-/**
- * Get displayName
- *
- * @return {string} displayName
- */
-ve.dm.MWMediaResourceProvider.prototype.getDisplayName = function () {
-       return this.displayName;
-};
-
-/**
- * Set displayName
- *
- * @param {string} displayName
- */
-ve.dm.MWMediaResourceProvider.prototype.setDisplayName = function ( 
displayName ) {
-       this.displayName = displayName;
 };
 
 /**
@@ -303,52 +255,6 @@
  */
 ve.dm.MWMediaResourceProvider.prototype.setScriptDirUrl = function ( 
scriptDirUrl ) {
        this.scriptDirUrl = scriptDirUrl;
-};
-
-/**
- * Get dataType
- *
- * @return {string} dataType
- */
-ve.dm.MWMediaResourceProvider.prototype.getDataType = function () {
-       return this.dataType;
-};
-
-/**
- * Set dataType
- *
- * @param {string} dataType
- */
-ve.dm.MWMediaResourceProvider.prototype.setDataType = function ( dataType ) {
-       this.dataType = dataType;
-};
-
-/**
- * Get cached
- *
- * @return {boolean} cached
- */
-ve.dm.MWMediaResourceProvider.prototype.isCached = function () {
-       return this.cached;
-};
-
-/**
- * Get fetch limit or 'page' size. This is the number
- * of results per request.
- *
- * @return {number} limit
- */
-ve.dm.MWMediaResourceProvider.prototype.getFetchLimit = function () {
-       return this.limit;
-};
-
-/**
- * Set limit
- *
- * @param {number} limit
- */
-ve.dm.MWMediaResourceProvider.prototype.setFetchLimit = function ( limit ) {
-       this.limit = limit;
 };
 
 /**
@@ -384,7 +290,11 @@
  * @return {number|undefined} fetchWidth
  */
 ve.dm.MWMediaResourceProvider.prototype.getStandardWidth = function () {
-       return this.thumbSizes && this.thumbSizes[ this.thumbSizes.length - 1 ];
+console.log( this.imageSizes );
+       return ( this.thumbSizes && this.thumbSizes[ this.thumbSizes.length - 1 
] ) ||
+               ( this.imageSizes && this.imageSizes[ 0 ] ) ||
+               // Fall back on a number
+               300;
 };
 
 /**
@@ -403,42 +313,6 @@
  */
 ve.dm.MWMediaResourceProvider.prototype.setFetchProp = function ( prop ) {
        this.fetchProp = prop;
-};
-
-/**
- * Get lang
- *
- * @return {string} lang
- */
-ve.dm.MWMediaResourceProvider.prototype.getLang = function () {
-       return this.lang;
-};
-
-/**
- * Set lang
- *
- * @param {string} lang
- */
-ve.dm.MWMediaResourceProvider.prototype.setLang = function ( lang ) {
-       this.lang = lang;
-};
-
-/**
- * Get Offset
- *
- * @return {number} Offset
- */
-ve.dm.MWMediaResourceProvider.prototype.getOffset = function () {
-       return this.offset;
-};
-
-/**
- * Set Offset
- *
- * @param {number} Offset
- */
-ve.dm.MWMediaResourceProvider.prototype.setOffset = function ( offset ) {
-       this.offset = offset;
 };
 
 /**
@@ -475,24 +349,6 @@
  */
 ve.dm.MWMediaResourceProvider.prototype.getImageSizes = function () {
        return this.imageSizes;
-};
-
-/**
- * Check whether the provider is depleted
- *
- * @return {boolean} depleted
- */
-ve.dm.MWMediaResourceProvider.prototype.isDepleted = function () {
-       return this.depleted;
-};
-
-/**
- * Toggle depleted state
- *
- * @param {boolean} depleted
- */
-ve.dm.MWMediaResourceProvider.prototype.toggleDepleted = function ( isDepleted 
) {
-       this.depleted = isDepleted !== undefined ? isDepleted : !this.depleted;
 };
 
 /**
diff --git a/modules/ve-mw/dm/models/ve.dm.MWMediaResourceQueue.js 
b/modules/ve-mw/dm/models/ve.dm.MWMediaResourceQueue.js
index 10ebc9a..22012b0 100644
--- a/modules/ve-mw/dm/models/ve.dm.MWMediaResourceQueue.js
+++ b/modules/ve-mw/dm/models/ve.dm.MWMediaResourceQueue.js
@@ -17,83 +17,16 @@
 ve.dm.MWMediaResourceQueue = function VeDmMWMediaResourceQueue( config ) {
        config = config || {};
 
-       this.fileRepoPromise = null;
-       this.providers = [];
-       this.providerPromises = [];
-
-       this.queue = [];
-
-       this.limit = config.limit || 20;
-       this.threshhold = config.threshhold || 10;
-
-       // Mixin constructors
-       OO.EventEmitter.call( this );
+       // Parent constructor
+       ve.dm.MWMediaResourceQueue.super.call( this, config );
 };
 
 /* Setup */
-OO.initClass( ve.dm.MWMediaResourceQueue );
-OO.mixinClass( ve.dm.MWMediaResourceQueue, OO.EventEmitter );
+OO.inheritClass( ve.dm.MWMediaResourceQueue, ve.dm.ResourceQueue );
 
 /**
- * Get items from the queue
- *
- * @param {number} [howMany] How many items to retrieve
- * @return {jQuery.Promise} Promise that resolves into an array of items
- */
-ve.dm.MWMediaResourceQueue.prototype.get = function ( howMany ) {
-       var me = this,
-               prepared = [];
-
-       howMany = howMany || this.limit;
-
-       // Check if the queue has enough items
-       if ( this.queue.length < howMany + this.threshhold ) {
-               // Call for more results
-               prepared.push(
-                       this.getResults( howMany + this.threshhold )
-                               .then( function ( items ) {
-                                       // Add to the queue
-                                       me.queue = me.queue.concat.apply( 
me.queue, items );
-                               } )
-               );
-       }
-
-       return $.when.apply( $, prepared )
-               .then( function () {
-                       return me.queue.splice( 0, howMany );
-               } );
-
-};
-
-/**
- * Get results from all providers
- * @return {jQuery.Promise} Promise that is resolved into an array of fetched 
items.
- */
-ve.dm.MWMediaResourceQueue.prototype.getResults = function ( howMany ) {
-       var i, len,
-               queue = this;
-
-       // Make sure there are resources set up
-       return this.setup()
-               .then( function () {
-                       queue.providerPromises = [];
-                       // Set up the query to all providers
-                       for ( i = 0, len = queue.providers.length; i < len; i++ 
) {
-                               queue.providers[i].setQuery( queue.getQuery() );
-                               if ( !queue.providers[i].isDepleted() ) {
-                                       queue.providerPromises.push(
-                                               queue.providers[i].getResults( 
howMany )
-                                       );
-                               }
-                       }
-
-                       return $.when.apply( $, queue.providerPromises )
-                               .then( Array.prototype.concat.bind( [] ) );
-               } );
-};
-
-/**
- * Set up the queue and its resources
+ * Override parent method to set up the providers according to
+ * the file repos
  *
  * @return {jQuery.Promise} Promise that resolves when the resources are set up
  */
@@ -105,12 +38,14 @@
                if ( queue.providers.length === 0 ) {
                        // Set up the providers
                        for ( i = 0, len = sources.length; i < len; i++ ) {
-                               queue.providers.push( new 
ve.dm.MWMediaResourceProvider( {
-                                       apiurl: sources[i].apiurl,
-                                       name: sources[i].name,
-                                       local: sources[i].local,
-                                       scriptDirUrl: sources[i].scriptDirUrl
-                               } ) );
+                               queue.providers.push( new 
ve.dm.MWMediaResourceProvider(
+                                       sources[i].apiurl,
+                                       {
+                                               name: sources[i].name,
+                                               local: sources[i].local,
+                                               scriptDirUrl: 
sources[i].scriptDirUrl
+                                       } )
+                               );
                        }
                }
        } );
@@ -142,33 +77,4 @@
        }
 
        return this.fileRepoPromise;
-};
-
-/**
- * Set the search query for all the providers.
- *
- * This also makes sure to abort any previous promises.
- *
- * @param {string} query Search query
- */
-ve.dm.MWMediaResourceQueue.prototype.setQuery = function ( query ) {
-       var i, len;
-       if ( query !== this.query ) {
-               this.query = query;
-               // Reset queue
-               this.queue = [];
-               // Reset promises
-               for ( i = 0, len = this.providerPromises.length; i < len; i++ ) 
{
-                       this.providerPromises[i].abort();
-               }
-       }
-};
-
-/**
- * Get the current search query.
- *
- * @param {string} query Search query
- */
-ve.dm.MWMediaResourceQueue.prototype.getQuery = function () {
-       return this.query;
 };

-- 
To view, visit https://gerrit.wikimedia.org/r/189628
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If34cd99334f4ccb93015c3646f68ae3040b9c5d7
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Mooeypoo <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to