Bug 877295 - Allow actors to be loaded as CommonJS modules. r=past

--HG--
extra : rebase_source : c9f1f7da216e006ab1983127f9aa61da25f7da92
This commit is contained in:
Dave Camp 2013-06-06 16:06:08 -07:00
parent af89ee022e
commit 64c9e404fc
6 changed files with 174 additions and 1 deletions

View File

@ -47,7 +47,10 @@ var BuiltinProvider = {
"": "resource://gre/modules/commonjs/",
"main": "resource:///modules/devtools/main.js",
"devtools": "resource:///modules/devtools",
"devtools/server": "resource://gre/modules/devtools/server"
"devtools/server": "resource://gre/modules/devtools/server",
// Allow access to xpcshell test items from the loader.
"xpcshell-test": "resource://test"
},
globals: loaderGlobals
});

View File

@ -50,6 +50,58 @@ const ServerSocket = CC("@mozilla.org/network/server-socket;1",
"nsIServerSocket",
"initSpecialConnection");
var gRegisteredModules = Object.create(null);
/**
* The ModuleAPI object is passed to modules loaded using the
* DebuggerServer.registerModule() API. Modules can use this
* object to register actor factories.
* Factories registered through the module API will be removed
* when the module is unregistered or when the server is
* destroyed.
*/
function ModuleAPI() {
let activeTabActors = new Set();
let activeGlobalActors = new Set();
return {
// See DebuggerServer.addGlobalActor for a description.
addGlobalActor: function(factory, name) {
DebuggerServer.addGlobalActor(factory, name);
activeGlobalActors.add(factory);
},
// See DebuggerServer.removeGlobalActor for a description.
removeGlobalActor: function(factory) {
DebuggerServer.removeGlobalActor(factory);
activeGlobalActors.delete(factory);
},
// See DebuggerServer.addTabActor for a description.
addTabActor: function(factory, name) {
DebuggerServer.addTabActor(factory, name);
activeTabActors.add(factory);
},
// See DebuggerServer.removeTabActor for a description.
removeTabActor: function(factory) {
DebuggerServer.removeTabActor(factory);
activeTabActors.delete(factory);
},
// Destroy the module API object, unregistering any
// factories registered by the module.
destroy: function() {
for (let factory of activeTabActors) {
DebuggerServer.removeTabActor(factory);
}
activeTabActors = null;
for (let factory of activeGlobalActors) {
DebuggerServer.removeGlobalActor(factory);
}
activeGlobalActors = null;
}
}
};
/***
* Public API
*/
@ -159,6 +211,13 @@ var DebuggerServer = {
for (let connID of Object.getOwnPropertyNames(this._connections)) {
this._connections[connID].close();
}
for (let id of Object.getOwnPropertyNames(gRegisteredModules)) {
let mod = gRegisteredModules[id];
mod.module.unregister(mod.api);
}
gRegisteredModules = {};
this.closeListener();
this.globalActorFactories = {};
this.tabActorFactories = {};
@ -180,6 +239,45 @@ var DebuggerServer = {
loadSubScript.call(this, aURL);
},
/**
* Register a CommonJS module with the debugger server.
* @param id string
* The ID of a CommonJS module. This module must export
* 'register' and 'unregister' functions.
*/
registerModule: function(id) {
if (id in gRegisteredModules) {
throw new Error("Tried to register a module twice: " + id + "\n");
}
let moduleAPI = ModuleAPI();
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let mod = devtools.require(id);
mod.register(moduleAPI);
gRegisteredModules[id] = { module: mod, api: moduleAPI };
},
/**
* Returns true if a module id has been registered.
*/
isModuleRegistered: function(id) {
return (id in gRegisteredModules);
},
/**
* Unregister a previously-loaded CommonJS module from the debugger server.
*/
unregisterModule: function(id) {
let mod = gRegisteredModules[id];
if (!mod) {
throw new Error("Tried to unregister a module that was not previously registered.");
}
mod.module.unregister(mod.api);
mod.api.destroy();
delete gRegisteredModules[id];
},
/**
* Install Firefox-specific actors.
*/

View File

@ -0,0 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function Actor() {}
exports.register = function(handle) {
handle.addTabActor(Actor, "registeredActor1");
handle.addGlobalActor(Actor, "registeredActor1");
}
exports.unregister = function(handle) {
handle.removeTabActor(Actor);
handle.removeGlobalActor(Actor);
}

View File

@ -0,0 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function Actor() {}
exports.register = function(handle) {
handle.addGlobalActor(Actor, "registeredActor2");
handle.addTabActor(Actor, "registeredActor2");
}
exports.unregister = function(handle) {
}

View File

@ -0,0 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const Profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
function check_actors(expect) {
do_check_eq(expect, DebuggerServer.tabActorFactories.hasOwnProperty("registeredActor1"));
do_check_eq(expect, DebuggerServer.tabActorFactories.hasOwnProperty("registeredActor2"));
do_check_eq(expect, DebuggerServer.globalActorFactories.hasOwnProperty("registeredActor2"));
do_check_eq(expect, DebuggerServer.globalActorFactories.hasOwnProperty("registeredActor1"));
}
function run_test()
{
DebuggerServer.init(function () { return true; });
// The xpcshell-test/ path maps to resource://test/
DebuggerServer.registerModule("xpcshell-test/registertestactors-01");
DebuggerServer.registerModule("xpcshell-test/registertestactors-02");
check_actors(true);
check_except(() => {
DebuggerServer.registerModule("xpcshell-test/registertestactors-01");
});
check_except(() => {
DebuggerServer.registerModule("xpcshell-test/registertestactors-02");
});
DebuggerServer.unregisterModule("xpcshell-test/registertestactors-01");
DebuggerServer.unregisterModule("xpcshell-test/registertestactors-02");
check_actors(false);
DebuggerServer.registerModule("xpcshell-test/registertestactors-01");
DebuggerServer.registerModule("xpcshell-test/registertestactors-02");
check_actors(true);
DebuggerServer.destroy();
check_actors(false);
}

View File

@ -42,6 +42,7 @@ reason = bug 821285
[test_eval-04.js]
[test_eval-05.js]
[test_breakpoint-01.js]
[test_register_actor.js]
skip-if = toolkit == "gonk"
reason = bug 820380
[test_breakpoint-02.js]