Order multiple matching listeners by selector specificity

This commit is contained in:
Nathan Sobo
2014-09-05 08:57:47 -06:00
parent a075aa2b07
commit 5eb22520f1
2 changed files with 34 additions and 4 deletions

View File

@@ -1,3 +1,8 @@
{specificity} = require 'clear-cut'
SequenceCount = 0
SpecificityCache = {}
module.exports =
class CommandRegistry
constructor: (@rootNode) ->
@@ -8,7 +13,7 @@ class CommandRegistry
@rootNode.addEventListener(commandName, @dispatchCommand, true)
@listenersByCommandName[commandName] = []
@listenersByCommandName[commandName].push({selector, callback})
@listenersByCommandName[commandName].push(new CommandListener(selector, callback))
dispatchCommand: (event) =>
syntheticEvent = Object.create event,
@@ -17,9 +22,22 @@ class CommandRegistry
currentTarget = event.target
loop
for listener in @listenersByCommandName[event.type]
if currentTarget.webkitMatchesSelector(listener.selector)
listener.callback.call(currentTarget, syntheticEvent)
matchingListeners =
@listenersByCommandName[event.type]
.filter (listener) -> currentTarget.webkitMatchesSelector(listener.selector)
.sort (a, b) -> a.compare(b)
for listener in matchingListeners
listener.callback.call(currentTarget, syntheticEvent)
break if currentTarget is @rootNode
currentTarget = currentTarget.parentNode
class CommandListener
constructor: (@selector, @callback) ->
@specificity = (SpecificityCache[@selector] ?= specificity(@selector))
@sequenceNumber = SequenceCount++
compare: (other) ->
other.specificity - @specificity or
other.sequenceNumber - @sequenceNumber