mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] event: no crash when using t-on + modifier on slots/components
closes #1185
This commit is contained in:
committed by
Bruno Boi
parent
b56a9c24cf
commit
31fce0926c
@@ -33,9 +33,12 @@ export function createCatcher(eventsSpec: EventsSpec): Catcher {
|
|||||||
this.afterNode = afterNode;
|
this.afterNode = afterNode;
|
||||||
this.child.mount(parent, afterNode);
|
this.child.mount(parent, afterNode);
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i = 0; i < n; i++) {
|
||||||
let origFn = this.handlers[i][0];
|
let handler = this.handlers[i];
|
||||||
|
// handler = [...mods, fn, comp], so we need to replace second to last elem
|
||||||
|
let idx = handler.length - 2;
|
||||||
|
let origFn = handler[idx];
|
||||||
const self = this;
|
const self = this;
|
||||||
this.handlers[i][0] = function (ev: any) {
|
handler[idx] = function (ev: any) {
|
||||||
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;
|
||||||
|
|||||||
@@ -212,6 +212,34 @@ exports[`t-on t-on on components, variation 2`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`t-on t-on on components, with 'prevent' modifier 1`] = `
|
||||||
|
"function anonymous(app, bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { createCatcher } = helpers;
|
||||||
|
const catcher1 = createCatcher({\\"click.prevent\\":0});
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
const hdlr1 = [\\"prevent\\", ctx['increment'], ctx];
|
||||||
|
return catcher1(component(\`Child\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx), [hdlr1]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-on t-on on components, with 'prevent' modifier 2`] = `
|
||||||
|
"function anonymous(app, bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
|
||||||
|
let block1 = createBlock(\`<button><block-text-0/></button>\`);
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
let txt1 = ctx['props'].value;
|
||||||
|
return block1([txt1]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`t-on t-on on destroyed components 1`] = `
|
exports[`t-on t-on on destroyed components 1`] = `
|
||||||
"function anonymous(app, bdom, helpers
|
"function anonymous(app, bdom, helpers
|
||||||
) {
|
) {
|
||||||
@@ -243,6 +271,38 @@ exports[`t-on t-on on destroyed components 2`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`t-on t-on on slot, with 'prevent' modifier 1`] = `
|
||||||
|
"function anonymous(app, bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { markRaw } = helpers;
|
||||||
|
|
||||||
|
let block1 = createBlock(\`<button>button</button>\`);
|
||||||
|
|
||||||
|
function slot1(ctx, node, key = \\"\\") {
|
||||||
|
return block1();
|
||||||
|
}
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
return component(\`Child\`, {slots: markRaw({'default': {__render: slot1, __ctx: ctx}})}, key + \`__1\`, node, ctx);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`t-on t-on on slot, with 'prevent' modifier 2`] = `
|
||||||
|
"function anonymous(app, bdom, helpers
|
||||||
|
) {
|
||||||
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
let { callSlot, createCatcher } = helpers;
|
||||||
|
const catcher1 = createCatcher({\\"click.prevent\\":0});
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
const hdlr1 = [\\"prevent\\", ctx['doSomething'], ctx];
|
||||||
|
return catcher1(callSlot(ctx, node, key, 'default', false, null), [hdlr1]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`t-on t-on on t-set-slots 1`] = `
|
exports[`t-on t-on on t-set-slots 1`] = `
|
||||||
"function anonymous(app, bdom, helpers
|
"function anonymous(app, bdom, helpers
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, mount, onMounted, useState, xml } from "../../src/index";
|
import { Component, mount, onMounted, useState, xml } from "../../src/index";
|
||||||
import { elem, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
|
import { elem, logStep, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
|
||||||
import { status } from "../../src/runtime/status";
|
import { status } from "../../src/runtime/status";
|
||||||
|
|
||||||
snapshotEverything();
|
snapshotEverything();
|
||||||
@@ -275,4 +275,48 @@ describe("t-on", () => {
|
|||||||
await nextTick();
|
await nextTick();
|
||||||
expect(fixture.innerHTML).toBe(" [1] <p>something</p><p>paragraph</p>");
|
expect(fixture.innerHTML).toBe(" [1] <p>something</p><p>paragraph</p>");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("t-on on components, with 'prevent' modifier", async () => {
|
||||||
|
expect.assertions(4); // 2 snaps and 2 expects
|
||||||
|
class Child extends Component {
|
||||||
|
static template = xml`<button t-esc="props.value"/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Parent extends Component {
|
||||||
|
static template = xml`<Child t-on-click.prevent="increment" value="state.value"/>`;
|
||||||
|
static components = { Child };
|
||||||
|
state = useState({ value: 1 });
|
||||||
|
increment(ev: MouseEvent) {
|
||||||
|
expect(ev.defaultPrevented).toBe(true);
|
||||||
|
this.state.value++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await mount(Parent, fixture);
|
||||||
|
fixture.querySelector("button")!.click();
|
||||||
|
await nextTick();
|
||||||
|
expect(fixture.innerHTML).toBe("<button>2</button>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-on on slot, with 'prevent' modifier", async () => {
|
||||||
|
class Child extends Component {
|
||||||
|
static template = xml`<t t-slot="default" t-on-click.prevent="doSomething"/>`;
|
||||||
|
doSomething(ev: MouseEvent) {
|
||||||
|
expect(ev.defaultPrevented).toBe(true);
|
||||||
|
logStep("hey");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Parent extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<Child>
|
||||||
|
<button>button</button>
|
||||||
|
</Child>`;
|
||||||
|
static components = { Child };
|
||||||
|
}
|
||||||
|
await mount(Parent, fixture);
|
||||||
|
fixture.querySelector("button")!.click();
|
||||||
|
await nextTick();
|
||||||
|
expect(fixture.innerHTML).toBe("<button>button</button>");
|
||||||
|
expect(["hey"]).toBeLogged();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user