Cscott has uploaded a new change for review.

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

Change subject: Allow more than one DataTransferHandler to match a given item.
......................................................................

Allow more than one DataTransferHandler to match a given item.

Instead of using a single-valued map, use a multimap to keep track
of possible DataTransferHandlers.  This ensures that adding a new
specialized DataTransferHandler with the same type as an existing
handler (cf https://gerrit.wikimedia.org/r/230146) doesn't prevent
the more general handler from firing once the `matchFunction`
on the specialized handler returns `false`.

Change-Id: I76f7ab81fdf3cafd551b9f04b19e0074a4d4b701
---
M src/ui/ve.ui.DataTransferHandlerFactory.js
1 file changed, 56 insertions(+), 22 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor 
refs/changes/10/230310/1

diff --git a/src/ui/ve.ui.DataTransferHandlerFactory.js 
b/src/ui/ve.ui.DataTransferHandlerFactory.js
index 2e9d8ad..bd80300 100644
--- a/src/ui/ve.ui.DataTransferHandlerFactory.js
+++ b/src/ui/ve.ui.DataTransferHandlerFactory.js
@@ -41,21 +41,35 @@
                types = constructor.static.types,
                extensions = constructor.static.extensions;
 
+       function ensureArray( obj, prop ) {
+               if ( obj[prop] === undefined ) {
+                       obj[prop] = [];
+               }
+               return obj[prop];
+       }
+       function ensureMap( obj, prop ) {
+               if ( obj[prop] === undefined ) {
+                       obj[prop] = {};
+               }
+               return obj[prop];
+       }
        if ( !kinds ) {
                for ( j = 0, jlen = types.length; j < jlen; j++ ) {
-                       this.handlerNamesByType[types[j]] = 
constructor.static.name;
+                       ensureArray( this.handlerNamesByType, types[j] 
).unshift( constructor.static.name );
                }
        } else {
                for ( i = 0, ilen = kinds.length; i < ilen; i++ ) {
                        for ( j = 0, jlen = types.length; j < jlen; j++ ) {
-                               this.handlerNamesByKindAndType[kinds[i]] = 
this.handlerNamesByKindAndType[kinds[i]] || {};
-                               
this.handlerNamesByKindAndType[kinds[i]][types[j]] = constructor.static.name;
+                               ensureArray(
+                                       ensureMap( 
this.handlerNamesByKindAndType, kinds[i] ),
+                                       types[j]
+                               ).unshift( constructor.static.name );
                        }
                }
        }
        if ( constructor.prototype instanceof ve.ui.FileTransferHandler ) {
                for ( i = 0, ilen = extensions.length; i < ilen; i++ ) {
-                       this.handlerNamesByExtension[extensions[i]] = 
constructor.static.name;
+                       ensureArray( this.handlerNamesByExtension, 
extensions[i] ).unshift( constructor.static.name );
                }
        }
 };
@@ -68,30 +82,50 @@
  * @returns {string|undefined} Handler name, or undefined if not found
  */
 ve.ui.DataTransferHandlerFactory.prototype.getHandlerNameForItem = function ( 
item, isPaste ) {
-       var constructor,
-               name =
-                       // 1. Match by kind + type (e.g. 'file' + 'text/html')
-                       ( this.handlerNamesByKindAndType[item.kind] && 
this.handlerNamesByKindAndType[item.kind][item.type] ) ||
-                       // 2. Match by just type (e.g. 'image/jpeg')
-                       this.handlerNamesByType[item.type] ||
-                       // 3. Match by file extension (e.g. 'csv')
-                       this.handlerNamesByExtension[item.getExtension()];
+       var i,
+               name,
+               constructor,
+               names;
 
-       if ( !name ) {
-               return;
+       // Fetch a given nested property, returning a zero-length array if
+       // any component of the path is not present.
+       function fetch( obj /*, args...*/ ) {
+               var i;
+               for ( i = 1; i < arguments.length; i++ ) {
+                       if ( !Object.prototype.hasOwnProperty.call( obj, 
arguments[i] ) ) {
+                               return [];
+                       }
+                       obj = obj[arguments[i]];
+               }
+               return obj;
        }
 
-       constructor = this.registry[name];
+       names = [].concat(
+               // 1. Match by kind + type (e.g. 'file' + 'text/html')
+               fetch( this.handlerNamesByKindAndType, item.kind, item.type ),
+               // 2. Match by just type (e.g. 'image/jpeg')
+               fetch( this.handlerNamesByType, item.type ),
+               // 3. Match by file extension (e.g. 'csv')
+               fetch( this.handlerNamesByExtension, item.getExtension() )
+       );
 
-       if ( isPaste && !constructor.static.handlesPaste ) {
-               return;
+       for ( i = 0; i < names.length; i++ ) {
+               name = names[i];
+               constructor = this.registry[name];
+
+               if ( isPaste && !constructor.static.handlesPaste ) {
+                       continue;
+               }
+
+               if ( constructor.static.matchFunction && 
!constructor.static.matchFunction( item ) ) {
+                       continue;
+               }
+
+               return name;
        }
 
-       if ( constructor.static.matchFunction && 
!constructor.static.matchFunction( item ) ) {
-               return;
-       }
-
-       return name;
+       // No matching handler
+       return;
 };
 
 /* Initialization */

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I76f7ab81fdf3cafd551b9f04b19e0074a4d4b701
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Cscott <[email protected]>

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

Reply via email to