mirror of
https://github.com/atom/atom.git
synced 2026-02-17 18:11:29 -05:00
Order multiple matching listeners by selector specificity
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user