[FIX] qweb: properly supports svg

Snabbdom supports svg, but it adds the namespace at the creation of the
virtual node.  However, owl works slightly differently: it adds children
after creating the parent virtual node.

So, we need to actually call the addNS method after the children nodes
have been created.

As a bonus, this is slightly faster than snabbdom: we only check at
template compilation time once if a node is a svg.
This commit is contained in:
Géry Debongnie
2019-09-24 21:38:51 +02:00
parent 82a6961b3a
commit ecf12f6eee
4 changed files with 42 additions and 10 deletions
+9 -1
View File
@@ -2,6 +2,7 @@ import { EventBus } from "../core/event_bus";
import { h, patch, VNode } from "../vdom/index";
import { Context } from "./context";
import { shallowEqual } from "../utils";
import { addNS } from "../vdom/vdom";
/**
* Owl QWeb Engine
@@ -93,7 +94,10 @@ const UTILS: Utils = {
}
return expr;
},
shallowEqual
shallowEqual,
addNameSpace(vnode) {
addNS(vnode.data, vnode.children, vnode.sel);
},
};
function parseXML(xml: string): Document {
@@ -537,6 +541,10 @@ export class QWeb extends EventBus {
}
this._compileChildren(node, ctx);
if (node.nodeName === 'svg') {
ctx.rootContext.shouldDefineUtils = true;
ctx.addLine(`utils.addNameSpace(vn${ctx.parentNode});`);
}
for (let { directive, value, fullName } of validDirectives) {
if (directive.finalize) {
+1 -9
View File
@@ -564,7 +564,7 @@ type VNodeChildElement = VNode | string | number | undefined | null;
type ArrayOrElement<T> = T | T[];
type VNodeChildren = ArrayOrElement<VNodeChildElement>;
function addNS(data: any, children: VNodes | undefined, sel: string | undefined): void {
export function addNS(data: any, children: VNodes | undefined, sel: string | undefined): void {
data.ns = "http://www.w3.org/2000/svg";
if (sel !== "foreignObject" && children !== undefined) {
for (let i = 0, iLen = children.length; i < iLen; ++i) {
@@ -612,13 +612,5 @@ export function h(sel: any, b?: any, c?: any): VNode {
children[i] = vnode(undefined, undefined, undefined, children[i], undefined);
}
}
if (
sel[0] === "s" &&
sel[1] === "v" &&
sel[2] === "g" &&
(sel.length === 3 || sel[3] === "." || sel[3] === "#")
) {
addNS(data, children, sel);
}
return vnode(sel, data, children, text, undefined);
}