Tuesday, January 4, 2011

Method (Overload) Madness

    _toggle: jQuery.fn.toggle,

toggle: function( fn, fn2, callback ) {
var bool = typeof fn === "boolean";

if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
this._toggle.apply( this, arguments );

} else if ( fn == null || bool ) {
this.each(function() {
var state = bool ? fn : jQuery(this).is(":hidden");
jQuery(this)[ state ? "show" : "hide" ]();
});

} else {
this.animate(genFx("toggle", 3), fn, fn2, callback);
}

return this;
},


....

animate: function( prop, speed, easing, callback ) {
var optall = jQuery.speed(speed, easing, callback);

if ( jQuery.isEmptyObject( prop ) ) {
return this.each( optall.complete );
}


....

jQuery.extend({
speed: function( speed, easing, fn ) {
var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
complete: fn || !fn && easing ||
jQuery.isFunction( speed ) && speed,
duration: speed,
easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
};

opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;

// Queueing
opt.old = opt.complete;
opt.complete = function() {
if ( opt.queue !== false ) {
jQuery(this).dequeue();
}
if ( jQuery.isFunction( opt.old ) ) {
opt.old.call( this );
}
};

return opt;
},





It's interesting. I thought they would have a more sophisticated and abstract dispatch method. Something declarative and usable by plugins.

I was hoping to be able enumerate the different valid signature types but I have a feeling there isn't going to be some 'easily' exploitable pattern. The args aren't optional in a left to right manner such that for all optional args all args to the left have been optioned. You can call toggle with a callback function as the sole argument. Complicating things somewhat more is the fact that some arguments are described as accepting multiple types. Duration can be a number or string.

fadeTo Shenanigans


Yet the following works perfectly


$(this).fadeTo(function(){ console.log('weird')}, Math.random());

Not that it would be a good idea to rely upon implementation quirks


I'm just interested in automatically computing the different valid combinations of working signatures. Should be doable. Working left to right, taking the first combination of each signature. Cheating for a second and altering my routines to swap out things like "String|Number" to "String" I can see I'm on the right path



'toggle()': {'args': [], 'name': 'toggle', 'sig': [], 'types': []},

'toggle(Boolean)': {'args': ['showOrHide'],
'name': 'toggle',
'sig': [],
'types': ['Boolean']},
'toggle(Callback)': {'args': ['callback'],
'name': 'toggle',
'sig': [],
'types': ['Callback']},
'toggle(Function, Function)': {'args': ['handler(eventObject)',
'handler(eventObject)'],
'name': 'toggle',
'sig': [],
'types': ['Function', 'Function']},
'toggle(Function, Function, Function)': {'args': ['handler(eventObject)',
'handler(eventObject)',
'handler(eventObject)'],
'name': 'toggle',
'sig': [],
'types': ['Function',
'Function',
'Function']},
'toggle(String)': {'args': ['duration'],
'name': 'toggle',
'sig': [],
'types': ['String']},
'toggle(String, Callback)': {'args': ['duration', 'callback'],
'name': 'toggle',
'sig': [],
'types': ['String', 'Callback']},
'toggle(String, String)': {'args': ['duration', 'easing'],
'name': 'toggle',
'sig': [],
'types': ['String', 'String']},
'toggle(String, String, Callback)': {'args': ['duration',
'easing',
'callback'],
'name': 'toggle',
'sig': [],
'types': ['String',
'String',
'Callback']},

I could make a special class for the the types currently represented by a string sourced directly from the xml. This could compare "String|Number" == "Number" as true. Then tuples could be compared ('String|Number', 'Callback') == ('Number', 'Callback')

No comments: