Skip to content

Commit

Permalink
Fixes #2253: refine logical tree check and populate parents of insert…
Browse files Browse the repository at this point in the history
…ion points with logical info only if necessary.

Fixes #2283: when a node is removed, we need to potentially distribute not only its host but also its parent.
  • Loading branch information
Steven Orvell committed Aug 17, 2015
1 parent a42ca09 commit 6619f6c
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 10 deletions.
22 changes: 13 additions & 9 deletions src/lib/dom-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@
// 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)) {
// if a <content> is added, make sure it's parent has logical info.
this._ensureContentLogicalInfo(node);
this._addLogicalInfo(node, this.node);
this._addNodeToHost(node);
handled = this._maybeDistribute(node, this.node);
Expand All @@ -90,10 +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)) {
// if a <content> is added, make sure it's parent has logical info.
this._ensureContentLogicalInfo(node);
var children = this.childNodes;
var index = children.indexOf(ref_node);
if (index < 0) {
Expand Down Expand Up @@ -242,11 +242,10 @@
}
},

// a node is in a shadyRoot, is a shadyRoot,
// or has a lightParent
// a node has logical info associated with it
_nodeIsInLogicalTree: function(node) {
return Boolean((node._lightParent !== undefined) || node._isShadyRoot ||
node.shadyRoot);
return Boolean(node._lightParent !== undefined ||
node._lightChildren !== undefined);
},

_ensureContentLogicalInfo: function(node) {
Expand All @@ -270,11 +269,16 @@
// NOTE: if `ensureComposedRemoval` is true then the node should be
// removed from its composed parent.
_removeNodeFromHost: function(node, ensureComposedRemoval) {
// note that it's possible for both the node's host and its parent
// to require distribution... both cases are handled here.
var hostNeedsDist;
var root;
var parent = node._lightParent;
if (parent) {
// distribute node's parent iff needed
factory(node)._distributeParent();
root = this._ownerShadyRootForNode(node);
// remove node from root and distribute it iff needed
if (root) {
root.host._elementRemove(node);
hostNeedsDist = this._removeDistributedChildren(root, node);
Expand Down Expand Up @@ -938,7 +942,7 @@
}

function hasInsertionPoint(root) {
return Boolean(root._insertionPoints.length);
return Boolean(root && root._insertionPoints.length);
}

var p = Element.prototype;
Expand Down
41 changes: 40 additions & 1 deletion test/unit/polymer-dom-content.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<dom-module id="x-dist">
<template>
x-dist
<div id="distWrapper"><content></content></div>
<div id="distWrapper"><content id="content"></content></div>
</template>
<script>
HTMLImports.whenReady(function() {
Expand Down Expand Up @@ -832,6 +832,45 @@
}
});

test('moving children between distributing hosts', function() {
var h1 = document.createElement('x-dist');
var h2 = document.createElement('x-dist');
document.body.appendChild(h1);
document.body.appendChild(h2);
Polymer.dom.flush();
var d = document.createElement('div');
Polymer.dom(h1).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h1).childNodes.length, 1);
assert.equal(Polymer.dom(h1).firstElementChild, d);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
assert.equal(Polymer.dom(h2).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
Polymer.dom(h1).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h1).childNodes.length, 1);
assert.equal(Polymer.dom(h1).firstElementChild, d);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
assert.equal(Polymer.dom(h2).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
document.body.removeChild(h1);
document.body.removeChild(h2);
});

});

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

test('mutations using fragments without logical dom', function() {
var d = document.createElement('div');
document.body.appendChild(d);
assert.equal(Polymer.dom(d).childNodes.length, 0);
var frag = document.createDocumentFragment();
var c = document.createElement('div');
frag.appendChild(c);
Polymer.dom(d).appendChild(frag);
assert.equal(Polymer.dom(d).childNodes.length, 1);
assert.equal(Polymer.dom(d).firstChild, c);
var c1 = document.createElement('div');
frag.appendChild(c1);
Polymer.dom(d).appendChild(frag);
assert.equal(Polymer.dom(d).childNodes.length, 2);
assert.equal(Polymer.dom(d).firstChild, c);
assert.equal(Polymer.dom(d).lastChild, c1);
});

test('appendChild interacts with unmanaged parent tree', function() {
var container = document.querySelector('#container');
var echo = Polymer.dom(container).firstElementChild;
Expand Down

0 comments on commit 6619f6c

Please sign in to comment.