Skip to content

Commit

Permalink
Update on():
Browse files Browse the repository at this point in the history
- press
- groups
- aspect pause
- use on() as multi if object passed instead of event
Added test
  • Loading branch information
Mike Wilcox committed Jun 24, 2012
1 parent 1207060 commit bcb3016
Show file tree
Hide file tree
Showing 2 changed files with 268 additions and 16 deletions.
125 changes: 109 additions & 16 deletions on.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,21 @@ define([
return evt;
},

on = function(/*DOMNode|String*/target, /*String*/event, /*Object|Function?*/ctx, /*Function|String*/scope, /*String*/group){
groups = {},
addGroup = function(groupId, handle){
if(!groups[groupId]) groups[groupId] = [];
groups[groupId].push(handle);
},

on = function(/*DOMNode|Object|String*/target, /*String|Object*/event, /*Object|Function?*/ctx, /*Function|String*/scope, /*String*/group){
// summary:
// Combination dojo/on and dojo/aspect.
// target:DOMNode|String
// target:DOMNode|Object|String
// If a string, the node is retrived via dojo.byId
// event:String
// The event to listen to.
// If an object, aspect will be used
// event:String|Object
// The event or function to listen to.
// If this argument is an object, the flow passes to on.multi
// ctx:Object|Function?
// Optionally pass the context (this). If no context is passed,
// this argument should be a Function.
Expand All @@ -76,9 +84,17 @@ define([
// name in the context.
// group: TODO
//
// mandating that there is always a target and event

if(typeof event == 'object'){
return on.multi(target, event, ctx, scope);
}

// mandate that there is always a target and event
// may not be ctx though
var fn;
var
fn,
handle,
_once = 0;
if(typeof ctx == 'function'){
fn = ctx;
group = scope;
Expand All @@ -90,11 +106,29 @@ define([
fn = fn || lang.hitch(ctx, scope);

if(typeof target == 'string'){
target = document.getElementById(target); // race condition with dx-alias/dom
// race condition, no access to dx-alias/dom
target = document.getElementById(target);

}else if(!target.addEventListener && !target.attachEvent){ // need better checking here (emtters, objects with addEventListener)
}else if(!target.addEventListener && !target.attachEvent){ // need better checking here (emitters, objects with addEventListener)
// ASPECT
// an object, not a node
return aspect.after(target, event, fn, true);
var paused = 0;
handle = aspect.after(target, event, function(){
if(paused) return;
if(_once) handle.remove();
fn.apply(null, arguments);
}, true);
handle.once = function(){
_once = 1;
};
handle.pause = function(){
paused = 1;
}
handle.resume = function(){
paused = 0;
}
if(group) addGroup(group, handle);
return handle;
}

if(event == 'scroll'){
Expand All @@ -105,22 +139,30 @@ define([
}

if(event == 'press'){
// TO PORT!
return on.press(target, fn);
}

// TODO:
// group
// on-press
// on-mouseleave, mouseenter
return dojoOn.pausable(target, event, fn);

handle = dojoOn.pausable(target, event, function(){
if(_once) handle.remove();
fn.apply(null, arguments);
});
handle.once = function(){
_once = 1;
};
if(group) addGroup(group, handle);
return handle;
};

on.multi = function(/*DOMNode|String*/target, /*Object*/obj, /*Object?*/ctx, /*String*/group){
// summary:
// A way of making multiple connections with one call.
// note:
// If context is used, all methods should resolve to that one
// context.
// If context is used, all methods will bind to it.
// example
// | on.multi(node, {
// | 'mousedown':'onMouseDown',
Expand All @@ -141,14 +183,49 @@ define([
},
resume: function(){
listeners.forEach(function(lis){ lis.resume(); });
},
once: function(){
console.error('once() cannot be applied to a multiple connection.');
}
};
};

on.press = function(node, ctx, method, arg, group){
var fn = lang.hitch(ctx, method);
var passArg = arg;
var tmr, offHandle, downHandle;
var tch = 0; //bv.supports.touch();
var fire = function(evt){
tmr = setInterval(function(){
fn(evt);
}, 20);
}
var stop = function(evt){
offHandle.pause();
clearInterval(tmr);
}
downHandle = on(node, tch ? "touchstart" : "mousedown", function(evt){
//console.log("PRESS");
event.stop(evt);
offHandle.resume();
fire(evt);
});
offHandle = on(document, tch ? "touchend" : "mouseup", function(evt){
//console.log("RELEASE CANCEL")
event.stop(evt);
stop();
});
stop();

if(group) addGroup(group, downHandle);

return downHandle;
};

on.once = function(target, event, ctx, method){
// summary:
// Connect then disconnect after it's been called once.
//
//
var fn = lang.hitch(ctx, method);
var handle = on(target, event, function(){
handle.remove();
Expand All @@ -157,13 +234,29 @@ define([

};

on.group = {
remove: function(groupId){
groups[groupId].forEach(function(lis){ lis.remove(); });
},
pause: function(groupId){
groups[groupId].forEach(function(lis){ lis.pause(); });
},
resume: function(groupId){
groups[groupId].forEach(function(lis){ lis.resume(); });
}
}

on.selector = dojoOn.selector;
on.stopEvent = event.stop; // move to dx-event?

// on.group = {
// on.group = {
// pause
// resume
//}
// add
// }
//
// on.group.pause(groupId);


return on;
});
159 changes: 159 additions & 0 deletions tests/test_on.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Test dx-alias/on</title>
<style>
html, body{
margin:10px;
padding:0;
background:#fff;
font-family: sans-serif;
}
</style>
<script>
dojoConfig = {
async:1
};
</script>
<script src="../../dojo/dojo.js"></script>

</head>
<body>
<h1>
Test dx-alias/on
</h1>
<p>Test results are in the console.</p>

<button id='btn'>Click Me</button>
<button id='rem'>Remove Group</button>
<button id='btn2'>Click Me Once</button>
<button id='btn3'>Press and Hold Me</button>

<script>
require([
"dx-alias/on",
"dx-alias/dom",
"dx-alias/log"
], function(on, dom, logger){

var log = logger('', 1);

var i = 0;
var inc = function(){ return i++; }

// namespace
var ns = {
foo: function(a){
log('foo', a);
},
bar: function(a){
log('bar', a);
},
zap: function(a){
log('zap', a);
}
};

// single aspect
var onFooHandle = on(ns, 'foo', function(a){
log(' - onFoo:', a)
});

// multiple aspect, including the same one twice
on(ns, {
foo:function(a){
log('multi - onFoo:', a)
},
bar: function(b){
log('multi - onBar', b)
},
foo:'bar'
}, ns);

// test aspect once()
on(ns, 'foo', function(a){
log('foo once (this should only appear once)');
}).once();
ns.foo(i++);
ns.foo(i++);

// test aspect pauseable
log('foo pause, - onFoo '+i+' should not fire.')
onFooHandle.pause();
ns.foo(i++);
log('foo resume, - onFoo '+i+' should fire.')
onFooHandle.resume();
ns.foo(i++);

// test multi DOM
on('btn', {
'click':function(){
log('click');
},
'mouseover': function(){
log('over');
},
'mouseout': function(){
log('out');
}
});

// test DOM once()
on('btn2', 'click', function(){
log('click - once');
}).once();


log('.....test groups.....');

var ns2 = {
foo: function(a){
//log('ns2 foo', a);
},
bar: function(a){
log('ns2 bar', a);
},
zap: function(a){
log('ns2 zap (group1)', a);
}
};

on(ns2, 'foo', function(a){
log('group foo', a);
}, 'group1');
on(ns2, 'bar', function(a){
log('group bar', a);
}, 'group1');

// group with context
on(ns2, 'foo', ns, 'zap', 'group1');

ns2.foo(i++);
ns2.foo(i++);

log('group foo '+i+', and zap '+i+' should NOT fire...');
on.group.pause('group1');
ns2.foo(i++);

log('adding DOM to same group (use Click ME again)');
on('btn', 'click', function(){
log('click group');
}, 'group1');
log('After clicking remove, "click group" should not fire');
on('rem', 'click', function(){
on.group.remove('group1');
});

// test on.press
on.press('btn3', function(e){
log('press - 1', e)
});
on('btn3', 'press', function(e){
log('press - 2', e)
});


});
</script>
</body>
</html>

0 comments on commit bcb3016

Please sign in to comment.