propCopy() parser function overrides can now invoke default functionality
parent
591434b82f
commit
6b6ffe0134
44
lib/util.js
44
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 an 'each' callback was provided, pass the data before parsing it
|
||||||
if ( callback_each )
|
if ( callback_each )
|
||||||
{
|
{
|
||||||
callback_each( prop, value );
|
callback_each.call( callback_each, prop, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
// getter/setter
|
// getter/setter
|
||||||
if ( getter || setter )
|
if ( getter || setter )
|
||||||
{
|
{
|
||||||
callback_getter( prop, getter );
|
callback_getter.call( callback_getter, prop, getter );
|
||||||
callback_setter( prop, setter );
|
callback_setter.call( callback_setter, prop, setter );
|
||||||
|
|
||||||
// we're done
|
// we're done
|
||||||
continue;
|
continue;
|
||||||
|
@ -164,7 +164,8 @@ exports.propParse = function( data, options )
|
||||||
// method
|
// method
|
||||||
else if ( value instanceof Function )
|
else if ( value instanceof Function )
|
||||||
{
|
{
|
||||||
callback_method(
|
callback_method.call(
|
||||||
|
callback_method,
|
||||||
prop,
|
prop,
|
||||||
value,
|
value,
|
||||||
exports.isAbstractMethod( value )
|
exports.isAbstractMethod( value )
|
||||||
|
@ -173,7 +174,7 @@ exports.propParse = function( data, options )
|
||||||
// simple property
|
// simple property
|
||||||
else
|
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;
|
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
|
// substitute default functionality if needed
|
||||||
actions = {
|
actions = {
|
||||||
each: actions.each || function( name, value )
|
each: use_or( actions.each, function( name, value )
|
||||||
{
|
{
|
||||||
// methods can only be overridden with methods
|
// methods can only be overridden with methods
|
||||||
if ( ( dest[ name ] instanceof Function )
|
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" );
|
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;
|
dest[ name ] = value;
|
||||||
},
|
} ),
|
||||||
|
|
||||||
getter: actions.getter || function( name, func )
|
getter: use_or( actions.getter, function( name, func )
|
||||||
{
|
{
|
||||||
dest.__defineGetter__( name, func );
|
dest.__defineGetter__( name, func );
|
||||||
},
|
} ),
|
||||||
|
|
||||||
setter: actions.setter || function( name, func )
|
setter: use_or( actions.setter, function( name, func )
|
||||||
{
|
{
|
||||||
dest.__defineSetter__( 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 },
|
var data = { abstractModified: false },
|
||||||
pre = dest[ name ];
|
pre = dest[ name ];
|
||||||
|
@ -284,7 +298,7 @@ exports.propCopy = function( props, dest, result_data, actions )
|
||||||
abstract_methods.push( name );
|
abstract_methods.push( name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
} ),
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.propParse( props, actions );
|
exports.propParse( props, actions );
|
||||||
|
|
|
@ -52,38 +52,43 @@ var each = false,
|
||||||
setter = false;
|
setter = false;
|
||||||
|
|
||||||
propCopy( props, dest, null, {
|
propCopy( props, dest, null, {
|
||||||
each: function()
|
each: function foo()
|
||||||
{
|
{
|
||||||
each = true;
|
each = this.performDefault;
|
||||||
},
|
},
|
||||||
|
|
||||||
property: function()
|
property: function()
|
||||||
{
|
{
|
||||||
prop = true;
|
prop = this.performDefault;
|
||||||
},
|
},
|
||||||
|
|
||||||
method: function()
|
method: function()
|
||||||
{
|
{
|
||||||
method = true;
|
method = this.performDefault;
|
||||||
},
|
},
|
||||||
|
|
||||||
getter: function()
|
getter: function()
|
||||||
{
|
{
|
||||||
getter = true;
|
getter = this.performDefault;
|
||||||
},
|
},
|
||||||
|
|
||||||
setter: function()
|
setter: function()
|
||||||
{
|
{
|
||||||
setter = true;
|
setter = this.performDefault;
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
[ each, prop, method, getter, setter ].forEach( function( item, i )
|
[ each, prop, method, getter, setter ].forEach( function( item, i )
|
||||||
{
|
{
|
||||||
assert.equal(
|
assert.notEqual(
|
||||||
item,
|
item,
|
||||||
true,
|
false,
|
||||||
"Can override propCopy() parser functions [" + i + "]"
|
"Can override propCopy() parser functions [" + i + "]"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
( item instanceof Function ),
|
||||||
|
"propCopy() parser function overrides can invoke default functionality"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue