From de4433cd319bc37f3ac2915d04cf8f2310c3bcf2 Mon Sep 17 00:00:00 2001 From: Samuel Tilly Date: Wed, 3 May 2017 20:55:56 +0200 Subject: [PATCH] Override namespace with xmlns attribute (#1825) Fixes issue #1819 foreignObject inside SVG --- render/render.js | 22 +++++++++++++--------- render/tests/test-createElement.js | 8 +++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/render/render.js b/render/render.js index 4800bb44..de1766b3 100644 --- a/render/render.js +++ b/render/render.js @@ -6,9 +6,18 @@ module.exports = function($window) { var $doc = $window.document var $emptyFragment = $doc.createDocumentFragment() + var nameSpace = { + svg: "http://www.w3.org/2000/svg", + math: "http://www.w3.org/1998/Math/MathML" + } + var onevent function setEventCallback(callback) {return onevent = callback} + function getNameSpace(vnode) { + return vnode.attrs && vnode.attrs.xmlns || nameSpace[vnode.tag] + } + //create function createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) { for (var i = start; i < end; i++) { @@ -66,14 +75,11 @@ module.exports = function($window) { } function createElement(parent, vnode, hooks, ns, nextSibling) { var tag = vnode.tag - switch (vnode.tag) { - case "svg": ns = "http://www.w3.org/2000/svg"; break - case "math": ns = "http://www.w3.org/1998/Math/MathML"; break - } - var attrs = vnode.attrs var is = attrs && attrs.is + ns = getNameSpace(vnode) || ns + var element = ns ? is ? $doc.createElementNS(ns, tag, {is: is}) : $doc.createElementNS(ns, tag) : is ? $doc.createElement(tag, {is: is}) : $doc.createElement(tag) @@ -289,10 +295,8 @@ module.exports = function($window) { } function updateElement(old, vnode, recycling, hooks, ns) { var element = vnode.dom = old.dom - switch (vnode.tag) { - case "svg": ns = "http://www.w3.org/2000/svg"; break - case "math": ns = "http://www.w3.org/1998/Math/MathML"; break - } + ns = getNameSpace(vnode) || ns + if (vnode.tag === "textarea") { if (vnode.attrs == null) vnode.attrs = {} if (vnode.text != null) { diff --git a/render/tests/test-createElement.js b/render/tests/test-createElement.js index 9e2827cf..4e3591f4 100644 --- a/render/tests/test-createElement.js +++ b/render/tests/test-createElement.js @@ -55,7 +55,10 @@ o.spec("createElement", function() { o(vnode.dom.childNodes[1].nodeName).equals("B") }) o("creates svg", function() { - var vnode = {tag: "svg", ns: "http://www.w3.org/2000/svg", children: [{tag: "a", ns: "http://www.w3.org/2000/svg", attrs: {"xlink:href": "javascript:;"}}]} + var vnode = {tag: "svg", ns: "http://www.w3.org/2000/svg", children: [ + {tag: "a", ns: "http://www.w3.org/2000/svg", attrs: {"xlink:href": "javascript:;"}}, + {tag: "foreignObject", children: [{tag: "body", attrs: {xmlns: "http://www.w3.org/1999/xhtml"}}]} + ]} render(root, [vnode]) o(vnode.dom.nodeName).equals("svg") @@ -64,6 +67,9 @@ o.spec("createElement", function() { o(vnode.dom.firstChild.namespaceURI).equals("http://www.w3.org/2000/svg") o(vnode.dom.firstChild.attributes["href"].nodeValue).equals("javascript:;") o(vnode.dom.firstChild.attributes["href"].namespaceURI).equals("http://www.w3.org/1999/xlink") + o(vnode.dom.childNodes[1].nodeName).equals("foreignObject") + o(vnode.dom.childNodes[1].firstChild.nodeName).equals("body") + o(vnode.dom.childNodes[1].firstChild.namespaceURI).equals("http://www.w3.org/1999/xhtml") }) o("sets attributes correctly for svg", function() { var vnode = {tag: "svg", ns: "http://www.w3.org/2000/svg", attrs: {viewBox: "0 0 100 100"}}