diff --git a/doc/reference/templates.md b/doc/reference/templates.md
index cbb3980a..91c62dfe 100644
--- a/doc/reference/templates.md
+++ b/doc/reference/templates.md
@@ -674,7 +674,9 @@ This `RootNode` component will then display a live SVG representation of the
graph described by the `graph` property. Note that there is a recursive structure
here: the `Node` component uses itself as a subcomponent.
-Note that since SVG needs to be handled in a specific way (its namespace needs
-to be properly set), there is a small constraint for Owl components: if an owl
-component is supposed to be a part of an svg graph, then its root node needs to
-be a `g` tag, so Owl can properly set the namespace.
+**Important note:** Owl needs to properly set the namespace for each svg elements.
+Since Owl compile each template separately, it is not able to determine easily
+if a template is supposed to be included in a svg namespace or not. Therefore,
+Owl depends on a heuristic: if a tag is either `svg`, `g` or `path`, then it will
+be considered as svg. In practice, this means that each component or each sub
+templates (included with `t-call`) should have one of these tag as root tag.
diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts
index 5ab4089f..61f2531e 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -285,6 +285,8 @@ function parseTDebugLog(node: Element, ctx: ParsingContext): AST | null {
const hasDotAtTheEnd = /\.[\w_]+\s*$/;
const hasBracketsAtTheEnd = /\[[^\[]+\]\s*$/;
+const ROOT_SVG_TAGS = new Set(["svg", "g", "path"]);
+
function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
const { tagName } = node;
const dynamicTag = node.getAttribute("t-tag");
@@ -296,7 +298,7 @@ function parseDOMNode(node: Element, ctx: ParsingContext): AST | null {
if (tagName === "pre") {
ctx.inPreTag = true;
}
- const shouldAddSVGNS = tagName === "svg" || (tagName === "g" && !ctx.inSVG);
+ const shouldAddSVGNS = ROOT_SVG_TAGS.has(tagName) && !ctx.inSVG;
ctx.inSVG = ctx.inSVG || shouldAddSVGNS;
const ns = shouldAddSVGNS ? "http://www.w3.org/2000/svg" : null;
const ref = node.getAttribute("t-ref");
diff --git a/tests/compiler/__snapshots__/svg.test.ts.snap b/tests/compiler/__snapshots__/svg.test.ts.snap
index 2161f05a..14c96c65 100644
--- a/tests/compiler/__snapshots__/svg.test.ts.snap
+++ b/tests/compiler/__snapshots__/svg.test.ts.snap
@@ -52,6 +52,35 @@ exports[`properly support svg namespace to svg tags added even if already in svg
}"
`;
+exports[`properly support svg svg namespace added to sub templates if root tag is path 1`] = `
+"function anonymous(bdom, helpers
+) {
+ let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
+ let { getTemplate } = helpers;
+ const callTemplate_1 = getTemplate(\`path\`);
+
+ let block1 = createBlock(\`\`);
+
+ return function template(ctx, node, key = \\"\\") {
+ let b2 = callTemplate_1.call(this, ctx, node, key + \`__1\`);
+ return block1([], [b2]);
+ }
+}"
+`;
+
+exports[`properly support svg svg namespace added to sub templates if root tag is path 2`] = `
+"function anonymous(bdom, helpers
+) {
+ let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
+
+ let block1 = createBlock(\`\`);
+
+ return function template(ctx, node, key = \\"\\") {
+ return block1();
+ }
+}"
+`;
+
exports[`properly support svg svg namespace added to sub-blocks 1`] = `
"function anonymous(bdom, helpers
) {
diff --git a/tests/compiler/svg.test.ts b/tests/compiler/svg.test.ts
index a56aa348..42b55d2d 100644
--- a/tests/compiler/svg.test.ts
+++ b/tests/compiler/svg.test.ts
@@ -1,5 +1,7 @@
import { renderToString, renderToBdom, snapshotEverything, makeTestFixture } from "../helpers";
import { mount } from "../../src/blockdom";
+import { mount as mountComponent, Component } from "../../src/index";
+
// NB: check the snapshots to see where the SVG namespaces are added
snapshotEverything();
@@ -52,4 +54,24 @@ describe("properly support svg", () => {
expect(el.namespaceURI).toBe("http://www.w3.org/2000/svg");
}
});
+
+ test("svg namespace added to sub templates if root tag is path", async () => {
+ const templates = `
+
+
+
+ `;
+ const fixture = makeTestFixture();
+
+ class Svg extends Component {
+ static template = "svg";
+ }
+
+ await mountComponent(Svg, fixture, { templates });
+ const elems = fixture.querySelectorAll("svg, path");
+ expect(elems.length).toEqual(2);
+ for (const el of elems) {
+ expect(el.namespaceURI).toBe("http://www.w3.org/2000/svg");
+ }
+ });
});