Skip to content
Browse files

Fixes #2253: refine logical tree check and populate parents of insert…

…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...
1 parent a42ca09 commit 6619f6ce4a7f1ac393621fc79a730f1015f7671c @sorvell sorvell committed
Showing with 71 additions and 10 deletions.
  1. +13 −9 src/lib/dom-api.html
  2. +40 −1 test/unit/polymer-dom-content.html
  3. +18 −0 test/unit/polymer-dom.js
View
22 src/lib/dom-api.html
@@ -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);
@@ -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) {
@@ -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) {
@@ -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);
@@ -938,7 +942,7 @@
}
function hasInsertionPoint(root) {
- return Boolean(root._insertionPoints.length);
+ return Boolean(root && root._insertionPoints.length);
}
var p = Element.prototype;
View
41 test/unit/polymer-dom-content.html
@@ -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() {
@@ -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() {
View
18 test/unit/polymer-dom.js
@@ -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;

0 comments on commit 6619f6c

Please sign in to comment.
Something went wrong with that request. Please try again.