[IMP] blockdom: t-on supports synthetic and native event handler

Synthetic handler is a sort of event delegation that allows placing
only one listener on the document to improve performance. It is an opt-in option.

Native listener places the listener on the node itself.
This commit is contained in:
Lucas Perais (lpe)
2021-10-26 11:01:57 +02:00
committed by Aaron Bohy
parent 3eb63452e7
commit 2ae0149adb
9 changed files with 244 additions and 18 deletions
@@ -106,3 +106,92 @@ test("two same block nodes with different handlers", async () => {
(fixture.firstChild!.nextSibling as HTMLDivElement).click();
expect(steps).toEqual(["1", "2"]);
});
test("two same block nodes with different handlers (synthetic)", async () => {
const block = createBlock('<div block-handler-0="click.synthetic"></div>');
let steps: string[] = [];
let handler1 = () => steps.push("1");
let handler2 = () => steps.push("2");
const tree = multi([block([handler1]), block([handler2])]);
mount(tree, fixture);
expect(fixture.innerHTML).toBe("<div></div><div></div>");
(fixture.firstChild as HTMLDivElement).click();
(fixture.firstChild!.nextSibling as HTMLDivElement).click();
expect(steps).toEqual(["1", "2"]);
});
test("synthetic and native handlers can cohabitate", async () => {
const block = createBlock('<div block-handler-0="click.synthetic"><div block-handler-1="click"/></div>');
let steps: string[] = [];
let handler1 = () => steps.push("1");;
let handler2 = () => steps.push("2");
const tree = block([handler1, handler2]);
mount(tree, fixture);
expect(fixture.innerHTML).toBe("<div><div></div></div>");
(fixture.firstChild!.firstChild as HTMLDivElement).click();
expect(steps).toEqual(["2", "1"]);
(fixture.firstChild as HTMLDivElement).click();
expect(steps).toEqual(["2", "1", "1"]);
});
test("synthetic and native handlers can cohabitate (2)", async () => {
const block = createBlock('<div block-handler-0="click"><div block-handler-1="click.synthetic"/></div>');
let steps: string[] = [];
let handler1 = () => steps.push("1");;
let handler2 = () => steps.push("2");
const tree = block([handler1, handler2]);
mount(tree, fixture);
expect(fixture.innerHTML).toBe("<div><div></div></div>");
(fixture.firstChild!.firstChild as HTMLDivElement).click();
expect(steps).toEqual(["1", "2"]);
(fixture.firstChild as HTMLDivElement).click();
expect(steps).toEqual(["1", "2", "1"]);
});
test("synthetic and native handlers can cohabitate (3)", async () => {
const parent = createBlock(`<div block-handler-0="click"><block-child-0/><block-child-1/></div>`)
const block = createBlock('<div block-handler-0="click"/>');
const blockSynth = createBlock('<div block-handler-0="click.synthetic"/>');
let steps: string[] = [];
const handler0 = () => steps.push("0");;
let handler1 = () => steps.push("1");;
let handler2 = () => steps.push("2");
const tree = parent([handler0], [block([handler1]), blockSynth([handler2])]);
mount(tree, fixture);
expect(fixture.innerHTML).toBe("<div><div></div><div></div></div>");
const children = fixture.children[0].children;
(children[0] as HTMLElement).click();
expect(steps).toEqual(["1", "0"]);
(children[1] as HTMLElement).click();
expect(steps).toEqual(["1", "0", "0", "2"]);
});
test("synthetic and native handlers can cohabitate (5)", async () => {
const parent = createBlock(`<div block-handler-0="click"><block-child-0/><block-child-1/></div>`)
const block = createBlock('<div block-handler-0="click"/>');
const blockSynth = createBlock('<div block-handler-0="click.synthetic"/>');
let steps: string[] = [];
const handler0 = (ev: Event) => { steps.push("0"); ev.stopPropagation();};
let handler1 = () => steps.push("1");;
let handler2 = () => steps.push("2");
const tree = parent([handler0], [block([handler1]), blockSynth([handler2])]);
mount(tree, fixture);
expect(fixture.innerHTML).toBe("<div><div></div><div></div></div>");
const children = fixture.children[0].children;
(children[0] as HTMLElement).click();
expect(steps).toEqual(["1", "0"]);
(children[1] as HTMLElement).click();
expect(steps).toEqual(["1", "0", "0"]);
});