Bug 1333014 - Change element.isDisconnected to take container; r?maja_zf draft
authorAndreas Tolfsen <ato@mozilla.com>
Tue, 07 Feb 2017 19:00:28 +0000
changeset 486092 ffc93aa89e4a8f6d72c713d779e824fd576a7968
parent 486091 e13b45ab9f0dc80cfa85bbcd02538d89da021b8d
child 486093 63714ee168c66e0847fac092f33bd645ad66eee0
push id45904
push userbmo:ato@mozilla.com
push dateFri, 17 Feb 2017 15:35:32 +0000
reviewersmaja_zf
bugs1333014
milestone54.0a1
Bug 1333014 - Change element.isDisconnected to take container; r?maja_zf It makes sense for element.isDisconnected to accept a container object with frame and shadowRoot, instead of taking the shadowRoot as an optional third argument, since this is what most consumers start out with. MozReview-Commit-ID: 6kfEIEf8u96
testing/marionette/element.js
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -3,16 +3,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/Log.jsm");
 
+Cu.import("chrome://marionette/content/assert.js");
 Cu.import("chrome://marionette/content/atom.js");
 Cu.import("chrome://marionette/content/error.js");
 Cu.import("chrome://marionette/content/wait.js");
 
 const logger = Log.repository.getLogger("Marionette");
 
 /**
  * This module provides shared functionality for dealing with DOM-
@@ -169,21 +170,24 @@ element.Store = class {
     }
 
     // use XPCNativeWrapper to compare elements (see bug 834266)
     let wrappedFrame = new XPCNativeWrapper(container.frame);
     let wrappedShadowRoot;
     if (container.shadowRoot) {
       wrappedShadowRoot = new XPCNativeWrapper(container.shadowRoot);
     }
-
     let wrappedEl = new XPCNativeWrapper(el);
+    let wrappedContainer = {
+      frame: wrappedFrame,
+      shadowRoot: wrappedShadowRoot,
+    };
     if (!el ||
         !(wrappedEl.ownerDocument == wrappedFrame.document) ||
-        element.isDisconnected(wrappedEl, wrappedFrame, wrappedShadowRoot)) {
+        element.isDisconnected(wrappedEl, wrappedContainer)) {
       throw new StaleElementReferenceError(
           error.pprint`The element reference of ${el} stale: ` +
               "either the element is no longer attached to the DOM " +
               "or the page has been refreshed");
     }
 
     return el;
   }
@@ -718,39 +722,42 @@ element.toJson = function (obj, seenEls)
 };
 
 /**
  * Check if the element is detached from the current frame as well as
  * the optional shadow root (when inside a Shadow DOM context).
  *
  * @param {nsIDOMElement} el
  *     Element to be checked.
- * @param {nsIDOMWindow} frame
- *     Window object that contains the element or the current host
- *     of the shadow root.
- * @param {ShadowRoot=} shadowRoot
- *     An optional shadow root containing an element.
+ * @param {Container} container
+ *     Container with |frame|, which is the window object that contains
+ *     the element, and an optional |shadowRoot|.
  *
  * @return {boolean}
  *     Flag indicating that the element is disconnected.
  */
-element.isDisconnected = function (el, frame, shadowRoot = undefined) {
+element.isDisconnected = function (el, container = {}) {
+  const {frame, shadowRoot} = container;
+  assert.defined(frame);
+
   // shadow dom
-  if (shadowRoot && frame.ShadowRoot) {
+  if (frame.ShadowRoot && shadowRoot) {
     if (el.compareDocumentPosition(shadowRoot) &
         DOCUMENT_POSITION_DISCONNECTED) {
       return true;
     }
 
     // looking for next possible ShadowRoot ancestor
     let parent = shadowRoot.host;
     while (parent && !(parent instanceof frame.ShadowRoot)) {
       parent = parent.parentNode;
     }
-    return element.isDisconnected(shadowRoot.host, frame, parent);
+    return element.isDisconnected(
+        shadowRoot.host,
+        {frame: frame, shadowRoot: parent});
 
   // outside shadow dom
   } else {
     let docEl = frame.document.documentElement;
     return el.compareDocumentPosition(docEl) &
         DOCUMENT_POSITION_DISCONNECTED;
   }
 };
@@ -984,17 +991,17 @@ element.getInViewCentrePoint = function 
  * @return {Array.<DOMElement>}
  *     Sequence of elements in paint order.
  */
 element.getPointerInteractablePaintTree = function (el) {
   const doc = el.ownerDocument;
   const win = doc.defaultView;
 
   // pointer-interactable elements tree, step 1
-  if (element.isDisconnected(el, win)) {
+  if (element.isDisconnected(el, {frame: win})) {
     return [];
   }
 
   // steps 2-3
   let rects = el.getClientRects();
   if (rects.length == 0) {
     return [];
   }