From b53f52771f2487bd274a34619c5c62e15e0c2d89 Mon Sep 17 00:00:00 2001 From: Alexey Plutalov Date: Fri, 5 May 2017 01:04:04 +0300 Subject: [PATCH] Add capturing support to `delegate` function --- d.ts/homey.d.ts | 2 +- spec/events/delegate.spec.js | 66 ++++++++++++++++++++++++++++++++++++ src/events/delegate.js | 5 +-- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/d.ts/homey.d.ts b/d.ts/homey.d.ts index 0533f4e..50c708b 100644 --- a/d.ts/homey.d.ts +++ b/d.ts/homey.d.ts @@ -58,5 +58,5 @@ export function remove(element: Element): boolean; export function on(element: Element, eventType: EventType, listener: EventListener, useCapture?: boolean): () => void; export function once(element: Element, eventType: EventType, listener: EventListener, useCapture?: boolean): () => void; -export function delegate(element: Element, selector: Selector, eventType: EventType, listener: EventListener): () => void; +export function delegate(element: Element, selector: Selector, eventType: EventType, listener: EventListener, useCapture?: boolean): () => void; export function dispatch(element: Element, eventType: EventType, listener: EventListener): boolean; diff --git a/spec/events/delegate.spec.js b/spec/events/delegate.spec.js index 9b576f0..5e7dad0 100644 --- a/spec/events/delegate.spec.js +++ b/spec/events/delegate.spec.js @@ -292,4 +292,70 @@ describe("delegate", () => { expect(listener).not.toHaveBeenCalled(); }); }); + + describe("supports events capturing", () => { + it("doesn't use capturing by default", () => { + useFixture(` +
+
+
+
+
+ `); + + const parent = document.querySelector(".parent"); + const subject = document.querySelector(".root"); + const child = document.querySelector(".child"); + const parentListener = jasmine.createSpy("parentListener"); + const subjectListener = jasmine.createSpy("subjectListener"); + + delegate(parent, ".child", "click", parentListener); + delegate(subject, ".child", "click", subjectListener); + + expect(parentListener).not.toHaveBeenCalled(); + expect(subjectListener).not.toHaveBeenCalled(); + + const event = createEvent("click"); + + child.dispatchEvent(event); + + expect(parentListener).toHaveBeenCalledTimes(1); + expect(parentListener).toHaveBeenCalledWith(event); + expect(subjectListener).toHaveBeenCalledTimes(1); + expect(subjectListener).toHaveBeenCalledWith(event); + expect(subjectListener).toHaveBeenCalledBefore(parentListener); + }); + + it("uses capturing when flag given", () => { + useFixture(` +
+
+
+
+
+ `); + + const parent = document.querySelector(".parent"); + const subject = document.querySelector(".root"); + const child = document.querySelector(".child"); + const parentListener = jasmine.createSpy("parentListener"); + const subjectListener = jasmine.createSpy("subjectListener"); + + delegate(parent, ".child", "click", parentListener, true); + delegate(subject, ".child", "click", subjectListener, true); + + expect(parentListener).not.toHaveBeenCalled(); + expect(subjectListener).not.toHaveBeenCalled(); + + const event = createEvent("click"); + + child.dispatchEvent(event); + + expect(parentListener).toHaveBeenCalledTimes(1); + expect(parentListener).toHaveBeenCalledWith(event); + expect(subjectListener).toHaveBeenCalledTimes(1); + expect(subjectListener).toHaveBeenCalledWith(event); + expect(parentListener).toHaveBeenCalledBefore(subjectListener); + }); + }); }); diff --git a/src/events/delegate.js b/src/events/delegate.js index 1321540..3723a78 100644 --- a/src/events/delegate.js +++ b/src/events/delegate.js @@ -11,7 +11,8 @@ function delegate( element: Element, selector: Selector, eventType: EventType, - listener: EventListener + listener: EventListener, + useCapture?: boolean = false ): () => void { function wrappedListener(event) { if (!(event.target instanceof Element)) { @@ -35,7 +36,7 @@ function delegate( } } - return on(element, eventType, wrappedListener); + return on(element, eventType, wrappedListener, useCapture); } export default delegate;