jenkins-bot has submitted this change and it was merged.

Change subject: Support RDFa type regexes in ModelRegistry
......................................................................


Support RDFa type regexes in ModelRegistry

Change-Id: Id19c3a567140f9e27ba732b6e8d9e25bc7a28a4f
---
M modules/ve/dm/ve.dm.Annotation.js
M modules/ve/dm/ve.dm.ModelRegistry.js
M modules/ve/dm/ve.dm.Node.js
M modules/ve/test/dm/ve.dm.ModelRegistry.test.js
4 files changed, 82 insertions(+), 43 deletions(-)

Approvals:
  Trevor Parscal: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/ve/dm/ve.dm.Annotation.js 
b/modules/ve/dm/ve.dm.Annotation.js
index 344e351..91fb778 100644
--- a/modules/ve/dm/ve.dm.Annotation.js
+++ b/modules/ve/dm/ve.dm.Annotation.js
@@ -67,7 +67,7 @@
  * @see ve.dm.ModelRegistry
  *
  * @static
- * @property {Array} static.matchTagNames
+ * @property {string[]} static.matchTagNames
  * @inheritable
  */
 ve.dm.Annotation.static.matchTagNames = null;
@@ -80,7 +80,7 @@
  * @see ve.dm.ModelRegistry
  *
  * @static
- * @property {Array} static.matchRdfaType
+ * @property {Array} static.matchRdfaType Array of strings or regular 
expressions
  * @inheritable
  */
 ve.dm.Annotation.static.matchRdfaTypes = null;
diff --git a/modules/ve/dm/ve.dm.ModelRegistry.js 
b/modules/ve/dm/ve.dm.ModelRegistry.js
index 26aa572..f265a1c 100644
--- a/modules/ve/dm/ve.dm.ModelRegistry.js
+++ b/modules/ve/dm/ve.dm.ModelRegistry.js
@@ -17,11 +17,17 @@
 ve.dm.ModelRegistry = function VeDmModelRegistry() {
        // Parent constructor
        ve.Registry.call( this );
+       // Map of func presence and tag names to model names
        // [ { tagName: [modelNamesWithoutFunc] }, { tagName: 
[modelNamesWithFunc] } ]
        this.modelsByTag = [ {}, {} ];
+       // Map of func presence and rdfaTypes to model names; only rdfaTypes 
specified as strings are in here
        // { matchFunctionPresence: { rdfaType: { tagName: [modelNames] } } }
        // [ { rdfaType: { tagName: [modelNamesWithoutFunc] } }, { rdfaType: { 
tagName: [modelNamesWithFunc] } ]
        this.modelsByTypeAndTag = [];
+       // Map of func presence to array of model names with rdfaType regexps
+       // [ [modelNamesWithoutFunc], [modelNamesWithFunc] ]
+       this.modelsWithTypeRegExps = [ [], [] ];
+       // Map tracking registration order
        // { nameA: 0, nameB: 1, ... }
        this.registrationOrder = {};
        this.nextNumber = 0;
@@ -36,33 +42,27 @@
 
 /**
  * Helper function for register(). Adds a value to the front of an array in a 
nested object.
- * Objects and arrays are created if needed. You can specify either two or 
three keys and a value.
+ * Objects and arrays are created if needed. You can specify one or more keys 
and a value.
  *
  * Specifically:
- * addType( obj, keyA, keyB, keyC, value ) does obj[keyA][keyB][keyC].unshift( 
value );
+ * addType( obj, keyA, value ) does obj[keyA].unshift( value );
  * addType( obj, keyA, keyB, value ) does obj[keyA][keyB].unshift( value );
+ * etc.
  *
  * @param {Object} obj Object to add to
- * @param {string} keyA Key into obj
- * @param {string} keyB Key into obj[keyA]
- * @param {string|Mixed} keyC Key into obj[keyA][keyB], or value to add to 
array if value not set
- * @param {Mixed} [value] Value to add to the array
  */
-function addType( obj, keyA, keyB, keyC, value ) {
-       if ( obj[keyA] === undefined ) {
-               obj[keyA] = {};
+function addType( obj /*, ...*/ ) {
+       var i, len, o = obj;
+       for ( i = 1, len = arguments.length - 2; i < len; i++ ) {
+               if ( o[arguments[i]] === undefined ) {
+                       o[arguments[i]] = {};
+               }
+               o = o[arguments[i]];
        }
-       if ( obj[keyA][keyB] === undefined ) {
-               obj[keyA][keyB] = value === undefined ? [] : {};
+       if ( o[arguments[i]] === undefined ) {
+               o[arguments[i]] = [];
        }
-       if ( value !== undefined && obj[keyA][keyB][keyC] === undefined ) {
-               obj[keyA][keyB][keyC] = [];
-       }
-       if ( value === undefined ) {
-               obj[keyA][keyB].unshift( keyC );
-       } else {
-               obj[keyA][keyB][keyC].unshift( value );
-       }
+       o[arguments[i]].unshift( arguments[i + 1] );
 }
 
 /* Public methods */
@@ -103,10 +103,14 @@
                );
        }
        for ( i = 0; i < types.length; i++ ) {
-               for ( j = 0; j < tags.length; j++ ) {
-                       addType( this.modelsByTypeAndTag,
-                               +!!constructor.static.matchFunction, types[i], 
tags[j], name
-                       );
+               if ( types[i] instanceof RegExp ) {
+                       addType( this.modelsWithTypeRegExps, 
+!!constructor.static.matchFunction, name );
+               } else {
+                       for ( j = 0; j < tags.length; j++ ) {
+                               addType( this.modelsByTypeAndTag,
+                                       +!!constructor.static.matchFunction, 
types[i], tags[j], name
+                               );
+                       }
                }
        }
 
@@ -177,13 +181,31 @@
                return reg.registrationOrder[b] - reg.registrationOrder[a];
        }
 
-       function matchWithFunc( types, tag ) {
-               var i, j, matches, queue = [];
-               for ( i = 0; i < types.length; i++ ) {
-                       matches = ve.getProp( reg.modelsByTypeAndTag, 1, 
types[i], tag ) || [];
-                       for ( j = 0; j < matches.length; j++ ) {
-                               queue.push( matches[j] );
+       function matchTypeRegExps( type, tag, withFunc ) {
+               var i, j, types, matches = [], models = 
reg.modelsWithTypeRegExps[+!!withFunc];
+               for ( i = 0; i < models.length; i++ ) {
+                       types = reg.registry[models[i]].static.matchRdfaTypes;
+                       for ( j = 0; j < types.length; j++ ) {
+                               if (
+                                       type.match( types[j] ) &&
+                                       (
+                                               
reg.registry[models[i]].static.matchTagNames === null ||
+                                               ve.indexOf( tag, 
reg.registry[models[i]].static.matchTagNames ) !== -1
+                                       )
+                               ) {
+                                       matches.push( models[i] );
+                               }
                        }
+               }
+               return matches;
+       }
+
+       function matchWithFunc( types, tag ) {
+               var i, queue = [];
+               for ( i = 0; i < types.length; i++ ) {
+                       queue = queue
+                               .concat( ve.getProp( reg.modelsByTypeAndTag, 1, 
types[i], tag ) || [] )
+                               .concat( matchTypeRegExps( types[i], tag, true 
) );
                }
                queue.sort( byRegistrationOrderDesc );
                for ( i = 0; i < queue.length; i++ ) {
@@ -195,16 +217,18 @@
        }
 
        function matchWithoutFunc( types, tag ) {
-               var i, j, matches, winningName = null;
+               var i, queue = [], winningName = null;
                for ( i = 0; i < types.length; i++ ) {
-                       matches = ve.getProp( reg.modelsByTypeAndTag, 0, 
types[i], tag ) || [];
-                       for ( j = 0; j < matches.length; j++ ) {
-                               if (
-                                       winningName === null ||
-                                       reg.registrationOrder[winningName] < 
reg.registrationOrder[matches[j]]
-                               ) {
-                                       winningName = matches[j];
-                               }
+                       queue = queue
+                               .concat( ve.getProp( reg.modelsByTypeAndTag, 0, 
types[i], tag ) || [] )
+                               .concat( matchTypeRegExps( types[i], tag, false 
) );
+               }
+               for ( i = 0; i < queue.length; i++ ) {
+                       if (
+                               winningName === null ||
+                               reg.registrationOrder[winningName] < 
reg.registrationOrder[queue[i]]
+                       ) {
+                               winningName = queue[i];
                        }
                }
                return winningName;
diff --git a/modules/ve/dm/ve.dm.Node.js b/modules/ve/dm/ve.dm.Node.js
index 07a5d65..49ede8e 100644
--- a/modules/ve/dm/ve.dm.Node.js
+++ b/modules/ve/dm/ve.dm.Node.js
@@ -54,7 +54,7 @@
  * Empty array means none, null means any.
  * For more information about element matching, see ve.dm.ModelRegistry.
  * @static
- * @property {Array} static.matchTagNames
+ * @property {string[]} static.matchTagNames
  * @inheritable
  */
 ve.dm.Node.static.matchTagNames = null;
@@ -64,7 +64,7 @@
  * Empty array means none, null means any.
  * For more information about element matching, see ve.dm.ModelRegistry.
  * @static
- * @property {Array} static.matchRdfaType
+ * @property {Array} static.matchRdfaType Array of strings or regular 
expressions
  * @inheritable
  */
 ve.dm.Node.static.matchRdfaTypes = null;
diff --git a/modules/ve/test/dm/ve.dm.ModelRegistry.test.js 
b/modules/ve/test/dm/ve.dm.ModelRegistry.test.js
index 8dfaa20..379ff45 100644
--- a/modules/ve/test/dm/ve.dm.ModelRegistry.test.js
+++ b/modules/ve/test/dm/ve.dm.ModelRegistry.test.js
@@ -83,9 +83,17 @@
 ve.dm.StubBarNode.static.toDataElement = function () {};
 ve.dm.StubBarNode.static.toDomElements = function () {};
 
+ve.dm.StubRegExpNode = function VeDmStubRegExpNode( children, element ) {
+       ve.dm.BranchNode.call( this, 'stub-regexp', children, element );
+};
+ve.inheritClass( ve.dm.StubRegExpNode, ve.dm.BranchNode );
+ve.dm.StubRegExpNode.static.name = 'stub-regexp';
+ve.dm.StubRegExpNode.static.matchTagNames = ['abbr'];
+ve.dm.StubRegExpNode.static.matchRdfaTypes = [ /^mw:/ ];
+
 /* Tests */
 
-QUnit.test( 'matchElement', 16, function ( assert ) {
+QUnit.test( 'matchElement', 18, function ( assert ) {
        var registry = new ve.dm.ModelRegistry(), element;
        element = document.createElement( 'a' );
        assert.deepEqual( registry.matchElement( element ), null, 
'matchElement() returns null if registry empty' );
@@ -99,6 +107,7 @@
        registry.register( ve.dm.StubSingleTypeAndFuncAnnotation );
        registry.register( ve.dm.StubSingleTagAndTypeAndFuncAnnotation );
        registry.register( ve.dm.StubBarNode );
+       registry.register( ve.dm.StubRegExpNode );
 
        element = document.createElement( 'b' );
        assert.deepEqual( registry.matchElement( element ), 'stubnothingset', 
'nothingset matches anything' );
@@ -117,6 +126,9 @@
        assert.deepEqual( registry.matchElement( element ), 'stubfunc', 
'func-only match' );
        element.setAttribute( 'rel', 'mw:foo' );
        assert.deepEqual( registry.matchElement( element ), 
'stubsingletypeandfunc', 'type and func match' );
+       element = document.createElement( 'abbr' );
+       element.setAttribute( 'rel', 'mw:baz' );
+       assert.deepEqual( registry.matchElement( element ), 'stub-regexp', 
'RegExp type match' );
 
        registry.registerExtensionSpecificType( /^mw:/ );
        registry.registerExtensionSpecificType( 'foo' );
@@ -135,4 +147,7 @@
        assert.deepEqual( registry.matchElement( element ), null, 
'extension-specific type matching string prevents type match' );
        element.setAttribute( 'rel', 'foo bar mw:bogus' );
        assert.deepEqual( registry.matchElement( element ), null, 'two 
extension-specific types prevent non-extension-specific type match' );
+       element = document.createElement( 'abbr' );
+       element.setAttribute( 'rel', 'mw:baz' );
+       assert.deepEqual( registry.matchElement( element ), 'stub-regexp', 
'RegExp type match for extension-specific type' );
 } );

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Id19c3a567140f9e27ba732b6e8d9e25bc7a28a4f
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot

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

Reply via email to