From 6332833688178567e06f7a1c83c9d192ed47ff8d Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Sat, 16 Sep 2017 14:37:21 +0100 Subject: [PATCH] Bug 1409040 - Make element.isXULElement more resiliant. r=maja_zf Fixes isXULElement to recognise XBL elements, such as . Also tightens up the input checks so that arbitrary objects can be tested, as checking node.namespaceURI directly could cause a JS error if node is not an object. Before checking the namespace we also ensure it's an element node so that text- and comment nodes are not picked up. This patch also introduces tests, which were sorely missing. MozReview-Commit-ID: 8LNF1z3X1gP --HG-- extra : rebase_source : ffacc5b1336b35624aaf0534101ce5c3fbdeaa95 --- testing/marionette/element.js | 18 ++++++++++-- testing/marionette/test_element.js | 45 ++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/testing/marionette/element.js b/testing/marionette/element.js index 58366937781f..ad9c0f605e76 100644 --- a/testing/marionette/element.js +++ b/testing/marionette/element.js @@ -19,6 +19,7 @@ const {PollPromise} = Cu.import("chrome://marionette/content/sync.js", {}); this.EXPORTED_SYMBOLS = ["element"]; +const XBLNS = "http://www.mozilla.org/xbl"; const XMLNS = "http://www.w3.org/1999/xhtml"; const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; @@ -1050,8 +1051,21 @@ element.scrollIntoView = function(el) { } }; -element.isXULElement = function(el) { - return el.namespaceURI === XULNS; +/** + * Ascertains whether el is a XUL- or XBL element. + * + * @param {*} node + * Element thought to be a XUL- or XBL element. + * + * @return {boolean} + * True if node is a XULElement or XBLElement, + * false otherwise. + */ +element.isXULElement = function(node) { + return typeof node == "object" && + node !== null && + node.nodeType === node.ELEMENT_NODE && + [XBLNS, XULNS].includes(node.namespaceURI); }; const boolEls = { diff --git a/testing/marionette/test_element.js b/testing/marionette/test_element.js index 8253bce913ed..4bf7388d0ee4 100644 --- a/testing/marionette/test_element.js +++ b/testing/marionette/test_element.js @@ -6,7 +6,10 @@ const {utils: Cu} = Components; Cu.import("chrome://marionette/content/element.js"); -class DOMElement { +const XBLNS = "http://www.mozilla.org/xbl"; +const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + +class Element { constructor(tagName, attrs = {}) { this.tagName = tagName; this.localName = tagName; @@ -14,6 +17,15 @@ class DOMElement { for (let attr in attrs) { this[attr] = attrs[attr]; } + } + + get nodeType() { return 1; } + get ELEMENT_NODE() { return 1; } +} + +class DOMElement extends Element { + constructor(tagName, attrs = {}) { + super(tagName, attrs); if (this.localName == "option") { this.selected = false; @@ -24,9 +36,6 @@ class DOMElement { } } - get nodeType() { return 1; } - get ELEMENT_NODE() { return 1; } - getBoundingClientRect() { return { top: 0, @@ -35,9 +44,25 @@ class DOMElement { height: 100, }; } -}; +} + +class XULElement extends Element { + constructor(tagName, attrs = {}) { + super(tagName, attrs); + this.namespaceURI = XULNS; + } +} + +class XBLElement extends XULElement { + constructor(tagName, attrs = {}) { + super(tagName, attrs); + this.namespaceURI = XBLNS; + } +} const domEl = new DOMElement("p"); +const xulEl = new XULElement("browser"); +const xblEl = new XBLElement("framebox"); add_test(function test_isSelected() { let checkbox = new DOMElement("input", {type: "checkbox"}); @@ -68,6 +93,16 @@ add_test(function test_isSelected() { run_next_test(); }); +add_test(function test_isXULElement() { + ok(element.isXULElement(xulEl)); + ok(element.isXULElement(xblEl)); + for (let typ of [true, 42, {}, [], undefined, null]) { + ok(!element.isXULElement(typ)); + } + + run_next_test(); +}); + add_test(function test_coordinates() { let p = element.coordinates(domEl); ok(p.hasOwnProperty("x"));