From 6b6ffe0134fa956a86682c1e9e152e6807855523 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Thu, 16 Dec 2010 23:49:52 -0500 Subject: [PATCH] propCopy() parser function overrides can now invoke default functionality --- lib/util.js | 44 ++++++++++++++++++++++++------------- test/test-util-prop-copy.js | 21 +++++++++++------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/lib/util.js b/lib/util.js index 543ea3e..9ead1dd 100644 --- a/lib/util.js +++ b/lib/util.js @@ -149,14 +149,14 @@ exports.propParse = function( data, options ) // if an 'each' callback was provided, pass the data before parsing it if ( callback_each ) { - callback_each( prop, value ); + callback_each.call( callback_each, prop, value ); } // getter/setter if ( getter || setter ) { - callback_getter( prop, getter ); - callback_setter( prop, setter ); + callback_getter.call( callback_getter, prop, getter ); + callback_setter.call( callback_setter, prop, setter ); // we're done continue; @@ -164,7 +164,8 @@ exports.propParse = function( data, options ) // method else if ( value instanceof Function ) { - callback_method( + callback_method.call( + callback_method, prop, value, exports.isAbstractMethod( value ) @@ -173,7 +174,7 @@ exports.propParse = function( data, options ) // simple property else { - callback_prop( prop, value ); + callback_prop.call( callback_prop, prop, value ); } } } @@ -215,9 +216,22 @@ exports.propCopy = function( props, dest, result_data, actions ) abstract_map[ method ] = i; } + var use_or = function( use, or ) + { + if ( use instanceof Function ) + { + // allow the override to invoke the default implementation + use.performDefault = or; + return use; + } + + // use the default + return or; + }; + // substitute default functionality if needed actions = { - each: actions.each || function( name, value ) + each: use_or( actions.each, function( name, value ) { // methods can only be overridden with methods if ( ( dest[ name ] instanceof Function ) @@ -226,24 +240,24 @@ exports.propCopy = function( props, dest, result_data, actions ) { throw new TypeError( "Cannot override method with non-method" ); } - }, + } ), - property: actions.property || function( name, value ) + property: use_or( actions.property, function( name, value ) { dest[ name ] = value; - }, + } ), - getter: actions.getter || function( name, func ) + getter: use_or( actions.getter, function( name, func ) { dest.__defineGetter__( name, func ); - }, + } ), - setter: actions.setter || function( name, func ) + setter: use_or( actions.setter, function( name, func ) { dest.__defineSetter__( name, func ); - }, + } ), - method: actions.method || function( name, func, is_abstract ) + method: use_or( actions.method, function( name, func, is_abstract ) { var data = { abstractModified: false }, pre = dest[ name ]; @@ -284,7 +298,7 @@ exports.propCopy = function( props, dest, result_data, actions ) abstract_methods.push( name ); } } - }, + } ), }; exports.propParse( props, actions ); diff --git a/test/test-util-prop-copy.js b/test/test-util-prop-copy.js index c81e20a..6b77706 100644 --- a/test/test-util-prop-copy.js +++ b/test/test-util-prop-copy.js @@ -52,38 +52,43 @@ var each = false, setter = false; propCopy( props, dest, null, { - each: function() + each: function foo() { - each = true; + each = this.performDefault; }, property: function() { - prop = true; + prop = this.performDefault; }, method: function() { - method = true; + method = this.performDefault; }, getter: function() { - getter = true; + getter = this.performDefault; }, setter: function() { - setter = true; + setter = this.performDefault; }, } ); [ each, prop, method, getter, setter ].forEach( function( item, i ) { - assert.equal( + assert.notEqual( item, - true, + false, "Can override propCopy() parser functions [" + i + "]" ); + + assert.ok( + ( item instanceof Function ), + "propCopy() parser function overrides can invoke default functionality" + ); });