diff --git a/src/lib/dom-tree-api.html b/src/lib/dom-tree-api.html
index be6df6db..afc1c02b 100644
--- a/src/lib/dom-tree-api.html
+++ b/src/lib/dom-tree-api.html
@@ -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;
}
diff --git a/test/unit/polymer-dom-elements.html b/test/unit/polymer-dom-elements.html
index 64ac6b59..d4afa8b2 100644
--- a/test/unit/polymer-dom-elements.html
+++ b/test/unit/polymer-dom-elements.html
@@ -126,6 +126,11 @@
+
+ simple
+
+
+
diff --git a/test/unit/polymer-dom.js b/test/unit/polymer-dom.js
index 285d0008..a4256b92 100644
--- a/test/unit/polymer-dom.js
+++ b/test/unit/polymer-dom.js
@@ -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';