Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize handler signature (and test fire) #105

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/bean.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,14 @@
// each handler is wrapped so we can handle delegation and custom events
var wrappedHandler = function (element, fn, condition, args) {
var call = function (event, eargs) {
return fn.apply(element, args ? slice.call(eargs, event ? 0 : 1).concat(args) : eargs)
return fn.apply(element, args ? slice.call(eargs).concat(args) : eargs)
}
, findTarget = function (event, eventElement) {
return fn.__beanDel ? fn.__beanDel.ft(event.target, element) : eventElement
}
, handler = condition
? function (event) {
var target = findTarget(event, this) // deleated event
var target = findTarget(event, this) // delegated event
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch

if (condition.apply(target, arguments)) {
if (event) event.currentTarget = target
return call(event, arguments)
Expand Down Expand Up @@ -656,7 +656,7 @@
*/
, fire = function (element, type, args) {
var types = str2arr(type)
, i, j, l, names, handlers
, i, j, l, call, event, names, handlers

for (i = types.length; i--;) {
type = types[i].replace(nameRegex, '')
Expand All @@ -667,10 +667,13 @@
// non-native event, either because of a namespace, arguments or a non DOM element
// iterate over all listeners and manually 'fire'
handlers = registry.get(element, type, null, false)
args = [false].concat(args)
event = new Event(null, element, nativeEvents[type])
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isNative use in the source makes me think this line should be be one of these:

  • event = new Event(null, element, !!element[eventSupport] && nativeEvents[type])
  • event = new Event(null, element)

depending on whether native events fired manually due to args or namespace need .isNative

event.type = type
call = args ? 'apply' : 'call'
args = args ? [event].concat(args) : event
for (j = 0, l = handlers.length; j < l; j++) {
if (handlers[j].inNamespaces(names)) {
handlers[j].handler.apply(element, args)
handlers[j].handler[call](element, args)
}
}
}
Expand Down
64 changes: 64 additions & 0 deletions tests/fire-demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<title>bean.fire() demo</title>
<style>
html { font-family:sans-serif; color:#111; background:#efefef }
body { margin:1em auto; width:96% }
#test { font-weight:bold }
#test:hover { cursor:crosshair }
</style>

<p>Open the console.</p>
<div id="test">div#test</div>

<script src="../src/bean.js"></script>
<script>
!function(bean) {
var empty = [], plain = {}
, win = window, doc = document
, el = doc.getElementById('test')

/**
* @param {Array|Object|Node|Window|*} obs target(s)
* @param {Array|string|null} type event names(s)
* @param {...*} additional arguments to pass to bean.fire()
*/
function demo(obs, type) {
var variants = [], rest = empty.slice.call(arguments, 2)
obs = empty.concat(null == obs ? demo.defaults[0] : obs)
type = null == type ? demo.defaults[1] : type
type = typeof type == 'string' ? type.split(' ') : type.slice()
obs.length*type.length || console.warn('No variants to demo')

obs.some(function(o) {
type.some(function(s) {
variants.push([o, s].concat(rest))
})
})

variants.some(function(a, i) {
var ons = [a[0], a[1], demo.handler]
i || console.log('')
i || console.info('Firing ' + variants.length + ' variants ' + (2 < a.length ? 'w/' : 'w/o') + ' extra args')
console.group(a)
bean.off.apply(bean, ons)
bean.on.apply(bean, ons)
bean.fire.apply(bean, a)
console.groupEnd()
})
}

console.group('EXAMPLES')
console.log('bean.fire.demo([{}, document], "blur madeup")')
console.log('bean.fire.demo([{}, document], "blur madeup", [1, 2])')
console.groupEnd()

demo.defaults = [[plain, el, doc, win], 'click click.namespaced madeup madeup.namespaced']
demo.handler = function() {
console.log(arguments)
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can override this in the console to quickly view specific event object properties

bean.fire.demo.handler = function() { console.log(arguments[0].type) }
bean.fire.demo()
bean.fire.demo(null, null, [1, 2])

demo(null, null)
demo(null, null, [1, 2])
bean.fire.demo = demo
}(bean);
</script>
17 changes: 10 additions & 7 deletions tests/fire-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,25 @@ buster.testCase('fire', {
bean.fire(el, 'mousedown mouseup')
}

, 'should be able to pass multiple arguments to custom event': function (done) {
, 'should be able to pass extra arguments to custom event': function (done) {
// jquery like array syntax
var el = this.byId('input')
, trigger = this.trigger()
, spy = this.spy()
, extra = [1, 2, 3]
, slice = extra.slice
, type = 'foo'

trigger.after(function () {
assert.equals(spy.callCount, 1, 'single call')
assert.equals(spy.firstCall.args.length, 3, 'called with 3 arguments')
assert.equals(spy.firstCall.args[0], 1, 'called with correct argument 1')
assert.equals(spy.firstCall.args[1], 2, 'called with correct argument 2')
assert.equals(spy.firstCall.args[2], 3, 'called with correct argument 3')
assert.equals(spy.firstCall.args.length, 1+extra.length, 'called with correct arguments.length')
assert.equals(typeof(spy.firstCall.args[0] || 0), 'object', 'called with correct arguments[0] type')
assert.equals(spy.firstCall.args[0].type, type.split('.')[0], 'called with correct event.type')
assert.equals(slice.call(spy.firstCall.args, 1).join(), extra.join(), 'called with correct extra arguments')
done()
})

bean.on(el, 'foo', trigger.wrap(spy))
bean.fire(el, 'foo', [1, 2, 3])
bean.on(el, type, trigger.wrap(spy))
bean.fire(el, type, extra)
}
})