gecko/b2g/chrome/content/dbg-browser-actors.js

134 lines
4.0 KiB
JavaScript

/* -*- 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
});