[FIX] blockdom: fix event_catcher traceback

When a parent component has an empty child with a t-on
and an event is triggered inside the parent, blockdom
checks if there is an event_catcher to call.
Doing so, an empty child would cause an error.

This commit fixes that.
This commit is contained in:
Bruno Boi
2022-10-21 09:47:39 +02:00
committed by Géry Debongnie
parent 6f23b18cab
commit bd199971bd
3 changed files with 67 additions and 1 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ export function createCatcher(eventsSpec: EventsSpec): Catcher {
const target = ev.target; const target = ev.target;
let currentNode: any = self.child.firstNode(); let currentNode: any = self.child.firstNode();
const afterNode = self.afterNode; const afterNode = self.afterNode;
while (currentNode !== afterNode) { while (currentNode && currentNode !== afterNode) {
if (currentNode.contains(target)) { if (currentNode.contains(target)) {
return origFn.call(this, ev); return origFn.call(this, ev);
} }
@@ -456,3 +456,45 @@ exports[`t-on t-on on t-slots 2`] = `
} }
}" }"
`; `;
exports[`t-on t-on when first component child is an empty component 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { createCatcher } = helpers;
const comp1 = app.createComponent(\`Child\`, true, false, false, false);
const catcher1 = createCatcher({\\"click\\":0});
let block1 = createBlock(\`<div block-handler-0=\\"click\\"><block-child-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['push'], ctx];
const hdlr2 = [()=>{}, ctx];
const b2 = catcher1(comp1({list: ctx['list']}, key + \`__1\`, node, this, null), [hdlr2]);
return block1([hdlr1], [b2]);
}
}"
`;
exports[`t-on t-on when first component child is an empty component 2`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let { prepareList, withKey } = helpers;
let block2 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['props'].list);;
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`c\`] = v_block1[i1];
ctx[\`c_index\`] = i1;
const key1 = ctx['c_index'];
let txt1 = ctx['c'];
c_block1[i1] = withKey(block2([txt1]), key1);
}
return list(c_block1);
}
}"
`;
+24
View File
@@ -41,6 +41,30 @@ describe("t-on", () => {
expect(steps).toEqual(["click"]); expect(steps).toEqual(["click"]);
}); });
test("t-on when first component child is an empty component", async () => {
class Child extends Component {
static template = xml`
<span t-foreach="props.list" t-as="c" t-key="c_index" t-esc="c"/>
`;
}
class Parent extends Component {
static template = xml`
<div t-on-click="push"><Child list="list" t-on-click="() => {}"/></div>
`;
static components = { Child };
list = useState([] as string[]);
push() {
this.list.push("foo");
}
}
const parent = await mount(Parent, fixture);
const el = elem(parent);
expect(el.innerHTML).toBe("");
el.click();
await nextTick();
expect(el.innerHTML).toBe("<span>foo</span>");
});
test("t-on expression in t-foreach", async () => { test("t-on expression in t-foreach", async () => {
class Comp extends Component { class Comp extends Component {
static template = xml` static template = xml`