diff --git a/packages/diffhtml/lib/node/create.js b/packages/diffhtml/lib/node/create.js
index f9e965fc..dc995bec 100644
--- a/packages/diffhtml/lib/node/create.js
+++ b/packages/diffhtml/lib/node/create.js
@@ -1,5 +1,5 @@
import { NodeCache, MiddlewareCache } from '../util/caches';
-import { elements, namespace } from '../util/svg';
+import { namespace } from '../util/svg';
import process from '../util/process';
const { CreateNodeHookCache } = MiddlewareCache;
@@ -11,9 +11,10 @@ const { CreateNodeHookCache } = MiddlewareCache;
*
* @param {Object} - A Virtual Tree Element or VTree-like element
* @param {Object} - Document to create Nodes in
+ * @param {Boolean} - Is their a root SVG element?
* @return {Object} - A DOM Node matching the vTree
*/
-export default function createNode(vTree, ownerDocument = document) {
+export default function createNode(vTree, ownerDocument = document, isSVG) {
if (process.env.NODE_ENV !== 'production') {
if (!vTree) {
throw new Error('Missing VTree when trying to create DOM Node');
@@ -28,6 +29,7 @@ export default function createNode(vTree, ownerDocument = document) {
}
const { nodeName, childNodes = [] } = vTree;
+ isSVG = isSVG || nodeName === 'svg';
// Will vary based on the properties of the VTree.
let domNode = null;
@@ -50,12 +52,8 @@ export default function createNode(vTree, ownerDocument = document) {
else if (nodeName === '#document-fragment') {
domNode = ownerDocument.createDocumentFragment();
}
- // If the nodeName matches any of the known SVG element names, mark it as
- // SVG. The reason for doing this over detecting if nested in an
- // element, is that we do not currently have circular dependencies in the
- // VTree, by avoiding parentNode, so there is no way to crawl up the
- // parents.
- else if (elements.indexOf(nodeName) > -1) {
+ // Support SVG.
+ else if (isSVG) {
domNode = ownerDocument.createElementNS(namespace, nodeName);
}
// If not a Text or SVG Node, then create with the standard method.
@@ -70,7 +68,7 @@ export default function createNode(vTree, ownerDocument = document) {
// Append all the children into the domNode, making sure to run them
// through this `createNode` function as well.
for (let i = 0; i < childNodes.length; i++) {
- domNode.appendChild(createNode(childNodes[i], ownerDocument));
+ domNode.appendChild(createNode(childNodes[i], ownerDocument, isSVG));
}
return domNode;
diff --git a/packages/diffhtml/lib/node/patch.js b/packages/diffhtml/lib/node/patch.js
index 41bd3677..e8f88289 100644
--- a/packages/diffhtml/lib/node/patch.js
+++ b/packages/diffhtml/lib/node/patch.js
@@ -15,9 +15,10 @@ const removeAttribute = (domNode, name) => {
}
};
-export default function patchNode(patches) {
+export default function patchNode(patches, state = {}) {
const promises = [];
const { TREE_OPS, NODE_VALUE, SET_ATTRIBUTE, REMOVE_ATTRIBUTE } = patches;
+ const { isSVG, ownerDocument } = state;
// Set attributes.
if (SET_ATTRIBUTE.length) {
@@ -26,7 +27,7 @@ export default function patchNode(patches) {
const _name = SET_ATTRIBUTE[i + 1];
const value = decodeEntities(SET_ATTRIBUTE[i + 2]);
- const domNode = createNode(vTree);
+ const domNode = createNode(vTree, ownerDocument, isSVG);
const attributeChanged = TransitionCache.get('attributeChanged');
const oldValue = domNode.getAttribute(_name);
const newPromises = runTransitions(
@@ -119,21 +120,21 @@ export default function patchNode(patches) {
for (let i = 0; i < INSERT_BEFORE.length; i += 3) {
const vTree = INSERT_BEFORE[i];
const newTree = INSERT_BEFORE[i + 1];
- const referenceTree = INSERT_BEFORE[i + 2];
+ const refTree = INSERT_BEFORE[i + 2];
const domNode = NodeCache.get(vTree);
- const referenceNode = referenceTree && createNode(referenceTree);
+ const refNode = refTree && createNode(refTree, ownerDocument, isSVG);
const attached = TransitionCache.get('attached');
- if (referenceTree) {
- protectVTree(referenceTree);
+ if (refTree) {
+ protectVTree(refTree);
}
- const newNode = createNode(newTree);
+ const newNode = createNode(newTree, ownerDocument, isSVG);
protectVTree(newTree);
// If refNode is `null` then it will simply append like `appendChild`.
- domNode.insertBefore(newNode, referenceNode);
+ domNode.insertBefore(newNode, refNode);
const attachedPromises = runTransitions('attached', newNode);
@@ -171,7 +172,7 @@ export default function patchNode(patches) {
const oldTree = REPLACE_CHILD[i + 1];
const oldDomNode = NodeCache.get(oldTree);
- const newDomNode = createNode(newTree);
+ const newDomNode = createNode(newTree, ownerDocument, isSVG);
const attached = TransitionCache.get('attached');
const detached = TransitionCache.get('detached');
const replaced = TransitionCache.get('replaced');
diff --git a/packages/diffhtml/lib/tasks/patch-node.js b/packages/diffhtml/lib/tasks/patch-node.js
index 105f1ecf..3b97d357 100644
--- a/packages/diffhtml/lib/tasks/patch-node.js
+++ b/packages/diffhtml/lib/tasks/patch-node.js
@@ -10,6 +10,12 @@ export default function patch(transaction) {
const { domNode, state, state: { measure }, patches } = transaction;
const { promises = [] } = transaction;
+ // Is the root SVG?
+ state.isSVG = transaction.oldTree.nodeName === 'svg';
+
+ // Set the ownerDocument.
+ state.ownerDocument = domNode.ownerDocument || document;
+
measure('patch node');
promises.push(...patchNode(patches, state));
measure('patch node');
diff --git a/packages/diffhtml/lib/util/svg.js b/packages/diffhtml/lib/util/svg.js
index 8d1770ea..d6b57e7a 100644
--- a/packages/diffhtml/lib/util/svg.js
+++ b/packages/diffhtml/lib/util/svg.js
@@ -1,82 +1,2 @@
// Namespace.
export const namespace = 'http://www.w3.org/2000/svg';
-
-// List of SVG elements.
-export const elements = [
- 'altGlyph',
- 'altGlyphDef',
- 'altGlyphItem',
- 'animate',
- 'animateColor',
- 'animateMotion',
- 'animateTransform',
- 'circle',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'defs',
- 'desc',
- 'ellipse',
- 'feBlend',
- 'feColorMatrix',
- 'feComponentTransfer',
- 'feComposite',
- 'feConvolveMatrix',
- 'feDiffuseLighting',
- 'feDisplacementMap',
- 'feDistantLight',
- 'feFlood',
- 'feFuncA',
- 'feFuncB',
- 'feFuncG',
- 'feFuncR',
- 'feGaussianBlur',
- 'feImage',
- 'feMerge',
- 'feMergeNode',
- 'feMorphology',
- 'feOffset',
- 'fePointLight',
- 'feSpecularLighting',
- 'feSpotLight',
- 'feTile',
- 'feTurbulence',
- 'filter',
- 'font',
- 'font-face',
- 'font-face-format',
- 'font-face-name',
- 'font-face-src',
- 'font-face-uri',
- 'foreignObject',
- 'g',
- 'glyph',
- 'glyphRef',
- 'hkern',
- 'image',
- 'line',
- 'linearGradient',
- 'marker',
- 'mask',
- 'metadata',
- 'missing-glyph',
- 'mpath',
- 'path',
- 'pattern',
- 'polygon',
- 'polyline',
- 'radialGradient',
- 'rect',
- 'set',
- 'stop',
- 'svg',
- 'switch',
- 'symbol',
- 'text',
- 'textPath',
- 'tref',
- 'tspan',
- 'use',
- 'view',
- 'vkern',
-];
diff --git a/packages/diffhtml/test/integration/svg.js b/packages/diffhtml/test/integration/svg.js
index e510b67e..4f7f3d6f 100644
--- a/packages/diffhtml/test/integration/svg.js
+++ b/packages/diffhtml/test/integration/svg.js
@@ -4,8 +4,7 @@ import validateMemory from '../util/validateMemory';
describe('Integration: SVG', function() {
beforeEach(function() {
- this.fixture = document.createElement('div');
- this.fixture.innerHTML = ' ';
+ this.fixture = document.createElement('svg');
this.namespace = 'http://www.w3.org/2000/svg';
});
diff --git a/packages/diffhtml/test/util.js b/packages/diffhtml/test/util.js
index bbf1a470..90deb40b 100644
--- a/packages/diffhtml/test/util.js
+++ b/packages/diffhtml/test/util.js
@@ -7,7 +7,7 @@ import decodeEntities from '../lib/util/decode-entities';
import escape from '../lib/util/escape';
import parse from '../lib/util/parse';
import _process from '../lib/util/process';
-import { namespace, elements } from '../lib/util/svg';
+import { namespace } from '../lib/util/svg';
import { protectVTree, unprotectVTree, cleanMemory } from '../lib/util/memory';
import makeMeasure from '../lib/util/make-measure';
import Pool from '../lib/util/pool';
@@ -853,11 +853,6 @@ describe('Util', function() {
});
describe('SVG', () => {
- it('exports a list of valid SVG elements', () => {
- ok(Array.isArray(elements));
- ok(elements.length);
- });
-
it('exports the SVG namespace', () => {
equal(namespace, 'http://www.w3.org/2000/svg');
});