123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /* 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";
- const { Ci } = require("chrome");
- const Services = require("Services");
- const { DebuggerServer } = require("../main");
- const { getChildDocShells, TabActor } = require("./webbrowser");
- const makeDebugger = require("./utils/make-debugger");
- /**
- * Creates a TabActor for debugging all the chrome content in the
- * current process. Most of the implementation is inherited from TabActor.
- * ChromeActor is a child of RootActor, it can be instanciated via
- * RootActor.getProcess request.
- * ChromeActor exposes all tab actors via its form() request, like TabActor.
- *
- * History lecture:
- * All tab actors used to also be registered as global actors,
- * so that the root actor was also exposing tab actors for the main process.
- * Tab actors ended up having RootActor as parent actor,
- * but more and more features of the tab actors were relying on TabActor.
- * So we are now exposing a process actor that offers the same API as TabActor
- * by inheriting its functionality.
- * Global actors are now only the actors that are meant to be global,
- * and are no longer related to any specific scope/document.
- *
- * @param aConnection DebuggerServerConnection
- * The connection to the client.
- */
- function ChromeActor(aConnection) {
- TabActor.call(this, aConnection);
- // This creates a Debugger instance for chrome debugging all globals.
- this.makeDebugger = makeDebugger.bind(null, {
- findDebuggees: dbg => dbg.findAllGlobals(),
- shouldAddNewGlobalAsDebuggee: () => true
- });
- // Ensure catching the creation of any new content docshell
- this.listenForNewDocShells = true;
- // Defines the default docshell selected for the tab actor
- let window = Services.wm.getMostRecentWindow(DebuggerServer.chromeWindowType);
- // Default to any available top level window if there is no expected window
- // (for example when we open firefox with -webide argument)
- if (!window) {
- window = Services.wm.getMostRecentWindow(null);
- }
- // On xpcshell, there is no window/docshell
- let docShell = window ? window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDocShell)
- : null;
- Object.defineProperty(this, "docShell", {
- value: docShell,
- configurable: true
- });
- }
- exports.ChromeActor = ChromeActor;
- ChromeActor.prototype = Object.create(TabActor.prototype);
- ChromeActor.prototype.constructor = ChromeActor;
- ChromeActor.prototype.isRootActor = true;
- /**
- * Getter for the list of all docshells in this tabActor
- * @return {Array}
- */
- Object.defineProperty(ChromeActor.prototype, "docShells", {
- get: function () {
- // Iterate over all top-level windows and all their docshells.
- let docShells = [];
- let e = Services.ww.getWindowEnumerator();
- while (e.hasMoreElements()) {
- let window = e.getNext();
- let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
- docShells = docShells.concat(getChildDocShells(docShell));
- }
- return docShells;
- }
- });
- ChromeActor.prototype.observe = function (aSubject, aTopic, aData) {
- TabActor.prototype.observe.call(this, aSubject, aTopic, aData);
- if (!this.attached) {
- return;
- }
- if (aTopic == "chrome-webnavigation-create") {
- aSubject.QueryInterface(Ci.nsIDocShell);
- this._onDocShellCreated(aSubject);
- } else if (aTopic == "chrome-webnavigation-destroy") {
- this._onDocShellDestroy(aSubject);
- }
- };
- ChromeActor.prototype._attach = function () {
- if (this.attached) {
- return false;
- }
- TabActor.prototype._attach.call(this);
- // Listen for any new/destroyed chrome docshell
- Services.obs.addObserver(this, "chrome-webnavigation-create", false);
- Services.obs.addObserver(this, "chrome-webnavigation-destroy", false);
- // Iterate over all top-level windows.
- let docShells = [];
- let e = Services.ww.getWindowEnumerator();
- while (e.hasMoreElements()) {
- let window = e.getNext();
- let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
- if (docShell == this.docShell) {
- continue;
- }
- this._progressListener.watch(docShell);
- }
- };
- ChromeActor.prototype._detach = function () {
- if (!this.attached) {
- return false;
- }
- Services.obs.removeObserver(this, "chrome-webnavigation-create");
- Services.obs.removeObserver(this, "chrome-webnavigation-destroy");
- // Iterate over all top-level windows.
- let docShells = [];
- let e = Services.ww.getWindowEnumerator();
- while (e.hasMoreElements()) {
- let window = e.getNext();
- let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
- if (docShell == this.docShell) {
- continue;
- }
- this._progressListener.unwatch(docShell);
- }
- TabActor.prototype._detach.call(this);
- };
- /* ThreadActor hooks. */
- /**
- * Prepare to enter a nested event loop by disabling debuggee events.
- */
- ChromeActor.prototype.preNest = function () {
- // Disable events in all open windows.
- let e = Services.wm.getEnumerator(null);
- while (e.hasMoreElements()) {
- let win = e.getNext();
- let windowUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- windowUtils.suppressEventHandling(true);
- windowUtils.suspendTimeouts();
- }
- };
- /**
- * Prepare to exit a nested event loop by enabling debuggee events.
- */
- ChromeActor.prototype.postNest = function (aNestData) {
- // Enable events in all open windows.
- let e = Services.wm.getEnumerator(null);
- while (e.hasMoreElements()) {
- let win = e.getNext();
- let windowUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- windowUtils.resumeTimeouts();
- windowUtils.suppressEventHandling(false);
- }
- };
|