From 6c3878be9e3376d98d053c1f2a4e6133c5f1fc1b Mon Sep 17 00:00:00 2001 From: Trevor Parscal Date: Thu, 4 Oct 2012 13:42:00 -0700 Subject: [PATCH] Added multiple name registration to ve.Factory Also changed from using "type" to "name" to make it less specific and added a test to make sure it's working. Change-Id: I150a7ab1a57b3df85b459dbc411c2eaefe08b5bb --- modules/ve/test/ve.Factory.test.js | 6 +++- modules/ve/ve.Factory.js | 45 ++++++++++++++++++------------ 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/modules/ve/test/ve.Factory.test.js b/modules/ve/test/ve.Factory.test.js index 0b654e4ac5..1aa5ee6ef8 100644 --- a/modules/ve/test/ve.Factory.test.js +++ b/modules/ve/test/ve.Factory.test.js @@ -18,7 +18,7 @@ ve.FactoryObjectStub = function VeFactoryObjectStub( a, b, c, d ) { /* Tests */ -QUnit.test( 'register', 1, function ( assert ) { +QUnit.test( 'register', 3, function ( assert ) { var factory = new ve.Factory(); assert.throws( function () { @@ -27,6 +27,10 @@ QUnit.test( 'register', 1, function ( assert ) { Error, 'Throws an exception when trying to register a non-function value as a constructor' ); + + factory.register( ['factory-object-stub-1', 'factory-object-stub-2'], ve.FactoryObjectStub ); + assert.strictEqual( factory.lookup( 'factory-object-stub-1' ), ve.FactoryObjectStub ); + assert.strictEqual( factory.lookup( 'factory-object-stub-2' ), ve.FactoryObjectStub ); } ); QUnit.test( 'create', 3, function ( assert ) { diff --git a/modules/ve/ve.Factory.js b/modules/ve/ve.Factory.js index f901ea61ca..79cf8519e2 100644 --- a/modules/ve/ve.Factory.js +++ b/modules/ve/ve.Factory.js @@ -34,43 +34,52 @@ ve.inheritClass( ve.Factory, ve.EventEmitter ); * @see {ve.Factory.prototype.create} * * @method - * @param {String} type Object type + * @param {String|String[]} name Symbolic name or list of symbolic names * @param {Function} constructor Constructor to use when creating object * @throws 'Constructor must be a function, cannot be a string' */ -ve.Factory.prototype.register = function ( type, constructor ) { +ve.Factory.prototype.register = function ( name, constructor ) { + var i, len; if ( typeof constructor !== 'function' ) { throw new Error( 'Constructor must be a function, cannot be a ' + typeof constructor ); } - this.registry[type] = constructor; - this.emit( 'register', type, constructor ); + if ( ve.isArray( name ) ) { + for ( i = 0, len = name.length; i < len; i++ ) { + this.register( name[i], constructor ); + } + } else if ( typeof name === 'string' ) { + this.registry[name] = constructor; + this.emit( 'register', name, constructor ); + } else { + throw new Error( 'Name must be a string or array of strings, cannot be a ' + typeof name ); + } }; /** - * Create an object based on a type. + * Create an object based on a name. * - * Type is used to look up the constructor to use, while all additional arguments are passed to the + * Name is used to look up the constructor to use, while all additional arguments are passed to the * constructor directly, so leaving one out will pass an undefined to the constructor. * * @method - * @param {string} type Object type. + * @param {string} name Object name. * @param {mixed} [...] Arguments to pass to the constructor. * @returns {Object} The new object. - * @throws 'Unknown object type' + * @throws 'Unknown object name' */ -ve.Factory.prototype.create = function ( type ) { +ve.Factory.prototype.create = function ( name ) { var args, obj, - constructor = this.registry[type]; + constructor = this.registry[name]; if ( constructor === undefined ) { - throw new Error( 'Unknown object type: ' + type ); + throw new Error( 'Unknown object name: ' + name ); } - // Convert arguments to array and shift the first argument (type) off + // Convert arguments to array and shift the first argument (name) off args = Array.prototype.slice.call( arguments, 1 ); // We can't use the "new" operator with .apply directly because apply needs a - // context. So instead just do what "new" does: Create an object that inherits from + // context. So instead just do what "new" does: create an object that inherits from // the constructor's prototype (which also makes it an "instanceof" the constructor), // then invoke the constructor with the object as context, and return it (ignoring // the constructor's return value). @@ -80,12 +89,12 @@ ve.Factory.prototype.create = function ( type ) { }; /** - * Gets a constructor for a given type. + * Gets a constructor for a given name. * * @method - * @param {String} type Object type - * @returns {Function|undefined} Constructor for type + * @param {String} name Object name + * @returns {Function|undefined} Constructor for name */ -ve.Factory.prototype.lookup = function ( type ) { - return this.registry[type]; +ve.Factory.prototype.lookup = function ( name ) { + return this.registry[name]; };