Skip to content

Commit

Permalink
Merge pull request #2243 from Polymer/fix-2235
Browse files Browse the repository at this point in the history
Fixes #2235. Manages logical information in shady distribution more d…
  • Loading branch information
kevinpschaaf committed Aug 11, 2015
2 parents d55be7d + 45cb150 commit 5a482c6
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 16 deletions.
40 changes: 33 additions & 7 deletions src/lib/dom-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,15 @@
// 3. node is <content> (host of container needs distribution)
appendChild: function(node) {
var handled;
// if a <content> is added, make sure it's parent has logical info.
this._ensureContentLogicalInfo(node);
this._removeNodeFromHost(node, true);
if (this._nodeIsInLogicalTree(this.node)) {
this._addLogicalInfo(node, this.node);
this._addNodeToHost(node);
handled = this._maybeDistribute(node, this.node);
} else {
this._addNodeToHost(node);
}
// if not distributing and not adding to host, do a fast path addition
if (!handled && !this._tryRemoveUndistributedNode(node)) {
Expand All @@ -86,9 +90,10 @@
return this.appendChild(node);
}
var handled;
// if a <content> is added, make sure it's parent has logical info.
this._ensureContentLogicalInfo(node);
this._removeNodeFromHost(node, true);
if (this._nodeIsInLogicalTree(this.node)) {
saveLightChildrenIfNeeded(this.node);
var children = this.childNodes;
var index = children.indexOf(ref_node);
if (index < 0) {
Expand All @@ -98,6 +103,8 @@
this._addLogicalInfo(node, this.node, index);
this._addNodeToHost(node);
handled = this._maybeDistribute(node, this.node);
} else {
this._addNodeToHost(node);
}
// if not distributing and not adding to host, do a fast path addition
if (!handled && !this._tryRemoveUndistributedNode(node)) {
Expand Down Expand Up @@ -125,6 +132,8 @@
if (this._nodeIsInLogicalTree(this.node)) {
this._removeNodeFromHost(node);
handled = this._maybeDistribute(node, this.node);
} else {
this._removeNodeFromHost(node);
}
if (!handled) {
// if removing from a shadyRoot, remove form host instead
Expand Down Expand Up @@ -223,18 +232,37 @@
},

_updateInsertionPoints: function(host) {
host.shadyRoot._insertionPoints =
var i$ = host.shadyRoot._insertionPoints =
factory(host.shadyRoot).querySelectorAll(CONTENT);
// ensure <content>'s and their parents have logical dom info.
for (var i=0, c; i < i$.length; i++) {
c = i$[i];
saveLightChildrenIfNeeded(c);
saveLightChildrenIfNeeded(factory(c).parentNode);
}
},

// a node is in a shadyRoot, is a shadyRoot,
// or has a lightParent
_nodeIsInLogicalTree: function(node) {
return Boolean((node._lightParent !== undefined) || node._isShadyRoot ||
this._ownerShadyRootForNode(node) ||
node.shadyRoot);
},

_ensureContentLogicalInfo: function(node) {
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
saveLightChildrenIfNeeded(this.node);
var c$ = Array.prototype.slice.call(node.childNodes);
for (var i=0, n; (i<c$.length) && (n=c$[i]); i++) {
this._ensureContentLogicalInfo(n);
}
} else if (node.localName === CONTENT) {
// should be parent not this.node, but this is before parent is set.
saveLightChildrenIfNeeded(this.node);
saveLightChildrenIfNeeded(node);
}
},

_parentNeedsDistribution: function(parent) {
return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);
},
Expand Down Expand Up @@ -292,17 +320,15 @@
}
},

// a node being added is always in this same host as this.node.
_addNodeToHost: function(node) {
var checkNode = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ?
node.firstChild : node;
var root = this._ownerShadyRootForNode(checkNode);
var root = this.getOwnerRoot();
if (root) {
root.host._elementAdd(node);
}
},

_addLogicalInfo: function(node, container, index) {
saveLightChildrenIfNeeded(container);
var children = factory(container).childNodes;
index = index === undefined ? children.length : index;
// handle document fragments
Expand Down
18 changes: 10 additions & 8 deletions src/mini/shady.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,19 @@
this.shadyRoot._isShadyRoot = true;
this.shadyRoot._dirtyRoots = [];
// capture insertion point list
this.shadyRoot._insertionPoints = !this._notes ||
var i$ = this.shadyRoot._insertionPoints = !this._notes ||
this._notes._hasContent ?
this.shadyRoot.querySelectorAll('content') : [];
// save logical tree info for shadyRoot.
// save logical tree info
// a. for shadyRoot
// b. for insertion points (fallback)
// c. for parents of insertion points
saveLightChildrenIfNeeded(this.shadyRoot);
for (var i=0, c; i < i$.length; i++) {
c = i$[i];
saveLightChildrenIfNeeded(c);
saveLightChildrenIfNeeded(c.parentNode);
}
this.shadyRoot.host = this;
},

Expand Down Expand Up @@ -406,9 +414,6 @@
}
// remove child from its old parent first
remove(newChild);
// make sure we never lose logical DOM information:
// if the parentNode doesn't have lightChildren, save that information now.
saveLightChildrenIfNeeded(parentNode);
// insert it into the real DOM
nativeInsertBefore.call(parentNode, newChild, refChild || null);
newChild._composedParent = parentNode;
Expand All @@ -417,9 +422,6 @@
function remove(node) {
var parentNode = getComposedParent(node);
if (parentNode) {
// make sure we never lose logical DOM information:
// if the parentNode doesn't have lightChildren, save that information now.
saveLightChildrenIfNeeded(parentNode);
node._composedParent = null;
// remove it from the real DOM
nativeRemoveChild.call(parentNode, node);
Expand Down
6 changes: 6 additions & 0 deletions test/unit/polymer-dom-shadow.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@

<x-redistribute-a-b></x-redistribute-a-b>

<div id="container">
<x-echo></x-echo>
<span>1</span>
<span>2</span>
</div>

<script src="polymer-dom.js"></script>

</body>
Expand Down
6 changes: 6 additions & 0 deletions test/unit/polymer-dom.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@

<x-redistribute-a-b></x-redistribute-a-b>

<div id="container">
<x-echo></x-echo>
<span>1</span>
<span>2</span>
</div>

<script src="polymer-dom.js"></script>

</body>
Expand Down
28 changes: 28 additions & 0 deletions test/unit/polymer-dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,34 @@ suite('Polymer.dom', function() {
assert.equal(Polymer.dom(rere.root).querySelectorAll('span').length, 0);
});

test('appendChild interacts with unmanaged parent tree', function() {
var container = document.querySelector('#container');
var echo = Polymer.dom(container).firstElementChild;
assert.equal(echo.localName, 'x-echo');
var s1 = Polymer.dom(echo).nextElementSibling;
assert.equal(s1.textContent, '1');
var s2 = Polymer.dom(s1).nextElementSibling;
assert.equal(s2.textContent, '2');
assert.equal(Polymer.dom(container).children.length, 3);
Polymer.dom(echo).appendChild(s1);
Polymer.dom.flush();
assert.equal(Polymer.dom(container).children.length, 2);
assert.equal(Polymer.dom(echo).nextElementSibling, s2);
Polymer.dom(echo).appendChild(s2);
Polymer.dom.flush();
assert.equal(Polymer.dom(container).children.length, 1);
assert.equal(Polymer.dom(echo).nextElementSibling, null);
Polymer.dom(container).appendChild(s1);
Polymer.dom.flush();
assert.equal(Polymer.dom(container).children.length, 2);
assert.equal(Polymer.dom(echo).nextElementSibling, s1);
Polymer.dom(container).appendChild(s2);
Polymer.dom.flush();
assert.equal(Polymer.dom(container).children.length, 3);
assert.equal(Polymer.dom(echo).nextElementSibling, s1);
assert.equal(Polymer.dom(s1).nextElementSibling, s2);
});

test('distribute (forced)', function() {
var rere = Polymer.dom(testElement.root).querySelector('x-rereproject');
var re = Polymer.dom(rere.root).querySelector('x-reproject');
Expand Down
2 changes: 1 addition & 1 deletion test/unit/shady.html
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@
}

function updateRootInsertionPoints(root) {
root._insertionPoints = root.querySelectorAll('content');
Polymer.dom(root.host)._updateInsertionPoints(root.host);
}

function getComposedHTML(node) {
Expand Down

0 comments on commit 5a482c6

Please sign in to comment.