forked from mirrors/gecko-dev
MozReview-Commit-ID: 2Qakr1PHKNZ --HG-- rename : devtools/client/debugger/test/mochitest/browser_dbg_WorkerActor.attach.js => devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attach.js rename : devtools/client/debugger/test/mochitest/browser_dbg_WorkerActor.attachThread.js => devtools/client/debugger/test/mochitest/browser_dbg_WorkerTargetActor.attachThread.js rename : devtools/client/debugger/test/mochitest/code_WorkerActor.attach-worker1.js => devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attach-worker1.js rename : devtools/client/debugger/test/mochitest/code_WorkerActor.attach-worker2.js => devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attach-worker2.js rename : devtools/client/debugger/test/mochitest/code_WorkerActor.attachThread-worker.js => devtools/client/debugger/test/mochitest/code_WorkerTargetActor.attachThread-worker.js rename : devtools/client/debugger/test/mochitest/doc_WorkerActor.attach-tab1.html => devtools/client/debugger/test/mochitest/doc_WorkerTargetActor.attach-tab1.html rename : devtools/client/debugger/test/mochitest/doc_WorkerActor.attach-tab2.html => devtools/client/debugger/test/mochitest/doc_WorkerTargetActor.attach-tab2.html rename : devtools/client/debugger/test/mochitest/doc_WorkerActor.attachThread-tab.html => devtools/client/debugger/test/mochitest/doc_WorkerTargetActor.attachThread-tab.html rename : devtools/server/actors/worker.js => devtools/server/actors/targets/worker.js rename : devtools/shared/specs/worker/worker.js => devtools/shared/specs/targets/worker.js extra : rebase_source : cc94b13a2e50db862bad9d7c518619052cc6e5b4
261 lines
7.9 KiB
JavaScript
261 lines
7.9 KiB
JavaScript
/* 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/. */
|
|
|
|
/* eslint-env browser */
|
|
|
|
"use strict";
|
|
|
|
const { Component } = require("devtools/client/shared/vendor/react");
|
|
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
|
const Services = require("Services");
|
|
|
|
loader.lazyRequireGetter(this, "DebuggerClient",
|
|
"devtools/shared/client/debugger-client", true);
|
|
loader.lazyRequireGetter(this, "gDevToolsBrowser",
|
|
"devtools/client/framework/devtools-browser", true);
|
|
|
|
const Strings = Services.strings.createBundle(
|
|
"chrome://devtools/locale/aboutdebugging.properties");
|
|
|
|
class ServiceWorkerTarget extends Component {
|
|
static get propTypes() {
|
|
return {
|
|
client: PropTypes.instanceOf(DebuggerClient).isRequired,
|
|
debugDisabled: PropTypes.bool,
|
|
target: PropTypes.shape({
|
|
active: PropTypes.bool,
|
|
fetch: PropTypes.bool.isRequired,
|
|
icon: PropTypes.string,
|
|
name: PropTypes.string.isRequired,
|
|
url: PropTypes.string,
|
|
scope: PropTypes.string.isRequired,
|
|
// registrationActor can be missing in e10s.
|
|
registrationActor: PropTypes.string,
|
|
workerTargetActor: PropTypes.string
|
|
}).isRequired
|
|
};
|
|
}
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.state = {
|
|
pushSubscription: null
|
|
};
|
|
|
|
this.debug = this.debug.bind(this);
|
|
this.push = this.push.bind(this);
|
|
this.start = this.start.bind(this);
|
|
this.unregister = this.unregister.bind(this);
|
|
this.onPushSubscriptionModified = this.onPushSubscriptionModified.bind(this);
|
|
this.updatePushSubscription = this.updatePushSubscription.bind(this);
|
|
this.isRunning = this.isRunning.bind(this);
|
|
this.isActive = this.isActive.bind(this);
|
|
this.getServiceWorkerStatus = this.getServiceWorkerStatus.bind(this);
|
|
this.renderButtons = this.renderButtons.bind(this);
|
|
this.renderUnregisterLink = this.renderUnregisterLink.bind(this);
|
|
}
|
|
|
|
componentDidMount() {
|
|
const { client } = this.props;
|
|
client.addListener("push-subscription-modified", this.onPushSubscriptionModified);
|
|
this.updatePushSubscription();
|
|
}
|
|
|
|
componentDidUpdate(oldProps, oldState) {
|
|
const wasActive = oldProps.target.active;
|
|
if (!wasActive && this.isActive()) {
|
|
// While the service worker isn't active, any calls to `updatePushSubscription`
|
|
// won't succeed. If we just became active, make sure we didn't miss a push
|
|
// subscription change by updating it now.
|
|
this.updatePushSubscription();
|
|
}
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
const { client } = this.props;
|
|
client.removeListener("push-subscription-modified", this.onPushSubscriptionModified);
|
|
}
|
|
|
|
debug() {
|
|
if (!this.isRunning()) {
|
|
// If the worker is not running, we can't debug it.
|
|
return;
|
|
}
|
|
|
|
const { client, target } = this.props;
|
|
gDevToolsBrowser.openWorkerToolbox(client, target.workerTargetActor);
|
|
}
|
|
|
|
push() {
|
|
if (!this.isActive() || !this.isRunning()) {
|
|
// If the worker is not running, we can't push to it.
|
|
// If the worker is not active, the registration might be unavailable and the
|
|
// push will not succeed.
|
|
return;
|
|
}
|
|
|
|
const { client, target } = this.props;
|
|
client.request({
|
|
to: target.workerTargetActor,
|
|
type: "push"
|
|
});
|
|
}
|
|
|
|
start() {
|
|
if (!this.isActive() || this.isRunning()) {
|
|
// If the worker is not active or if it is already running, we can't start it.
|
|
return;
|
|
}
|
|
|
|
const { client, target } = this.props;
|
|
client.request({
|
|
to: target.registrationActor,
|
|
type: "start"
|
|
});
|
|
}
|
|
|
|
unregister() {
|
|
const { client, target } = this.props;
|
|
client.request({
|
|
to: target.registrationActor,
|
|
type: "unregister"
|
|
});
|
|
}
|
|
|
|
onPushSubscriptionModified(type, data) {
|
|
const { target } = this.props;
|
|
if (data.from === target.registrationActor) {
|
|
this.updatePushSubscription();
|
|
}
|
|
}
|
|
|
|
updatePushSubscription() {
|
|
if (!this.props.target.registrationActor) {
|
|
// A valid registrationActor is needed to retrieve the push subscription.
|
|
return;
|
|
}
|
|
|
|
const { client, target } = this.props;
|
|
client.request({
|
|
to: target.registrationActor,
|
|
type: "getPushSubscription"
|
|
}, ({ subscription }) => {
|
|
this.setState({ pushSubscription: subscription });
|
|
});
|
|
}
|
|
|
|
isRunning() {
|
|
// We know the target is running if it has a worker actor.
|
|
return !!this.props.target.workerTargetActor;
|
|
}
|
|
|
|
isActive() {
|
|
return this.props.target.active;
|
|
}
|
|
|
|
getServiceWorkerStatus() {
|
|
if (this.isActive() && this.isRunning()) {
|
|
return "running";
|
|
} else if (this.isActive()) {
|
|
return "stopped";
|
|
}
|
|
// We cannot get service worker registrations unless the registration is in
|
|
// ACTIVE state. Unable to know the actual state ("installing", "waiting"), we
|
|
// display a custom state "registering" for now. See Bug 1153292.
|
|
return "registering";
|
|
}
|
|
|
|
renderButtons() {
|
|
const pushButton = dom.button({
|
|
className: "push-button",
|
|
onClick: this.push,
|
|
disabled: this.props.debugDisabled
|
|
}, Strings.GetStringFromName("push"));
|
|
|
|
const debugButton = dom.button({
|
|
className: "debug-button",
|
|
onClick: this.debug,
|
|
disabled: this.props.debugDisabled
|
|
}, Strings.GetStringFromName("debug"));
|
|
|
|
const startButton = dom.button({
|
|
className: "start-button",
|
|
onClick: this.start,
|
|
disabled: this.props.debugDisabled
|
|
}, Strings.GetStringFromName("start"));
|
|
|
|
if (this.isRunning()) {
|
|
if (this.isActive()) {
|
|
return [pushButton, debugButton];
|
|
}
|
|
// Only debug button is available if the service worker is not active.
|
|
return debugButton;
|
|
}
|
|
return startButton;
|
|
}
|
|
|
|
renderUnregisterLink() {
|
|
if (!this.isActive()) {
|
|
// If not active, there might be no registrationActor available.
|
|
return null;
|
|
}
|
|
|
|
return dom.a({
|
|
onClick: this.unregister,
|
|
className: "unregister-link",
|
|
}, Strings.GetStringFromName("unregister"));
|
|
}
|
|
|
|
render() {
|
|
const { target } = this.props;
|
|
const { pushSubscription } = this.state;
|
|
const status = this.getServiceWorkerStatus();
|
|
|
|
const fetch = target.fetch ? Strings.GetStringFromName("listeningForFetchEvents") :
|
|
Strings.GetStringFromName("notListeningForFetchEvents");
|
|
|
|
return dom.div({ className: "target-container" },
|
|
dom.img({
|
|
className: "target-icon",
|
|
role: "presentation",
|
|
src: target.icon
|
|
}),
|
|
dom.span({ className: `target-status target-status-${status}` },
|
|
Strings.GetStringFromName(status)),
|
|
dom.div({ className: "target" },
|
|
dom.div({ className: "target-name", title: target.name }, target.name),
|
|
dom.ul({ className: "target-details" },
|
|
(pushSubscription ?
|
|
dom.li({ className: "target-detail" },
|
|
dom.strong(null, Strings.GetStringFromName("pushService")),
|
|
dom.span({
|
|
className: "service-worker-push-url",
|
|
title: pushSubscription.endpoint
|
|
}, pushSubscription.endpoint)) :
|
|
null
|
|
),
|
|
dom.li({ className: "target-detail" },
|
|
dom.strong(null, Strings.GetStringFromName("fetch")),
|
|
dom.span({
|
|
className: "service-worker-fetch-flag",
|
|
title: fetch
|
|
}, fetch)),
|
|
dom.li({ className: "target-detail" },
|
|
dom.strong(null, Strings.GetStringFromName("scope")),
|
|
dom.span({
|
|
className: "service-worker-scope",
|
|
title: target.scope
|
|
}, target.scope),
|
|
this.renderUnregisterLink()
|
|
)
|
|
)
|
|
),
|
|
this.renderButtons()
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = ServiceWorkerTarget;
|