diff --git a/control/control.js b/control/control.js index 87a832c54b2..91305fac81e 100644 --- a/control/control.js +++ b/control/control.js @@ -147,7 +147,7 @@ steal('can/util','can/construct', function( can ) { // Get the parts of the function // `[convertedName, delegatePart, eventPart]` // `/^(?:(.*?)\s)?([\w\.\:>]+)$/` - Breaker `RegExp`. - parts = (arr ? convertedName[1] : convertedName).match(/^(?:(.*?)\s)?([\w\-\.\:>]+)$/), + parts = (arr ? convertedName[1] : convertedName).match(/^(?:(.*?)\s)?(.+?)$/), event = parts[2], diff --git a/control/modifier/modifier.js b/control/modifier/modifier.js index a756bb8d87e..3000e4fff9c 100644 --- a/control/modifier/modifier.js +++ b/control/modifier/modifier.js @@ -1,43 +1,81 @@ steal("can/control", "can/util/function", function() { // Hang on to original action - var originalAction = can.Control._action, - originalShifter = can.Control._shifter; + var originalSetup = can.Control.setup, + processors = can.Control.processors, + modifier = { + delim: ":", + hasModifier: function( name ) { + return name.indexOf( modifier.delim ) !== -1; + }, + modify: function( name, fn, options ) { + var parts = name.match(/([\w]+)\((.+)\)/), + mod, args; - // Redefine _isAction to handle new syntax - can.extend( can.Control, { + if ( parts ) { + mod = can.getObject( parts[1], [options || {}, can, window] ); + args = can.sub( parts[2], [options || {}, can, window] ).split(","); + if ( mod ) { + args.unshift( fn ); + fn = mod.apply( null, args ); + } + } - _action: function( methodName, options ) { + return fn; + }, + addProcessor : function( event, mod ) { + + var processorName = [event, mod].join( modifier.delim ); + + processors[ processorName ] = function( el, nil, selector, methodName, control ) { + + var callback = modifier.modify( mod, can.Control._shifter(control, methodName), control.options ); + control[event] = callback; + + if ( selector ) { + can.bind( el, event, callback ); + return function() { + can.unbind( el, event, callback ); + }; + } else { + selector = can.trim( selector ); + can.delegate.call(el, selector, event, callback); + return function() { + can.undelegate.call(el, selector, event, callback); + }; + } - var parts = methodName.split(":"), - name = parts.shift(); - return originalAction.apply( this, [ name, options ] ); - }, + }; + } + }; - _shifter: function( context, name ) { - var fn = originalShifter.apply( this, arguments ), - parts = name.split(":"), - fnName, args, modifier; + // Redefine _isAction to handle new syntax + can.extend( can.Control, { - // If there's still a part left, this means we have a modifier - if ( parts[1] ) { - parts = parts.pop().match(/([\w]+)\((.+)\)/); + modifier: modifier, - if(parts){ - fnName = parts[1]; - args = parts[2] ? parts[2].split(","): []; + setup: function( el, options ) { - modifier = can.getObject( fnName, [ context.options, can, window ]); + can.each( this.prototype, function( fn, key, prototype ) { + var parts, event, mod; + if ( modifier.hasModifier( key )) { + // Figure out parts + parts = key.split( modifier.delim ); + event = parts.shift().split(" ").pop(); + mod = parts.join(""); - if ( modifier ) { - args.unshift( fn ); - fn = modifier.apply( null, args ); + if ( ! ( key in processors )) { + modifier.addProcessor( event, mod ); } + } - } - return fn; + }); + + originalSetup.apply( this, arguments ); + } + }); }); diff --git a/control/modifier/modifier_test.js b/control/modifier/modifier_test.js index 7decfb1e833..8711e843a79 100644 --- a/control/modifier/modifier_test.js +++ b/control/modifier/modifier_test.js @@ -2,7 +2,7 @@ steal('can/util', 'can/control/modifier', function(can) { module("can/control/modifier"); - asyncTest("pluginName", 8, function() { + asyncTest("pluginName", function() { var controllerClass = can.Control({ }, { @@ -11,12 +11,18 @@ steal('can/util', 'can/control/modifier', function(can) { ok( this instanceof can.Control, "Debounced function has the correct context." ); foo = true; run++; + }, + + "bar:debounce(30)" : function() { + run2++; } - }), - run = 0, - controller1 = new controllerClass( $("#foo") ), + }); + /**/ + var controller1 = new controllerClass( $("#foo") ), controller2 = new controllerClass( $("#bar") ), + run = 0, + run2 = 0, foo; // Do a bunch of clicks! @@ -30,10 +36,18 @@ steal('can/util', 'can/control/modifier', function(can) { // Make sure foo is still undefined (should be > 30ms before its defined) ok( ! foo, "`foo` is undefined." ); + console.dir( controller1 ); + ok( "bar" in controller1, "Method name gets aliased correctly"); + controller1.bar(); + controller1.bar(); + controller1.bar(); + controller1.bar(); + // Check if setTimeout(function() { ok( foo, "`foo` is true." ); - ok( run === 2, "`run` is 2" ); + equals( run, 2, "`run` is 2" ); + equals( run2, 1, "`run2` is 1" ); // Do a bunch more clicks! $("#foo").trigger("click"); @@ -48,6 +62,7 @@ steal('can/util', 'can/control/modifier', function(can) { start(); }, 40); }, 40); + /**/ });