diff --git a/src/command-registry.coffee b/src/command-registry.coffee index d2fa1c019..5543737c1 100644 --- a/src/command-registry.coffee +++ b/src/command-registry.coffee @@ -175,17 +175,8 @@ class CommandRegistry # * `commandName` {String} indicating the name of the command to dispatch. dispatch: (target, commandName, detail) -> event = new CustomEvent(commandName, {bubbles: true, detail}) - eventWithTarget = Object.create {}, - target: value: target - preventDefault: value: -> - stopPropagation: value: -> - stopImmediatePropagation: value: -> - # NOTE: In Chrome 43, Object.create doesn't work well with CustomEvent; - # However utilizing _.defaults here doesn't really do anything since all properties have been - # moved from "own" to the prototype, so we should update this to fully shadowing the properties - # from Event.prototype (+ detail property from CustomEvent). - eventWithTarget = _.defaults(eventWithTarget, event) - @handleCommandEvent(eventWithTarget) + Object.defineProperty(event, 'target', value: target) + @handleCommandEvent(event) # Public: Invoke the given callback before dispatching a command event. # @@ -213,37 +204,36 @@ class CommandRegistry @selectorBasedListenersByCommandName[commandName] = listeners.slice() return - handleCommandEvent: (originalEvent) => + handleCommandEvent: (event) => propagationStopped = false immediatePropagationStopped = false matched = false - currentTarget = originalEvent.target + currentTarget = event.target + {preventDefault, stopPropagation, stopImmediatePropagation, abortKeyBinding} = event - syntheticEvent = Object.create {}, - eventPhase: value: Event.BUBBLING_PHASE - currentTarget: get: -> currentTarget - target: value: currentTarget - preventDefault: value: -> - originalEvent.preventDefault() - stopPropagation: value: -> - originalEvent.stopPropagation() - propagationStopped = true - stopImmediatePropagation: value: -> - originalEvent.stopImmediatePropagation() - propagationStopped = true - immediatePropagationStopped = true - abortKeyBinding: value: -> - originalEvent.abortKeyBinding?() - # NOTE: See similar scenario in ::dispatch. - syntheticEvent = _.defaults(syntheticEvent, originalEvent) + dispatchedEvent = new CustomEvent(event.type, {bubbles: true, detail: event.detail}) + Object.defineProperty dispatchedEvent, 'eventPhase', value: Event.BUBBLING_PHASE + Object.defineProperty dispatchedEvent, 'currentTarget', get: -> currentTarget + Object.defineProperty dispatchedEvent, 'target', value: currentTarget + Object.defineProperty dispatchedEvent, 'preventDefault', value: -> + event.preventDefault() + Object.defineProperty dispatchedEvent, 'stopPropagation', value: -> + event.stopPropagation() + propagationStopped = true + Object.defineProperty dispatchedEvent, 'stopImmediatePropagation', value: -> + event.stopImmediatePropagation() + propagationStopped = true + immediatePropagationStopped = true + Object.defineProperty dispatchedEvent, 'abortKeyBinding', value: -> + event.abortKeyBinding?() - @emitter.emit 'will-dispatch', syntheticEvent + @emitter.emit 'will-dispatch', dispatchedEvent loop - listeners = @inlineListenersByCommandName[originalEvent.type]?.get(currentTarget) ? [] + listeners = @inlineListenersByCommandName[event.type]?.get(currentTarget) ? [] if currentTarget.webkitMatchesSelector? selectorBasedListeners = - (@selectorBasedListenersByCommandName[originalEvent.type] ? []) + (@selectorBasedListenersByCommandName[event.type] ? []) .filter (listener) -> currentTarget.webkitMatchesSelector(listener.selector) .sort (a, b) -> a.compare(b) listeners = listeners.concat(selectorBasedListeners) @@ -252,7 +242,7 @@ class CommandRegistry for listener in listeners break if immediatePropagationStopped - listener.callback.call(currentTarget, syntheticEvent) + listener.callback.call(currentTarget, dispatchedEvent) break if currentTarget is window break if propagationStopped