mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1225473 - Support Service workers in child process. r=janx
This commit is contained in:
parent
ccf55f2114
commit
5affcaefe8
@ -27,7 +27,7 @@ exports.TargetListComponent = React.createClass({
|
||||
return React.createElement(TargetComponent, { client, target });
|
||||
});
|
||||
return (
|
||||
React.createElement("div", { className: "targets" },
|
||||
React.createElement("div", { id: this.props.id, className: "targets" },
|
||||
React.createElement("h4", null, this.props.name),
|
||||
targets.length > 0 ? targets :
|
||||
React.createElement("p", null, Strings.GetStringFromName("nothing"))
|
||||
|
@ -14,6 +14,8 @@ loader.lazyRequireGetter(this, "TargetListComponent",
|
||||
"devtools/client/aboutdebugging/components/target-list", true);
|
||||
loader.lazyRequireGetter(this, "Services");
|
||||
|
||||
loader.lazyImporter(this, "Task", "resource://gre/modules/Task.jsm");
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
|
||||
@ -32,12 +34,16 @@ exports.WorkersComponent = React.createClass({
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
this.props.client.addListener("workerListChanged", this.update);
|
||||
let client = this.props.client;
|
||||
client.addListener("workerListChanged", this.update);
|
||||
client.addListener("processListChanged", this.update);
|
||||
this.update();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.client.removeListener("workerListChanged", this.update);
|
||||
let client = this.props.client;
|
||||
client.removeListener("processListChanged", this.update);
|
||||
client.removeListener("workerListChanged", this.update);
|
||||
},
|
||||
|
||||
render() {
|
||||
@ -45,22 +51,23 @@ exports.WorkersComponent = React.createClass({
|
||||
let workers = this.state.workers;
|
||||
return React.createElement("div", { className: "inverted-icons" },
|
||||
React.createElement(TargetListComponent, {
|
||||
id: "service-workers",
|
||||
name: Strings.GetStringFromName("serviceWorkers"),
|
||||
targets: workers.service, client }),
|
||||
React.createElement(TargetListComponent, {
|
||||
id: "shared-workers",
|
||||
name: Strings.GetStringFromName("sharedWorkers"),
|
||||
targets: workers.shared, client }),
|
||||
React.createElement(TargetListComponent, {
|
||||
id: "other-workers",
|
||||
name: Strings.GetStringFromName("otherWorkers"),
|
||||
targets: workers.other, client })
|
||||
);
|
||||
},
|
||||
|
||||
update() {
|
||||
let client = this.props.client;
|
||||
let workers = this.getInitialState().workers;
|
||||
client.mainRoot.listWorkers(response => {
|
||||
let forms = response.workers;
|
||||
this.getWorkerForms().then(forms => {
|
||||
forms.forEach(form => {
|
||||
let worker = {
|
||||
name: form.url,
|
||||
@ -83,5 +90,29 @@ exports.WorkersComponent = React.createClass({
|
||||
});
|
||||
this.setState({ workers });
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getWorkerForms: Task.async(function*() {
|
||||
let client = this.props.client;
|
||||
|
||||
// List workers from the Parent process
|
||||
let result = yield client.mainRoot.listWorkers();
|
||||
let forms = result.workers;
|
||||
|
||||
// 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 { workers } = yield client.request({to: processActor,
|
||||
type: "listWorkers"});
|
||||
forms = forms.concat(workers);
|
||||
}
|
||||
|
||||
return forms;
|
||||
}),
|
||||
});
|
||||
|
@ -5,5 +5,8 @@ support-files =
|
||||
head.js
|
||||
addons/unpacked/bootstrap.js
|
||||
addons/unpacked/install.rdf
|
||||
service-workers/empty-sw.html
|
||||
service-workers/empty-sw.js
|
||||
|
||||
[browser_addons_install.js]
|
||||
[browser_service_workers.js]
|
||||
|
@ -0,0 +1,66 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Service workers can't be loaded from chrome://,
|
||||
// but http:// is ok with dom.serviceWorkers.testing.enabled turned on.
|
||||
const HTTP_ROOT = CHROME_ROOT.replace("chrome://mochitests/content/",
|
||||
"http://mochi.test:8888/");
|
||||
const SERVICE_WORKER = HTTP_ROOT + "service-workers/empty-sw.js";
|
||||
const TAB_URL = HTTP_ROOT + "service-workers/empty-sw.html";
|
||||
|
||||
function waitForWorkersUpdate(document) {
|
||||
return new Promise(done => {
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
observer.disconnect();
|
||||
done();
|
||||
});
|
||||
var target = document.getElementById("service-workers");
|
||||
observer.observe(target, { childList: true });
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function *() {
|
||||
yield new Promise(done => {
|
||||
let options = {"set": [
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
]};
|
||||
SpecialPowers.pushPrefEnv(options, done);
|
||||
});
|
||||
|
||||
let { tab, document } = yield openAboutDebugging("workers");
|
||||
|
||||
let swTab = yield addTab(TAB_URL);
|
||||
|
||||
yield waitForWorkersUpdate(document);
|
||||
|
||||
// Check that the service worker appears in the UI
|
||||
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||
names = names.map(element => element.textContent);
|
||||
ok(names.includes(SERVICE_WORKER), "The service worker url appears in the list: " + names);
|
||||
|
||||
// Use message manager to work with e10s
|
||||
let frameScript = function () {
|
||||
// Retrieve the `sw` promise created in the html page
|
||||
let { sw } = content.wrappedJSObject;
|
||||
sw.then(function (registration) {
|
||||
registration.unregister().then(function (success) {
|
||||
dump("SW unregistered: " + success + "\n");
|
||||
},
|
||||
function (e) {
|
||||
dump("SW not unregistered; " + e + "\n");
|
||||
});
|
||||
});
|
||||
};
|
||||
swTab.linkedBrowser.messageManager.loadFrameScript("data:,(" + encodeURIComponent(frameScript) + ")()", true);
|
||||
|
||||
yield waitForWorkersUpdate(document);
|
||||
|
||||
// Check that the service worker disappeared from the UI
|
||||
names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||
names = names.map(element => element.textContent);
|
||||
ok(!names.includes(SERVICE_WORKER), "The service worker url is no longer in the list: " + names);
|
||||
|
||||
yield removeTab(swTab);
|
||||
yield closeAboutDebugging(tab);
|
||||
});
|
@ -16,9 +16,13 @@ registerCleanupFunction(() => {
|
||||
DevToolsUtils.testing = false;
|
||||
});
|
||||
|
||||
function openAboutDebugging() {
|
||||
function openAboutDebugging(page) {
|
||||
info("opening about:debugging");
|
||||
return addTab("about:debugging").then(tab => {
|
||||
let url = "about:debugging";
|
||||
if (page) {
|
||||
url += "#" + page;
|
||||
}
|
||||
return addTab(url).then(tab => {
|
||||
let browser = tab.linkedBrowser;
|
||||
return {
|
||||
tab,
|
||||
|
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Service worker test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var sw = navigator.serviceWorker.register("empty-sw.js");
|
||||
sw.then(
|
||||
function (registration) {
|
||||
dump("SW registered\n");
|
||||
},
|
||||
function (e) {
|
||||
dump("SW not registered: " + e + "\n");
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1 @@
|
||||
// Empty, just test registering.
|
@ -14,6 +14,8 @@ const Services = require("Services");
|
||||
const { assert } = require("devtools/shared/DevToolsUtils");
|
||||
const { TabSources } = require("./utils/TabSources");
|
||||
|
||||
loader.lazyRequireGetter(this, "WorkerActorList", "devtools/server/actors/worker", true);
|
||||
|
||||
function ChildProcessActor(aConnection) {
|
||||
this.conn = aConnection;
|
||||
this._contextPool = new ActorPool(this.conn);
|
||||
@ -32,6 +34,10 @@ function ChildProcessActor(aConnection) {
|
||||
.createInstance(Ci.nsIPrincipal);
|
||||
let sandbox = Cu.Sandbox(systemPrincipal);
|
||||
this._consoleScope = sandbox;
|
||||
|
||||
this._workerList = null;
|
||||
this._workerActorPool = null;
|
||||
this._onWorkerListChanged = this._onWorkerListChanged.bind(this);
|
||||
}
|
||||
exports.ChildProcessActor = ChildProcessActor;
|
||||
|
||||
@ -87,9 +93,42 @@ ChildProcessActor.prototype = {
|
||||
};
|
||||
},
|
||||
|
||||
onListWorkers: function () {
|
||||
if (!this._workerList) {
|
||||
this._workerList = new WorkerActorList({});
|
||||
}
|
||||
return this._workerList.getList().then(actors => {
|
||||
let pool = new ActorPool(this.conn);
|
||||
for (let actor of actors) {
|
||||
pool.addActor(actor);
|
||||
}
|
||||
|
||||
this.conn.removeActorPool(this._workerActorPool);
|
||||
this._workerActorPool = pool;
|
||||
this.conn.addActorPool(this._workerActorPool);
|
||||
|
||||
this._workerList.onListChanged = this._onWorkerListChanged;
|
||||
|
||||
return {
|
||||
"from": this.actorID,
|
||||
"workers": actors.map(actor => actor.form())
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
_onWorkerListChanged: function () {
|
||||
this.conn.send({ from: this.actorID, type: "workerListChanged" });
|
||||
this._workerList.onListChanged = null;
|
||||
},
|
||||
|
||||
disconnect: function() {
|
||||
this.conn.removeActorPool(this._contextPool);
|
||||
this._contextPool = null;
|
||||
|
||||
// Tell the live lists we aren't watching any more.
|
||||
if (this._workerList) {
|
||||
this._workerList.onListChanged = null;
|
||||
}
|
||||
},
|
||||
|
||||
preNest: function() {
|
||||
@ -103,4 +142,5 @@ ChildProcessActor.prototype = {
|
||||
};
|
||||
|
||||
ChildProcessActor.prototype.requestTypes = {
|
||||
"listWorkers": ChildProcessActor.prototype.onListWorkers,
|
||||
};
|
||||
|
@ -207,6 +207,9 @@ RootActor.prototype = {
|
||||
if (this._parameters.addonList) {
|
||||
this._parameters.addonList.onListChanged = null;
|
||||
}
|
||||
if (this._parameters.workerList) {
|
||||
this._parameters.workerList.onListChanged = null;
|
||||
}
|
||||
if (typeof this._parameters.onShutdown === 'function') {
|
||||
this._parameters.onShutdown();
|
||||
}
|
||||
|
@ -193,6 +193,9 @@ WorkerActorList.prototype = {
|
||||
if (typeof onListChanged !== "function" && onListChanged !== null) {
|
||||
throw new Error("onListChanged must be either a function or null.");
|
||||
}
|
||||
if (onListChanged === this._onListChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._mustNotify) {
|
||||
if (this._onListChanged === null && onListChanged !== null) {
|
||||
|
@ -13,14 +13,7 @@ const { DevToolsLoader } = Cu.import("resource://devtools/shared/Loader.jsm", {}
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["init"];
|
||||
|
||||
var started = false;
|
||||
|
||||
function init(msg) {
|
||||
if (started) {
|
||||
return;
|
||||
}
|
||||
started = true;
|
||||
|
||||
// Init a custom, invisible DebuggerServer, in order to not pollute
|
||||
// the debugger with all devtools modules, nor break the debugger itself with using it
|
||||
// in the same process.
|
||||
@ -61,6 +54,5 @@ function init(msg) {
|
||||
mm.removeMessageListener("debug:content-process-destroy", onDestroy);
|
||||
|
||||
DebuggerServer.destroy();
|
||||
started = false;
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user