mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 977443 - Implement an actor that defines new actors. r=ochameau
This commit is contained in:
parent
52706a954d
commit
113d163096
@ -86,11 +86,10 @@ exports.makeInfallible = function makeInfallible(aHandler, aName) {
|
|||||||
if (aName) {
|
if (aName) {
|
||||||
who += " " + aName;
|
who += " " + aName;
|
||||||
}
|
}
|
||||||
exports.reportException(who, ex);
|
return exports.reportException(who, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interleaves two arrays element by element, returning the combined array, like
|
* Interleaves two arrays element by element, returning the combined array, like
|
||||||
* a zip. In the case of arrays with different sizes, undefined values will be
|
* a zip. In the case of arrays with different sizes, undefined values will be
|
||||||
|
153
toolkit/devtools/server/actors/actor-registry.js
Normal file
153
toolkit/devtools/server/actors/actor-registry.js
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/* 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 protocol = require("devtools/server/protocol");
|
||||||
|
const { method, custom, Arg, Option, RetVal } = protocol;
|
||||||
|
|
||||||
|
const { Cu, CC, components } = require("chrome");
|
||||||
|
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||||
|
const Services = require("Services");
|
||||||
|
const { DebuggerServer } = require("devtools/server/main");
|
||||||
|
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ActorActor gives you a handle to an actor you've dynamically
|
||||||
|
* registered and allows you to unregister it.
|
||||||
|
*/
|
||||||
|
const ActorActor = protocol.ActorClass({
|
||||||
|
typeName: "actorActor",
|
||||||
|
|
||||||
|
initialize: function (conn, options) {
|
||||||
|
protocol.Actor.prototype.initialize.call(this, conn);
|
||||||
|
|
||||||
|
this.options = options;
|
||||||
|
},
|
||||||
|
|
||||||
|
unregister: method(function () {
|
||||||
|
if (this.options.tab) {
|
||||||
|
DebuggerServer.removeTabActor(this.options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.global) {
|
||||||
|
DebuggerServer.removeGlobalActor(this.options);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
request: {},
|
||||||
|
response: {}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const ActorActorFront = protocol.FrontClass(ActorActor, {
|
||||||
|
initialize: function (client, form) {
|
||||||
|
protocol.Front.prototype.initialize.call(this, client, form);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.ActorActorFront = ActorActorFront;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ActorRegistryActor allows clients to define new actors on the
|
||||||
|
* server. This is particularly useful for addons.
|
||||||
|
*/
|
||||||
|
const ActorRegistryActor = protocol.ActorClass({
|
||||||
|
typeName: "actorRegistry",
|
||||||
|
|
||||||
|
initialize: function (conn) {
|
||||||
|
protocol.Actor.prototype.initialize.call(this, conn);
|
||||||
|
},
|
||||||
|
|
||||||
|
registerActor: method(function (sourceText, fileName, options) {
|
||||||
|
const principal = CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")();
|
||||||
|
const sandbox = Cu.Sandbox(principal);
|
||||||
|
const exports = sandbox.exports = {};
|
||||||
|
sandbox.require = require;
|
||||||
|
|
||||||
|
Cu.evalInSandbox(sourceText, sandbox, "1.8", fileName, 1);
|
||||||
|
|
||||||
|
let { prefix, constructor, type } = options;
|
||||||
|
|
||||||
|
if (type.global) {
|
||||||
|
DebuggerServer.addGlobalActor({
|
||||||
|
constructorName: constructor,
|
||||||
|
constructorFun: sandbox[constructor]
|
||||||
|
}, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.tab) {
|
||||||
|
DebuggerServer.addTabActor({
|
||||||
|
constructorName: constructor,
|
||||||
|
constructorFun: sandbox[constructor]
|
||||||
|
}, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActorActor(this.conn, {
|
||||||
|
name: constructor,
|
||||||
|
tab: type.tab,
|
||||||
|
global: type.global
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
request: {
|
||||||
|
sourceText: Arg(0, "string"),
|
||||||
|
filename: Arg(1, "string"),
|
||||||
|
options: Arg(2, "json")
|
||||||
|
},
|
||||||
|
|
||||||
|
response: {
|
||||||
|
actorActor: RetVal("actorActor")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.ActorRegistryActor = ActorRegistryActor;
|
||||||
|
|
||||||
|
function request(uri) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
uri = Services.io.newURI(uri, null, null);
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uri.scheme != "resource") {
|
||||||
|
reject(new Error(
|
||||||
|
"Can only register actors whose URI scheme is 'resource'."));
|
||||||
|
}
|
||||||
|
|
||||||
|
NetUtil.asyncFetch(uri, (stream, status, req) => {
|
||||||
|
if (!components.isSuccessCode(status)) {
|
||||||
|
reject(new Error("Request failed with status code = "
|
||||||
|
+ status
|
||||||
|
+ " after NetUtil.asyncFetch for url = "
|
||||||
|
+ uri));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let source = NetUtil.readInputStreamToString(stream, stream.available());
|
||||||
|
stream.close();
|
||||||
|
resolve(source);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const ActorRegistryFront = protocol.FrontClass(ActorRegistryActor, {
|
||||||
|
initialize: function (client, form) {
|
||||||
|
protocol.Front.prototype.initialize.call(this, client,
|
||||||
|
{ actor: form.actorRegistryActor });
|
||||||
|
|
||||||
|
this.manage(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
registerActor: custom(function (uri, options) {
|
||||||
|
return request(uri, options)
|
||||||
|
.then(sourceText => {
|
||||||
|
return this._registerActor(sourceText, uri, options);
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
impl: "_registerActor"
|
||||||
|
})
|
||||||
|
});
|
||||||
|
exports.ActorRegistryFront = ActorRegistryFront;
|
@ -33,6 +33,10 @@ function RegisteredActorFactory(options, prefix) {
|
|||||||
// By default the actor name will also be used for the actorID prefix.
|
// By default the actor name will also be used for the actorID prefix.
|
||||||
this._prefix = prefix;
|
this._prefix = prefix;
|
||||||
if (typeof(options) != "function") {
|
if (typeof(options) != "function") {
|
||||||
|
// actors definition registered by actorRegistryActor
|
||||||
|
if (options.constructorFun) {
|
||||||
|
this._getConstructor = () => options.constructorFun;
|
||||||
|
} else {
|
||||||
// Lazy actor definition, where options contains all the information
|
// Lazy actor definition, where options contains all the information
|
||||||
// required to load the actor lazily.
|
// required to load the actor lazily.
|
||||||
this._getConstructor = function () {
|
this._getConstructor = function () {
|
||||||
@ -52,16 +56,21 @@ function RegisteredActorFactory(options, prefix) {
|
|||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
// Exposes `name` attribute in order to allow removeXXXActor to match
|
||||||
|
// the actor by its actor constructor name.
|
||||||
|
this.name = options.constructorName;
|
||||||
} else {
|
} else {
|
||||||
// Old actor case, where options is a function that is the actor constructor.
|
// Old actor case, where options is a function that is the actor constructor.
|
||||||
this._getConstructor = () => options;
|
this._getConstructor = () => options;
|
||||||
// Exposes `name` attribute in order to allow removeXXXActor to match
|
// Exposes `name` attribute in order to allow removeXXXActor to match
|
||||||
// the actor by its actor contructor name.
|
// the actor by its actor constructor name.
|
||||||
this.name = options.name;
|
this.name = options.name;
|
||||||
|
|
||||||
// For old actors, we allow the use of a different prefix for actorID
|
// For old actors, we allow the use of a different prefix for actorID
|
||||||
// than for listTabs actor names, by fetching a prefix on the actor prototype.
|
// than for listTabs actor names, by fetching a prefix on the actor prototype.
|
||||||
// (Used by ChromeDebuggerActor)
|
// (Used by ChromeDebuggerActor)
|
||||||
if (options.prototype.actorPrefix) {
|
if (options.prototype && options.prototype.actorPrefix) {
|
||||||
this._prefix = options.prototype.actorPrefix;
|
this._prefix = options.prototype.actorPrefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,9 +88,9 @@ exports.RegisteredActorFactory = RegisteredActorFactory;
|
|||||||
*
|
*
|
||||||
* ObservedActorFactory fakes the following actors attributes:
|
* ObservedActorFactory fakes the following actors attributes:
|
||||||
* actorPrefix (string) Used by ActorPool.addActor to compute the actor id
|
* actorPrefix (string) Used by ActorPool.addActor to compute the actor id
|
||||||
* actorID (string) Set by ActorPool.addActor just after being instanciated
|
* actorID (string) Set by ActorPool.addActor just after being instantiated
|
||||||
* registeredPool (object) Set by ActorPool.addActor just after being
|
* registeredPool (object) Set by ActorPool.addActor just after being
|
||||||
* instanciated
|
* instantiated
|
||||||
* And exposes the following method:
|
* And exposes the following method:
|
||||||
* createActor (function) Instantiate an actor that is going to replace
|
* createActor (function) Instantiate an actor that is going to replace
|
||||||
* this factory in the actor pool.
|
* this factory in the actor pool.
|
||||||
@ -123,7 +132,7 @@ exports.ObservedActorFactory = ObservedActorFactory;
|
|||||||
* |aPool|.
|
* |aPool|.
|
||||||
*
|
*
|
||||||
* The root actor and the tab actor use this to instantiate actors that other
|
* The root actor and the tab actor use this to instantiate actors that other
|
||||||
* parts of the browser have specified with DebuggerServer.addTabActor antd
|
* parts of the browser have specified with DebuggerServer.addTabActor and
|
||||||
* DebuggerServer.addGlobalActor.
|
* DebuggerServer.addGlobalActor.
|
||||||
*
|
*
|
||||||
* @param aFactories
|
* @param aFactories
|
||||||
@ -158,12 +167,17 @@ exports.createExtraActors = function createExtraActors(aFactories, aPool) {
|
|||||||
// Register another factory, but this time specific to this connection.
|
// Register another factory, but this time specific to this connection.
|
||||||
// It creates a fake actor that looks like an regular actor in the pool,
|
// It creates a fake actor that looks like an regular actor in the pool,
|
||||||
// but without actually instantiating the actor.
|
// but without actually instantiating the actor.
|
||||||
// It will only be instanciated on the first request made to the actor.
|
// It will only be instantiated on the first request made to the actor.
|
||||||
actor = aFactories[name].createObservedActorFactory(this.conn, this);
|
actor = aFactories[name].createObservedActorFactory(this.conn, this);
|
||||||
this._extraActors[name] = actor;
|
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 (!aPool.has(actor.actorID)) {
|
||||||
aPool.addActor(actor);
|
aPool.addActor(actor);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -270,7 +284,13 @@ ActorPool.prototype = {
|
|||||||
actor.disconnect();
|
actor.disconnect();
|
||||||
}
|
}
|
||||||
this._cleanups = {};
|
this._cleanups = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
forEach: function(callback) {
|
||||||
|
for (let name in this._actors) {
|
||||||
|
callback(this._actors[name]);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.ActorPool = ActorPool;
|
exports.ActorPool = ActorPool;
|
||||||
|
@ -280,14 +280,12 @@ RootActor.prototype = {
|
|||||||
newActorPool.addActor(tabActor);
|
newActorPool.addActor(tabActor);
|
||||||
tabActorList.push(tabActor);
|
tabActorList.push(tabActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DebuggerServer.addGlobalActor support: create actors. */
|
/* DebuggerServer.addGlobalActor support: create actors. */
|
||||||
if (!this._globalActorPool) {
|
if (!this._globalActorPool) {
|
||||||
this._globalActorPool = new ActorPool(this.conn);
|
this._globalActorPool = new ActorPool(this.conn);
|
||||||
this._createExtraActors(this._parameters.globalActorFactories, this._globalActorPool);
|
|
||||||
this.conn.addActorPool(this._globalActorPool);
|
this.conn.addActorPool(this._globalActorPool);
|
||||||
}
|
}
|
||||||
|
this._createExtraActors(this._parameters.globalActorFactories, this._globalActorPool);
|
||||||
/*
|
/*
|
||||||
* Drop the old actorID -> actor map. Actors that still mattered were
|
* Drop the old actorID -> actor map. Actors that still mattered were
|
||||||
* added to the new map; others will go away.
|
* added to the new map; others will go away.
|
||||||
@ -436,7 +434,7 @@ RootActor.prototype = {
|
|||||||
* is here because the Style Editor and Inspector share style sheet actors.
|
* is here because the Style Editor and Inspector share style sheet actors.
|
||||||
*
|
*
|
||||||
* @param DOMStyleSheet styleSheet
|
* @param DOMStyleSheet styleSheet
|
||||||
* The style sheet to creat an actor for.
|
* The style sheet to create an actor for.
|
||||||
* @return StyleSheetActor actor
|
* @return StyleSheetActor actor
|
||||||
* The actor for this style sheet.
|
* The actor for this style sheet.
|
||||||
*
|
*
|
||||||
@ -451,6 +449,27 @@ RootActor.prototype = {
|
|||||||
this._globalActorPool.addActor(actor);
|
this._globalActorPool.addActor(actor);
|
||||||
|
|
||||||
return actor;
|
return actor;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the extra actor (added by DebuggerServer.addGlobalActor or
|
||||||
|
* DebuggerServer.addTabActor) name |aName|.
|
||||||
|
*/
|
||||||
|
removeActorByName: function(aName) {
|
||||||
|
if (aName in this._extraActors) {
|
||||||
|
const actor = this._extraActors[aName];
|
||||||
|
if (this._globalActorPool.has(actor)) {
|
||||||
|
this._globalActorPool.removeActor(actor);
|
||||||
|
}
|
||||||
|
if (this._tabActorPool) {
|
||||||
|
// Iterate over TabActor instances to also remove tab actors
|
||||||
|
// created during listTabs for each document.
|
||||||
|
this._tabActorPool.forEach(tab => {
|
||||||
|
tab.removeActorByName(aName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
delete this._extraActors[aName];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -856,7 +856,7 @@ TabActor.prototype = {
|
|||||||
_appendExtraActors: appendExtraActors,
|
_appendExtraActors: appendExtraActors,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the actual work of attching to a tab.
|
* Does the actual work of attaching to a tab.
|
||||||
*/
|
*/
|
||||||
_attach: function BTA_attach() {
|
_attach: function BTA_attach() {
|
||||||
if (this._attached) {
|
if (this._attached) {
|
||||||
@ -1512,7 +1512,7 @@ TabActor.prototype = {
|
|||||||
* is here because the Style Editor and Inspector share style sheet actors.
|
* is here because the Style Editor and Inspector share style sheet actors.
|
||||||
*
|
*
|
||||||
* @param DOMStyleSheet styleSheet
|
* @param DOMStyleSheet styleSheet
|
||||||
* The style sheet to creat an actor for.
|
* The style sheet to create an actor for.
|
||||||
* @return StyleSheetActor actor
|
* @return StyleSheetActor actor
|
||||||
* The actor for this style sheet.
|
* The actor for this style sheet.
|
||||||
*
|
*
|
||||||
@ -1527,7 +1527,17 @@ TabActor.prototype = {
|
|||||||
this._tabPool.addActor(actor);
|
this._tabPool.addActor(actor);
|
||||||
|
|
||||||
return actor;
|
return actor;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeActorByName: function BTA_removeActor(aName) {
|
||||||
|
if (aName in this._extraActors) {
|
||||||
|
const actor = this._extraActors[aName];
|
||||||
|
if (this._tabActorPool.has(actor)) {
|
||||||
|
this._tabActorPool.removeActor(actor);
|
||||||
}
|
}
|
||||||
|
delete this._extraActors[aName];
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1550,7 +1560,7 @@ exports.TabActor = TabActor;
|
|||||||
* <browser> tab. Most of the implementation comes from TabActor.
|
* <browser> tab. Most of the implementation comes from TabActor.
|
||||||
*
|
*
|
||||||
* @param aConnection DebuggerServerConnection
|
* @param aConnection DebuggerServerConnection
|
||||||
* The conection to the client.
|
* The connection to the client.
|
||||||
* @param aBrowser browser
|
* @param aBrowser browser
|
||||||
* The browser instance that contains this tab.
|
* The browser instance that contains this tab.
|
||||||
* @param aTabBrowser tabbrowser
|
* @param aTabBrowser tabbrowser
|
||||||
|
@ -324,7 +324,7 @@ var DebuggerServer = {
|
|||||||
* - constructor (string):
|
* - constructor (string):
|
||||||
* the name of the exported symbol to be used as the actor
|
* the name of the exported symbol to be used as the actor
|
||||||
* constructor.
|
* constructor.
|
||||||
* - type (a dictionnary of booleans with following attribute names):
|
* - type (a dictionary of booleans with following attribute names):
|
||||||
* - "global"
|
* - "global"
|
||||||
* registers a global actor instance, if true.
|
* registers a global actor instance, if true.
|
||||||
* A global actor has the root actor as its parent.
|
* A global actor has the root actor as its parent.
|
||||||
@ -347,7 +347,7 @@ var DebuggerServer = {
|
|||||||
throw new Error("Lazy actor definition for '" + id + "' requires a string 'constructor' option.");
|
throw new Error("Lazy actor definition for '" + id + "' requires a string 'constructor' option.");
|
||||||
}
|
}
|
||||||
if (!("global" in type) && !("tab" in type)) {
|
if (!("global" in type) && !("tab" in type)) {
|
||||||
throw new Error("Lazy actor definition for '" + id + "' requires a dictionnary 'type' option whose attributes can be 'global' or 'tab'.");
|
throw new Error("Lazy actor definition for '" + id + "' requires a dictionary 'type' option whose attributes can be 'global' or 'tab'.");
|
||||||
}
|
}
|
||||||
let name = prefix + "Actor";
|
let name = prefix + "Actor";
|
||||||
let mod = {
|
let mod = {
|
||||||
@ -433,6 +433,11 @@ var DebuggerServer = {
|
|||||||
constructor: "PreferenceActor",
|
constructor: "PreferenceActor",
|
||||||
type: { global: true }
|
type: { global: true }
|
||||||
});
|
});
|
||||||
|
this.registerModule("devtools/server/actors/actor-registry", {
|
||||||
|
prefix: "actorRegistry",
|
||||||
|
constructor: "ActorRegistryActor",
|
||||||
|
type: { global: true }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.registerModule("devtools/server/actors/webapps", {
|
this.registerModule("devtools/server/actors/webapps", {
|
||||||
@ -979,6 +984,8 @@ var DebuggerServer = {
|
|||||||
/**
|
/**
|
||||||
* Unregisters the handler for the specified tab-scoped request type.
|
* Unregisters the handler for the specified tab-scoped request type.
|
||||||
* This may be used for example by add-ons when shutting down or upgrading.
|
* This may be used for example by add-ons when shutting down or upgrading.
|
||||||
|
* When unregistering an existing tab actor remove related tab factory
|
||||||
|
* as well as all existing instances of the actor.
|
||||||
*
|
*
|
||||||
* @param aActor function, object
|
* @param aActor function, object
|
||||||
* In case of function:
|
* In case of function:
|
||||||
@ -992,6 +999,9 @@ var DebuggerServer = {
|
|||||||
if ((handler.name && handler.name == aActor.name) ||
|
if ((handler.name && handler.name == aActor.name) ||
|
||||||
(handler.id && handler.id == aActor.id)) {
|
(handler.id && handler.id == aActor.id)) {
|
||||||
delete DebuggerServer.tabActorFactories[name];
|
delete DebuggerServer.tabActorFactories[name];
|
||||||
|
for (let connID of Object.getOwnPropertyNames(this._connections)) {
|
||||||
|
this._connections[connID].rootActor.removeActorByName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1033,6 +1043,8 @@ var DebuggerServer = {
|
|||||||
/**
|
/**
|
||||||
* Unregisters the handler for the specified browser-scoped request type.
|
* Unregisters the handler for the specified browser-scoped request type.
|
||||||
* This may be used for example by add-ons when shutting down or upgrading.
|
* This may be used for example by add-ons when shutting down or upgrading.
|
||||||
|
* When unregistering an existing global actor remove related global factory
|
||||||
|
* as well as all existing instances of the actor.
|
||||||
*
|
*
|
||||||
* @param aActor function, object
|
* @param aActor function, object
|
||||||
* In case of function:
|
* In case of function:
|
||||||
@ -1046,6 +1058,9 @@ var DebuggerServer = {
|
|||||||
if ((handler.name && handler.name == aActor.name) ||
|
if ((handler.name && handler.name == aActor.name) ||
|
||||||
(handler.id && handler.id == aActor.id)) {
|
(handler.id && handler.id == aActor.id)) {
|
||||||
delete DebuggerServer.globalActorFactories[name];
|
delete DebuggerServer.globalActorFactories[name];
|
||||||
|
for (let connID of Object.getOwnPropertyNames(this._connections)) {
|
||||||
|
this._connections[connID].rootActor.removeActorByName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ EXTRA_JS_MODULES.devtools.server += [
|
|||||||
]
|
]
|
||||||
|
|
||||||
EXTRA_JS_MODULES.devtools.server.actors += [
|
EXTRA_JS_MODULES.devtools.server.actors += [
|
||||||
|
'actors/actor-registry.js',
|
||||||
'actors/call-watcher.js',
|
'actors/call-watcher.js',
|
||||||
'actors/canvas.js',
|
'actors/canvas.js',
|
||||||
'actors/child-process.js',
|
'actors/child-process.js',
|
||||||
|
15
toolkit/devtools/server/tests/unit/hello-actor.js
Normal file
15
toolkit/devtools/server/tests/unit/hello-actor.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
const protocol = require("devtools/server/protocol");
|
||||||
|
|
||||||
|
const HelloActor = protocol.ActorClass({
|
||||||
|
typeName: "helloActor",
|
||||||
|
|
||||||
|
hello: protocol.method(function () {
|
||||||
|
return;
|
||||||
|
}, {
|
||||||
|
request: {},
|
||||||
|
response: {}
|
||||||
|
})
|
||||||
|
});
|
@ -9,5 +9,7 @@ exports.register = function(handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exports.unregister = function(handle) {
|
exports.unregister = function(handle) {
|
||||||
|
handle.removeTabActor(Actor);
|
||||||
|
handle.removeGlobalActor(Actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that you can register new actors via the ActorRegistrationActor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var gClient;
|
||||||
|
var gRegistryFront;
|
||||||
|
var gActorFront;
|
||||||
|
var gOldPref;
|
||||||
|
|
||||||
|
const { ActorRegistryFront } = devtools.require("devtools/server/actors/actor-registry");
|
||||||
|
|
||||||
|
function run_test()
|
||||||
|
{
|
||||||
|
gOldPref = Services.prefs.getBoolPref("devtools.debugger.forbid-certified-apps");
|
||||||
|
Services.prefs.setBoolPref("devtools.debugger.forbid-certified-apps", false);
|
||||||
|
initTestDebuggerServer();
|
||||||
|
DebuggerServer.addBrowserActors();
|
||||||
|
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||||
|
gClient.connect(getRegistry);
|
||||||
|
do_test_pending();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRegistry() {
|
||||||
|
gClient.listTabs((response) => {
|
||||||
|
gRegistryFront = ActorRegistryFront(gClient, response);
|
||||||
|
registerNewActor();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerNewActor() {
|
||||||
|
let options = {
|
||||||
|
prefix: "helloActor",
|
||||||
|
constructor: "HelloActor",
|
||||||
|
type: { global: true }
|
||||||
|
};
|
||||||
|
|
||||||
|
gRegistryFront
|
||||||
|
.registerActor("resource://test/hello-actor.js", options)
|
||||||
|
.then(actorFront => gActorFront = actorFront)
|
||||||
|
.then(talkToNewActor)
|
||||||
|
.then(null, e => {
|
||||||
|
DevToolsUtils.reportException("registerNewActor", e)
|
||||||
|
do_check_true(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function talkToNewActor() {
|
||||||
|
gClient.listTabs(({ helloActor }) => {
|
||||||
|
do_check_true(!!helloActor);
|
||||||
|
gClient.request({
|
||||||
|
to: helloActor,
|
||||||
|
type: "hello"
|
||||||
|
}, response => {
|
||||||
|
do_check_true(!response.error);
|
||||||
|
unregisterNewActor();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function unregisterNewActor() {
|
||||||
|
gActorFront
|
||||||
|
.unregister()
|
||||||
|
.then(testActorIsUnregistered)
|
||||||
|
.then(null, e => {
|
||||||
|
DevToolsUtils.reportException("registerNewActor", e)
|
||||||
|
do_check_true(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testActorIsUnregistered() {
|
||||||
|
gClient.listTabs(({ helloActor }) => {
|
||||||
|
do_check_true(!helloActor);
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref("devtools.debugger.forbid-certified-apps", gOldPref);
|
||||||
|
finishClient(gClient);
|
||||||
|
});
|
||||||
|
}
|
@ -52,8 +52,11 @@ TestTabList.prototype = {
|
|||||||
|
|
||||||
function createRootActor(aConnection)
|
function createRootActor(aConnection)
|
||||||
{
|
{
|
||||||
let root = new RootActor(aConnection,
|
let root = new RootActor(aConnection, {
|
||||||
{ tabList: new TestTabList(aConnection) });
|
tabList: new TestTabList(aConnection),
|
||||||
|
globalActorFactories: DebuggerServer.globalActorFactories,
|
||||||
|
});
|
||||||
|
|
||||||
root.applicationType = "xpcshell-tests";
|
root.applicationType = "xpcshell-tests";
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
@ -126,6 +129,14 @@ TestTabActor.prototype = {
|
|||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeActorByName: function(aName) {
|
||||||
|
const actor = this._extraActors[aName];
|
||||||
|
if (this._tabActorPool) {
|
||||||
|
this._tabActorPool.removeActor(actor);
|
||||||
|
}
|
||||||
|
delete this._extraActors[aName];
|
||||||
|
},
|
||||||
|
|
||||||
/* Support for DebuggerServer.addTabActor. */
|
/* Support for DebuggerServer.addTabActor. */
|
||||||
_createExtraActors: createExtraActors,
|
_createExtraActors: createExtraActors,
|
||||||
_appendExtraActors: appendExtraActors
|
_appendExtraActors: appendExtraActors
|
||||||
|
@ -16,7 +16,9 @@ support-files =
|
|||||||
sourcemapped.js
|
sourcemapped.js
|
||||||
testactors.js
|
testactors.js
|
||||||
tracerlocations.js
|
tracerlocations.js
|
||||||
|
hello-actor.js
|
||||||
|
|
||||||
|
[test_actor-registry-actor.js]
|
||||||
[test_nesting-01.js]
|
[test_nesting-01.js]
|
||||||
[test_nesting-02.js]
|
[test_nesting-02.js]
|
||||||
[test_nesting-03.js]
|
[test_nesting-03.js]
|
||||||
|
Loading…
Reference in New Issue
Block a user