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));