Skip to content

Commit 9106398

Browse files
author
Steven Orvell
committed
Fixes #3308. Use an explicit undefined check to test if logical tree information exists.
1 parent 9cd6b79 commit 9106398

File tree

3 files changed

+60
-11
lines changed

3 files changed

+60
-11
lines changed

src/lib/dom-tree-api.html

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,28 +82,39 @@
8282
return node.__dom.childNodes;
8383
},
8484

85+
// NOTE: __dom can be created under 2 conditions: (1) an element has a
86+
// logical tree, or (2) an element is in a logical tree. In case (1), the
87+
// element will store firstChild/lastChild, and in case (2), the element
88+
// will store parentNode, nextSibling, previousSibling. This means that
89+
// the mere existence of __dom is not enough to know if the requested
90+
// logical data is available and instead we do an explicit undefined check.
8591
getParentNode: function(node) {
86-
return node.__dom && node.__dom.parentNode || node.parentNode;
92+
return node.__dom && node.__dom.parentNode !== undefined ?
93+
node.__dom.parentNode : node.parentNode;
8794
},
8895

8996
getFirstChild: function(node) {
90-
return node.__dom && node.__dom.firstChild || node.firstChild;
97+
return node.__dom && node.__dom.firstChild !== undefined ?
98+
node.__dom.firstChild : node.firstChild;
9199
},
92100

93101
getLastChild: function(node) {
94-
return node.__dom && node.__dom.lastChild || node.lastChild;
102+
return node.__dom && node.__dom.lastChild !== undefined ?
103+
node.__dom.lastChild : node.lastChild;
95104
},
96105

97106
getNextSibling: function(node) {
98-
return node.__dom && node.__dom.nextSibling || node.nextSibling;
107+
return node.__dom && node.__dom.nextSibling !== undefined ?
108+
node.__dom.nextSibling : node.nextSibling;
99109
},
100110

101111
getPreviousSibling: function(node) {
102-
return node.__dom && node.__dom.previousSibling || node.previousSibling;
112+
return node.__dom && node.__dom.previousSibling !== undefined ?
113+
node.__dom.previousSibling : node.previousSibling;
103114
},
104115

105116
getFirstElementChild: function(node) {
106-
return node.__dom && node.__dom.firstChild ?
117+
return node.__dom && node.__dom.firstChild !== undefined ?
107118
this._getFirstElementChild(node) : node.firstElementChild;
108119
},
109120

@@ -116,8 +127,8 @@
116127
},
117128

118129
getLastElementChild: function(node) {
119-
return node.__dom && node.__dom.lastChild ?
120-
this._getLastElementChild(node) : node.firstElementChild;
130+
return node.__dom && node.__dom.lastChild !== undefined ?
131+
this._getLastElementChild(node) : node.lastElementChild;
121132
},
122133

123134
_getLastElementChild: function(node) {
@@ -129,7 +140,7 @@
129140
},
130141

131142
getNextElementSibling: function(node) {
132-
return node.__dom && node.__dom.nextSibling ?
143+
return node.__dom && node.__dom.nextSibling !== undefined ?
133144
this._getNextElementSibling(node) : node.nextElementSibling;
134145
},
135146

@@ -142,7 +153,7 @@
142153
},
143154

144155
getPreviousElementSibling: function(node) {
145-
return node.__dom && node.__dom.previousSibling ?
156+
return node.__dom && node.__dom.previousSibling !== undefined ?
146157
this._getPreviousElementSibling(node) : node.previousElementSibling;
147158
},
148159

@@ -241,8 +252,11 @@
241252
if (n) {
242253
n.__dom.previousSibling = p;
243254
}
255+
// When an element is removed, logical data is no longer tracked.
256+
// Explicitly set `undefined` here to indicate this. This is disginguished
257+
// from `null` which is set if info is null.
244258
node.__dom.parentNode = node.__dom.previousSibling =
245-
node.__dom.nextSibling = null;
259+
node.__dom.nextSibling = undefined;
246260
// remove caching of childNodes
247261
container.__dom.childNodes = null;
248262
}

test/unit/polymer-dom-elements.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@
126126
<script>Polymer({is: 'x-echo'});</script>
127127
</dom-module>
128128

129+
<dom-module id="x-simple">
130+
<template><div>simple</div></template>
131+
<script>Polymer({is: 'x-simple'});</script>
132+
</dom-module>
133+
129134

130135
<dom-module id="x-redistribute-a-b">
131136
<template>

test/unit/polymer-dom.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,36 @@ suite('Polymer.dom accessors', function() {
755755
assert.equal(Polymer.dom(child).previousElementSibling, before, 'previousElementSibling incorrect');
756756
});
757757

758+
test('Polymer.dom node accessors (empty logical tree)', function() {
759+
var element = document.createElement('x-simple');
760+
assert.equal(Polymer.dom(element).parentNode, null, 'parentNode incorrect');
761+
assert.equal(Polymer.dom(element).firstChild, null, 'firstChild incorrect');
762+
assert.equal(Polymer.dom(element).lastChild, null, 'lastChild incorrect');
763+
assert.equal(Polymer.dom(element).nextSibling, null, 'nextSibling incorrect');
764+
assert.equal(Polymer.dom(element).previousSibling, null, 'previousSibling incorrect');
765+
assert.equal(Polymer.dom(element).firstElementChild, null, 'firstElementChild incorrect');
766+
assert.equal(Polymer.dom(element).lastElementChild, null, 'lastElementChild incorrect');
767+
assert.equal(Polymer.dom(element).nextElementSibling, null, 'nextElementSibling incorrect');
768+
assert.equal(Polymer.dom(element).previousElementSibling, null, 'previousElementSibling incorrect');
769+
});
770+
771+
test('Polymer.dom node accessors (unmanaged logical tree)', function() {
772+
var element = document.createElement('div');
773+
var child1 = document.createElement('div');
774+
var child2 = document.createElement('div');
775+
element.appendChild(child1);
776+
element.appendChild(child2);
777+
assert.equal(Polymer.dom(element).parentNode, null, 'parentNode incorrect');
778+
assert.equal(Polymer.dom(element).firstChild, child1, 'firstChild incorrect');
779+
assert.equal(Polymer.dom(element).lastChild, child2, 'lastChild incorrect');
780+
assert.equal(Polymer.dom(element).nextSibling, null, 'nextSibling incorrect');
781+
assert.equal(Polymer.dom(element).previousSibling, null, 'previousSibling incorrect');
782+
assert.equal(Polymer.dom(element).firstElementChild, child1, 'firstElementChild incorrect');
783+
assert.equal(Polymer.dom(element).lastElementChild, child2, 'lastElementChild incorrect');
784+
assert.equal(Polymer.dom(element).nextElementSibling, null, 'nextElementSibling incorrect');
785+
assert.equal(Polymer.dom(element).previousElementSibling, null, 'previousElementSibling incorrect');
786+
});
787+
758788
test('Polymer.dom textContent', function() {
759789
var testElement = document.createElement('x-project');
760790
Polymer.dom(testElement).textContent = 'Hello World';

0 commit comments

Comments
 (0)