From 79ea50aab99ffcb9711a96c0aa5c099ac6deb1a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Sun, 5 Mar 2023 09:04:42 +0100 Subject: [PATCH] [FIX] compiler: throw if using `t-slot` on a htmlelement tag Before this commit, the tagName of a `t-slot` directive was ignored. So, ... and
...
were basically equivalent. This is not really acceptable, since it most likely hides a developer error. So, the question is what to do about it? There are two obvious solutions: - either make the `t-slot` directive behave as t-esc: the above example would then be equivalent to
...
- or throw an error. However, the first solution seems to be ambiguous when using a component with slot props. How should the following code be interpreted? Should the 'a' and 'b' props be considered props for the component or for the slot? I guess we could make an exception for components, but it seems more complicated than what it should be. Because of that, it seems simpler to just throw an error. closes #1354 --- doc/reference/slots.md | 2 ++ src/compiler/parser.ts | 6 ++++++ tests/compiler/parser.test.ts | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/doc/reference/slots.md b/doc/reference/slots.md index 7c9637ec..d9a64ec2 100644 --- a/doc/reference/slots.md +++ b/doc/reference/slots.md @@ -46,6 +46,8 @@ Here is how the `Navbar` component could be defined, with the `t-slot` directive ``` +Note that `t-slot` can only be used on a `` element. + ## Named slots Default slots are very useful, but sometimes, we may need more than one slot. diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0bf572d9..49585004 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -798,6 +798,12 @@ function parseTSlot(node: Element, ctx: ParsingContext): AST | null { if (!node.hasAttribute("t-slot")) { return null; } + if (node.tagName !== "t") { + throw new OwlError( + `Directive 't-slot' can only be used on nodes (used on a <${node.tagName}>)` + ); + } + const name = node.getAttribute("t-slot")!; node.removeAttribute("t-slot"); let attrs: Attrs | null = null; diff --git a/tests/compiler/parser.test.ts b/tests/compiler/parser.test.ts index 52178251..b3ac6acf 100644 --- a/tests/compiler/parser.test.ts +++ b/tests/compiler/parser.test.ts @@ -1686,6 +1686,12 @@ describe("qweb parser", () => { }); }); + test("t-slot on a div tag should throw", async () => { + expect(() => parse(`
`)).toThrowError( + "Directive 't-slot' can only be used on nodes (used on a
)" + ); + }); + // --------------------------------------------------------------------------- // t-debug // ---------------------------------------------------------------------------