mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] components: crash when using unknown suffix/modifiers
This commit is contained in:
@@ -39,6 +39,7 @@ export interface CodeGenOptions extends Config {
|
|||||||
// of HTML (as we will parse it as xml later)
|
// of HTML (as we will parse it as xml later)
|
||||||
const xmlDoc = document.implementation.createDocument(null, null, null);
|
const xmlDoc = document.implementation.createDocument(null, null, null);
|
||||||
|
|
||||||
|
const MODS = new Set(["stop", "capture", "prevent", "self", "synthetic"]);
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// BlockDescription
|
// BlockDescription
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -504,7 +505,12 @@ export class CodeGenerator {
|
|||||||
const modifiers = rawEvent
|
const modifiers = rawEvent
|
||||||
.split(".")
|
.split(".")
|
||||||
.slice(1)
|
.slice(1)
|
||||||
.map((m) => `"${m}"`);
|
.map((m) => {
|
||||||
|
if (!MODS.has(m)) {
|
||||||
|
throw new Error(`Unknown event modifier: '${m}'`);
|
||||||
|
}
|
||||||
|
return `"${m}"`;
|
||||||
|
});
|
||||||
let modifiersCode = "";
|
let modifiersCode = "";
|
||||||
if (modifiers.length) {
|
if (modifiers.length) {
|
||||||
modifiersCode = `${modifiers.join(",")}, `;
|
modifiersCode = `${modifiers.join(",")}, `;
|
||||||
@@ -1022,6 +1028,8 @@ export class CodeGenerator {
|
|||||||
this.helpers.add("bind");
|
this.helpers.add("bind");
|
||||||
propName = name;
|
propName = name;
|
||||||
propValue = `bind(ctx, ${propValue})`;
|
propValue = `bind(ctx, ${propValue})`;
|
||||||
|
} else {
|
||||||
|
throw new Error("Invalid prop suffix");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
propName = /^[a-z_]+$/i.test(propName) ? propName : `'${propName}'`;
|
propName = /^[a-z_]+$/i.test(propName) ? propName : `'${propName}'`;
|
||||||
|
|||||||
@@ -480,6 +480,14 @@ describe("t-on", () => {
|
|||||||
button.click();
|
button.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("t-on crashes when used with unknown modifier", async () => {
|
||||||
|
const template = `<div t-on-click.somemodifier="onClick" />`;
|
||||||
|
|
||||||
|
let owner = { onClick(e: Event) {} };
|
||||||
|
|
||||||
|
expect(() => mountToFixture(template, owner)).toThrowError("Unknown event modifier");
|
||||||
|
});
|
||||||
|
|
||||||
test("t-on combined with t-esc", async () => {
|
test("t-on combined with t-esc", async () => {
|
||||||
expect.assertions(3);
|
expect.assertions(3);
|
||||||
const template = `<div><button t-on-click="onClick" t-esc="text"/></div>`;
|
const template = `<div><button t-on-click="onClick" t-esc="text"/></div>`;
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ exports[`basics support prop names that aren't valid bare object property names
|
|||||||
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
|
||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
return component(\`Child\`, {'some-dashed-prop': 5,'a.b': 'keyword prop'}, key + \`__1\`, node, ctx);
|
return component(\`Child\`, {'some-dashed-prop': 5}, key + \`__1\`, node, ctx);
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -142,17 +142,16 @@ describe("basics", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("support prop names that aren't valid bare object property names", async () => {
|
test("support prop names that aren't valid bare object property names", async () => {
|
||||||
expect.assertions(4);
|
expect.assertions(3);
|
||||||
class Child extends Component {
|
class Child extends Component {
|
||||||
static template = xml`<button t-on-click="props.onClick"/>`;
|
static template = xml`<button t-on-click="props.onClick"/>`;
|
||||||
setup() {
|
setup() {
|
||||||
expect(this.props["some-dashed-prop"]).toBe(5);
|
expect(this.props["some-dashed-prop"]).toBe(5);
|
||||||
expect(this.props["a.b"]).toBe("keyword prop");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component {
|
class Parent extends Component {
|
||||||
static template = xml`<Child some-dashed-prop="5" a.b="'keyword prop'"/>`;
|
static template = xml`<Child some-dashed-prop="5"/>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
await mount(Parent, fixture);
|
await mount(Parent, fixture);
|
||||||
@@ -225,3 +224,18 @@ test("bound functions is referentially equal after update", async () => {
|
|||||||
expect(fixture.innerHTML).toBe("3");
|
expect(fixture.innerHTML).toBe("3");
|
||||||
expect(isEqual).toBe(true);
|
expect(isEqual).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("throw if prop uses an unknown suffix", async () => {
|
||||||
|
class Child extends Component {
|
||||||
|
static template = xml`<t t-esc="props.val"/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Parent extends Component {
|
||||||
|
static template = xml`<Child val.somesuffix="state.val"/>`;
|
||||||
|
static components = { Child };
|
||||||
|
}
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
|
await mount(Parent, fixture);
|
||||||
|
}).rejects.toThrowError("Invalid prop suffix");
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user