/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* 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'; let promise = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {}).Promise; /** * B2G-specific actors. */ /** * Construct a root actor appropriate for use in a server running in B2G. The * returned root actor: * - respects the factories registered with DebuggerServer.addGlobalActor, * - uses a ContentTabList to supply tab actors, * - sends all navigator:browser window documents a Debugger:Shutdown event * when it exits. * * * @param connection DebuggerServerConnection * The conection to the client. */ function createRootActor(connection) { let parameters = { tabList: { getList: function() { return promise.resolve([]); } }, globalActorFactories: DebuggerServer.globalActorFactories, onShutdown: sendShutdownEvent }; let root = new RootActor(connection, parameters); root.applicationType = "operating-system"; return root; } /** * A live list of BrowserTabActors representing the current browser tabs, * to be provided to the root actor to answer 'listTabs' requests. In B2G, * only a single tab is ever present. * * @param connection DebuggerServerConnection * The connection in which this list's tab actors may participate. * * @see BrowserTabList for more a extensive description of how tab list objects * work. */ function ContentTabList(connection) { BrowserTabList.call(this, connection); } ContentTabList.prototype = Object.create(BrowserTabList.prototype); ContentTabList.prototype.constructor = ContentTabList; ContentTabList.prototype.getList = function() { let browser = Services.wm.getMostRecentWindow('navigator:browser'); // Do we have an existing actor for this browser? If not, create one. let actor = this._actorByBrowser.get(browser); if (!actor) { actor = new ContentTabActor(this._connection, browser); this._actorByBrowser.set(browser, actor); actor.selected = true; } return promise.resolve([actor]); }; ContentTabList.prototype.onCloseWindow = makeInfallible(function(aWindow) { /* * nsIWindowMediator deadlocks if you call its GetEnumerator method from * a nsIWindowMediatorListener's onCloseWindow hook (bug 873589), so * handle the close in a different tick. */ Services.tm.currentThread.dispatch(makeInfallible(() => { /* * Scan the entire map for actors representing tabs that were in this * top-level window, and exit them. */ for (let [browser, actor] of this._actorByBrowser) { this._handleActorClose(actor, browser); } }, "ContentTabList.prototype.onCloseWindow's delayed body"), 0); }, "ContentTabList.prototype.onCloseWindow"); /** * Creates a tab actor for handling requests to the single tab, like * attaching and detaching. ContentTabActor respects the actor factories * registered with DebuggerServer.addTabActor. * * @param connection DebuggerServerConnection * The conection to the client. * @param browser browser * The browser instance that contains this tab. */ function ContentTabActor(connection, browser) { BrowserTabActor.call(this, connection, browser); } ContentTabActor.prototype.constructor = ContentTabActor; ContentTabActor.prototype = Object.create(BrowserTabActor.prototype); Object.defineProperty(ContentTabActor.prototype, "title", { get: function() { return this.browser.title; }, enumerable: true, configurable: false }); Object.defineProperty(ContentTabActor.prototype, "url", { get: function() { return this.browser.document.documentURI; }, enumerable: true, configurable: false }); Object.defineProperty(ContentTabActor.prototype, "window", { get: function() { return this.browser; }, enumerable: true, configurable: false });