Bug 1065933 - recover if containing frame is closed during touch, r=jgriffin
authorMalini Das <mdas@mozilla.com>
Fri, 03 Oct 2014 09:54:10 -0400
changeset 208696 ca7dc8cb97bc4fe965d34ae2b5e590d864655921
parent 208695 696baf50aabd5185d3b4e937f83a8fd8897ad3c2
child 208697 87916d61ca999868992ae86487969ff7786e8bfe
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjgriffin
bugs1065933
milestone35.0a1
Bug 1065933 - recover if containing frame is closed during touch, r=jgriffin
testing/marionette/marionette-server.js
--- a/testing/marionette/marionette-server.js
+++ b/testing/marionette/marionette-server.js
@@ -369,16 +369,29 @@ MarionetteServerConnection.prototype = {
     let type = null;
     if (appName != "B2G" && this.context == "content") {
       type = 'navigator:browser';
     }
     return Services.wm.getEnumerator(type);
   },
 
   /**
+  */
+  addFrameCloseListener: function MDA_addFrameCloseListener(action) {
+    let curWindow = this.getCurrentWindow();
+    let self = this;
+    this.mozBrowserClose = function() {
+      curWindow.removeEventListener('mozbrowserclose', self.mozBrowserClose, true);
+      self.switchToGlobalMessageManager();
+      self.sendError("The frame closed during the " + action +  ", recovering to allow further communications", 500, null, self.command_id);
+    };
+    curWindow.addEventListener('mozbrowserclose', this.mozBrowserClose, true);
+  },
+
+  /**
    * Create a new BrowserObj for window and add to known browsers
    *
    * @param nsIDOMWindow win
    *        Window for which we will create a BrowserObj
    *
    * @return string
    *        Returns the unique server-assigned ID of the window
    */
@@ -1521,16 +1534,17 @@ MarionetteServerConnection.prototype = {
     this.command_id = this.getCommandId();
     let serId = aRequest.parameters.id;
     let x = aRequest.parameters.x;
     let y = aRequest.parameters.y;
     if (this.context == "chrome") {
       this.sendError("Command 'singleTap' is not available in chrome context", 500, null, this.command_id);
     }
     else {
+      this.addFrameCloseListener("tap");
       this.sendAsync("singleTap",
                      {
                        id: serId,
                        corx: x,
                        cory: y
                      },
                      this.command_id);
     }
@@ -1543,16 +1557,17 @@ MarionetteServerConnection.prototype = {
    *        'value' represents a nested array: inner array represents each event; outer array represents collection of events
    */
   actionChain: function MDA_actionChain(aRequest) {
     this.command_id = this.getCommandId();
     if (this.context == "chrome") {
       this.sendError("Command 'actionChain' is not available in chrome context", 500, null, this.command_id);
     }
     else {
+      this.addFrameCloseListener("action chain");
       this.sendAsync("actionChain",
                      {
                        chain: aRequest.parameters.chain,
                        nextId: aRequest.parameters.nextId
                      },
                      this.command_id);
     }
   },
@@ -1567,16 +1582,17 @@ MarionetteServerConnection.prototype = {
    */
 
   multiAction: function MDA_multiAction(aRequest) {
     this.command_id = this.getCommandId();
     if (this.context == "chrome") {
        this.sendError("Command 'multiAction' is not available in chrome context", 500, null, this.command_id);
     }
     else {
+      this.addFrameCloseListener("multi action chain");
       this.sendAsync("multiAction",
                      {
                        value: aRequest.parameters.value,
                        maxlen: aRequest.parameters.max_length
                      },
                      this.command_id);
    }
  },
@@ -1729,24 +1745,17 @@ MarionetteServerConnection.prototype = {
         this.sendError(e.message, e.code, e.stack, command_id);
       }
     }
     else {
       // We need to protect against the click causing an OOP frame to close.
       // This fires the mozbrowserclose event when it closes so we need to
       // listen for it and then just send an error back. The person making the
       // call should be aware something isnt right and handle accordingly
-      let curWindow = this.getCurrentWindow();
-      let self = this;
-      this.mozBrowserClose = function() {
-        curWindow.removeEventListener('mozbrowserclose', self.mozBrowserClose, true);
-        self.switchToGlobalMessageManager();
-        self.sendError("The frame closed during the click, recovering to allow further communications", 500, null, command_id);
-      };
-      curWindow.addEventListener('mozbrowserclose', this.mozBrowserClose, true);
+      this.addFrameCloseListener("click");
       this.sendAsync("clickElement",
                      { id: aRequest.parameters.id },
                      command_id);
     }
   },
 
   /**
    * Get a given attribute of an element