diff --git a/src/lib/dom-api-classlist.html b/src/lib/dom-api-classlist.html
index 80d4720814..a5ef7940ba 100644
--- a/src/lib/dom-api-classlist.html
+++ b/src/lib/dom-api-classlist.html
@@ -56,7 +56,7 @@
_distributeParent: function() {
if (!useShadow) {
- this.domApi._distributeParent();
+ this.domApi._maybeDistributeParent();
}
},
diff --git a/src/lib/dom-api-shady.html b/src/lib/dom-api-shady.html
index 61888b3894..8f034cd0fa 100644
--- a/src/lib/dom-api-shady.html
+++ b/src/lib/dom-api-shady.html
@@ -25,9 +25,6 @@
return;
}
- var nativeInsertBefore = Element.prototype.insertBefore;
- var nativeRemoveChild = Element.prototype.removeChild;
- var nativeAppendChild = Element.prototype.appendChild;
var nativeCloneNode = Element.prototype.cloneNode;
var nativeImportNode = Document.prototype.importNode;
@@ -73,11 +70,10 @@
// if adding to a shadyRoot, add to host instead
var container = this.node._isShadyRoot ? this.node.host : this.node;
if (ref_node) {
- nativeInsertBefore.call(container, node, ref_node);
+ TreeApi.Composed.insertBefore(container, node, ref_node);
} else {
- nativeAppendChild.call(container, node);
+ TreeApi.Composed.appendChild(container, node);
}
- TreeApi.Composed.recordInsertBefore(container, node, ref_node);
}
this.notifyObserver();
return node;
@@ -105,8 +101,8 @@
This method also performs dom composition.
*/
removeChild: function(node) {
- if (dom(node).parentNode !== this.node) {
- console.warn('The node to be removed is not a child of this node',
+ if (TreeApi.Logical.getParentNode(node) !== this.node) {
+ throw Error('The node to be removed is not a child of this node: ' +
node);
}
if (!this._removeNode(node)) {
@@ -115,8 +111,7 @@
// not guaranteed to physically be in container; e.g.
// undistributed nodes.
if (container === node.parentNode) {
- nativeRemoveChild.call(container, node);
- TreeApi.Composed.recordRemoveChild(container, node);
+ TreeApi.Composed.removeChild(container, node);
}
}
this.notifyObserver();
@@ -128,8 +123,6 @@
// note that it's possible for both the node's host and its parent
// to require distribution... both cases are handled here.
_removeNode: function(node) {
- TreeApi.Composed.recordRemoveChild(
- TreeApi.Composed.getParentNode(node), node);
// important that we want to do this only if the node has a logical parent
var logicalParent = TreeApi.Logical.hasParentNode(node) &&
TreeApi.Logical.getParentNode(node);
@@ -137,7 +130,7 @@
var root = this._ownerShadyRootForNode(node);
if (logicalParent) {
// distribute node's parent iff needed
- distributed = dom(node)._distributeParent();
+ distributed = dom(node)._maybeDistributeParent();
TreeApi.Logical.recordRemoveChild(node, logicalParent);
// remove node from root and distribute it iff needed
if (root && this._removeDistributedChildren(root, node)) {
@@ -175,7 +168,7 @@
if (node._isShadyRoot) {
root = node;
} else {
- var parent = Polymer.dom(node).parentNode;
+ var parent = TreeApi.Logical.getParentNode(node);
if (parent) {
root = parent._isShadyRoot ? parent :
this._ownerShadyRootForNode(parent);
@@ -196,9 +189,9 @@
// distributeContent(true), which updates insertion points manually
// and forces distribution.
var fragContent = (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) &&
- !node.__noContent && Polymer.dom(node).querySelector(CONTENT);
+ !node.__noContent && dom(node).querySelector(CONTENT);
var wrappedContent = fragContent &&
- (Polymer.dom(fragContent).parentNode.nodeType !==
+ (TreeApi.Logical.getParentNode(fragContent).nodeType !==
Node.DOCUMENT_FRAGMENT_NODE);
var hasContent = fragContent || (node.localName === CONTENT);
// There are 2 possible cases where a distribution may need to occur:
@@ -234,7 +227,7 @@
!node.__noContent) {
var c$ = dom(node).querySelectorAll(CONTENT);
for (var i=0, n, np, na; (i ref_node
+ // update ref_node.previousSibling <-> node
node.__previousSibling = ref_node ? ref_node.__previousSibling :
container.__lastChild;
if (node.__previousSibling) {
node.__previousSibling.__nextSibling = node;
}
+ // update node <-> ref_node
node.__nextSibling = ref_node;
- if (ref_node) {
- ref_node.__previousSibling = node;
+ if (node.__nextSibling) {
+ node.__nextSibling.__previousSibling = node;
}
// update node <-> container
node.__parentNode = container;
- if (ref_node && ref_node === container.__firstChild) {
- container.__firstChild = node;
+ if (ref_node) {
+ if (ref_node === container.__firstChild) {
+ container.__firstChild = node;
+ }
} else {
container.__lastChild = node;
if (!container.__firstChild) {
@@ -182,13 +206,20 @@
return node.parentNode;
},
- recordInsertBefore: function(parent, node, ref_node) {
+ getFirstChild: function(node) {
+ return node.firstChild;
},
- recordRemoveChild: function(parent, node) {
+ getLastChild: function(node) {
+ return node.lastChild;
},
- recordParentNode: function(node, parent) {
+ getNextSibling: function(node) {
+ return node.nextSibling;
+ },
+
+ getPreviousSibling: function(node) {
+ return node.previousSibling;
},
// composed tracking needs to reset composed children here in case
@@ -200,24 +231,15 @@
},
insertBefore: function(parentNode, newChild, refChild) {
- var newChildParent = this.getParentNode(newChild);
- if (newChildParent !== parentNode) {
- this.recordRemoveChild(newChildParent, newChild);
- }
- // remove child from its old parent first
- this.removeChild(newChild);
- // insert it into the real DOM
- nativeInsertBefore.call(parentNode, newChild, refChild || null);
- this.recordParentNode(newChild, parentNode);
- },
-
- removeChild: function(node) {
- var parentNode = this.getParentNode(node);
- if (parentNode) {
- this.recordParentNode(node, null);
- // remove it from the real DOM
- nativeRemoveChild.call(parentNode, node);
- }
+ return nativeInsertBefore.call(parentNode, newChild, refChild || null);
+ },
+
+ appendChild: function(parentNode, newChild) {
+ return nativeAppendChild.call(parentNode, newChild);
+ },
+
+ removeChild: function(parentNode, node) {
+ return nativeRemoveChild.call(parentNode, node);
}
};
diff --git a/src/mini/shady.html b/src/mini/shady.html
index 5d446a31c9..90ae45ddd2 100644
--- a/src/mini/shady.html
+++ b/src/mini/shady.html
@@ -121,22 +121,19 @@
*/
distributeContent: function(updateInsertionPoints) {
if (this.shadyRoot) {
- var dom = Polymer.dom(this);
- if (updateInsertionPoints) {
- dom._updateInsertionPoints(this);
- }
+ this.shadyRoot._invalidInsertionPoints =
+ this.shadyRoot._invalidInsertionPoints || updateInsertionPoints;
// Distribute the host that's the top of this element's distribution
// tree. Distributing that host will *always* distibute this element.
var host = getTopDistributingHost(this);
- dom._lazyDistribute(host);
+ Polymer.dom(this)._lazyDistribute(host);
}
},
_distributeContent: function() {
if (this._useContent && !this.shadyRoot._distributionClean) {
if (this.shadyRoot._invalidInsertionPoints) {
- var dom = Polymer.dom(this);
- dom._updateInsertionPoints(this);
+ Polymer.dom(this)._updateInsertionPoints(this);
this.shadyRoot._invalidInsertionPoints = false;
}
// logically distribute self
@@ -298,7 +295,7 @@
this._updateChildNodes(this, this._composeNode(this));
var p$ = this.shadyRoot._insertionPoints;
for (var i=0, l=p$.length, p, parent; (i