From 9106398ccfb73417058efde706097818ad01f2c5 Mon Sep 17 00:00:00 2001 From: Steven Orvell Date: Tue, 19 Jan 2016 11:45:29 -0800 Subject: [PATCH] Fixes #3308. Use an explicit undefined check to test if logical tree information exists. --- src/lib/dom-tree-api.html | 36 ++++++++++++++++++++--------- test/unit/polymer-dom-elements.html | 5 ++++ test/unit/polymer-dom.js | 30 ++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/lib/dom-tree-api.html b/src/lib/dom-tree-api.html index be6df6db4d..afc1c02b11 100644 --- a/src/lib/dom-tree-api.html +++ b/src/lib/dom-tree-api.html @@ -82,28 +82,39 @@ 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 @@ }, 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 @@ }, 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 @@ }, 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 @@ 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 64ac6b5972..d4afa8b281 100644 --- a/test/unit/polymer-dom-elements.html +++ b/test/unit/polymer-dom-elements.html @@ -126,6 +126,11 @@ + + + + +