Bug 789114 - Make B2G and Fennec browser actors inherit the extensibility API changes. f=glandium r=msucan,mfinkle,vingtetun
authorPanos Astithas <past@mozilla.com>
Thu, 20 Sep 2012 09:38:11 +0300
changeset 107595 642f820edff86c51f7ca2002181ee63c15c7cdde
parent 107594 fc935d3901cd0ad8c2dc35d4932b6fcaa78b269c
child 107596 22af72b981a08563702b5c1a062680c6a85cd01e
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersmsucan, mfinkle, vingtetun
bugs789114
milestone18.0a1
Bug 789114 - Make B2G and Fennec browser actors inherit the extensibility API changes. f=glandium r=msucan,mfinkle,vingtetun
b2g/chrome/content/dbg-browser-actors.js
mobile/android/chrome/content/dbg-browser-actors.js
toolkit/devtools/debugger/server/dbg-browser-actors.js
--- a/b2g/chrome/content/dbg-browser-actors.js
+++ b/b2g/chrome/content/dbg-browser-actors.js
@@ -33,16 +33,17 @@ function DeviceRootActor(connection) {
 }
 
 DeviceRootActor.prototype = new BrowserRootActor();
 
 /**
  * Disconnects the actor from the browser window.
  */
 DeviceRootActor.prototype.disconnect = function DRA_disconnect() {
+  this._extraActors = null;
   let actor = this._tabActors.get(this.browser);
   if (actor) {
     actor.exit();
   }
 };
 
 /**
  * Handles the listTabs request.  Builds a list of actors for the single
@@ -56,29 +57,33 @@ DeviceRootActor.prototype.onListTabs = f
     // this.actorID is set by ActorPool when an actor is put into one.
     actor.parentID = this.actorID;
     this._tabActors.set(this.browser, actor);
   }
 
   let actorPool = new ActorPool(this.conn);
   actorPool.addActor(actor);
 
+  this._createExtraActors(DebuggerServer.globalActorFactories, actorPool);
+
   // Now drop the old actorID -> actor map. Actors that still mattered were
   // added to the new map, others will go away.
   if (this._tabActorPool) {
     this.conn.removeActorPool(this._tabActorPool);
   }
   this._tabActorPool = actorPool;
   this.conn.addActorPool(this._tabActorPool);
 
-  return {
+  let response = {
     'from': 'root',
     'selected': 0,
     'tabs': [actor.grip()]
   };
+  this._appendExtraActors(response);
+  return response;
 };
 
 /**
  * The request types this actor can handle.
  */
 DeviceRootActor.prototype.requestTypes = {
   'listTabs': DeviceRootActor.prototype.onListTabs
 };
@@ -98,21 +103,33 @@ function DeviceTabActor(connection, brow
 
 DeviceTabActor.prototype = new BrowserTabActor();
 
 DeviceTabActor.prototype.grip = function DTA_grip() {
   dbg_assert(!this.exited,
              'grip() should not be called on exited browser actor.');
   dbg_assert(this.actorID,
              'tab should have an actorID.');
-  return {
+
+  let response = {
     'actor': this.actorID,
     'title': this.browser.title,
     'url': this.browser.document.documentURI
+  };
+
+  // Walk over tab actors added by extensions and add them to a new ActorPool.
+  let actorPool = new ActorPool(this.conn);
+  this._createExtraActors(DebuggerServer.globalActorFactories, actorPool);
+  if (!actorPool.isEmpty()) {
+    this._tabActorPool = actorPool;
+    this.conn.addActorPool(this._tabActorPool);
   }
+
+  this._appendExtraActors(response);
+  return response;
 };
 
 /**
  * Creates a thread actor and a pool for context-lifetime actors. It then sets
  * up the content window for debugging.
  */
 DeviceTabActor.prototype._pushContext = function DTA_pushContext() {
   dbg_assert(!this._contextPool, "Can't push multiple contexts");
--- a/mobile/android/chrome/content/dbg-browser-actors.js
+++ b/mobile/android/chrome/content/dbg-browser-actors.js
@@ -38,60 +38,65 @@ DeviceRootActor.prototype = new BrowserR
  * until at least the next listTabs request.
  */
 DeviceRootActor.prototype.onListTabs = function DRA_onListTabs() {
   // Get actors for all the currently-running tabs (reusing
   // existing actors where applicable), and store them in
   // an ActorPool.
 
   let actorPool = new ActorPool(this.conn);
-  let actorList = [];
+  let tabActorList = [];
 
   let win = windowMediator.getMostRecentWindow("navigator:browser");
   this.browser = win.BrowserApp.selectedBrowser;
 
   // Watch the window for tab closes so we can invalidate
   // actors as needed.
   this.watchWindow(win);
 
   let tabs = win.BrowserApp.tabs;
   let selected;
 
   for each (let tab in tabs) {
     let browser = tab.browser;
 
     if (browser == this.browser) {
-      selected = actorList.length;
+      selected = tabActorList.length;
     }
 
     let actor = this._tabActors.get(browser);
     if (!actor) {
       actor = new BrowserTabActor(this.conn, browser);
       actor.parentID = this.actorID;
       this._tabActors.set(browser, actor);
     }
 
     actorPool.addActor(actor);
-    actorList.push(actor);
+    tabActorList.push(actor);
   }
 
+  this._createExtraActors(DebuggerServer.globalActorFactories, actorPool);
+
   // Now drop the old actorID -> actor map.  Actors that still
   // mattered were added to the new map, others will go
   // away.
   if (this._tabActorPool) {
     this.conn.removeActorPool(this._tabActorPool);
   }
 
   this._tabActorPool = actorPool;
   this.conn.addActorPool(this._tabActorPool);
 
-  return { "from": "root",
-           "selected": selected,
-           "tabs": [actor.grip()
-                    for each (actor in actorList)] };
+  let response = {
+    "from": "root",
+    "selected": selected,
+    "tabs": [actor.grip() for (actor of tabActorList)]
+  };
+  this._appendExtraActors(response);
+  return response;
 };
 
 /**
  * Return the tab container for the specified window.
  */
 DeviceRootActor.prototype.getTabContainer = function DRA_getTabContainer(aWindow) {
   return aWindow.document.getElementById("browsers");
 };
--- a/toolkit/devtools/debugger/server/dbg-browser-actors.js
+++ b/toolkit/devtools/debugger/server/dbg-browser-actors.js
@@ -108,47 +108,61 @@ BrowserRootActor.prototype = {
           actor.parentID = this.actorID;
           this._tabActors.set(browser, actor);
         }
         actorPool.addActor(actor);
         tabActorList.push(actor);
       }
     }
 
-    // Walk over global actors added by extensions.
-    for (let name in DebuggerServer.globalActorFactories) {
-      let actor = this._extraActors[name];
-      if (!actor) {
-        actor = DebuggerServer.globalActorFactories[name].bind(null, this.conn);
-        actor.prototype = DebuggerServer.globalActorFactories[name].prototype;
-        actor.parentID = this.actorID;
-        this._extraActors[name] = actor;
-      }
-      actorPool.addActor(actor);
-    }
+    this._createExtraActors(DebuggerServer.globalActorFactories, actorPool);
 
     // Now drop the old actorID -> actor map.  Actors that still
     // mattered were added to the new map, others will go
     // away.
     if (this._tabActorPool) {
       this.conn.removeActorPool(this._tabActorPool);
     }
     this._tabActorPool = actorPool;
     this.conn.addActorPool(this._tabActorPool);
 
     let response = {
       "from": "root",
       "selected": selected,
       "tabs": [actor.grip() for (actor of tabActorList)]
     };
+    this._appendExtraActors(response);
+    return response;
+  },
+
+  /**
+   * Adds dynamically-added actors from add-ons to the provided pool.
+   */
+  _createExtraActors: function BRA_createExtraActors(aFactories, aPool) {
+    // Walk over global actors added by extensions.
+    for (let name in aFactories) {
+      let actor = this._extraActors[name];
+      if (!actor) {
+        actor = aFactories[name].bind(null, this.conn);
+        actor.prototype = aFactories[name].prototype;
+        actor.parentID = this.actorID;
+        this._extraActors[name] = actor;
+      }
+      aPool.addActor(actor);
+    }
+  },
+
+  /**
+   * Appends the extra actors to the specified object.
+   */
+  _appendExtraActors: function BRA_appendExtraActors(aObject) {
     for (let name in this._extraActors) {
       let actor = this._extraActors[name];
-      response[name] = actor.actorID;
+      aObject[name] = actor.actorID;
     }
-    return response;
   },
 
   /**
    * Watch a window that was visited during onListTabs for
    * tab closures.
    */
   watchWindow: function BRA_watchWindow(aWindow) {
     this.getTabContainer(aWindow).addEventListener("TabClose",
@@ -225,16 +239,18 @@ function BrowserTabActor(aConnection, aB
 {
   this.conn = aConnection;
   this._browser = aBrowser;
   this._tabbrowser = aTabBrowser;
   this._tabActorPool = null;
   // A map of actor names to actor instances provided by extensions.
   this._extraActors = {};
 
+  this._createExtraActors = BrowserRootActor.prototype._createExtraActors.bind(this);
+  this._appendExtraActors = BrowserRootActor.prototype._appendExtraActors.bind(this);
   this._onWindowCreated = this.onWindowCreated.bind(this);
 }
 
 // XXX (bug 710213): BrowserTabActor attach/detach/exit/disconnect is a
 // *complete* mess, needs to be rethought asap.
 
 BrowserTabActor.prototype = {
   get browser() { return this._browser; },
@@ -283,35 +299,23 @@ BrowserTabActor.prototype = {
     let response = {
       actor: this.actorID,
       title: this.browser.contentTitle,
       url: this.browser.currentURI.spec
     };
 
     // Walk over tab actors added by extensions and add them to a new ActorPool.
     let actorPool = new ActorPool(this.conn);
-    for (let name in DebuggerServer.tabActorFactories) {
-      let actor = this._extraActors[name];
-      if (!actor) {
-        actor = DebuggerServer.tabActorFactories[name].bind(null, this.conn);
-        actor.prototype = DebuggerServer.tabActorFactories[name].prototype;
-        actor.parentID = this.actorID;
-        this._extraActors[name] = actor;
-      }
-      actorPool.addActor(actor);
-    }
+    this._createExtraActors(DebuggerServer.tabActorFactories, actorPool);
     if (!actorPool.isEmpty()) {
       this._tabActorPool = actorPool;
       this.conn.addActorPool(this._tabActorPool);
     }
 
-    for (let name in this._extraActors) {
-      let actor = this._extraActors[name];
-      response[name] = actor.actorID;
-    }
+    this._appendExtraActors(response);
     return response;
   },
 
   /**
    * Called when the actor is removed from the connection.
    */
   disconnect: function BTA_disconnect() {
     this._detach();