From decc9834200bbd804063aa30938af2d557070825 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 5 Sep 2014 08:22:28 -0600 Subject: [PATCH] Start on CommandRegistry --- spec/command-registry-spec.coffee | 30 ++++++++++++++++++++++++++++++ src/command-registry.coffee | 21 +++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 spec/command-registry-spec.coffee create mode 100644 src/command-registry.coffee diff --git a/spec/command-registry-spec.coffee b/spec/command-registry-spec.coffee new file mode 100644 index 000000000..aec55e920 --- /dev/null +++ b/spec/command-registry-spec.coffee @@ -0,0 +1,30 @@ +CommandRegistry = require '../src/command-registry' + +describe "CommandRegistry", -> + [registry, parent, child, grandchild] = [] + + beforeEach -> + parent = document.createElement("div") + child = document.createElement("div") + grandchild = document.createElement("div") + parent.classList.add('parent') + child.classList.add('child') + grandchild.classList.add('grandchild') + child.appendChild(grandchild) + parent.appendChild(child) + document.querySelector('#jasmine-content').appendChild(parent) + + registry = new CommandRegistry(parent) + + it "invokes callbacks with selectors matching the target", -> + called = false + registry.add 'command', '.grandchild', (event) -> + expect(this).toBe grandchild + expect(event.type).toBe 'command' + expect(event.eventPhase).toBe Event.BUBBLING_PHASE + expect(event.target).toBe grandchild + expect(event.currentTarget).toBe grandchild + called = true + + grandchild.dispatchEvent(new CustomEvent('command', bubbles: true)) + expect(called).toBe true diff --git a/src/command-registry.coffee b/src/command-registry.coffee new file mode 100644 index 000000000..3c17f2ea8 --- /dev/null +++ b/src/command-registry.coffee @@ -0,0 +1,21 @@ +module.exports = +class CommandRegistry + constructor: (@rootNode) -> + @listenersByCommandName = {} + + add: (commandName, selector, callback) -> + unless @listenersByCommandName[commandName]? + @rootNode.addEventListener(commandName, @dispatchCommand, true) + @listenersByCommandName[commandName] = [] + + @listenersByCommandName[commandName].push({selector, callback}) + + dispatchCommand: (event) => + syntheticEvent = Object.create event, + eventPhase: value: Event.BUBBLING_PHASE + currentTarget: get: -> currentTarget + + currentTarget = event.target + for listener in @listenersByCommandName[event.type] + if event.target.webkitMatchesSelector(listener.selector) + listener.callback.call(currentTarget, syntheticEvent)