diff --git a/lib/class.js b/lib/class.js index b89c4d8..44c4411 100644 --- a/lib/class.js +++ b/lib/class.js @@ -259,8 +259,14 @@ function createNamedClass( name, def ) ); } + // if no definition was given, return a staging object, to apply the name to + // the class once it is actually created + if ( def === undefined ) + { + return createStaging( name ); + } // the definition must be an object - if ( typeof def !== 'object' ) + else if ( typeof def !== 'object' ) { throw TypeError( "Unexpected value for named class definition; object expected" @@ -274,6 +280,39 @@ function createNamedClass( name, def ) } +/** + * Creates a staging object to stage a class name + * + * The class name will be applied to the class generated by operations performed + * on the staging object. This allows applying names to classes that need to be + * extended or need to implement interfaces. + * + * @param {string} cname desired class name + * + * @return {Object} object staging the given class name + */ +function createStaging( cname ) +{ + return { + extend: function() + { + var args = Array.prototype.slice.apply( arguments ); + + // extend() takes a maximum of two arguments. If only one + // argument is provided, then it is to be the class definition. + // Otherwise, the first argument is the supertype and the second + // argument is the class definition. Either way you look at it, + // the class definition is always the final argument. + // + // We want to add the name to the definition. + args[ args.length - 1 ].__name = cname; + + return extend.apply( null, args ); + }, + }; +} + + /** * Creates extend function * diff --git a/test/test-class-name.js b/test/test-class-name.js index 360c943..6fbf3fa 100644 --- a/test/test-class-name.js +++ b/test/test-class-name.js @@ -149,3 +149,32 @@ var common = require( './common' ), ); } )(); + +/** + * In order to accommodate syntax such as extending classes, ease.js supports + * staging class names. This will return an object that operates exactly like + * the normal Class module, but will result in a named class once the class is + * created. + */ +( function testCanCreateNamedClassUsingStagingMethod() +{ + var name = 'Foo', + named = Class( name ).extend( {} ) + ; + + // ensure what was returned is a valid class + assert.equal( + Class.isClass( named ), + true, + "Named class generated via staging method is considered to be a " + + "valid class" + ); + + // was the name set? + assert.equal( + named.toString(), + '[object Class <' + name + '>]', + "Name is set on named clas via staging method" + ); +} )(); +