|
82 | 82 | return node.__dom.childNodes;
|
83 | 83 | },
|
84 | 84 |
|
| 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. |
85 | 91 | 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; |
87 | 94 | },
|
88 | 95 |
|
89 | 96 | 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; |
91 | 99 | },
|
92 | 100 |
|
93 | 101 | 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; |
95 | 104 | },
|
96 | 105 |
|
97 | 106 | 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; |
99 | 109 | },
|
100 | 110 |
|
101 | 111 | 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; |
103 | 114 | },
|
104 | 115 |
|
105 | 116 | getFirstElementChild: function(node) {
|
106 |
| - return node.__dom && node.__dom.firstChild ? |
| 117 | + return node.__dom && node.__dom.firstChild !== undefined ? |
107 | 118 | this._getFirstElementChild(node) : node.firstElementChild;
|
108 | 119 | },
|
109 | 120 |
|
|
116 | 127 | },
|
117 | 128 |
|
118 | 129 | 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; |
121 | 132 | },
|
122 | 133 |
|
123 | 134 | _getLastElementChild: function(node) {
|
|
129 | 140 | },
|
130 | 141 |
|
131 | 142 | getNextElementSibling: function(node) {
|
132 |
| - return node.__dom && node.__dom.nextSibling ? |
| 143 | + return node.__dom && node.__dom.nextSibling !== undefined ? |
133 | 144 | this._getNextElementSibling(node) : node.nextElementSibling;
|
134 | 145 | },
|
135 | 146 |
|
|
142 | 153 | },
|
143 | 154 |
|
144 | 155 | getPreviousElementSibling: function(node) {
|
145 |
| - return node.__dom && node.__dom.previousSibling ? |
| 156 | + return node.__dom && node.__dom.previousSibling !== undefined ? |
146 | 157 | this._getPreviousElementSibling(node) : node.previousElementSibling;
|
147 | 158 | },
|
148 | 159 |
|
|
241 | 252 | if (n) {
|
242 | 253 | n.__dom.previousSibling = p;
|
243 | 254 | }
|
| 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. |
244 | 258 | node.__dom.parentNode = node.__dom.previousSibling =
|
245 |
| - node.__dom.nextSibling = null; |
| 259 | + node.__dom.nextSibling = undefined; |
246 | 260 | // remove caching of childNodes
|
247 | 261 | container.__dom.childNodes = null;
|
248 | 262 | }
|
|
0 commit comments