From 9a3bead5688610c8f290249b351df59fe6d6f3ca Mon Sep 17 00:00:00 2001 From: Steven Orvell Date: Mon, 14 Dec 2015 18:40:01 -0800 Subject: [PATCH] Store all dom tree data in `__dom` private storage; implement composed patching via a linked list. --- src/lib/dom-tree-api.html | 224 +++++++++---------- src/lib/experimental/patch-dom.html | 330 ++++++++++++++++++---------- src/mini/shady.html | 7 +- test/smoke/patch/patch-dom.html | 12 +- test/unit/shady.html | 63 +++--- 5 files changed, 359 insertions(+), 277 deletions(-) diff --git a/src/lib/dom-tree-api.html b/src/lib/dom-tree-api.html index a1889cab79..be6df6db4d 100644 --- a/src/lib/dom-tree-api.html +++ b/src/lib/dom-tree-api.html @@ -55,101 +55,103 @@ Polymer.TreeApi.Logical = { - hasChildNodes: function(node) { - return Boolean(node.__childNodes !== undefined); - }, - hasParentNode: function(node) { - return Boolean(node.__parentNode); + return Boolean(node.__dom && node.__dom.parentNode); }, + hasChildNodes: function(node) { + return Boolean(node.__dom && node.__dom.childNodes !== undefined); + }, + getChildNodes: function(node) { // note: we're distinguishing here between undefined and false-y: // hasChildNodes uses undefined check to see if this element has logical // children; the false-y check indicates whether or not we should rebuild // the cached childNodes array. - if (this.hasChildNodes(node)) { - if (!node.__childNodes) { - node.__childNodes = []; - for (var n=node.__firstChild; n; n=n.__nextSibling) { - node.__childNodes.push(n); - } - } - return node.__childNodes; - } else { - // TODO(sorvell): it's more correct to `Composed.getChildNodes` - // instead of `childNodes` here but any trivial failure - //to use Polymer.dom will result in an error. - return node.childNodes; + return this.hasChildNodes(node) ? this._getChildNodes(node) : + node.childNodes; + }, + + _getChildNodes: function(node) { + if (!node.__dom.childNodes) { + node.__dom.childNodes = []; + for (var n=node.__dom.firstChild; n; n=n.__dom.nextSibling) { + node.__dom.childNodes.push(n); + } } + return node.__dom.childNodes; }, getParentNode: function(node) { - return node.__parentNode || TreeApi.Composed.getParentNode(node); + return node.__dom && node.__dom.parentNode || node.parentNode; }, getFirstChild: function(node) { - return node.__firstChild || TreeApi.Composed.getFirstChild(node); + return node.__dom && node.__dom.firstChild || node.firstChild; }, getLastChild: function(node) { - return node.__lastChild || TreeApi.Composed.getLastChild(node); + return node.__dom && node.__dom.lastChild || node.lastChild; }, getNextSibling: function(node) { - return node.__nextSibling || TreeApi.Composed.getNextSibling(node); + return node.__dom && node.__dom.nextSibling || node.nextSibling; }, getPreviousSibling: function(node) { - return node.__previousSibling || TreeApi.Composed.getPreviousSibling(node); + return node.__dom && node.__dom.previousSibling || node.previousSibling; }, getFirstElementChild: function(node) { - if (node.__firstChild) { - var n = node.__firstChild; - while (n && n.nodeType !== Node.ELEMENT_NODE) { - n = n.__nextSibling; - } - return n; - } else { - return TreeApi.Composed.getFirstElementChild(node); + return node.__dom && node.__dom.firstChild ? + this._getFirstElementChild(node) : node.firstElementChild; + }, + + _getFirstElementChild: function(node) { + var n = node.__dom.firstChild; + while (n && n.nodeType !== Node.ELEMENT_NODE) { + n = n.__dom.nextSibling; } + return n; }, getLastElementChild: function(node) { - if (node.__lastChild) { - var n = node.__lastChild; - while (n && n.nodeType !== Node.ELEMENT_NODE) { - n = n.__previousSibling; - } - return n; - } else { - return TreeApi.Composed.getLastElementChild(node); + return node.__dom && node.__dom.lastChild ? + this._getLastElementChild(node) : node.firstElementChild; + }, + + _getLastElementChild: function(node) { + var n = node.__dom.lastChild; + while (n && n.nodeType !== Node.ELEMENT_NODE) { + n = n.__dom.previousSibling; } + return n; }, getNextElementSibling: function(node) { - if (node.__nextSibling) { - var n = node.__nextSibling; - while (n && n.nodeType !== Node.ELEMENT_NODE) { - n = n.__nextSibling; - } - return n; - } else { - return TreeApi.Composed.getNextElementSibling(node); + return node.__dom && node.__dom.nextSibling ? + this._getNextElementSibling(node) : node.nextElementSibling; + }, + + _getNextElementSibling: function(node) { + var n = node.__dom.nextSibling; + while (n && n.nodeType !== Node.ELEMENT_NODE) { + n = n.__dom.nextSibling; } + return n; }, getPreviousElementSibling: function(node) { - if (node.__previousSibling) { - var n = node.__previousSibling; - while (n && n.nodeType !== Node.ELEMENT_NODE) { - n = n.__previousSibling; - } - return n; - } else { - return TreeApi.Composed.getPreviousElementSibling(node); + return node.__dom && node.__dom.previousSibling ? + this._getPreviousElementSibling(node) : node.previousElementSibling; + }, + + _getPreviousElementSibling: function(node) { + var n = node.__dom.previousSibling; + while (n && n.nodeType !== Node.ELEMENT_NODE) { + n = n.__dom.previousSibling; } + return n; }, // Capture the list of light children. It's important to do this before we @@ -160,20 +162,22 @@ // has been called. saveChildNodes: function(node) { if (!this.hasChildNodes(node)) { - node.__firstChild = node.firstChild; - node.__lastChild = node.lastChild; - node.__childNodes = []; + node.__dom = node.__dom || {}; + node.__dom.firstChild = node.firstChild; + node.__dom.lastChild = node.lastChild; + node.__dom.childNodes = []; for (var n=node.firstChild; n; n=n.nextSibling) { - n.__parentNode = node; - node.__childNodes.push(n); - n.__nextSibling = n.nextSibling; - n.__previousSibling = n.previousSibling; + n.__dom = n.__dom || {}; + n.__dom.parentNode = node; + node.__dom.childNodes.push(n); + n.__dom.nextSibling = n.nextSibling; + n.__dom.previousSibling = n.previousSibling; } } }, recordInsertBefore: function(node, container, ref_node) { - container.__childNodes = null; + container.__dom.childNodes = null; // handle document fragments if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { // TODO(sorvell): remember this for patching: @@ -188,52 +192,60 @@ }, _linkNode: function(node, container, ref_node) { + node.__dom = node.__dom || {}; + container.__dom = container.__dom || {}; + if (ref_node) { + ref_node.__dom = ref_node.__dom || {}; + } // update ref_node.previousSibling <-> node - node.__previousSibling = ref_node ? ref_node.__previousSibling : - container.__lastChild; - if (node.__previousSibling) { - node.__previousSibling.__nextSibling = node; + node.__dom.previousSibling = ref_node ? ref_node.__dom.previousSibling : + container.__dom.lastChild; + if (node.__dom.previousSibling) { + node.__dom.previousSibling.__dom.nextSibling = node; } // update node <-> ref_node - node.__nextSibling = ref_node; - if (node.__nextSibling) { - node.__nextSibling.__previousSibling = node; + node.__dom.nextSibling = ref_node; + if (node.__dom.nextSibling) { + node.__dom.nextSibling.__dom.previousSibling = node; } // update node <-> container - node.__parentNode = container; + node.__dom.parentNode = container; if (ref_node) { - if (ref_node === container.__firstChild) { - container.__firstChild = node; + if (ref_node === container.__dom.firstChild) { + container.__dom.firstChild = node; } } else { - container.__lastChild = node; - if (!container.__firstChild) { - container.__firstChild = node; + container.__dom.lastChild = node; + if (!container.__dom.firstChild) { + container.__dom.firstChild = node; } } // remove caching of childNodes - container.__childNodes = null; + container.__dom.childNodes = null; }, recordRemoveChild: function(node, container) { - if (node === container.__firstChild) { - container.__firstChild = node.__nextSibling; + node.__dom = node.__dom || {}; + container.__dom = container.__dom || {}; + if (node === container.__dom.firstChild) { + container.__dom.firstChild = node.__dom.nextSibling; } - if (node === container.__lastChild) { - container.__lastChild = node.__previousSibling; + if (node === container.__dom.lastChild) { + container.__dom.lastChild = node.__dom.previousSibling; } - var p = node.__previousSibling; - var n = node.__nextSibling; + var p = node.__dom.previousSibling; + var n = node.__dom.nextSibling; if (p) { - p.__nextSibling = n; + p.__dom.nextSibling = n; } if (n) { - n.__previousSibling = p; + n.__dom.previousSibling = p; } - node.__parentNode = node.__previousSibling = node.__nextSibling = null; + node.__dom.parentNode = node.__dom.previousSibling = + node.__dom.nextSibling = null; // remove caching of childNodes - container.__childNodes = null; - }, + container.__dom.childNodes = null; + } } @@ -242,10 +254,6 @@ // to the tree for optional patching pluggability. Polymer.TreeApi.Composed = { - - ensureParentNodes: function(parent, children) { - }, - getChildNodes: function(node) { return Polymer.TreeApi.arrayCopyChildNodes(node); }, @@ -254,38 +262,6 @@ return node.parentNode; }, - getFirstChild: function(node) { - return node.firstChild; - }, - - getLastChild: function(node) { - return node.lastChild; - }, - - getNextSibling: function(node) { - return node.nextSibling; - }, - - getPreviousSibling: function(node) { - return node.previousSibling; - }, - - getFirstElementChild: function(node) { - return node.firstElementChild; - }, - - getLastElementChild: function(node) { - return node.lastElementChild; - }, - - getNextElementSibling: function(node) { - return node.nextElementSibling; - }, - - getPreviousElementSibling: function(node) { - return node.previousElementSibling; - }, - // composed tracking needs to reset composed children here in case // they may have already been set (this shouldn't happen but can // if dependency ordering is incorrect and as a result upgrade order diff --git a/src/lib/experimental/patch-dom.html b/src/lib/experimental/patch-dom.html index 571983e67c..b8d424efee 100644 --- a/src/lib/experimental/patch-dom.html +++ b/src/lib/experimental/patch-dom.html @@ -245,24 +245,27 @@ // NOTE: patch logical implementations here so we can use // composed getters - Polymer.TreeApi.Logical.saveChildNodes = function(node) { + TreeApi.Logical.saveChildNodes = function(node) { if (!this.hasChildNodes(node)) { - node.__firstChild = node.firstChild; - node.__lastChild = node.lastChild; - node.__childNodes = []; + if (!node.__dom) { + node.__dom = {}; + } + node.__dom.firstChild = node.firstChild; + node.__dom.lastChild = node.lastChild; + node.__dom.childNodes = []; for (var n=TreeApi.Composed.getFirstChild(node); n; n=TreeApi.Composed.getNextSibling(n)) { - n.__parentNode = node; - node.__childNodes.push(n); - n.__nextSibling = TreeApi.Composed.getNextSibling(n); - n.__previousSibling = TreeApi.Composed.getPreviousSibling(n); + n.__dom = n.__dom || {}; + n.__dom.parentNode = node; + node.__dom.childNodes.push(n); + n.__dom.nextSibling = TreeApi.Composed.getNextSibling(n); + n.__dom.previousSibling = TreeApi.Composed.getPreviousSibling(n); } } } - Polymer.TreeApi.Logical.recordInsertBefore = - function(node, container, ref_node) { - container.__childNodes = null; + TreeApi.Logical.recordInsertBefore = function(node, container, ref_node) { + container.__dom.childNodes = null; // handle document fragments if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { // TODO(sorvell): remember this for patching: @@ -277,131 +280,245 @@ } } - Polymer.TreeApi.Composed = { + TreeApi.Logical.getChildNodes = function(node) { + if (this.hasChildNodes(node)) { + return this._getChildNodes(node); + } else { + // TODO(sorvell): it's more correct to `Composed.getChildNodes` + // instead of `childNodes` here but any trivial failure + //to use Polymer.dom will result in an error. + return node.childNodes; + } + }; + + + TreeApi.Logical.getParentNode = function(node) { + return node.__dom && node.__dom.parentNode || + TreeApi.Composed.getParentNode(node); + }; + + TreeApi.Logical.getFirstChild = function(node) { + return node.__dom && node.__dom.firstChild || + TreeApi.Composed.getFirstChild(node); + }; + + TreeApi.Logical.getLastChild = function(node) { + return node.__dom && node.__dom.lastChild || + TreeApi.Composed.getLastChild(node); + }; + + TreeApi.Logical.getNextSibling = function(node) { + return node.__dom && node.__dom.nextSibling || + TreeApi.Composed.getNextSibling(node); + }; + + TreeApi.Logical.getPreviousSibling = function(node) { + return node.__dom && node.__dom.previousSibling || + TreeApi.Composed.getPreviousSibling(node); + }; + + TreeApi.Logical.getFirstElementChild = function(node) { + return node.__dom && node.__dom.firstChild ? + this._getFirstElementChild(node) : + TreeApi.Composed.getFirstElementChild(node); + }; + + TreeApi.Logical.getLastElementChild = function(node) { + return node.__dom && node.__dom.lastChild ? + this._getLastElementChild(node) : + TreeApi.Composed.getLastElementChild(node); + }; + + TreeApi.Logical.getNextElementSibling = function(node) { + return node.__dom && node.__dom.nextSibling ? + this._getNextElementSibling(node) : + TreeApi.Composed.getNextElementSibling(node); + }; + + TreeApi.Logical.getPreviousElementSibling = function(node) { + return node.__dom && node.__dom.previousSibling ? + this._getPreviousElementSibling(node) : + TreeApi.Composed.getPreviousElementSibling(node); + }; + + + TreeApi.Composed = { hasParentNode: function(node) { - return Boolean(node.__composedParent !== undefined); + return Boolean(node.__dom && node.__dom.$parentNode !== undefined); }, hasChildNodes: function(node) { - return Boolean(node.__composedChildNodes !== undefined); + return Boolean(node.__dom && node.__dom.$childNodes !== undefined); }, getChildNodes: function(node) { - return node.__composedChildNodes || + return node.__dom.$childNodes || (!node.__patched && TreeApi.arrayCopy(node.childNodes)); }, getComposedChildNodes: function(node) { - return node.__composedChildNodes; + return node.__dom.$childNodes; }, getParentNode: function(node) { - return this.hasParentNode(node) ? node.__composedParent : + return this.hasParentNode(node) ? node.__dom.$parentNode : (!node.__patched && node.parentNode); }, getFirstChild: function(node) { - if (node.__patched) { - return this.getChildNodes(node)[0]; - } else { - return node.firstChild; - } + return node.__patched ? node.__dom.$firstChild : node.firstChild; }, getLastChild: function(node) { - if (node.__patched) { - var c$ = this.getChildNodes(node); - return c$[c$.length-1]; - } else { - return node.lastChild; - } + return node.__patched ? node.__dom.$lastChild : node.lastChild; }, getNextSibling: function(node) { - // TODO(sorvell): linked list - var parent = this.getParentNode(node); - if (parent.__patched) { - var c$ = this.getChildNodes(parent); - var i = c$.indexOf(node); - return c$[i+1]; - } else if (!node.__patched) { - return node.nextSibling; - } + return node.__patched ? node.__dom.$nextSibling : node.nextSibling; }, getPreviousSibling: function(node) { - // TODO(sorvell): linked list - var parent = this.getParentNode(node); - if (parent.__patched) { - var c$ = this.getChildNodes(parent); - var i = c$.indexOf(node); - return c$[i-1]; - } else if (!node.__patched) { - return node.previousSibling; - } + return node.__patched ? node.__dom.$previousSibling : node.previousSibling; }, getFirstElementChild: function(node) { - if (node.__patched) { - var c$ = this.getChildNodes(node); - for (var i=0, n; i < c$.length; i++) { - n = c$[i]; - if (n.nodeType === Node.ELEMENT_NODE) { - return n; - } - } - } else { - return node.firstElementChild; + return node.__patched ? this._getFirstElementChild(node) : + node.firstElementChild; + }, + + _getFirstElementChild: function(node) { + var n = node.__dom.$firstChild; + while (n && n.nodeType !== Node.ELEMENT_NODE) { + n = n.__dom.$nextSibling; } + return n; }, getLastElementChild: function(node) { - if (node.__patched) { - var c$ = this.getChildNodes(node); - for (var i=c$.length, n; i >=0 ; i--) { - n = c$[i]; - if (n.nodeType === Node.ELEMENT_NODE) { - return n; - } - } - } else { - return node.lastElementChild; + return node.__patched ? this._getLastElementChild(node) : + node.firstElementChild; + }, + + _getLastElementChild: function(node) { + var n = node.__dom.$lastChild; + while (n && n.nodeType !== Node.ELEMENT_NODE) { + n = n.__dom.$previousSibling; } + return n; }, getNextElementSibling: function(node) { - if (node.__patched) { - var c$ = this.getChildNodes(node); - var i = c$.indexOf(node); - if (i >= 0) { - for (var n; i < c$.length; i++) { - n = c$[i]; - if (n.nodeType === Node.ELEMENT_NODE) { - return n; - } - } + return node.__patched ? this._getNextElementSibling(node) : + node.nextElementSibling; + }, + + _getNextElementSibling: function(node) { + var n = node.__dom.$nextSibling; + while (n && n.nodeType !== Node.ELEMENT_NODE) { + n = n.__dom.$nextSibling; + } + return n; + }, + + getPreviousElementSibling: function(node) { + return node.__patched ? this._getPreviousElementSibling(node) : + node.previousElementSibling; + }, + + _getPreviousElementSibling: function(node) { + var n = node.__dom.$previousSibling; + while (n && n.nodeType !== Node.ELEMENT_NODE) { + n = n.__dom.$previousSibling; + } + return n; + }, + + saveChildNodes: function(node) { + if (!this.hasChildNodes(node)) { + node.__dom = node.__dom || {}; + node.__dom.$firstChild = node.firstChild; + node.__dom.$lastChild = node.lastChild; + node.__dom.$childNodes = []; + for (var n=node.firstChild; n; n=n.nextSibling) { + n.__dom = n.__dom || {}; + n.__dom.$parentNode = node; + node.__dom.$childNodes.push(n); + n.__dom.$nextSibling = n.nextSibling; + n.__dom.$previousSibling = n.previousSibling; + } + } + }, + + recordInsertBefore: function(node, container, ref_node) { + container.__dom.$childNodes = null; + // handle document fragments + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + // TODO(sorvell): remember this for patching: + // the act of setting this info can affect patched nodes + // getters; therefore capture childNodes before patching. + for (var n=this.getFirstChild(node); n; n=this.getNextSibling(n)) { + this._linkNode(n, container, ref_node); } } else { - return node.nextElementSibling; + this._linkNode(node, container, ref_node); } }, - getPreviousElementSibling: function(node) { - if (node.__patched) { - var c$ = this.getChildNodes(node); - var i = c$.indexOf(node); - if (i >= 0) { - for (var n; i >=0 ; i--) { - n = c$[i]; - if (n.nodeType === Node.ELEMENT_NODE) { - return n; - } - } + _linkNode: function(node, container, ref_node) { + node.__dom = node.__dom || {}; + container.__dom = container.__dom || {}; + if (ref_node) { + ref_node.__dom = ref_node.__dom || {}; + } + // update ref_node.previousSibling <-> node + node.__dom.$previousSibling = ref_node ? ref_node.__dom.$previousSibling : + container.__dom.$lastChild; + if (node.__dom.$previousSibling) { + node.__dom.$previousSibling.__dom.$nextSibling = node; + } + // update node <-> ref_node + node.__dom.$nextSibling = ref_node; + if (node.__dom.$nextSibling) { + node.__dom.$nextSibling.__dom.$previousSibling = node; + } + // update node <-> container + node.__dom.$parentNode = container; + if (ref_node) { + if (ref_node === container.__dom.$firstChild) { + container.__dom.$firstChild = node; } } else { - return node.previousElementSibling; + container.__dom.$lastChild = node; + if (!container.__dom.$firstChild) { + container.__dom.$firstChild = node; + } } + // remove caching of childNodes + container.__dom.$childNodes = null; + }, + + recordRemoveChild: function(node, container) { + node.__dom = node.__dom || {}; + container.__dom = container.__dom || {}; + if (node === container.__dom.$firstChild) { + container.__dom.$firstChild = node.__dom.$nextSibling; + } + if (node === container.__dom.$lastChild) { + container.__dom.$lastChild = node.__dom.$previousSibling; + } + var p = node.__dom.$previousSibling; + var n = node.__dom.$nextSibling; + if (p) { + p.__dom.$nextSibling = n; + } + if (n) { + n.__dom.$previousSibling = p; + } + node.__dom.$parentNode = node.__dom.$previousSibling = + node.__dom.$nextSibling = null; + // remove caching of childNodes + container.__dom.$childNodes = null; }, // composed tracking needs to reset composed children here in case @@ -409,28 +526,19 @@ // if dependency ordering is incorrect and as a result upgrade order // is unexpected) clearChildNodes: function(node) { - if (node.__composedParent) { - node.__composedParent.__composedChildNodes = []; + if (node.__dom && node.__dom.$parentNode) { + node.__dom.$parentNode.__dom.$childNodes = []; } node.textContent = ''; }, - saveChildNodes: function(node) { - var c$ = node.__composedChildNodes = []; - for (var n=node.firstChild; n; n=n.nextSibling) { - n.__composedParent = node; - c$.push(n); - } - }, - saveParentNode: function(node) { - node.__composedParent = node.parentNode; + node.__dom = node.__dom || {}; + node.__dom.$parentNode = node.parentNode; }, insertBefore: function(parentNode, newChild, refChild) { - if (!this.hasChildNodes(parentNode)) { - this.saveChildNodes(parentNode); - } + this.saveChildNodes(parentNode); // remove from current location. if (this.hasParentNode(newChild)) { var oldParent = this.getParentNode(newChild); @@ -443,9 +551,7 @@ }, appendChild: function(parentNode, newChild) { - if (!this.hasChildNodes(parentNode)) { - this.saveChildNodes(parentNode); - } + this.saveChildNodes(parentNode); // remove from current location. if (this.hasParentNode(newChild)) { var oldParent = this.getParentNode(newChild); @@ -459,13 +565,11 @@ removeChild: function(parentNode, node) { var currentParent = this.getParentNode(node); - if (!this.hasChildNodes(parentNode)) { - this.saveChildNodes(parentNode); - } + this.saveChildNodes(parentNode); this._removeChild(parentNode, node); if (currentParent === parentNode) { // TODO(sorvell); abort if the composedParent is not expected... - if (!node.__patched && node.parentNode !== node.__composedParent) { + if (!node.__patched && node.parentNode !== node.__dom.$parentNode) { return; } return nativeRemoveChild.call(parentNode, node); @@ -479,7 +583,8 @@ this._addChild(parentNode, c$[j], refChild); } } else { - newChild.__composedParent = parentNode; + newChild.__dom = newChild.__dom || {}; + newChild.__dom.$parentNode = parentNode; var c$ = this.getComposedChildNodes(parentNode); if (c$) { var i = c$.indexOf(refChild); @@ -490,7 +595,8 @@ }, _removeChild: function(parentNode, node) { - node.__composedParent = null; + node.__dom = node.__dom || {}; + node.__dom.$parentNode = null; var c$ = this.getComposedChildNodes(parentNode); if (c$) { var i = c$.indexOf(node); diff --git a/src/mini/shady.html b/src/mini/shady.html index 314a6fb847..641566da65 100644 --- a/src/mini/shady.html +++ b/src/mini/shady.html @@ -40,6 +40,9 @@ if (!this.__domApi) { this.__domApi = null; } + if (!this.__dom) { + this.__dom = null; + } if (!this._ownerShadyRoot) { this._ownerShadyRoot = undefined; } @@ -417,7 +420,9 @@ // dirty a shadyRoot if a change may trigger reprojection! function maybeRedistributeParent(content, host) { - var parent = content.__parentNode; + // only get logical parent. + var parent = TreeApi.Logical.hasParentNode(content) && + TreeApi.Logical.getParentNode(content); if (parent && parent.shadyRoot && DomApi.hasInsertionPoint(parent.shadyRoot) && parent.shadyRoot._distributionClean) { diff --git a/test/smoke/patch/patch-dom.html b/test/smoke/patch/patch-dom.html index 1db4259f93..92e3a2fe0e 100644 --- a/test/smoke/patch/patch-dom.html +++ b/test/smoke/patch/patch-dom.html @@ -251,19 +251,19 @@ assert.equal(s.parentNode, rere); Polymer.dom.flush(); if (rere.shadyRoot) { - assert.notEqual(s.__composedParent, rere); + assert.notEqual(s.__dom.$parentNode, rere); } Polymer.dom.flush(); if (rere.shadyRoot) { - assert.equal(s.__composedParent, p); + assert.equal(s.__dom.$parentNode, p); } rere.removeChild(s); if (rere.shadyRoot) { - assert.equal(s.__composedParent, p); + assert.equal(s.__dom.$parentNode, p); } Polymer.dom.flush(); if (rere.shadyRoot) { - assert.equal(s.__composedParent, null); + assert.equal(s.__dom.$parentNode, null); } }); @@ -343,13 +343,13 @@ function testNoAttr() { assert.equal(Polymer.dom(child).getDestinationInsertionPoints()[0], d.$.notTestContent, 'child not distributed logically'); if (shady) { - assert.equal(child.__composedParent, d.$.notTestContainer, 'child not rendered in composed dom'); + assert.equal(child.__dom.$parentNode, d.$.notTestContainer, 'child not rendered in composed dom'); } } function testWithAttr() { assert.equal(Polymer.dom(child).getDestinationInsertionPoints()[0], d.$.testContent, 'child not distributed logically'); if (shady) { - assert.equal(child.__composedParent, d.$.testContainer, 'child not rendered in composed dom'); + assert.equal(child.__dom.$parentNode, d.$.testContainer, 'child not rendered in composed dom'); } } // test with x-distribute diff --git a/test/unit/shady.html b/test/unit/shady.html index a7ed04a793..b1abbfcd47 100644 --- a/test/unit/shady.html +++ b/test/unit/shady.html @@ -135,14 +135,14 @@ assert.strictEqual(getComposedHTML(host), 'a: b: '); - assertArrayEqual(host.__childNodes, [a]); - assert.strictEqual(a.__parentNode, host); - assertArrayEqual(host.shadyRoot.__childNodes, [p]); - assert.strictEqual(p.__parentNode, host.shadyRoot); - assertArrayEqual(p.__childNodes, [b, content]); - assert.strictEqual(b.__parentNode, p); - assert.strictEqual(content.__parentNode, p); - assertArrayEqual(p.shadyRoot.__childNodes, + assertArrayEqual(host.__dom.childNodes, [a]); + assert.strictEqual(a.__dom.parentNode, host); + assertArrayEqual(host.shadyRoot.__dom.childNodes, [p]); + assert.strictEqual(p.__dom.parentNode, host.shadyRoot); + assertArrayEqual(p.__dom.childNodes, [b, content]); + assert.strictEqual(b.__dom.parentNode, p); + assert.strictEqual(content.__dom.parentNode, p); + assertArrayEqual(p.shadyRoot.__dom.childNodes, [textNodeA, contentA, textNodeB, contentB]); } @@ -165,7 +165,7 @@ distributeContentNow(host); assert.strictEqual(getComposedHTML(host), ''); - host.__childNodes = []; + host.__dom.childNodes = []; distributeContentNow(host); assert.strictEqual(getComposedHTML(host), 'fallback'); }); @@ -180,11 +180,11 @@ distributeContentNow(host); assert.strictEqual(getComposedHTML(host), 'Helloafter'); - host.shadyRoot.__childNodes[1].textContent = ''; + host.shadyRoot.__dom.childNodes[1].textContent = ''; distributeContentNow(host); assert.strictEqual(getComposedHTML(host), 'Hello'); - host.shadyRoot.__childNodes = []; + host.shadyRoot.__dom.childNodes = []; distributeContentNow(host); assert.strictEqual(getComposedHTML(host), ''); }); @@ -203,11 +203,11 @@ distributeContentNow(host); assert.strictEqual(getComposedHTML(host), ''); - host.shadyRoot.firstChild.__childNodes = []; + host.shadyRoot.firstChild.__dom.childNodes = []; distributeContentNow(host); assert.strictEqual(getComposedHTML(host), ''); - host.shadyRoot.__childNodes = []; + host.shadyRoot.__dom.childNodes = []; distributeContentNow(host); assert.strictEqual(getComposedHTML(host), ''); }); @@ -225,7 +225,7 @@ distributeContentNow(host); assert.strictEqual(getComposedHTML(host), ''); - host.__childNodes = []; + host.__dom.childNodes = []; distributeContentNow(host); assert.strictEqual(getComposedHTML(host), 'fallback'); }); @@ -265,11 +265,11 @@ distributeContentNow(host); assert.strictEqual(getComposedHTML(host), 'Hello'); - host.shadyRoot.__childNodes.splice(1, 1); // remove b + host.shadyRoot.__dom.childNodes.splice(1, 1); // remove b distributeContentNow(host); assert.strictEqual(getComposedHTML(host), 'Hello'); - host.shadyRoot.__childNodes = []; // remove a + host.shadyRoot.__dom.childNodes = []; // remove a distributeContentNow(host); assert.strictEqual(getComposedHTML(host), ''); }); @@ -368,7 +368,7 @@ assert.strictEqual(getComposedHTML(host), 'Hello'); var b = document.createElement('b'); - host.__childNodes[0] = b; + host.__dom.childNodes[0] = b; distributeContentNow(host); assert.strictEqual(getComposedHTML(host), ''); }); @@ -437,16 +437,17 @@ }); function syncLightDOM(n) { - if (n.__childNodes) { - var c$ = n.__patched ? n._composedChildren || [] : Array.prototype.slice.call(n.childNodes); - n.__firstChild = c$[0]; - n.__lastChild = c$[c$.length-1]; + if (n.__dom.childNodes !== undefined) { + var c$ = Array.prototype.slice.call(n.childNodes); + n.__dom.firstChild = c$[0]; + n.__dom.lastChild = c$[c$.length-1]; c$.forEach(function(c, i) { - if (n.__childNodes.indexOf(c) < 0) { - c.__parentNode = n; - c.__previousSibling = c$[i-1]; - c.__nextSibling = c$[i+1]; - n.__childNodes.push(c); + if (n.__dom.childNodes.indexOf(c) < 0) { + c.__dom = c.__dom || {}; + c.__dom.parentNode = n; + c.__dom.previousSibling = c$[i-1]; + c.__dom.nextSibling = c$[i+1]; + n.__dom.childNodes.push(c); } }); } @@ -456,17 +457,11 @@ function setInnerHTML(node, value) { node.textContent = ''; - if (node._composedChildren) { - node._composedChildren = []; - } var temp = node.ownerDocument.createElement('div'); temp.innerHTML = value; var firstChild; while (firstChild = temp.firstChild) { nativeAppendChild.call(node, firstChild); - if (node._composedChildren) { - node._composedChildren.push(firstChild); - } } } @@ -481,11 +476,11 @@ } function getComposedHTML(node) { - return node.__patched ? Polymer.domInnerHTML.getInnerHTML(node, true) : node.innerHTML; + return node.innerHTML; } function getComposedChildAtIndex(node, index) { - var c$ = node._composedChildren || node.childNodes; + var c$ = node.childNodes; if (c$) { index = index || 0; index = Math.max(0, Math.min(index, c$.length-1));