fix svg across component boundaries

This commit is contained in:
Leo Horie 2016-06-03 12:27:24 -04:00
parent 7b268c6ee8
commit ca784a684e
6 changed files with 64 additions and 75 deletions

View file

@ -40,12 +40,7 @@ function hyperscript(selector) {
if (children instanceof Array && children.length == 1 && children[0] != null && children[0].tag === "#") text = children[0].children
else childList = children
var vnode = Node(tag || "div", attrs.key, hasAttrs ? attrs : undefined, childList, text, undefined)
switch (vnode.tag) {
case "svg": changeNS("http://www.w3.org/2000/svg", vnode); break
case "math": changeNS("http://www.w3.org/1998/Math/MathML", vnode); break
}
return vnode
return Node(tag || "div", attrs.key, hasAttrs ? attrs : undefined, childList, text, undefined)
}
}
}
@ -68,11 +63,4 @@ function hyperscript(selector) {
return Node(selector, attrs && attrs.key, attrs || {}, Node.normalizeChildren(children), undefined, undefined)
}
function changeNS(ns, vnode) {
vnode.ns = ns
if (vnode.children != null) {
for (var i = 0; i < vnode.children.length; i++) changeNS(ns, vnode.children[i])
}
}
module.exports = hyperscript

View file

@ -1,5 +1,5 @@
function Node(tag, key, attrs, children, text, dom) {
return {tag: tag, key: key, attrs: attrs, children: children, text: text, dom: dom, domSize: undefined, state: {}, events: undefined, ns: undefined, instance: undefined}
return {tag: tag, key: key, attrs: attrs, children: children, text: text, dom: dom, domSize: undefined, state: {}, events: undefined, instance: undefined}
}
Node.normalize = function(node) {
if (node instanceof Array) return Node("[", undefined, undefined, Node.normalizeChildren(node), undefined, undefined)

View file

@ -10,26 +10,26 @@ module.exports = function($window) {
function setEventCallback(callback) {return onevent = callback}
//create
function createNodes(parent, vnodes, start, end, hooks, nextSibling) {
function createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) {
for (var i = start; i < end; i++) {
var vnode = vnodes[i]
if (vnode != null) {
insertNode(parent, createNode(vnode, hooks), nextSibling)
insertNode(parent, createNode(vnode, hooks, ns), nextSibling)
}
}
}
function createNode(vnode, hooks) {
function createNode(vnode, hooks, ns) {
var tag = vnode.tag
if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)
if (typeof tag === "string") {
switch (tag) {
case "#": return createText(vnode)
case "<": return createHTML(vnode)
case "[": return createFragment(vnode, hooks)
default: return createElement(vnode, hooks)
case "[": return createFragment(vnode, hooks, ns)
default: return createElement(vnode, hooks, ns)
}
}
else return createComponent(vnode, hooks)
else return createComponent(vnode, hooks, ns)
}
function createText(vnode) {
return vnode.dom = $doc.createTextNode(vnode.children)
@ -49,19 +49,22 @@ module.exports = function($window) {
}
return fragment
}
function createFragment(vnode, hooks) {
function createFragment(vnode, hooks, ns) {
var fragment = $doc.createDocumentFragment()
if (vnode.children != null) {
var children = vnode.children
createNodes(fragment, children, 0, children.length, hooks, null)
createNodes(fragment, children, 0, children.length, hooks, null, ns)
}
vnode.dom = fragment.firstChild
vnode.domSize = fragment.childNodes.length
return fragment
}
function createElement(vnode, hooks) {
function createElement(vnode, hooks, ns) {
var tag = vnode.tag
var ns = vnode.ns
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
@ -82,18 +85,18 @@ module.exports = function($window) {
if (vnode.children != null) {
var children = vnode.children
createNodes(element, children, 0, children.length, hooks, null)
createNodes(element, children, 0, children.length, hooks, null, ns)
setLateAttrs(vnode)
}
return element
}
function createComponent(vnode, hooks) {
function createComponent(vnode, hooks, ns) {
vnode.state = copy(vnode.tag)
initLifecycle(vnode.tag, vnode, hooks)
vnode.instance = Node.normalize(vnode.tag.view.call(vnode.state, vnode))
if (vnode.instance != null) {
var element = createNode(vnode.instance, hooks)
var element = createNode(vnode.instance, hooks, ns)
vnode.dom = vnode.instance.dom
vnode.domSize = vnode.instance.domSize
return element

View file

@ -67,6 +67,27 @@ o.spec("component", function() {
o(root.childNodes.length).equals(1)
o(root.firstChild).equals(div.dom)
})
o("svg works when creating across component boundary", function() {
var component = {
view: function(vnode) {
return {tag: "g"}
}
}
render(root, [{tag: "svg", children: [{tag: component}]}])
o(root.firstChild.firstChild.namespaceURI).equals("http://www.w3.org/2000/svg")
})
o("svg works when updating across component boundary", function() {
var component = {
view: function(vnode) {
return {tag: "g"}
}
}
render(root, [{tag: "svg", children: [{tag: component}]}])
render(root, [{tag: "svg", children: [{tag: component}]}])
o(root.firstChild.firstChild.namespaceURI).equals("http://www.w3.org/2000/svg")
})
})
o.spec("return value", function() {
o("can return fragments", function() {

View file

@ -394,24 +394,6 @@ o.spec("hyperscript", function() {
o(vnode.children[0].children[0].children[1].tag).equals("s")
})
})
o.spec("namespaced", function() {
o("handles svg ns", function() {
var vnode = m("svg", m("g"))
o(vnode.tag).equals("svg")
o(vnode.ns).equals("http://www.w3.org/2000/svg")
o(vnode.children[0].tag).equals("g")
o(vnode.children[0].ns).equals("http://www.w3.org/2000/svg")
})
o("handles mathml ns", function() {
var vnode = m("math", m("mrow"))
o(vnode.tag).equals("math")
o(vnode.ns).equals("http://www.w3.org/1998/Math/MathML")
o(vnode.children[0].tag).equals("mrow")
o(vnode.children[0].ns).equals("http://www.w3.org/1998/Math/MathML")
})
})
o.spec("components", function() {
o("works", function() {
var component = {