diff --git a/src/blockdom/events.ts b/src/blockdom/events.ts index 47d31745..4f663bcb 100644 --- a/src/blockdom/events.ts +++ b/src/blockdom/events.ts @@ -47,14 +47,18 @@ function createElementHandler(evName: string, capture: boolean = false): EventHa // Synthetic handler: a form of event delegation that allows placing only one // listener per event type. +let nextSyntheticEventId = 1; function createSyntheticHandler(evName: string, capture: boolean = false): EventHandlerCreator { let eventKey = `__event__synthetic_${evName}`; if (capture) { eventKey = `${eventKey}_capture`; } setupSyntheticEvent(evName, eventKey, capture); + const currentId = nextSyntheticEventId++; function setup(this: HTMLElement, data: any) { - (this as any)[eventKey] = data; + const _data = (this as any)[eventKey] || {}; + _data[currentId] = data; + (this as any)[eventKey] = _data; } return { setup, update: setup }; } @@ -62,10 +66,12 @@ function createSyntheticHandler(evName: string, capture: boolean = false): Event function nativeToSyntheticEvent(eventKey: string, event: Event) { let dom = event.target; while (dom !== null) { - const data = (dom as any)[eventKey]; - if (data) { - const stopped = config.mainEventHandler(data, event, dom); - if (stopped) return; + const _data = (dom as any)[eventKey]; + if (_data) { + for (const data of Object.values(_data)) { + const stopped = config.mainEventHandler(data, event, dom); + if (stopped) return; + } } dom = (dom as any).parentNode; } diff --git a/tests/blockdom/block_event_handling.test.ts b/tests/blockdom/block_event_handling.test.ts index a791c7a8..781356e0 100644 --- a/tests/blockdom/block_event_handling.test.ts +++ b/tests/blockdom/block_event_handling.test.ts @@ -123,6 +123,40 @@ test("two same block nodes with different handlers (synthetic)", async () => { expect(steps).toEqual(["1", "2"]); }); +test("two event handlers on same event", async () => { + const block = createBlock('
'); + let n = 0; + let m = 0; + const tree = block([() => m++, () => n++]); + + mount(tree, fixture); + expect(fixture.innerHTML).toBe(""); + + expect(m).toBe(0); + expect(n).toBe(0); + (fixture.firstChild as HTMLDivElement).click(); + expect(m).toBe(1); + expect(n).toBe(1); +}); + +test("two synthetic event handlers on same event", async () => { + const block = createBlock( + '' + ); + let n = 0; + let m = 0; + const tree = block([() => m++, () => n++]); + + mount(tree, fixture); + expect(fixture.innerHTML).toBe(""); + + expect(m).toBe(0); + expect(n).toBe(0); + (fixture.firstChild as HTMLDivElement).click(); + expect(m).toBe(1); + expect(n).toBe(1); +}); + test("synthetic and native handlers can cohabitate", async () => { const block = createBlock( '