зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1473513 - Backed out changeset 27419719402e for failures on mobile/android/tests/browser/chrome/test_debugger_server.html CLOSED TREE
Summary: MozReview-Commit-ID: 43tUMmC1Je0 Depends on D6811 Bug #: 1473513 Differential Revision: https://phabricator.services.mozilla.com/D6812
This commit is contained in:
Родитель
3695cdf575
Коммит
18a737b18d
|
@ -8,6 +8,161 @@
|
|||
|
||||
const { method } = require("devtools/shared/protocol");
|
||||
|
||||
/**
|
||||
* Creates "registered" actors factory meant for creating another kind of
|
||||
* factories, ObservedActorFactory, during the call to listTabs.
|
||||
* These factories live in DebuggerServer.{tab|global}ActorFactories.
|
||||
*
|
||||
* These actors only exposes:
|
||||
* - `name` string attribute used to match actors by constructor name
|
||||
* in DebuggerServer.remove{Global,Tab}Actor.
|
||||
* - `createObservedActorFactory` function to create "observed" actors factory
|
||||
*
|
||||
* @param options object
|
||||
* - constructorName: (required)
|
||||
* name of actor constructor, which is also used when removing the actor.
|
||||
* One of the following:
|
||||
* - id:
|
||||
* module ID that contains the actor
|
||||
* - constructorFun:
|
||||
* a function to construct the actor
|
||||
*/
|
||||
function RegisteredActorFactory(options, prefix) {
|
||||
// By default the actor name will also be used for the actorID prefix.
|
||||
this._prefix = prefix;
|
||||
if (options.constructorFun) {
|
||||
// Actor definition registered by ActorRegistryActor or testing helpers
|
||||
this._getConstructor = () => options.constructorFun;
|
||||
} else {
|
||||
// Lazy actor definition, where options contains all the information
|
||||
// required to load the actor lazily.
|
||||
this._getConstructor = function() {
|
||||
// Load the module
|
||||
let mod;
|
||||
try {
|
||||
mod = require(options.id);
|
||||
} catch (e) {
|
||||
throw new Error("Unable to load actor module '" + options.id + "'.\n" +
|
||||
e.message + "\n" + e.stack + "\n");
|
||||
}
|
||||
// Fetch the actor constructor
|
||||
const c = mod[options.constructorName];
|
||||
if (!c) {
|
||||
throw new Error("Unable to find actor constructor named '" +
|
||||
options.constructorName + "'. (Is it exported?)");
|
||||
}
|
||||
return c;
|
||||
};
|
||||
}
|
||||
// Exposes `name` attribute in order to allow removeXXXActor to match
|
||||
// the actor by its actor constructor name.
|
||||
this.name = options.constructorName;
|
||||
}
|
||||
RegisteredActorFactory.prototype.createObservedActorFactory = function(conn,
|
||||
parentActor) {
|
||||
return new ObservedActorFactory(this._getConstructor, this._prefix, conn, parentActor);
|
||||
};
|
||||
exports.RegisteredActorFactory = RegisteredActorFactory;
|
||||
|
||||
/**
|
||||
* Creates "observed" actors factory meant for creating real actor instances.
|
||||
* These factories lives in actor pools and fake various actor attributes.
|
||||
* They will be replaced in actor pools by final actor instances during
|
||||
* the first request for the same actorID from DebuggerServer._getOrCreateActor.
|
||||
*
|
||||
* ObservedActorFactory fakes the following actors attributes:
|
||||
* actorPrefix (string) Used by ActorPool.addActor to compute the actor id
|
||||
* actorID (string) Set by ActorPool.addActor just after being instantiated
|
||||
* registeredPool (object) Set by ActorPool.addActor just after being
|
||||
* instantiated
|
||||
* And exposes the following method:
|
||||
* createActor (function) Instantiate an actor that is going to replace
|
||||
* this factory in the actor pool.
|
||||
*/
|
||||
function ObservedActorFactory(getConstructor, prefix, conn, parentActor) {
|
||||
this._getConstructor = getConstructor;
|
||||
this._conn = conn;
|
||||
this._parentActor = parentActor;
|
||||
|
||||
this.actorPrefix = prefix;
|
||||
|
||||
this.actorID = null;
|
||||
this.registeredPool = null;
|
||||
}
|
||||
ObservedActorFactory.prototype.createActor = function() {
|
||||
// Fetch the actor constructor
|
||||
const C = this._getConstructor();
|
||||
// Instantiate a new actor instance
|
||||
const instance = new C(this._conn, this._parentActor);
|
||||
instance.conn = this._conn;
|
||||
instance.parentID = this._parentActor.actorID;
|
||||
// We want the newly-constructed actor to completely replace the factory
|
||||
// actor. Reusing the existing actor ID will make sure ActorPool.addActor
|
||||
// does the right thing.
|
||||
instance.actorID = this.actorID;
|
||||
this.registeredPool.addActor(instance);
|
||||
return instance;
|
||||
};
|
||||
exports.ObservedActorFactory = ObservedActorFactory;
|
||||
|
||||
/*
|
||||
* Methods shared between RootActor and BrowsingContextTargetActor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Populate |this._extraActors| as specified by |factories|, reusing whatever
|
||||
* actors are already there. Add all actors in the final extra actors table to
|
||||
* |pool|.
|
||||
*
|
||||
* The root actor and the target actor use this to instantiate actors that other
|
||||
* parts of the browser have specified with DebuggerServer.addTargetScopedActor and
|
||||
* DebuggerServer.addGlobalActor.
|
||||
*
|
||||
* @param factories
|
||||
* An object whose own property names are the names of properties to add to
|
||||
* some reply packet (say, a target actor grip or the "listTabs" response
|
||||
* form), and whose own property values are actor constructor functions, as
|
||||
* documented for addTargetScopedActor and addGlobalActor.
|
||||
*
|
||||
* @param this
|
||||
* The RootActor or BrowsingContextTargetActor with which the new actors
|
||||
* will be associated. It should support whatever API the |factories|
|
||||
* constructor functions might be interested in, as it is passed to them.
|
||||
* For the sake of CommonCreateExtraActors itself, it should have at least
|
||||
* the following properties:
|
||||
*
|
||||
* - _extraActors
|
||||
* An object whose own property names are factory table (and packet)
|
||||
* property names, and whose values are no-argument actor constructors,
|
||||
* of the sort that one can add to an ActorPool.
|
||||
*
|
||||
* - conn
|
||||
* The DebuggerServerConnection in which the new actors will participate.
|
||||
*
|
||||
* - actorID
|
||||
* The actor's name, for use as the new actors' parentID.
|
||||
*/
|
||||
exports.createExtraActors = function createExtraActors(factories, pool) {
|
||||
// Walk over global actors added by extensions.
|
||||
for (const name in factories) {
|
||||
let actor = this._extraActors[name];
|
||||
if (!actor) {
|
||||
// Register another factory, but this time specific to this connection.
|
||||
// It creates a fake actor that looks like an regular actor in the pool,
|
||||
// but without actually instantiating the actor.
|
||||
// It will only be instantiated on the first request made to the actor.
|
||||
actor = factories[name].createObservedActorFactory(this.conn, this);
|
||||
this._extraActors[name] = actor;
|
||||
}
|
||||
|
||||
// If the actor already exists in the pool, it may have been instantiated,
|
||||
// so make sure not to overwrite it by a non-instantiated version.
|
||||
if (!pool.has(actor.actorID)) {
|
||||
pool.addActor(actor);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Append the extra actors in |this._extraActors|, constructed by a prior call
|
||||
* to CommonCreateExtraActors, to |object|.
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
|
||||
const { Cu } = require("chrome");
|
||||
const Services = require("Services");
|
||||
const { ActorPool, appendExtraActors } = require("devtools/server/actors/common");
|
||||
const { ActorPool, appendExtraActors, createExtraActors } = require("devtools/server/actors/common");
|
||||
const { Pool } = require("devtools/shared/protocol");
|
||||
const { LazyPool, createExtraActors } = require("devtools/shared/protocol/lazy-pool");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
|
||||
loader.lazyRequireGetter(this, "ChromeWindowTargetActor",
|
||||
|
@ -101,7 +100,8 @@ function RootActor(connection, parameters) {
|
|||
this._onProcessListChanged = this.onProcessListChanged.bind(this);
|
||||
this._extraActors = {};
|
||||
|
||||
this._globalActorPool = new LazyPool(this.conn);
|
||||
this._globalActorPool = new ActorPool(this.conn);
|
||||
this.conn.addActorPool(this._globalActorPool);
|
||||
|
||||
this._parentProcessTargetActor = null;
|
||||
this._processActors = new Map();
|
||||
|
@ -240,9 +240,10 @@ RootActor.prototype = {
|
|||
|
||||
// Create global actors
|
||||
if (!this._globalActorPool) {
|
||||
this._globalActorPool = new LazyPool(this.conn);
|
||||
this._globalActorPool = new ActorPool(this.conn);
|
||||
this.conn.addActorPool(this._globalActorPool);
|
||||
}
|
||||
createExtraActors(this._parameters.globalActorFactories, this._globalActorPool, this);
|
||||
this._createExtraActors(this._parameters.globalActorFactories, this._globalActorPool);
|
||||
|
||||
// List the global actors
|
||||
this._appendExtraActors(reply);
|
||||
|
@ -518,7 +519,7 @@ RootActor.prototype = {
|
|||
if ((!("id" in request)) || request.id === 0) {
|
||||
if (this._parentProcessTargetActor && (!this._parentProcessTargetActor.docShell ||
|
||||
this._parentProcessTargetActor.docShell.isBeingDestroyed)) {
|
||||
this._parentProcessTargetActor.destroy();
|
||||
this._globalActorPool.removeActor(this._parentProcessTargetActor);
|
||||
this._parentProcessTargetActor = null;
|
||||
}
|
||||
if (!this._parentProcessTargetActor) {
|
||||
|
@ -526,7 +527,7 @@ RootActor.prototype = {
|
|||
const { ParentProcessTargetActor } =
|
||||
require("devtools/server/actors/targets/parent-process");
|
||||
this._parentProcessTargetActor = new ParentProcessTargetActor(this.conn);
|
||||
this._globalActorPool.manage(this._parentProcessTargetActor);
|
||||
this._globalActorPool.addActor(this._parentProcessTargetActor);
|
||||
}
|
||||
|
||||
return { form: this._parentProcessTargetActor.form() };
|
||||
|
@ -564,6 +565,7 @@ RootActor.prototype = {
|
|||
},
|
||||
|
||||
/* Support for DebuggerServer.addGlobalActor. */
|
||||
_createExtraActors: createExtraActors,
|
||||
_appendExtraActors: appendExtraActors,
|
||||
|
||||
/**
|
||||
|
@ -573,8 +575,8 @@ RootActor.prototype = {
|
|||
removeActorByName: function(name) {
|
||||
if (name in this._extraActors) {
|
||||
const actor = this._extraActors[name];
|
||||
if (this._globalActorPool.has(actor.actorID)) {
|
||||
actor.destroy();
|
||||
if (this._globalActorPool.has(actor)) {
|
||||
this._globalActorPool.removeActor(actor);
|
||||
}
|
||||
if (this._tabTargetActorPool) {
|
||||
// Iterate over BrowsingContextTargetActor instances to also remove target-scoped
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
var { Ci, Cu, Cr, Cc } = require("chrome");
|
||||
var Services = require("Services");
|
||||
const ChromeUtils = require("ChromeUtils");
|
||||
var { appendExtraActors } = require("devtools/server/actors/common");
|
||||
var {
|
||||
ActorPool, createExtraActors, appendExtraActors
|
||||
} = require("devtools/server/actors/common");
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
var { assert } = DevToolsUtils;
|
||||
|
@ -40,7 +42,6 @@ const STRINGS_URI = "devtools/shared/locales/browsing-context.properties";
|
|||
const L10N = new LocalizationHelper(STRINGS_URI);
|
||||
|
||||
const { ActorClassWithSpec, Actor, Pool } = require("devtools/shared/protocol");
|
||||
const { LazyPool, createExtraActors } = require("devtools/shared/protocol/lazy-pool");
|
||||
const { browsingContextTargetSpec } = require("devtools/shared/specs/targets/browsing-context");
|
||||
|
||||
loader.lazyRequireGetter(this, "ThreadActor", "devtools/server/actors/thread", true);
|
||||
|
@ -477,18 +478,16 @@ const browsingContextTargetPrototype = {
|
|||
// Always use the same ActorPool, so existing actor instances
|
||||
// (created in createExtraActors) are not lost.
|
||||
if (!this._targetScopedActorPool) {
|
||||
this._targetScopedActorPool = new LazyPool(this.conn);
|
||||
this._targetScopedActorPool = new ActorPool(this.conn);
|
||||
this.conn.addActorPool(this._targetScopedActorPool);
|
||||
}
|
||||
|
||||
// Walk over target-scoped actor factories and make sure they are all
|
||||
// instantiated and added into the ActorPool.
|
||||
const addedActors = createExtraActors(
|
||||
DebuggerServer.targetScopedActorFactories,
|
||||
this._targetScopedActorPool,
|
||||
this
|
||||
);
|
||||
this._createExtraActors(DebuggerServer.targetScopedActorFactories,
|
||||
this._targetScopedActorPool);
|
||||
|
||||
Object.assign(response, addedActors);
|
||||
this._appendExtraActors(response);
|
||||
return response;
|
||||
},
|
||||
|
||||
|
@ -563,6 +562,7 @@ const browsingContextTargetPrototype = {
|
|||
},
|
||||
|
||||
/* Support for DebuggerServer.addTargetScopedActor. */
|
||||
_createExtraActors: createExtraActors,
|
||||
_appendExtraActors: appendExtraActors,
|
||||
|
||||
/**
|
||||
|
@ -891,7 +891,7 @@ const browsingContextTargetPrototype = {
|
|||
// Shut down actors that belong to this target's pool.
|
||||
this._styleSheetActors.clear();
|
||||
if (this._targetScopedActorPool) {
|
||||
this._targetScopedActorPool.destroy();
|
||||
this.conn.removeActorPool(this._targetScopedActorPool);
|
||||
this._targetScopedActorPool = null;
|
||||
}
|
||||
|
||||
|
@ -1443,7 +1443,7 @@ const browsingContextTargetPrototype = {
|
|||
const actor = new StyleSheetActor(styleSheet, this);
|
||||
this._styleSheetActors.set(styleSheet, actor);
|
||||
|
||||
this._targetScopedActorPool.manage(actor);
|
||||
this._targetScopedActorPool.addActor(actor);
|
||||
this.emit("stylesheet-added", actor);
|
||||
|
||||
return actor;
|
||||
|
@ -1457,7 +1457,7 @@ const browsingContextTargetPrototype = {
|
|||
}
|
||||
delete this._extraActors[name];
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
exports.browsingContextTargetPrototype = browsingContextTargetPrototype;
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
*/
|
||||
var { Ci, Cc } = require("chrome");
|
||||
var Services = require("Services");
|
||||
var { ActorPool } = require("devtools/server/actors/common");
|
||||
var { ActorPool, RegisteredActorFactory,
|
||||
ObservedActorFactory } = require("devtools/server/actors/common");
|
||||
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
var { dumpn } = DevToolsUtils;
|
||||
|
||||
|
@ -1169,7 +1170,7 @@ var DebuggerServer = {
|
|||
* existing protocol packet properties, like 'title', 'url' or 'actor', since that would
|
||||
* break the protocol.
|
||||
*
|
||||
* @param options object
|
||||
* @param actor object
|
||||
* - constructorName: (required)
|
||||
* name of actor constructor, which is also used when removing the actor.
|
||||
* One of the following:
|
||||
|
@ -1180,7 +1181,7 @@ var DebuggerServer = {
|
|||
* @param name string
|
||||
* The name of the new request type.
|
||||
*/
|
||||
addTargetScopedActor(options, name) {
|
||||
addTargetScopedActor(actor, name) {
|
||||
if (!name) {
|
||||
throw Error("addTargetScopedActor requires the `name` argument");
|
||||
}
|
||||
|
@ -1190,7 +1191,8 @@ var DebuggerServer = {
|
|||
if (DebuggerServer.targetScopedActorFactories.hasOwnProperty(name)) {
|
||||
throw Error(name + " already exists");
|
||||
}
|
||||
DebuggerServer.targetScopedActorFactories[name] = { options, name };
|
||||
DebuggerServer.targetScopedActorFactories[name] =
|
||||
new RegisteredActorFactory(actor, name);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1213,8 +1215,8 @@ var DebuggerServer = {
|
|||
const actor = actorOrName;
|
||||
for (const factoryName in DebuggerServer.targetScopedActorFactories) {
|
||||
const handler = DebuggerServer.targetScopedActorFactories[factoryName];
|
||||
if ((handler.options.constructorName == actor.name) ||
|
||||
(handler.options.id == actor.id)) {
|
||||
if ((handler.name && handler.name == actor.name) ||
|
||||
(handler.id && handler.id == actor.id)) {
|
||||
name = factoryName;
|
||||
break;
|
||||
}
|
||||
|
@ -1239,7 +1241,7 @@ var DebuggerServer = {
|
|||
* existing protocol packet properties, like 'from', 'tabs' or 'selected', since that
|
||||
* would break the protocol.
|
||||
*
|
||||
* @param options object
|
||||
* @param actor object
|
||||
* - constructorName: (required)
|
||||
* name of actor constructor, which is also used when removing the actor.
|
||||
* One of the following:
|
||||
|
@ -1250,7 +1252,7 @@ var DebuggerServer = {
|
|||
* @param name string
|
||||
* The name of the new request type.
|
||||
*/
|
||||
addGlobalActor(options, name) {
|
||||
addGlobalActor(actor, name) {
|
||||
if (!name) {
|
||||
throw Error("addGlobalActor requires the `name` argument");
|
||||
}
|
||||
|
@ -1260,7 +1262,7 @@ var DebuggerServer = {
|
|||
if (DebuggerServer.globalActorFactories.hasOwnProperty(name)) {
|
||||
throw Error(name + " already exists");
|
||||
}
|
||||
DebuggerServer.globalActorFactories[name] = { options, name };
|
||||
DebuggerServer.globalActorFactories[name] = new RegisteredActorFactory(actor, name);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1283,8 +1285,8 @@ var DebuggerServer = {
|
|||
const actor = actorOrName;
|
||||
for (const factoryName in DebuggerServer.globalActorFactories) {
|
||||
const handler = DebuggerServer.globalActorFactories[factoryName];
|
||||
if ((handler.options.constructorName == actor.name) ||
|
||||
(handler.options.id == actor.id)) {
|
||||
if ((handler.name && handler.name == actor.name) ||
|
||||
(handler.id && handler.id == actor.id)) {
|
||||
name = factoryName;
|
||||
break;
|
||||
}
|
||||
|
@ -1524,27 +1526,30 @@ DebuggerServerConnection.prototype = {
|
|||
},
|
||||
|
||||
_getOrCreateActor(actorID) {
|
||||
try {
|
||||
const actor = this.getActor(actorID);
|
||||
if (!actor) {
|
||||
this.transport.send({ from: actorID ? actorID : "root",
|
||||
error: "noSuchActor",
|
||||
message: "No such actor for ID: " + actorID });
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof (actor) !== "object") {
|
||||
// ActorPools should now contain only actor instances (i.e. objects)
|
||||
throw new Error("Unexpected actor constructor/function in ActorPool " +
|
||||
"for actorID=" + actorID + ".");
|
||||
}
|
||||
|
||||
return actor;
|
||||
} catch (error) {
|
||||
const prefix = `Error occurred while creating actor' ${actorID}`;
|
||||
this.transport.send(this._unknownError(actorID, prefix, error));
|
||||
let actor = this.getActor(actorID);
|
||||
if (!actor) {
|
||||
this.transport.send({ from: actorID ? actorID : "root",
|
||||
error: "noSuchActor",
|
||||
message: "No such actor for ID: " + actorID });
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
// Dynamically-loaded actors have to be created lazily.
|
||||
if (actor instanceof ObservedActorFactory) {
|
||||
try {
|
||||
actor = actor.createActor();
|
||||
} catch (error) {
|
||||
const prefix = "Error occurred while creating actor '" + actor.name;
|
||||
this.transport.send(this._unknownError(actorID, prefix, error));
|
||||
}
|
||||
} else if (typeof (actor) !== "object") {
|
||||
// ActorPools should now contain only actor instances (i.e. objects)
|
||||
// or ObservedActorFactory instances.
|
||||
throw new Error("Unexpected actor constructor/function in ActorPool " +
|
||||
"for actorID=" + actorID + ".");
|
||||
}
|
||||
|
||||
return actor;
|
||||
},
|
||||
|
||||
poolFor(actorID) {
|
||||
|
|
|
@ -24,6 +24,8 @@ add_task(async function() {
|
|||
"Expect the target BrowsingContextTargetActor in response form field.");
|
||||
Assert.equal(response.type, "tabAttached",
|
||||
"Expect tabAttached in the response type.");
|
||||
Assert.ok(typeof response.promisesActor === "string",
|
||||
"Should have a tab context PromisesActor.");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { appendExtraActors } = require("devtools/server/actors/common");
|
||||
const { LazyPool, createExtraActors } = require("devtools/shared/protocol/lazy-pool");
|
||||
const { ActorPool, appendExtraActors, createExtraActors } = require("devtools/server/actors/common");
|
||||
const { RootActor } = require("devtools/server/actors/root");
|
||||
const { ThreadActor } = require("devtools/server/actors/thread");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
|
@ -41,17 +40,19 @@ function TestTabList(connection) {
|
|||
this._targetActors = [];
|
||||
|
||||
// A pool mapping those actors' names to the actors.
|
||||
this._targetActorPool = new LazyPool(connection);
|
||||
this._targetActorPool = new ActorPool(connection);
|
||||
|
||||
for (const global of gTestGlobals) {
|
||||
const actor = new TestTargetActor(connection, global);
|
||||
actor.selected = false;
|
||||
this._targetActors.push(actor);
|
||||
this._targetActorPool.manage(actor);
|
||||
this._targetActorPool.addActor(actor);
|
||||
}
|
||||
if (this._targetActors.length > 0) {
|
||||
this._targetActors[0].selected = true;
|
||||
}
|
||||
|
||||
connection.addActorPool(this._targetActorPool);
|
||||
}
|
||||
|
||||
TestTabList.prototype = {
|
||||
|
@ -110,25 +111,26 @@ TestTargetActor.prototype = {
|
|||
form: function() {
|
||||
const response = { actor: this.actorID, title: this._global.__name };
|
||||
|
||||
// Walk over target-scoped actors and add them to a new LazyPool.
|
||||
const actorPool = new LazyPool(this.conn);
|
||||
const actors = createExtraActors(
|
||||
DebuggerServer.targetScopedActorFactories,
|
||||
actorPool,
|
||||
this
|
||||
);
|
||||
// Walk over target-scoped actors and add them to a new ActorPool.
|
||||
const actorPool = new ActorPool(this.conn);
|
||||
this._createExtraActors(DebuggerServer.targetScopedActorFactories, actorPool);
|
||||
if (!actorPool.isEmpty()) {
|
||||
this._targetActorPool = actorPool;
|
||||
this.conn.addActorPool(this._targetActorPool);
|
||||
}
|
||||
|
||||
return { ...response, ...actors };
|
||||
this._appendExtraActors(response);
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
onAttach: function(request) {
|
||||
this._attached = true;
|
||||
|
||||
return { type: "tabAttached", threadActor: this.threadActor.actorID };
|
||||
const response = { type: "tabAttached", threadActor: this.threadActor.actorID };
|
||||
this._appendExtraActors(response);
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
onDetach: function(request) {
|
||||
|
@ -154,6 +156,7 @@ TestTargetActor.prototype = {
|
|||
},
|
||||
|
||||
/* Support for DebuggerServer.addTargetScopedActor. */
|
||||
_createExtraActors: createExtraActors,
|
||||
_appendExtraActors: appendExtraActors
|
||||
};
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ DIRS += [
|
|||
'node-properties',
|
||||
'performance',
|
||||
'platform',
|
||||
'protocol',
|
||||
'pretty-fast',
|
||||
'qrcode',
|
||||
'screenshot',
|
||||
|
|
|
@ -826,10 +826,6 @@ Pool.prototype = extend(EventEmitter.prototype, {
|
|||
return this.conn.poolFor(this.actorID);
|
||||
},
|
||||
|
||||
poolFor: function(actorID) {
|
||||
return this.conn.poolFor(actorID);
|
||||
},
|
||||
|
||||
/**
|
||||
* Override this if you want actors returned by this actor
|
||||
* to belong to a different actor by default.
|
||||
|
@ -862,9 +858,7 @@ Pool.prototype = extend(EventEmitter.prototype, {
|
|||
}
|
||||
|
||||
// If the actor is already in a pool, remove it without destroying it.
|
||||
// TODO: not all actors have been moved to protocol.js, so they do not all have
|
||||
// a parent field. Remove the check for the parent once the conversion is finished
|
||||
const parent = this.poolFor(actor.actorID);
|
||||
const parent = actor.parent();
|
||||
if (parent) {
|
||||
parent.unmanage(actor);
|
||||
}
|
||||
|
@ -887,19 +881,13 @@ Pool.prototype = extend(EventEmitter.prototype, {
|
|||
|
||||
// The actor for a given actor id stored in this pool
|
||||
actor: function(actorID) {
|
||||
if (this.__poolMap) {
|
||||
return this._poolMap.get(actorID);
|
||||
}
|
||||
return null;
|
||||
return this.__poolMap ? this._poolMap.get(actorID) : null;
|
||||
},
|
||||
|
||||
// Same as actor, should update debugger connection to use 'actor'
|
||||
// and then remove this.
|
||||
get: function(actorID) {
|
||||
if (this.__poolMap) {
|
||||
return this._poolMap.get(actorID);
|
||||
}
|
||||
return null;
|
||||
return this.__poolMap ? this._poolMap.get(actorID) : null;
|
||||
},
|
||||
|
||||
// True if this pool has no children.
|
||||
|
|
|
@ -1,231 +0,0 @@
|
|||
/* 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 { extend } = require("devtools/shared/extend");
|
||||
const { Pool } = require("devtools/shared/protocol");
|
||||
|
||||
/**
|
||||
* A Special Pool for RootActor and BrowsingContextTargetActor, which allows lazy loaded
|
||||
* actors to be added to the pool.
|
||||
*
|
||||
* Like the Pool, this is a protocol object that can manage the lifetime of other protocol
|
||||
* objects. Pools are used on both sides of the connection to help coordinate lifetimes.
|
||||
*
|
||||
* @param conn
|
||||
* Is a DebuggerServerConnection. Must have
|
||||
* addActorPool, removeActorPool, and poolFor.
|
||||
* @constructor
|
||||
*/
|
||||
function LazyPool(conn) {
|
||||
this.conn = conn;
|
||||
}
|
||||
|
||||
LazyPool.prototype = extend(Pool.prototype, {
|
||||
// The actor for a given actor id stored in this pool
|
||||
actor: function(actorID) {
|
||||
if (this.__poolMap) {
|
||||
const entry = this._poolMap.get(actorID);
|
||||
if (entry instanceof LazyActor) {
|
||||
return entry.createActor();
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
// Same as actor, should update debugger connection to use 'actor'
|
||||
// and then remove this.
|
||||
get: function(actorID) {
|
||||
return this.actor(actorID);
|
||||
},
|
||||
});
|
||||
|
||||
exports.LazyPool = LazyPool;
|
||||
|
||||
/**
|
||||
* Populate |parent._extraActors| as specified by |registeredActors|, reusing whatever
|
||||
* actors are already there. Add all actors in the final extra actors table to
|
||||
* |pool|. _extraActors is treated as a cache for lazy actors
|
||||
*
|
||||
* The target actor uses this to instantiate actors that other
|
||||
* parts of the browser have specified with DebuggerServer.addTargetScopedActor
|
||||
*
|
||||
* @param factories
|
||||
* An object whose own property names are the names of properties to add to
|
||||
* some reply packet (say, a target actor grip or the "listTabs" response
|
||||
* form), and whose own property values are actor constructor functions, as
|
||||
* documented for addTargetScopedActor
|
||||
*
|
||||
* @param parent
|
||||
* The parent TargetActor with which the new actors
|
||||
* will be associated. It should support whatever API the |factories|
|
||||
* constructor functions might be interested in, as it is passed to them.
|
||||
* For the sake of CommonCreateExtraActors itself, it should have at least
|
||||
* the following properties:
|
||||
*
|
||||
* - _extraActors
|
||||
* An object whose own property names are factory table (and packet)
|
||||
* property names, and whose values are no-argument actor constructors,
|
||||
* of the sort that one can add to an ActorPool.
|
||||
*
|
||||
* - conn
|
||||
* The DebuggerServerConnection in which the new actors will participate.
|
||||
*
|
||||
* - actorID
|
||||
* The actor's name, for use as the new actors' parentID.
|
||||
* @param pool
|
||||
* An object which implements the protocol.js Pool interface, and has the
|
||||
* following properties
|
||||
*
|
||||
* - manage
|
||||
* a function which adds a given actor to an actor pool
|
||||
*/
|
||||
function createExtraActors(registeredActors, pool, parent) {
|
||||
// Walk over global actors added by extensions.
|
||||
const nameMap = {};
|
||||
for (const name in registeredActors) {
|
||||
let actor = parent._extraActors[name];
|
||||
if (!actor) {
|
||||
// Register another factory, but this time specific to this connection.
|
||||
// It creates a fake actor that looks like an regular actor in the pool,
|
||||
// but without actually instantiating the actor.
|
||||
// It will only be instantiated on the first request made to the actor.
|
||||
actor = new LazyActor(registeredActors[name], parent, pool);
|
||||
parent._extraActors[name] = actor;
|
||||
}
|
||||
|
||||
// If the actor already exists in the pool, it may have been instantiated,
|
||||
// so make sure not to overwrite it by a non-instantiated version.
|
||||
if (!pool.has(actor.actorID)) {
|
||||
pool.manage(actor);
|
||||
}
|
||||
nameMap[name] = actor.actorID;
|
||||
}
|
||||
return nameMap;
|
||||
}
|
||||
|
||||
exports.createExtraActors = createExtraActors;
|
||||
|
||||
/**
|
||||
* Creates an "actor-like" object which responds in the same way as an ordinary actor
|
||||
* but has fewer capabilities (ie, does not manage lifetimes or have it's own pool).
|
||||
*
|
||||
*
|
||||
* @param factories
|
||||
* An object whose own property names are the names of properties to add to
|
||||
* some reply packet (say, a target actor grip or the "listTabs" response
|
||||
* form), and whose own property values are actor constructor functions, as
|
||||
* documented for addTargetScopedActor
|
||||
*
|
||||
* @param parent
|
||||
* The parent TargetActor with which the new actors
|
||||
* will be associated. It should support whatever API the |factories|
|
||||
* constructor functions might be interested in, as it is passed to them.
|
||||
* For the sake of CommonCreateExtraActors itself, it should have at least
|
||||
* the following properties:
|
||||
*
|
||||
* - _extraActors
|
||||
* An object whose own property names are factory table (and packet)
|
||||
* property names, and whose values are no-argument actor constructors,
|
||||
* of the sort that one can add to an ActorPool.
|
||||
*
|
||||
* - conn
|
||||
* The DebuggerServerConnection in which the new actors will participate.
|
||||
*
|
||||
* - actorID
|
||||
* The actor's name, for use as the new actors' parentID.
|
||||
* @param pool
|
||||
* An object which implements the protocol.js Pool interface, and has the
|
||||
* following properties
|
||||
*
|
||||
* - manage
|
||||
* a function which adds a given actor to an actor pool
|
||||
*/
|
||||
|
||||
function LazyActor(factory, parent, pool) {
|
||||
this._options = factory.options;
|
||||
this._parentActor = parent;
|
||||
this._name = factory.name;
|
||||
this._pool = pool;
|
||||
|
||||
// needed for taking a place in a pool
|
||||
this.typeName = factory.name;
|
||||
}
|
||||
|
||||
LazyActor.prototype = {
|
||||
loadModule(id) {
|
||||
const options = this._options;
|
||||
try {
|
||||
return require(id);
|
||||
// Fetch the actor constructor
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Unable to load actor module '${options.id}'\n${e.message}\n${e.stack}\n`
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
getConstructor() {
|
||||
const options = this._options;
|
||||
if (options.constructorFun) {
|
||||
// Actor definition registered by ActorRegistryActor or testing helpers
|
||||
return options.constructorFun;
|
||||
}
|
||||
// Lazy actor definition, where options contains all the information
|
||||
// required to load the actor lazily.
|
||||
// Exposes `name` attribute in order to allow removeXXXActor to match
|
||||
// the actor by its actor constructor name.
|
||||
this.name = options.constructorName;
|
||||
const module = this.loadModule(options.id);
|
||||
const constructor = module[options.constructorName];
|
||||
if (!constructor) {
|
||||
throw new Error(
|
||||
`Unable to find actor constructor named '${this.name}'. (Is it exported?)`
|
||||
);
|
||||
}
|
||||
return constructor;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the parent pool for this lazy actor.
|
||||
*/
|
||||
parent: function() {
|
||||
return this.conn && this.conn.poolFor(this.actorID);
|
||||
},
|
||||
|
||||
/**
|
||||
* This will only happen if the actor is destroyed before it is created
|
||||
* We do not want to use the Pool destruction method, because this actor
|
||||
* has no pool. However, it might have a parent that should unmange this
|
||||
* actor
|
||||
*/
|
||||
destroy() {
|
||||
const parent = this.parent();
|
||||
if (parent) {
|
||||
parent.unmanage(this);
|
||||
}
|
||||
},
|
||||
|
||||
createActor() {
|
||||
// Fetch the actor constructor
|
||||
const Constructor = this.getConstructor();
|
||||
// Instantiate a new actor instance
|
||||
const conn = this._parentActor.conn;
|
||||
// this should be taken care of once all actors are moved to protocol.js
|
||||
const instance = new Constructor(conn, this._parentActor);
|
||||
instance.conn = conn;
|
||||
|
||||
// We want the newly-constructed actor to completely replace the factory
|
||||
// actor. Reusing the existing actor ID will make sure Pool.manage
|
||||
// replaces the old actor with the new actor.
|
||||
instance.actorID = this.actorID;
|
||||
|
||||
this._pool.manage(instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'lazy-pool.js',
|
||||
)
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { appendExtraActors } = require("devtools/server/actors/common");
|
||||
const { LazyPool, createExtraActors } = require("devtools/shared/protocol/lazy-pool");
|
||||
const { ActorPool, appendExtraActors, createExtraActors } =
|
||||
require("devtools/server/actors/common");
|
||||
const { RootActor } = require("devtools/server/actors/root");
|
||||
const { ThreadActor } = require("devtools/server/actors/thread");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
|
@ -30,17 +30,19 @@ function TestTabList(connection) {
|
|||
this._targetActors = [];
|
||||
|
||||
// A pool mapping those actors' names to the actors.
|
||||
this._targetActorPool = new LazyPool(connection);
|
||||
this._targetActorPool = new ActorPool(connection);
|
||||
|
||||
for (const global of gTestGlobals) {
|
||||
const actor = new TestTargetActor(connection, global);
|
||||
actor.selected = false;
|
||||
this._targetActors.push(actor);
|
||||
this._targetActorPool.manage(actor);
|
||||
this._targetActorPool.addActor(actor);
|
||||
}
|
||||
if (this._targetActors.length > 0) {
|
||||
this._targetActors[0].selected = true;
|
||||
}
|
||||
|
||||
connection.addActorPool(this._targetActorPool);
|
||||
}
|
||||
|
||||
TestTabList.prototype = {
|
||||
|
@ -83,25 +85,26 @@ TestTargetActor.prototype = {
|
|||
form: function() {
|
||||
const response = { actor: this.actorID, title: this._global.__name };
|
||||
|
||||
// Walk over target-scoped actors and add them to a new LazyPool.
|
||||
const actorPool = new LazyPool(this.conn);
|
||||
const actors = createExtraActors(
|
||||
DebuggerServer.targetScopedActorFactories,
|
||||
actorPool,
|
||||
this
|
||||
);
|
||||
// Walk over target-scoped actors and add them to a new ActorPool.
|
||||
const actorPool = new ActorPool(this.conn);
|
||||
this._createExtraActors(DebuggerServer.targetScopedActorFactories, actorPool);
|
||||
if (!actorPool.isEmpty()) {
|
||||
this._targetActorPool = actorPool;
|
||||
this.conn.addActorPool(this._targetActorPool);
|
||||
}
|
||||
|
||||
return { ...response, ...actors };
|
||||
this._appendExtraActors(response);
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
onAttach: function(request) {
|
||||
this._attached = true;
|
||||
|
||||
return { type: "tabAttached", threadActor: this._threadActor.actorID };
|
||||
const response = { type: "tabAttached", threadActor: this._threadActor.actorID };
|
||||
this._appendExtraActors(response);
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
onDetach: function(request) {
|
||||
|
@ -112,6 +115,7 @@ TestTargetActor.prototype = {
|
|||
},
|
||||
|
||||
/* Support for DebuggerServer.addTargetScopedActor. */
|
||||
_createExtraActors: createExtraActors,
|
||||
_appendExtraActors: appendExtraActors
|
||||
};
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const { appendExtraActors } = require("devtools/server/actors/common");
|
||||
const { LazyPool, createExtraActors } = require("devtools/shared/protocol/lazy-pool");
|
||||
const { ActorPool, appendExtraActors, createExtraActors } =
|
||||
require("devtools/server/actors/common");
|
||||
const { RootActor } = require("devtools/server/actors/root");
|
||||
const { ThreadActor } = require("devtools/server/actors/thread");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
|
@ -28,17 +28,19 @@ function TestTabList(connection) {
|
|||
this._targetActors = [];
|
||||
|
||||
// A pool mapping those actors' names to the actors.
|
||||
this._targetActorPool = new LazyPool(connection);
|
||||
this._targetActorPool = new ActorPool(connection);
|
||||
|
||||
for (const global of gTestGlobals) {
|
||||
const actor = new TestTargetActor(connection, global);
|
||||
actor.selected = false;
|
||||
this._targetActors.push(actor);
|
||||
this._targetActorPool.manage(actor);
|
||||
this._targetActorPool.addActor(actor);
|
||||
}
|
||||
if (this._targetActors.length > 0) {
|
||||
this._targetActors[0].selected = true;
|
||||
}
|
||||
|
||||
connection.addActorPool(this._targetActorPool);
|
||||
}
|
||||
|
||||
TestTabList.prototype = {
|
||||
|
@ -81,25 +83,26 @@ TestTargetActor.prototype = {
|
|||
form: function() {
|
||||
const response = { actor: this.actorID, title: this._global.__name };
|
||||
|
||||
// Walk over target-scoped actors and add them to a new LazyPool.
|
||||
const actorPool = new LazyPool(this.conn);
|
||||
const actors = createExtraActors(
|
||||
DebuggerServer.targetScopedActorFactories,
|
||||
actorPool,
|
||||
this
|
||||
);
|
||||
// Walk over target-scoped actors and add them to a new ActorPool.
|
||||
const actorPool = new ActorPool(this.conn);
|
||||
this._createExtraActors(DebuggerServer.targetScopedActorFactories, actorPool);
|
||||
if (!actorPool.isEmpty()) {
|
||||
this._targetActorPool = actorPool;
|
||||
this.conn.addActorPool(this._targetActorPool);
|
||||
}
|
||||
|
||||
return { ...response, ...actors };
|
||||
this._appendExtraActors(response);
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
onAttach: function(request) {
|
||||
this._attached = true;
|
||||
|
||||
return { type: "tabAttached", threadActor: this._threadActor.actorID };
|
||||
const response = { type: "tabAttached", threadActor: this._threadActor.actorID };
|
||||
this._appendExtraActors(response);
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
onDetach: function(request) {
|
||||
|
@ -110,6 +113,7 @@ TestTargetActor.prototype = {
|
|||
},
|
||||
|
||||
/* Support for DebuggerServer.addTargetScopedActor. */
|
||||
_createExtraActors: createExtraActors,
|
||||
_appendExtraActors: appendExtraActors
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче