Fixes #3308. Use an explicit undefined check to test if logical tree information exists.

This commit is contained in:
Steven Orvell 2016-01-19 11:45:29 -08:00
parent 9cd6b796a1
commit 9106398ccf
3 changed files with 60 additions and 11 deletions

View File

@ -82,28 +82,39 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
return node.__dom.childNodes;
},
// NOTE: __dom can be created under 2 conditions: (1) an element has a
// logical tree, or (2) an element is in a logical tree. In case (1), the
// element will store firstChild/lastChild, and in case (2), the element
// will store parentNode, nextSibling, previousSibling. This means that
// the mere existence of __dom is not enough to know if the requested
// logical data is available and instead we do an explicit undefined check.
getParentNode: function(node) {
return node.__dom && node.__dom.parentNode || node.parentNode;
return node.__dom && node.__dom.parentNode !== undefined ?
node.__dom.parentNode : node.parentNode;
},
getFirstChild: function(node) {
return node.__dom && node.__dom.firstChild || node.firstChild;
return node.__dom && node.__dom.firstChild !== undefined ?
node.__dom.firstChild : node.firstChild;
},
getLastChild: function(node) {
return node.__dom && node.__dom.lastChild || node.lastChild;
return node.__dom && node.__dom.lastChild !== undefined ?
node.__dom.lastChild : node.lastChild;
},
getNextSibling: function(node) {
return node.__dom && node.__dom.nextSibling || node.nextSibling;
return node.__dom && node.__dom.nextSibling !== undefined ?
node.__dom.nextSibling : node.nextSibling;
},
getPreviousSibling: function(node) {
return node.__dom && node.__dom.previousSibling || node.previousSibling;
return node.__dom && node.__dom.previousSibling !== undefined ?
node.__dom.previousSibling : node.previousSibling;
},
getFirstElementChild: function(node) {
return node.__dom && node.__dom.firstChild ?
return node.__dom && node.__dom.firstChild !== undefined ?
this._getFirstElementChild(node) : node.firstElementChild;
},
@ -116,8 +127,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
},
getLastElementChild: function(node) {
return node.__dom && node.__dom.lastChild ?
this._getLastElementChild(node) : node.firstElementChild;
return node.__dom && node.__dom.lastChild !== undefined ?
this._getLastElementChild(node) : node.lastElementChild;
},
_getLastElementChild: function(node) {
@ -129,7 +140,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
},
getNextElementSibling: function(node) {
return node.__dom && node.__dom.nextSibling ?
return node.__dom && node.__dom.nextSibling !== undefined ?
this._getNextElementSibling(node) : node.nextElementSibling;
},
@ -142,7 +153,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
},
getPreviousElementSibling: function(node) {
return node.__dom && node.__dom.previousSibling ?
return node.__dom && node.__dom.previousSibling !== undefined ?
this._getPreviousElementSibling(node) : node.previousElementSibling;
},
@ -241,8 +252,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
if (n) {
n.__dom.previousSibling = p;
}
// When an element is removed, logical data is no longer tracked.
// Explicitly set `undefined` here to indicate this. This is disginguished
// from `null` which is set if info is null.
node.__dom.parentNode = node.__dom.previousSibling =
node.__dom.nextSibling = null;
node.__dom.nextSibling = undefined;
// remove caching of childNodes
container.__dom.childNodes = null;
}

View File

@ -126,6 +126,11 @@
<script>Polymer({is: 'x-echo'});</script>
</dom-module>
<dom-module id="x-simple">
<template><div>simple</div></template>
<script>Polymer({is: 'x-simple'});</script>
</dom-module>
<dom-module id="x-redistribute-a-b">
<template>

View File

@ -755,6 +755,36 @@ suite('Polymer.dom accessors', function() {
assert.equal(Polymer.dom(child).previousElementSibling, before, 'previousElementSibling incorrect');
});
test('Polymer.dom node accessors (empty logical tree)', function() {
var element = document.createElement('x-simple');
assert.equal(Polymer.dom(element).parentNode, null, 'parentNode incorrect');
assert.equal(Polymer.dom(element).firstChild, null, 'firstChild incorrect');
assert.equal(Polymer.dom(element).lastChild, null, 'lastChild incorrect');
assert.equal(Polymer.dom(element).nextSibling, null, 'nextSibling incorrect');
assert.equal(Polymer.dom(element).previousSibling, null, 'previousSibling incorrect');
assert.equal(Polymer.dom(element).firstElementChild, null, 'firstElementChild incorrect');
assert.equal(Polymer.dom(element).lastElementChild, null, 'lastElementChild incorrect');
assert.equal(Polymer.dom(element).nextElementSibling, null, 'nextElementSibling incorrect');
assert.equal(Polymer.dom(element).previousElementSibling, null, 'previousElementSibling incorrect');
});
test('Polymer.dom node accessors (unmanaged logical tree)', function() {
var element = document.createElement('div');
var child1 = document.createElement('div');
var child2 = document.createElement('div');
element.appendChild(child1);
element.appendChild(child2);
assert.equal(Polymer.dom(element).parentNode, null, 'parentNode incorrect');
assert.equal(Polymer.dom(element).firstChild, child1, 'firstChild incorrect');
assert.equal(Polymer.dom(element).lastChild, child2, 'lastChild incorrect');
assert.equal(Polymer.dom(element).nextSibling, null, 'nextSibling incorrect');
assert.equal(Polymer.dom(element).previousSibling, null, 'previousSibling incorrect');
assert.equal(Polymer.dom(element).firstElementChild, child1, 'firstElementChild incorrect');
assert.equal(Polymer.dom(element).lastElementChild, child2, 'lastElementChild incorrect');
assert.equal(Polymer.dom(element).nextElementSibling, null, 'nextElementSibling incorrect');
assert.equal(Polymer.dom(element).previousElementSibling, null, 'previousElementSibling incorrect');
});
test('Polymer.dom textContent', function() {
var testElement = document.createElement('x-project');
Polymer.dom(testElement).textContent = 'Hello World';