fix: ensure SVG namespaces are added to nodes (#996)

This ensures that SVG namespaces are correct on children and when copying a thunk.

ISSUES CLOSED: #388 #867

Co-authored-by: macarc <pipescore@outlook.com>
Co-authored-by: Jan van Brügge <supermanitu@gmail.com>
pull/995/head
macarc 3 years ago committed by GitHub
parent 9de2307dd9
commit f89f085f55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -13,17 +13,19 @@ export type VNodeChildElement =
export type ArrayOrElement<T> = T | T[];
export type VNodeChildren = ArrayOrElement<VNodeChildElement>;
function addNS(
export function addNS(
data: any,
children: VNodes | undefined,
children: Array<VNode | string> | undefined,
sel: string | undefined
): void {
data.ns = "http://www.w3.org/2000/svg";
if (sel !== "foreignObject" && children !== undefined) {
for (let i = 0; i < children.length; ++i) {
const childData = children[i].data;
const child = children[i];
if (typeof child === "string") continue;
const childData = child.data;
if (childData !== undefined) {
addNS(childData, children[i].children as VNodes, children[i].sel);
addNS(childData, child.children as VNodes, child.sel);
}
}
}

@ -1,5 +1,5 @@
import { VNode, VNodeData } from "./vnode";
import { h } from "./h";
import { h, addNS } from "./h";
export interface ThunkData extends VNodeData {
fn: () => VNode;
@ -16,12 +16,14 @@ export interface ThunkFn {
}
function copyToThunk(vnode: VNode, thunk: VNode): void {
const ns = thunk.data?.ns;
(vnode.data as VNodeData).fn = (thunk.data as VNodeData).fn;
(vnode.data as VNodeData).args = (thunk.data as VNodeData).args;
thunk.data = vnode.data;
thunk.children = vnode.children;
thunk.text = vnode.text;
thunk.elm = vnode.elm;
if (ns) addNS(thunk.data, thunk.children, thunk.sel);
}
function init(thunk: VNode): void {

@ -1,3 +1,4 @@
import { addNS } from "./h";
import { vnode, VNode } from "./vnode";
import { htmlDomApi, DOMAPI } from "./htmldomapi";
@ -24,7 +25,16 @@ export function toVNode(node: Node, domApi?: DOMAPI): VNode {
for (i = 0, n = elmChildren.length; i < n; i++) {
children.push(toVNode(elmChildren[i], domApi));
}
return vnode(sel, { attrs }, children, undefined, node);
const data = { attrs };
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, undefined, node);
} else if (api.isText(node)) {
text = api.getTextContent(node) as string;
return vnode(undefined, undefined, undefined, text, node);

Loading…
Cancel
Save