mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] svg: allow path as root tag
This commit is contained in:
committed by
Aaron Bohy
parent
1e8576ad40
commit
a4d9aae9a7
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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(\`<svg block-ns=\\"http://www.w3.org/2000/svg\\"><block-child-0/></svg>\`);
|
||||
|
||||
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(\`<path block-ns=\\"http://www.w3.org/2000/svg\\"/>\`);
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return block1();
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`properly support svg svg namespace added to sub-blocks 1`] = `
|
||||
"function anonymous(bdom, helpers
|
||||
) {
|
||||
|
||||
@@ -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 = `<t>
|
||||
<t t-name="svg"><svg><t t-call="path" /></svg></t>
|
||||
<t t-name="path"><path /></t>
|
||||
</t>
|
||||
`;
|
||||
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");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user