Merge pull request #3112 from Polymer/shady-linked

ShadyDOM: use a linked-list for tree accessors
This commit is contained in:
Kevin Schaaf
2015-12-15 17:09:54 -08:00
22 changed files with 1732 additions and 1092 deletions

View File

@@ -948,7 +948,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.equal(host.$.distWrapper.children[1], s2);
assert.equal(host.$.distWrapper.children[2], s3);
assert.equal(host.$.distWrapper.children[3], s0);
var composedChildren = host.$.distWrapper._composedChildren;
var composedChildren = Polymer.TreeApi.Composed.getChildNodes(host.$.distWrapper);
assert.equal(composedChildren.length, 4);
assert.equal(composedChildren[0], s1);
assert.equal(composedChildren[1], s2);
@@ -961,7 +961,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom.flush();
if (host.shadyRoot) {
assert.equal(host.$.distWrapper.children.length, 1);
var composedChildren = host.$.distWrapper._composedChildren;
var composedChildren = Polymer.TreeApi.Composed.getChildNodes(host.$.distWrapper);
assert.equal(composedChildren.length, 1);
assert.equal(composedChildren[0], s0);
}
@@ -987,7 +987,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.equal(host.$.distWrapper.children[1], s2);
assert.equal(host.$.distWrapper.children[2], s3);
assert.equal(host.$.distWrapper.children[3], s0);
var composedChildren = host.$.distWrapper._composedChildren;
var composedChildren = Polymer.TreeApi.Composed.getChildNodes(host.$.distWrapper);
assert.equal(composedChildren.length, 4);
assert.equal(composedChildren[0], s1);
assert.equal(composedChildren[1], s2);
@@ -1000,7 +1000,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom.flush();
if (host.shadyRoot) {
assert.equal(host.$.distWrapper.children.length, 1);
var composedChildren = host.$.distWrapper._composedChildren;
var composedChildren = Polymer.TreeApi.Composed.getChildNodes(host.$.distWrapper);
assert.equal(composedChildren.length, 1);
assert.equal(composedChildren[0], s0);
}
@@ -1100,7 +1100,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
Polymer.dom(h1).appendChild(d);
@@ -1112,7 +1112,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
document.body.removeChild(h1);
@@ -1134,7 +1134,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
Polymer.dom(h1).appendChild(d);
@@ -1146,7 +1146,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
document.body.removeChild(h1);
@@ -1246,7 +1246,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
Polymer.dom(h1).appendChild(d);
@@ -1258,7 +1258,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
document.body.removeChild(h1);
@@ -1280,7 +1280,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
Polymer.dom(h1).appendChild(d);
@@ -1292,7 +1292,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
document.body.removeChild(h1);
@@ -1313,7 +1313,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
Polymer.dom(h1).appendChild(d);
@@ -1325,7 +1325,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
document.body.removeChild(h1);
@@ -1335,7 +1335,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var div = document.createElement('div');
div.innerHTML = '<x-dist-simple><div></div></x-dist-simple>';
var h1 = div.firstChild;
var h2 = document.createDocumentFragment();;
var h2 = document.createDocumentFragment();
document.body.appendChild(h1);
Polymer.dom.flush();
var d = Polymer.dom(h1).firstElementChild;
@@ -1347,7 +1347,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
Polymer.dom(h1).appendChild(d);
@@ -1359,7 +1359,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.dom(h2).appendChild(d);
Polymer.dom.flush();
assert.equal(Polymer.dom(h2).childNodes.length, 1);
assert.equal(Polymer.dom(h2).firstElementChild, d);
assert.equal(Polymer.dom(h2).firstChild, d);
assert.equal(Polymer.dom(h1).childNodes.length, 0);
assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
document.body.removeChild(h1);

View File

@@ -489,19 +489,19 @@ suite('Polymer.dom', function() {
assert.equal(Polymer.dom(rere).querySelector('#light'), s);
assert.equal(Polymer.dom(s).parentNode, rere);
if (rere.shadyRoot) {
assert.notEqual(s._composedParent, rere);
assert.notEqual(Polymer.TreeApi.Composed.getParentNode(s), rere);
}
Polymer.dom(testElement).flush();
if (rere.shadyRoot) {
assert.equal(s._composedParent, p);
assert.equal(Polymer.TreeApi.Composed.getParentNode(s), p);
}
Polymer.dom(rere).removeChild(s);
if (rere.shadyRoot) {
assert.equal(s._composedParent, p);
assert.equal(Polymer.TreeApi.Composed.getParentNode(s), p);
}
Polymer.dom(testElement).flush();
if (rere.shadyRoot) {
assert.equal(s._composedParent, null);
assert.equal(Polymer.TreeApi.Composed.getParentNode(s), null);
}
});
@@ -760,7 +760,7 @@ suite('Polymer.dom accessors', function() {
assert.equal(Polymer.dom(testElement).textContent, 'Hello World', 'textContent getter incorrect');
if (testElement.shadyRoot) {
Polymer.dom.flush();
assert.equal(testElement._composedChildren[1].textContent, 'Hello World', 'text content setter incorrect');
assert.equal(Polymer.TreeApi.Composed.getChildNodes(testElement)[1].textContent, 'Hello World', 'text content setter incorrect');
}
testElement = document.createElement('x-commented');
assert.equal(Polymer.dom(testElement.root).textContent, '[]', 'text content getter with comment incorrect');
@@ -784,9 +784,10 @@ suite('Polymer.dom accessors', function() {
assert.equal(Polymer.dom(testElement).innerHTML , '<div>Hello World</div><div>2</div><div>3</div>', 'innerHTML getter incorrect');
if (testElement.shadyRoot) {
Polymer.dom.flush();
assert.equal(testElement._composedChildren[1], added, 'innerHTML setter composed incorrectly');
assert.equal(testElement._composedChildren[2].textContent, '2', 'innerHTML setter composed incorrectly');
assert.equal(testElement._composedChildren[3].textContent, '3', 'innerHTML setter composed incorrectly');
var children = Polymer.TreeApi.Composed.getChildNodes(testElement);
assert.equal(children[1], added, 'innerHTML setter composed incorrectly');
assert.equal(children[2].textContent, '2', 'innerHTML setter composed incorrectly');
assert.equal(children[3].textContent, '3', 'innerHTML setter composed incorrectly');
}
});
@@ -851,13 +852,13 @@ suite('Polymer.dom non-distributed elements', function() {
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(Polymer.TreeApi.Composed.getParentNode(child), 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(Polymer.TreeApi.Composed.getParentNode(child), d.$.testContainer, 'child not rendered in composed dom');
}
}
// test with x-distribute

View File

@@ -135,14 +135,14 @@ test('Reproject', function() {
assert.strictEqual(getComposedHTML(host),
'<x-content-test id="p">a: <a></a>b: <b></b></x-content-test>');
assertArrayEqual(host._lightChildren, [a]);
assert.strictEqual(a._lightParent, host);
assertArrayEqual(host.shadyRoot._lightChildren, [p]);
assert.strictEqual(p._lightParent, host.shadyRoot);
assertArrayEqual(p._lightChildren, [b, content]);
assert.strictEqual(b._lightParent, p);
assert.strictEqual(content._lightParent, p);
assertArrayEqual(p.shadyRoot._lightChildren,
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 @@ suite('Mutate light DOM', function() {
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '<a></a>');
host._lightChildren = [];
host.__dom.childNodes = [];
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), 'fallback');
});
@@ -180,11 +180,11 @@ suite('Mutate light DOM', function() {
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '<a>Hello</a><b>after</b>');
host.shadyRoot._lightChildren[1].textContent = '';
host.shadyRoot.__dom.childNodes[1].textContent = '';
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '<a>Hello</a><b></b>');
host.shadyRoot._lightChildren = [];
host.shadyRoot.__dom.childNodes = [];
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '');
});
@@ -203,11 +203,11 @@ suite('Mutate light DOM', function() {
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '<b></b>');
host.shadyRoot.firstChild._lightChildren = [];
host.shadyRoot.firstChild.__dom.childNodes = [];
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '');
host.shadyRoot._lightChildren = [];
host.shadyRoot.__dom.childNodes = [];
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '');
});
@@ -225,7 +225,7 @@ suite('Mutate light DOM', function() {
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '<a></a>');
host._lightChildren = [];
host.__dom.childNodes = [];
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), 'fallback');
});
@@ -265,11 +265,11 @@ suite('Mutate light DOM', function() {
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '<a>Hello</a><b></b>');
host.shadyRoot._lightChildren.splice(1, 1); // remove b
host.shadyRoot.__dom.childNodes.splice(1, 1); // remove b
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '<a>Hello</a>');
host.shadyRoot._lightChildren = []; // remove a
host.shadyRoot.__dom.childNodes = []; // remove a
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '');
});
@@ -368,7 +368,7 @@ suite('Mutate light DOM', function() {
assert.strictEqual(getComposedHTML(host), '<a>Hello</a>');
var b = document.createElement('b');
host._lightChildren[0] = b;
host.__dom.childNodes[0] = b;
distributeContentNow(host);
assert.strictEqual(getComposedHTML(host), '<b></b>');
});
@@ -437,12 +437,17 @@ suite('Mutate light DOM', function() {
});
function syncLightDOM(n) {
if (n._lightChildren) {
var c$ = n.__patched ? n._composedChildren || [] : Array.prototype.slice.call(n.childNodes);
c$.forEach(function(c) {
if (n._lightChildren.indexOf(c) < 0) {
c._lightParent = n;
n._lightChildren.push(c);
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.__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);
}
});
}
@@ -452,17 +457,11 @@ var nativeAppendChild = Element.prototype.appendChild;
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);
}
}
}
@@ -477,11 +476,11 @@ function updateRootInsertionPoints(root) {
}
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));