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
