Skip to content

Commit

Permalink
clone delegated events properly
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed Jan 31, 2012
1 parent 3194455 commit 88cebe0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 18 deletions.
41 changes: 29 additions & 12 deletions src/bean.js
Expand Up @@ -299,28 +299,32 @@
}

, nativeHandler = function (element, fn, args) {
var ft = fn.__findTarget
return function (event) {
var beanDel = fn.__beanDel
, handler = function (event) {
event = fixEvent(event || ((this.ownerDocument || this.document || this).parentWindow || win).event, true)
if (ft) // delegated event, fix the fix
event.currentTarget = ft(event.target, element)
if (beanDel) // delegated event, fix the fix
event.currentTarget = beanDel.ft(event.target, element)
return fn.apply(element, [event].concat(args))
}
handler.__beanDel = beanDel
return handler
}

, customHandler = function (element, fn, type, condition, args, isNative) {
var ft = fn.__findTarget
return function (event) {
var target = ft ? ft(event.target, element) : this // deleated event
var beanDel = fn.__beanDel
, handler = function (event) {
var target = beanDel ? beanDel.ft(event.target, element) : this // deleated event
if (condition ? condition.apply(target, arguments) : W3C_MODEL ? true : event && event.propertyName === '_on' + type || !event) {
if (event) {
event = fixEvent(event || ((this.ownerDocument || this.document || this).parentWindow || win).event, isNative)
if (ft) // for delegated events
if (beanDel) // for delegated events
event.currentTarget = target
}
fn.apply(element, event && (!args || args.length === 0) ? arguments : slice.call(arguments, event ? 0 : 1).concat(args))
}
}
handler.__beanDel = beanDel
return handler
}

, once = function (rm, element, type, fn, originalFn) {
Expand Down Expand Up @@ -388,7 +392,11 @@
fn.apply(match, arguments)
}

handler.__findTarget = findTarget // attach it here for customEvents to use too
handler.__beanDel = {
ft: findTarget // attach it here for customEvents to use too
, selector: selector
, $: $
}
return handler
}

Expand Down Expand Up @@ -488,9 +496,18 @@
var i = 0
, handlers = registry.get(from, type)
, l = handlers.length

for (;i < l; i++)
handlers[i].original && add(element, handlers[i].type, handlers[i].original)
, args, beanDel

for (;i < l; i++) {
if (handlers[i].original) {
beanDel = handlers[i].handler.__beanDel
if (beanDel) {
args = [ element, beanDel.selector, handlers[i].type, handlers[i].original, beanDel.$]
} else
args = [ element, handlers[i].type, handlers[i].original ]
add.apply(null, args)
}
}
return element
}

Expand Down
22 changes: 16 additions & 6 deletions tests/tests.js
Expand Up @@ -589,14 +589,24 @@ sink('clone', function (test, ok, before, after) {
Syn.click(el2)
});

test('clone: should work with delegated events', 1, function () {
var foo = document.createElement('div');
bean.add(foo, '.bang', 'click', function () {ok(true, 'fires intended event')});
bean.add(foo, '.baz', 'click', function () { ok(false, 'fires unintended event')})
var realfoo = document.getElementById('foo');
test('clone: should work with delegated events', 3, function () {
var foo = document.createElement('div')
, realfoo = document.getElementById('foo')
, bang = document.getElementById('bang')

bean.add(foo, '.bang', 'click', function (e) {
bean.remove(foo)
ok(true, 'fires intended event')
ok(this == bang, 'context was set to delegated element')
ok(e.currentTarget === bang, 'degated event has currentTarget property correctly set')
}, qwery)

bean.add(foo, '.baz', 'click', function () {
ok(false, 'fires unintended event')
}, qwery)

bean.clone(realfoo, foo);

var bang = document.getElementById('bang');
Syn.click(bang);
});
})
Expand Down

0 comments on commit 88cebe0

Please sign in to comment.