Forward stop[Immediate]Propagation to original event in CommandRegistry

Previously, stopping propagation would work on the synthetic bubbling
phase of the command registry itself, but the original event would
continue to propagate which is counterintuitive.
This commit is contained in:
Nathan Sobo
2014-09-23 17:23:46 -06:00
parent 40f8b990d0
commit 066f6bf03c
2 changed files with 24 additions and 6 deletions

View File

@@ -66,8 +66,11 @@ describe "CommandRegistry", ->
registry.add '.child', 'command', -> calls.push('child-2')
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopPropagation()
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'stopPropagation')
grandchild.dispatchEvent(dispatchedEvent)
expect(calls).toEqual ['child-1', 'child-2']
expect(dispatchedEvent.stopPropagation).toHaveBeenCalled()
it "stops invoking callbacks when .stopImmediatePropagation() is called on the event", ->
calls = []
@@ -76,8 +79,21 @@ describe "CommandRegistry", ->
registry.add '.child', 'command', -> calls.push('child-2')
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopImmediatePropagation()
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'stopImmediatePropagation')
grandchild.dispatchEvent(dispatchedEvent)
expect(calls).toEqual ['child-1']
expect(dispatchedEvent.stopImmediatePropagation).toHaveBeenCalled()
it "forwards .preventDefault() calls from the synthetic event to the original", ->
calls = []
registry.add '.child', 'command', (event) -> event.preventDefault()
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'preventDefault')
grandchild.dispatchEvent(dispatchedEvent)
expect(dispatchedEvent.preventDefault).toHaveBeenCalled()
it "allows listeners to be removed via a disposable returned by ::add", ->
calls = []

View File

@@ -179,24 +179,26 @@ class CommandRegistry
@listenersByCommandName = _.deepClone(snapshot)
@setRootNode(rootNode) # restore listeners for commands in snapshot
handleCommandEvent: (event) =>
handleCommandEvent: (originalEvent) =>
propagationStopped = false
immediatePropagationStopped = false
matched = false
currentTarget = event.target
currentTarget = originalEvent.target
syntheticEvent = Object.create event,
syntheticEvent = Object.create originalEvent,
eventPhase: value: Event.BUBBLING_PHASE
currentTarget: get: -> currentTarget
stopPropagation: value: ->
originalEvent.stopPropagation()
propagationStopped = true
stopImmediatePropagation: value: ->
originalEvent.stopImmediatePropagation()
propagationStopped = true
immediatePropagationStopped = true
loop
matchingListeners =
(@listenersByCommandName[event.type] ? [])
(@listenersByCommandName[originalEvent.type] ? [])
.filter (listener) -> currentTarget.webkitMatchesSelector(listener.selector)
.sort (a, b) -> a.compare(b)