/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; /** * Fennec-specific root actor that extends BrowserRootActor and overrides some * of its methods. */ /** * The function that creates the root actor. DebuggerServer expects to find this * function in the loaded actors in order to initialize properly. */ function createRootActor(aConnection) { return new DeviceRootActor(aConnection); } /** * Creates the root actor that client-server communications always start with. * The root actor is responsible for the initial 'hello' packet and for * responding to a 'listTabs' request that produces the list of currently open * tabs. * * @param aConnection DebuggerServerConnection * The conection to the client. */ function DeviceRootActor(aConnection) { BrowserRootActor.call(this, aConnection); } DeviceRootActor.prototype = new BrowserRootActor(); /** * Handles the listTabs request. Builds a list of actors * for the tabs running in the process. The actors will survive * 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 tabActorList = []; // Get the chrome debugger actor. let actor = this._chromeDebugger; if (!actor) { actor = new ChromeDebuggerActor(this); actor.parentID = this.actorID; this._chromeDebugger = actor; actorPool.addActor(actor); } 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 = 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); 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); let response = { "from": "root", "selected": selected, "tabs": [actor.grip() for (actor of tabActorList)], "chromeDebugger": this._chromeDebugger.actorID }; 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"); }; /** * When a tab is closed, exit its tab actor. The actor * will be dropped at the next listTabs request. */ DeviceRootActor.prototype.onTabClosed = function DRA_onTabClosed(aEvent) { this.exitTabActor(aEvent.target.browser); }; // nsIWindowMediatorListener DeviceRootActor.prototype.onCloseWindow = function DRA_onCloseWindow(aWindow) { if (aWindow.BrowserApp) { this.unwatchWindow(aWindow); } }; /** * The request types this actor can handle. */ DeviceRootActor.prototype.requestTypes = { "listTabs": DeviceRootActor.prototype.onListTabs };