mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-22 02:09:28 +00:00
Bug 1212797 - Show all registered service workers in about:debugging. r=ochameau
This commit is contained in:
parent
ea10bbdb0c
commit
eb7e62b31c
@ -26,47 +26,60 @@ const Strings = Services.strings.createBundle(
|
||||
exports.Target = React.createClass({
|
||||
displayName: "Target",
|
||||
|
||||
debug() {
|
||||
let { client, target } = this.props;
|
||||
switch (target.type) {
|
||||
case "extension":
|
||||
BrowserToolboxProcess.init({ addonID: target.addonID });
|
||||
break;
|
||||
case "serviceworker":
|
||||
// Fall through.
|
||||
case "sharedworker":
|
||||
// Fall through.
|
||||
case "worker":
|
||||
let workerActor = this.props.target.actorID;
|
||||
client.attachWorker(workerActor, (response, workerClient) => {
|
||||
gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
|
||||
"jsdebugger", Toolbox.HostType.WINDOW)
|
||||
.then(toolbox => {
|
||||
toolbox.once("destroy", () => workerClient.detach());
|
||||
});
|
||||
});
|
||||
break;
|
||||
default:
|
||||
alert("Not implemented yet!");
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
let { target, debugDisabled } = this.props;
|
||||
let isServiceWorker = (target.type === "serviceworker");
|
||||
let isRunning = (!isServiceWorker || target.workerActor);
|
||||
return React.createElement("div", { className: "target" },
|
||||
React.createElement("img", {
|
||||
className: "target-icon",
|
||||
role: "presentation",
|
||||
src: target.icon }),
|
||||
React.createElement("div", { className: "target-details" },
|
||||
React.createElement("div", { className: "target-name" }, target.name),
|
||||
React.createElement("div", { className: "target-url" }, target.url)
|
||||
React.createElement("div", { className: "target-name" }, target.name)
|
||||
),
|
||||
React.createElement("button", {
|
||||
className: "debug-button",
|
||||
onClick: this.debug,
|
||||
disabled: debugDisabled,
|
||||
}, Strings.GetStringFromName("debug"))
|
||||
(isRunning ?
|
||||
React.createElement("button", {
|
||||
className: "debug-button",
|
||||
onClick: this.debug,
|
||||
disabled: debugDisabled,
|
||||
}, Strings.GetStringFromName("debug")) :
|
||||
null
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
debug() {
|
||||
let { target } = this.props;
|
||||
switch (target.type) {
|
||||
case "extension":
|
||||
BrowserToolboxProcess.init({ addonID: target.addonID });
|
||||
break;
|
||||
case "serviceworker":
|
||||
if (target.workerActor) {
|
||||
this.openWorkerToolbox(target.workerActor);
|
||||
}
|
||||
break;
|
||||
case "sharedworker":
|
||||
this.openWorkerToolbox(target.workerActor);
|
||||
break;
|
||||
case "worker":
|
||||
this.openWorkerToolbox(target.workerActor);
|
||||
break;
|
||||
default:
|
||||
alert("Not implemented yet!");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
openWorkerToolbox(workerActor) {
|
||||
let { client } = this.props;
|
||||
client.attachWorker(workerActor, (response, workerClient) => {
|
||||
gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
|
||||
"jsdebugger", Toolbox.HostType.WINDOW)
|
||||
.then(toolbox => {
|
||||
toolbox.once("destroy", () => workerClient.detach());
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -38,6 +38,7 @@ exports.WorkersTab = React.createClass({
|
||||
componentDidMount() {
|
||||
let client = this.props.client;
|
||||
client.addListener("workerListChanged", this.update);
|
||||
client.addListener("serviceWorkerRegistrationListChanged", this.update);
|
||||
client.addListener("processListChanged", this.update);
|
||||
this.update();
|
||||
},
|
||||
@ -45,6 +46,7 @@ exports.WorkersTab = React.createClass({
|
||||
componentWillUnmount() {
|
||||
let client = this.props.client;
|
||||
client.removeListener("processListChanged", this.update);
|
||||
client.removeListener("serviceWorkerRegistrationListChanged", this.update);
|
||||
client.removeListener("workerListChanged", this.update);
|
||||
},
|
||||
|
||||
@ -77,52 +79,90 @@ exports.WorkersTab = React.createClass({
|
||||
|
||||
update() {
|
||||
let workers = this.getInitialState().workers;
|
||||
|
||||
this.getWorkerForms().then(forms => {
|
||||
forms.forEach(form => {
|
||||
let worker = {
|
||||
name: form.url,
|
||||
forms.registrations.forEach(form => {
|
||||
workers.service.push({
|
||||
type: "serviceworker",
|
||||
icon: WorkerIcon,
|
||||
actorID: form.actor
|
||||
name: form.url,
|
||||
url: form.url,
|
||||
scope: form.scope,
|
||||
registrationActor: form.actor
|
||||
});
|
||||
});
|
||||
|
||||
forms.workers.forEach(form => {
|
||||
let worker = {
|
||||
type: "worker",
|
||||
icon: WorkerIcon,
|
||||
name: form.url,
|
||||
url: form.url,
|
||||
workerActor: form.actor
|
||||
};
|
||||
switch (form.type) {
|
||||
case Ci.nsIWorkerDebugger.TYPE_SERVICE:
|
||||
worker.type = "serviceworker";
|
||||
workers.service.push(worker);
|
||||
for (let registration of workers.service) {
|
||||
if (registration.scope === form.scope) {
|
||||
// XXX: Race, sometimes a ServiceWorkerRegistrationInfo doesn't
|
||||
// have a scriptSpec, but its associated WorkerDebugger does.
|
||||
if (!registration.url) {
|
||||
registration.name = registration.url = form.url;
|
||||
}
|
||||
registration.workerActor = form.actor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Ci.nsIWorkerDebugger.TYPE_SHARED:
|
||||
worker.type = "sharedworker";
|
||||
workers.shared.push(worker);
|
||||
break;
|
||||
default:
|
||||
worker.type = "worker";
|
||||
workers.other.push(worker);
|
||||
}
|
||||
});
|
||||
|
||||
// XXX: Filter out the service worker registrations for which we couldn't
|
||||
// find the scriptSpec.
|
||||
workers.service = workers.service.filter(reg => !!reg.url);
|
||||
|
||||
this.setState({ workers });
|
||||
});
|
||||
},
|
||||
|
||||
getWorkerForms: Task.async(function*() {
|
||||
let client = this.props.client;
|
||||
let registrations = [];
|
||||
let workers = [];
|
||||
|
||||
// List workers from the Parent process
|
||||
let result = yield client.mainRoot.listWorkers();
|
||||
let forms = result.workers;
|
||||
try {
|
||||
// List service worker registrations
|
||||
({ registrations } =
|
||||
yield client.mainRoot.listServiceWorkerRegistrations());
|
||||
|
||||
// And then from the Child processes
|
||||
let { processes } = yield client.mainRoot.listProcesses();
|
||||
for (let process of processes) {
|
||||
// Ignore parent process
|
||||
if (process.parent) {
|
||||
continue;
|
||||
// List workers from the Parent process
|
||||
({ workers } = yield client.mainRoot.listWorkers());
|
||||
|
||||
// And then from the Child processes
|
||||
let { processes } = yield client.mainRoot.listProcesses();
|
||||
for (let process of processes) {
|
||||
// Ignore parent process
|
||||
if (process.parent) {
|
||||
continue;
|
||||
}
|
||||
let { form } = yield client.getProcess(process.id);
|
||||
let processActor = form.actor;
|
||||
let response = yield client.request({
|
||||
to: processActor,
|
||||
type: "listWorkers"
|
||||
});
|
||||
workers = workers.concat(response.workers);
|
||||
}
|
||||
let { form } = yield client.getProcess(process.id);
|
||||
let processActor = form.actor;
|
||||
let { workers } = yield client.request({to: processActor,
|
||||
type: "listWorkers"});
|
||||
forms = forms.concat(workers);
|
||||
} catch (e) {
|
||||
// Something went wrong, maybe our client is disconnected?
|
||||
}
|
||||
|
||||
return forms;
|
||||
return { registrations, workers };
|
||||
}),
|
||||
});
|
||||
|
@ -67,7 +67,8 @@ add_task(function* () {
|
||||
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||
let name = names.filter(element => element.textContent === SERVICE_WORKER)[0];
|
||||
ok(name, "Found the service worker in the list");
|
||||
let debugBtn = name.parentNode.parentNode.querySelector("button");
|
||||
let targetElement = name.parentNode.parentNode;
|
||||
let debugBtn = targetElement.querySelector(".debug-button");
|
||||
ok(debugBtn, "Found its debug button");
|
||||
|
||||
// Click on it and wait for the toolbox to be ready
|
||||
@ -88,16 +89,18 @@ add_task(function* () {
|
||||
});
|
||||
|
||||
assertHasWorker(true, document, "service-workers", SERVICE_WORKER);
|
||||
ok(targetElement.querySelector(".debug-button"),
|
||||
"The debug button is still there");
|
||||
|
||||
yield toolbox.destroy();
|
||||
toolbox = null;
|
||||
|
||||
// Now ensure that the worker is correctly destroyed
|
||||
// after we destroy the toolbox.
|
||||
// The list should update once it get destroyed.
|
||||
yield waitForMutation(serviceWorkersElement, { childList: true });
|
||||
|
||||
assertHasWorker(false, document, "service-workers", SERVICE_WORKER);
|
||||
// The DEBUG button should disappear once the worker is destroyed.
|
||||
yield waitForMutation(targetElement, { childList: true });
|
||||
ok(!targetElement.querySelector(".debug-button"),
|
||||
"The debug button was removed when the worker was killed");
|
||||
|
||||
// Finally, unregister the service worker itself
|
||||
// Use message manager to work with e10s
|
||||
@ -124,6 +127,11 @@ add_task(function* () {
|
||||
});
|
||||
ok(true, "Service worker registration unregistered");
|
||||
|
||||
// Now ensure that the worker registration is correctly removed.
|
||||
// The list should update once the registration is destroyed.
|
||||
yield waitForMutation(serviceWorkersElement, { childList: true });
|
||||
assertHasWorker(false, document, "service-workers", SERVICE_WORKER);
|
||||
|
||||
yield removeTab(swTab);
|
||||
yield closeAboutDebugging(tab);
|
||||
});
|
||||
|
@ -53,12 +53,17 @@ let WorkerActor = protocol.ActorClass({
|
||||
if (detail === "actorid") {
|
||||
return this.actorID;
|
||||
}
|
||||
return {
|
||||
let form = {
|
||||
actor: this.actorID,
|
||||
consoleActor: this._consoleActor,
|
||||
url: this._dbg.url,
|
||||
type: this._dbg.type
|
||||
};
|
||||
if (this._dbg.type === Ci.nsIWorkerDebugger.TYPE_SERVICE) {
|
||||
let registration = this._getServiceWorkerRegistrationInfo();
|
||||
form.scope = registration.scope;
|
||||
}
|
||||
return form;
|
||||
},
|
||||
|
||||
attach: method(function () {
|
||||
|
Loading…
x
Reference in New Issue
Block a user