Bug 929175: Part 1: Allow Marionette to switch to frameset frames. ; r=mdas
☠☠ backed out by 59d2341b206a ☠ ☠
authorDavid Burns <dburns@mozilla.com>
Sat, 18 Jan 2014 20:08:36 +0000
changeset 198644 bc6ddc5dc31af1f5b0aeb56bb39030611f7a3767
parent 198643 a0fb78183db0df06d7c1354f307ae96506d0c761
child 198645 6bb03867a3adb440473efb256d7fd91a54a1dbec
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmdas
bugs929175
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 929175: Part 1: Allow Marionette to switch to frameset frames. ; r=mdas
testing/marionette/marionette-frame-manager.js
testing/marionette/marionette-listener.js
--- a/testing/marionette/marionette-frame-manager.js
+++ b/testing/marionette/marionette-frame-manager.js
@@ -90,17 +90,17 @@ FrameManager.prototype = {
         return {value: isLocal};
       case "MarionetteFrame:getCurrentFrameId":
         if (this.currentRemoteFrame != null) {
           return this.currentRemoteFrame.frameId;
         }
     }
   },
 
-  //This is just 'switch to OOP frame'. We're handling this here so we can maintain a list of remoteFrames. 
+  //This is just 'switch to OOP frame'. We're handling this here so we can maintain a list of remoteFrames.
   switchToFrame: function FM_switchToFrame(message) {
     // Switch to a remote frame.
     let frameWindow = Services.wm.getOuterWindowWithId(message.json.win); //get the original frame window
     let oopFrame = frameWindow.document.getElementsByTagName("iframe")[message.json.frame]; //find the OOP frame
     let mm = oopFrame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager; //get the OOP frame's mm
 
     // See if this frame already has our frame script loaded in it; if so,
     // just wake it up.
@@ -121,17 +121,17 @@ FrameManager.prototype = {
       if (frameMessageManager == mm) {
         this.currentRemoteFrame = frame;
         this.addMessageManagerListeners(mm);
         mm.sendAsyncMessage("Marionette:restart", {});
         return;
       }
     }
 
-    // If we get here, then we need to load the frame script in this frame, 
+    // If we get here, then we need to load the frame script in this frame,
     // and set the frame's ChromeMessageSender as the active message manager the server will listen to
     this.addMessageManagerListeners(mm);
     logger.info("frame-manager load script: " + mm.toString());
     mm.loadFrameScript(FRAME_SCRIPT, true, true);
     let aFrame = new MarionetteRemoteFrame(message.json.win, message.json.frame);
     aFrame.messageManager = Cu.getWeakReference(mm);
     remoteFrames.push(aFrame);
     this.currentRemoteFrame = aFrame;
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -1802,109 +1802,105 @@ function switchToFrame(msg) {
     }
     else if (curFrame.document.readyState == "interactive" && errorRegex.exec(curFrame.document.baseURI)) {
       sendError("Error loading page", 13, null, command_id);
       return;
     }
     checkTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT);
   }
   let foundFrame = null;
-  let frames = []; //curFrame.document.getElementsByTagName("iframe");
-  let parWindow = null; //curFrame.QueryInterface(Ci.nsIInterfaceRequestor)
+  let frames = [];
+  let parWindow = null;
   // Check of the curFrame reference is dead
   try {
-    frames = curFrame.document.getElementsByTagName("iframe");
+    frames = curFrame.frames;
     //Until Bug 761935 lands, we won't have multiple nested OOP iframes. We will only have one.
     //parWindow will refer to the iframe above the nested OOP frame.
     parWindow = curFrame.QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
   } catch (e) {
     // We probably have a dead compartment so accessing it is going to make Firefox
     // very upset. Let's now try redirect everything to the top frame even if the
     // user has given us a frame since search doesnt look up.
     msg.json.id = null;
     msg.json.element = null;
   }
-  if ((msg.json.id == null) && (msg.json.element == null)) {
+
+  if ((msg.json.id === null || msg.json.id === undefined) && (msg.json.element == null)) {
     // returning to root frame
     sendSyncMessage("Marionette:switchedToFrame", { frameValue: null });
 
     curFrame = content;
     if(msg.json.focus == true) {
       curFrame.focus();
     }
     sandbox = null;
     checkTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT);
     return;
   }
   if (msg.json.element != undefined) {
     if (elementManager.seenItems[msg.json.element] != undefined) {
       let wantedFrame;
       try {
-        wantedFrame = elementManager.getKnownElement(msg.json.element, curFrame); //HTMLIFrameElement
+        wantedFrame = elementManager.getKnownElement(msg.json.element, curFrame); //Frame Element
       }
       catch(e) {
         sendError(e.message, e.code, e.stack, command_id);
       }
-      for (let i = 0; i < frames.length; i++) {
-        // use XPCNativeWrapper to compare elements; see bug 834266
-        if (XPCNativeWrapper(frames[i]) == XPCNativeWrapper(wantedFrame)) {
-          curFrame = frames[i];
-          foundFrame = i;
+
+      if (frames.length > 0) {
+        for (let i = 0; i < frames.length; i++) {
+          logger.info("frame[i] is " + frames[i].frameElement);
+          // use XPCNativeWrapper to compare elements; see bug 834266
+          if (XPCNativeWrapper(frames[i].frameElement) == XPCNativeWrapper(wantedFrame)) {
+            logger.info("we have found it")
+            curFrame = frames[i].frameElement;
+            foundFrame = i;
+          }
+        }
+      }
+      if(foundFrame == null) {
+        // Either the frame has been removed or we have a OOP frame
+        // so lets just get all the iframes and do a quick loop before
+        // throwing in the towel
+        let iframes = curFrame.document.getElementsByTagName("iframe");
+        for (var i = 0; i < iframes.length; i++) {
+          if (XPCNativeWrapper(iframes[i]) == XPCNativeWrapper(wantedFrame)) {
+            curFrame = iframes[i];
+            foundFrame = i;
+          }
         }
       }
     }
   }
   if (foundFrame == null) {
-    switch(typeof(msg.json.id)) {
-      case "string" :
-        let foundById = null;
-        for (let i = 0; i < frames.length; i++) {
-          //give precedence to name
-          let frame = frames[i];
-          let name = utils.getElementAttribute(frame, 'name');
-          let id = utils.getElementAttribute(frame, 'id');
-          if (name == msg.json.id) {
-            foundFrame = i;
-            break;
-          } else if ((foundById == null) && (id == msg.json.id)) {
-            foundById = i;
-          }
-        }
-        if ((foundFrame == null) && (foundById != null)) {
-          foundFrame = foundById;
-          curFrame = frames[foundFrame];
-        }
-        break;
-      case "number":
-        if (frames[msg.json.id] != undefined) {
-          foundFrame = msg.json.id;
-          curFrame = frames[foundFrame];
-        }
-        break;
+    if (typeof(msg.json.id) === 'number') {
+      foundFrame = frames[msg.json.id].frameElement;
+      curFrame = foundFrame;
+      foundFrame = elementManager.addToKnownElements(curFrame);
     }
   }
   if (foundFrame == null) {
-    sendError("Unable to locate frame: " + msg.json.id, 8, null, command_id);
-    return;
+    sendError("Unable to locate frame: " + (msg.json.id || msg.json.element), 8, null, command_id);
+    return true;
   }
 
   sandbox = null;
 
   // send a synchronous message to let the server update the currently active
   // frame element (for getActiveFrame)
   let frameValue = elementManager.wrapValue(curFrame.wrappedJSObject)['ELEMENT'];
   sendSyncMessage("Marionette:switchedToFrame", { frameValue: frameValue });
 
   if (curFrame.contentWindow == null) {
     // The frame we want to switch to is a remote (out-of-process) frame;
     // notify our parent to handle the switch.
     curFrame = content;
-    sendToServer('Marionette:switchToFrame', {frame: foundFrame,
-                                              win: parWindow,
+    sendToServer('Marionette:switchToFrame', {win: parWindow,
+                                              frame: foundFrame,
                                               command_id: command_id});
   }
   else {
     curFrame = curFrame.contentWindow;
     if(msg.json.focus == true) {
       curFrame.focus();
     }
     checkTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT);