--- a/devtools/client/aboutdebugging/components/Aboutdebugging.js
+++ b/devtools/client/aboutdebugging/components/Aboutdebugging.js
@@ -1,17 +1,17 @@
/* 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 { createFactory, createClass, DOM: dom, PropTypes } =
+const { createFactory, Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const Services = require("Services");
const PanelMenu = createFactory(require("./PanelMenu"));
loader.lazyGetter(this, "AddonsPanel",
() => createFactory(require("./addons/Panel")));
loader.lazyGetter(this, "TabsPanel",
@@ -41,51 +41,56 @@ const panels = [{
id: "workers",
name: Strings.GetStringFromName("workers"),
icon: "chrome://devtools/skin/images/debugging-workers.svg",
component: WorkersPanel
}];
const defaultPanelId = "addons";
-module.exports = createClass({
- displayName: "AboutDebuggingApp",
+class AboutDebuggingApp extends Component {
+ static get propTypes() {
+ return {
+ client: PropTypes.instanceOf(DebuggerClient).isRequired,
+ telemetry: PropTypes.instanceOf(Telemetry).isRequired
+ };
+ }
- propTypes: {
- client: PropTypes.instanceOf(DebuggerClient).isRequired,
- telemetry: PropTypes.instanceOf(Telemetry).isRequired
- },
+ constructor(props) {
+ super(props);
- getInitialState() {
- return {
+ this.state = {
selectedPanelId: defaultPanelId
};
- },
+
+ this.onHashChange = this.onHashChange.bind(this);
+ this.selectPanel = this.selectPanel.bind(this);
+ }
componentDidMount() {
window.addEventListener("hashchange", this.onHashChange);
this.onHashChange();
this.props.telemetry.toolOpened("aboutdebugging");
- },
+ }
componentWillUnmount() {
window.removeEventListener("hashchange", this.onHashChange);
this.props.telemetry.toolClosed("aboutdebugging");
this.props.telemetry.destroy();
- },
+ }
onHashChange() {
this.setState({
selectedPanelId: window.location.hash.substr(1) || defaultPanelId
});
- },
+ }
selectPanel(panelId) {
window.location.hash = "#" + panelId;
- },
+ }
render() {
let { client } = this.props;
let { selectedPanelId } = this.state;
let selectPanel = this.selectPanel;
let selectedPanel = panels.find(p => p.id == selectedPanelId);
let panel;
@@ -103,9 +108,11 @@ module.exports = createClass({
);
}
return dom.div({ className: "app" },
PanelMenu({ panels, selectedPanelId, selectPanel }),
dom.div({ className: "main-content" }, panel)
);
}
-});
+}
+
+module.exports = AboutDebuggingApp;
--- a/devtools/client/aboutdebugging/components/PanelHeader.js
+++ b/devtools/client/aboutdebugging/components/PanelHeader.js
@@ -1,24 +1,26 @@
/* 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 { createClass, DOM: dom, PropTypes } =
+const { Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
-module.exports = createClass({
- displayName: "PanelHeader",
-
- propTypes: {
- id: PropTypes.string.isRequired,
- name: PropTypes.string.isRequired
- },
+class PanelHeader extends Component {
+ static get propTypes() {
+ return {
+ id: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired
+ };
+ }
render() {
let { name, id } = this.props;
return dom.div({ className: "header" },
dom.h1({ id, className: "header-name" }, name));
- },
-});
+ }
+}
+
+module.exports = PanelHeader;
--- a/devtools/client/aboutdebugging/components/PanelMenu.js
+++ b/devtools/client/aboutdebugging/components/PanelMenu.js
@@ -1,41 +1,43 @@
/* 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 { createClass, createFactory, DOM: dom, PropTypes } =
+const { Component, createFactory, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const PanelMenuEntry = createFactory(require("./PanelMenuEntry"));
-module.exports = createClass({
- displayName: "PanelMenu",
-
- propTypes: {
- panels: PropTypes.arrayOf(PropTypes.shape({
- id: PropTypes.string.isRequired,
- name: PropTypes.string.isRequired,
- icon: PropTypes.string.isRequired,
- component: PropTypes.func.isRequired
- })).isRequired,
- selectPanel: PropTypes.func.isRequired,
- selectedPanelId: PropTypes.string
- },
+class PanelMenu extends Component {
+ static get propTypes() {
+ return {
+ panels: PropTypes.arrayOf(PropTypes.shape({
+ id: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ icon: PropTypes.string.isRequired,
+ component: PropTypes.func.isRequired
+ })).isRequired,
+ selectPanel: PropTypes.func.isRequired,
+ selectedPanelId: PropTypes.string
+ };
+ }
render() {
let { panels, selectedPanelId, selectPanel } = this.props;
let panelLinks = panels.map(({ id, name, icon }) => {
let selected = id == selectedPanelId;
return PanelMenuEntry({
id,
name,
icon,
selected,
selectPanel
});
});
// "categories" id used for styling purposes
return dom.div({ id: "categories", role: "tablist" }, panelLinks);
- },
-});
+ }
+}
+
+module.exports = PanelMenu;
--- a/devtools/client/aboutdebugging/components/PanelMenuEntry.js
+++ b/devtools/client/aboutdebugging/components/PanelMenuEntry.js
@@ -1,31 +1,36 @@
/* 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 { createClass, DOM: dom, PropTypes } =
+const { Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
-module.exports = createClass({
- displayName: "PanelMenuEntry",
+class PanelMenuEntry extends Component {
+ static get propTypes() {
+ return {
+ icon: PropTypes.string.isRequired,
+ id: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ selected: PropTypes.bool,
+ selectPanel: PropTypes.func.isRequired
+ };
+ }
- propTypes: {
- icon: PropTypes.string.isRequired,
- id: PropTypes.string.isRequired,
- name: PropTypes.string.isRequired,
- selected: PropTypes.bool,
- selectPanel: PropTypes.func.isRequired
- },
+ constructor(props) {
+ super(props);
+ this.onClick = this.onClick.bind(this);
+ }
onClick() {
this.props.selectPanel(this.props.id);
- },
+ }
render() {
let { id, name, icon, selected } = this.props;
// Here .category, .category-icon, .category-name classnames are used to
// apply common styles defined.
let className = "category" + (selected ? " selected" : "");
return dom.button({
@@ -33,9 +38,11 @@ module.exports = createClass({
"aria-controls": id + "-panel",
className,
onClick: this.onClick,
tabIndex: "0",
role: "tab" },
dom.img({ className: "category-icon", src: icon, role: "presentation" }),
dom.div({ className: "category-name" }, name));
}
-});
+}
+
+module.exports = PanelMenuEntry;
--- a/devtools/client/aboutdebugging/components/TargetList.js
+++ b/devtools/client/aboutdebugging/components/TargetList.js
@@ -1,41 +1,41 @@
/* 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 { createClass, DOM: dom, PropTypes } =
+const { Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const Services = require("Services");
loader.lazyRequireGetter(this, "DebuggerClient",
"devtools/shared/client/debugger-client", true);
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
const LocaleCompare = (a, b) => {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
};
-module.exports = createClass({
- displayName: "TargetList",
-
- propTypes: {
- client: PropTypes.instanceOf(DebuggerClient).isRequired,
- debugDisabled: PropTypes.bool,
- error: PropTypes.node,
- id: PropTypes.string.isRequired,
- name: PropTypes.string,
- sort: PropTypes.bool,
- targetClass: PropTypes.func.isRequired,
- targets: PropTypes.arrayOf(PropTypes.object).isRequired
- },
+class TargetList extends Component {
+ static get propTypes() {
+ return {
+ client: PropTypes.instanceOf(DebuggerClient).isRequired,
+ debugDisabled: PropTypes.bool,
+ error: PropTypes.node,
+ id: PropTypes.string.isRequired,
+ name: PropTypes.string,
+ sort: PropTypes.bool,
+ targetClass: PropTypes.func.isRequired,
+ targets: PropTypes.arrayOf(PropTypes.object).isRequired
+ };
+ }
render() {
let { client, debugDisabled, error, targetClass, targets, sort } = this.props;
if (sort) {
targets = targets.sort(LocaleCompare);
}
targets = targets.map(target => {
return targetClass({ client, target, debugDisabled });
@@ -47,10 +47,12 @@ module.exports = createClass({
} else if (targets.length > 0) {
content = dom.ul({ className: "target-list" }, targets);
} else {
content = dom.p(null, Strings.GetStringFromName("nothing"));
}
return dom.div({ id: this.props.id, className: "targets" },
dom.h2(null, this.props.name), content);
- },
-});
+ }
+}
+
+module.exports = TargetList;
--- a/devtools/client/aboutdebugging/components/addons/Controls.js
+++ b/devtools/client/aboutdebugging/components/addons/Controls.js
@@ -6,45 +6,52 @@
/* globals AddonManager */
"use strict";
loader.lazyImporter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
const { Cc, Ci } = require("chrome");
-const { createFactory, createClass, DOM: dom, PropTypes } =
+const { createFactory, Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const Services = require("Services");
const AddonsInstallError = createFactory(require("./InstallError"));
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
const MORE_INFO_URL = "https://developer.mozilla.org/docs/Tools" +
"/about:debugging#Enabling_add-on_debugging";
-module.exports = createClass({
- displayName: "AddonsControls",
+class AddonsControls extends Component {
+ static get propTypes() {
+ return {
+ debugDisabled: PropTypes.bool
+ };
+ }
- propTypes: {
- debugDisabled: PropTypes.bool
- },
+ constructor(props) {
+ super(props);
- getInitialState() {
- return {
+ this.state = {
installError: null,
};
- },
+
+ this.onEnableAddonDebuggingChange = this.onEnableAddonDebuggingChange.bind(this);
+ this.loadAddonFromFile = this.loadAddonFromFile.bind(this);
+ this.retryInstall = this.retryInstall.bind(this);
+ this.installAddon = this.installAddon.bind(this);
+ }
onEnableAddonDebuggingChange(event) {
let enabled = event.target.checked;
Services.prefs.setBoolPref("devtools.chrome.enabled", enabled);
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", enabled);
- },
+ }
loadAddonFromFile() {
this.setState({ installError: null });
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window,
Strings.GetStringFromName("selectAddonFromFile2"),
Ci.nsIFilePicker.modeOpen);
fp.open(res => {
@@ -55,33 +62,33 @@ module.exports = createClass({
// AddonManager.installTemporaryAddon accepts either
// addon directory or final xpi file.
if (!file.isDirectory() && !file.leafName.endsWith(".xpi")) {
file = file.parent;
}
this.installAddon(file);
});
- },
+ }
retryInstall() {
this.setState({ installError: null });
this.installAddon(this.state.lastInstallErrorFile);
- },
+ }
installAddon(file) {
AddonManager.installTemporaryAddon(file)
.then(() => {
this.setState({ lastInstallErrorFile: null });
})
.catch(e => {
console.error(e);
this.setState({ installError: e.message, lastInstallErrorFile: file });
});
- },
+ }
render() {
let { debugDisabled } = this.props;
return dom.div({ className: "addons-top" },
dom.div({ className: "addons-controls" },
dom.div({ className: "addons-options toggle-container-with-text" },
dom.input({
@@ -105,9 +112,11 @@ module.exports = createClass({
onClick: this.loadAddonFromFile,
}, Strings.GetStringFromName("loadTemporaryAddon"))
),
AddonsInstallError({
error: this.state.installError,
retryInstall: this.retryInstall,
}));
}
-});
+}
+
+module.exports = AddonsControls;
--- a/devtools/client/aboutdebugging/components/addons/InstallError.js
+++ b/devtools/client/aboutdebugging/components/addons/InstallError.js
@@ -1,29 +1,29 @@
/* 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 { createClass, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react");
+const { Component, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react");
const Services = require("Services");
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
-module.exports = createClass({
- displayName: "AddonsInstallError",
-
- propTypes: {
- error: PropTypes.string,
- retryInstall: PropTypes.func,
- },
+class AddonsInstallError extends Component {
+ static get propTypes() {
+ return {
+ error: PropTypes.string,
+ retryInstall: PropTypes.func,
+ };
+ }
render() {
if (!this.props.error) {
return null;
}
let text = `There was an error during installation: ${this.props.error}`;
return dom.div(
{ className: "addons-install-error" },
@@ -31,9 +31,11 @@ module.exports = createClass({
{},
dom.div({ className: "warning" }),
dom.span({}, text),
),
dom.button(
{ className: "addons-install-retry", onClick: this.props.retryInstall },
Strings.GetStringFromName("retryTemporaryInstall")));
}
-});
+}
+
+module.exports = AddonsInstallError;
--- a/devtools/client/aboutdebugging/components/addons/Panel.js
+++ b/devtools/client/aboutdebugging/components/addons/Panel.js
@@ -1,17 +1,17 @@
/* 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 { AddonManager } = require("resource://gre/modules/AddonManager.jsm");
const { Management } = require("resource://gre/modules/Extension.jsm");
-const { createFactory, createClass, DOM: dom, PropTypes } =
+const { createFactory, Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const Services = require("Services");
const AddonsControls = createFactory(require("./Controls"));
const AddonTarget = createFactory(require("./Target"));
const PanelHeader = createFactory(require("../PanelHeader"));
const TargetList = createFactory(require("../TargetList"));
@@ -22,63 +22,72 @@ const Strings = Services.strings.createB
"chrome://devtools/locale/aboutdebugging.properties");
const ExtensionIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
const CHROME_ENABLED_PREF = "devtools.chrome.enabled";
const REMOTE_ENABLED_PREF = "devtools.debugger.remote-enabled";
const WEB_EXT_URL = "https://developer.mozilla.org/Add-ons" +
"/WebExtensions/Getting_started_with_web-ext";
-module.exports = createClass({
- displayName: "AddonsPanel",
+class AddonsPanel extends Component {
+ static get propTypes() {
+ return {
+ client: PropTypes.instanceOf(DebuggerClient).isRequired,
+ id: PropTypes.string.isRequired
+ };
+ }
- propTypes: {
- client: PropTypes.instanceOf(DebuggerClient).isRequired,
- id: PropTypes.string.isRequired
- },
+ constructor(props) {
+ super(props);
- getInitialState() {
- return {
+ this.state = {
extensions: [],
debugDisabled: false,
};
- },
+
+ this.updateDebugStatus = this.updateDebugStatus.bind(this);
+ this.updateAddonsList = this.updateAddonsList.bind(this);
+ this.onInstalled = this.onInstalled.bind(this);
+ this.onUninstalled = this.onUninstalled.bind(this);
+ this.onEnabled = this.onEnabled.bind(this);
+ this.onDisabled = this.onDisabled.bind(this);
+ }
componentDidMount() {
AddonManager.addAddonListener(this);
// Listen to startup since that's when errors and warnings
// get populated on the extension.
Management.on("startup", this.updateAddonsList);
Services.prefs.addObserver(CHROME_ENABLED_PREF,
this.updateDebugStatus);
Services.prefs.addObserver(REMOTE_ENABLED_PREF,
this.updateDebugStatus);
this.updateDebugStatus();
this.updateAddonsList();
- },
+ }
componentWillUnmount() {
AddonManager.removeAddonListener(this);
Management.off("startup", this.updateAddonsList);
Services.prefs.removeObserver(CHROME_ENABLED_PREF,
this.updateDebugStatus);
Services.prefs.removeObserver(REMOTE_ENABLED_PREF,
this.updateDebugStatus);
- },
+ }
updateDebugStatus() {
let debugDisabled =
!Services.prefs.getBoolPref(CHROME_ENABLED_PREF) ||
!Services.prefs.getBoolPref(REMOTE_ENABLED_PREF);
this.setState({ debugDisabled });
- },
+ }
updateAddonsList() {
this.props.client.listAddons()
.then(({addons}) => {
let extensions = addons.filter(addon => addon.debuggable).map(addon => {
return {
name: addon.name,
icon: addon.iconURL || ExtensionIcon,
@@ -90,45 +99,45 @@ module.exports = createClass({
warnings: addon.warnings,
};
});
this.setState({ extensions });
}, error => {
throw new Error("Client error while listing addons: " + error);
});
- },
+ }
/**
* Mandatory callback as AddonManager listener.
*/
onInstalled() {
this.updateAddonsList();
- },
+ }
/**
* Mandatory callback as AddonManager listener.
*/
onUninstalled() {
this.updateAddonsList();
- },
+ }
/**
* Mandatory callback as AddonManager listener.
*/
onEnabled() {
this.updateAddonsList();
- },
+ }
/**
* Mandatory callback as AddonManager listener.
*/
onDisabled() {
this.updateAddonsList();
- },
+ }
render() {
let { client, id } = this.props;
let { debugDisabled, extensions: targets } = this.state;
let installedName = Strings.GetStringFromName("extensions");
let temporaryName = Strings.GetStringFromName("temporaryExtensions");
let targetClass = AddonTarget;
@@ -172,9 +181,11 @@ module.exports = createClass({
targets: installedTargets,
client,
debugDisabled,
targetClass,
sort: true
})
));
}
-});
+}
+
+module.exports = AddonsPanel;
--- a/devtools/client/aboutdebugging/components/addons/Target.js
+++ b/devtools/client/aboutdebugging/components/addons/Target.js
@@ -1,17 +1,17 @@
/* 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 { createClass, DOM: dom, PropTypes } =
+const { Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { debugAddon, isTemporaryID, parseFileUri, uninstallAddon } =
require("../../modules/addon");
const Services = require("Services");
loader.lazyImporter(this, "BrowserToolboxProcess",
"resource://devtools/client/framework/ToolboxProcess.jsm");
@@ -117,55 +117,62 @@ function infoMessages(target) {
function warningMessages(warnings = []) {
return warnings.map((warning) => {
return dom.li(
{ className: "addon-target-warning-message addon-target-message" },
warning);
});
}
-module.exports = createClass({
- displayName: "AddonTarget",
+class AddonTarget extends Component {
+ static get propTypes() {
+ return {
+ client: PropTypes.instanceOf(DebuggerClient).isRequired,
+ debugDisabled: PropTypes.bool,
+ target: PropTypes.shape({
+ addonActor: PropTypes.string.isRequired,
+ addonID: PropTypes.string.isRequired,
+ icon: PropTypes.string,
+ name: PropTypes.string.isRequired,
+ temporarilyInstalled: PropTypes.bool,
+ url: PropTypes.string,
+ warnings: PropTypes.array,
+ }).isRequired
+ };
+ }
- propTypes: {
- client: PropTypes.instanceOf(DebuggerClient).isRequired,
- debugDisabled: PropTypes.bool,
- target: PropTypes.shape({
- addonActor: PropTypes.string.isRequired,
- addonID: PropTypes.string.isRequired,
- icon: PropTypes.string,
- name: PropTypes.string.isRequired,
- temporarilyInstalled: PropTypes.bool,
- url: PropTypes.string,
- warnings: PropTypes.array,
- }).isRequired
- },
+ constructor(props) {
+ super(props);
+ this.debug = this.debug.bind(this);
+ this.uninstall = this.uninstall.bind(this);
+ this.reload = this.reload.bind(this);
+ }
debug() {
let { target } = this.props;
debugAddon(target.addonID);
- },
+ }
uninstall() {
let { target } = this.props;
uninstallAddon(target.addonID);
- },
+ }
reload() {
let { client, target } = this.props;
// This function sometimes returns a partial promise that only
// implements then().
client.request({
to: target.addonActor,
type: "reload"
}).then(() => {}, error => {
throw new Error(
"Error reloading addon " + target.addonID + ": " + error);
});
- },
+ }
render() {
let { target, debugDisabled } = this.props;
return dom.li(
{ className: "addon-target-container", "data-addon-id": target.addonID },
dom.div({ className: "target" },
dom.img({
@@ -200,9 +207,11 @@ module.exports = createClass({
? dom.button({
className: "uninstall-button addon-target-button",
onClick: this.uninstall,
}, Strings.GetStringFromName("remove"))
: null,
),
);
}
-});
+}
+
+module.exports = AddonTarget;
--- a/devtools/client/aboutdebugging/components/tabs/Panel.js
+++ b/devtools/client/aboutdebugging/components/tabs/Panel.js
@@ -1,54 +1,58 @@
/* 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 { createClass, createFactory, DOM: dom, PropTypes } =
+const { Component, createFactory, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const Services = require("Services");
const PanelHeader = createFactory(require("../PanelHeader"));
const TargetList = createFactory(require("../TargetList"));
const TabTarget = createFactory(require("./Target"));
loader.lazyRequireGetter(this, "DebuggerClient",
"devtools/shared/client/debugger-client", true);
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
-module.exports = createClass({
- displayName: "TabsPanel",
+class TabsPanel extends Component {
+ static get propTypes() {
+ return {
+ client: PropTypes.instanceOf(DebuggerClient).isRequired,
+ id: PropTypes.string.isRequired
+ };
+ }
- propTypes: {
- client: PropTypes.instanceOf(DebuggerClient).isRequired,
- id: PropTypes.string.isRequired
- },
+ constructor(props) {
+ super(props);
- getInitialState() {
- return {
+ this.state = {
tabs: []
};
- },
+
+ this.update = this.update.bind(this);
+ }
componentDidMount() {
let { client } = this.props;
client.addListener("tabListChanged", this.update);
this.update();
- },
+ }
componentWillUnmount() {
let { client } = this.props;
client.removeListener("tabListChanged", this.update);
- },
+ }
update() {
this.props.client.mainRoot.listTabs().then(({ tabs }) => {
// Filter out closed tabs (represented as `null`).
tabs = tabs.filter(tab => !!tab);
tabs.forEach(tab => {
// FIXME Also try to fetch low-res favicon. But we should use actor
// support for this to get the high-res one (bug 1061654).
@@ -63,17 +67,17 @@ module.exports = createClass({
}
tab.icon = prePath + "/favicon.ico";
} else {
tab.icon = "chrome://devtools/skin/images/globe.svg";
}
});
this.setState({ tabs });
});
- },
+ }
render() {
let { client, id } = this.props;
let { tabs } = this.state;
return dom.div({
id: id + "-panel",
className: "panel",
@@ -90,9 +94,11 @@ module.exports = createClass({
id: "tabs",
name: Strings.GetStringFromName("tabs"),
sort: false,
targetClass: TabTarget,
targets: tabs
})
));
}
-});
+}
+
+module.exports = TabsPanel;
--- a/devtools/client/aboutdebugging/components/tabs/Target.js
+++ b/devtools/client/aboutdebugging/components/tabs/Target.js
@@ -1,39 +1,44 @@
/* 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 { createClass, DOM: dom, PropTypes } =
+const { Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const Services = require("Services");
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
-module.exports = createClass({
- displayName: "TabTarget",
+class TabTarget extends Component {
+ static get propTypes() {
+ return {
+ target: PropTypes.shape({
+ icon: PropTypes.string,
+ outerWindowID: PropTypes.number.isRequired,
+ title: PropTypes.string,
+ url: PropTypes.string.isRequired
+ }).isRequired
+ };
+ }
- propTypes: {
- target: PropTypes.shape({
- icon: PropTypes.string,
- outerWindowID: PropTypes.number.isRequired,
- title: PropTypes.string,
- url: PropTypes.string.isRequired
- }).isRequired
- },
+ constructor(props) {
+ super(props);
+ this.debug = this.debug.bind(this);
+ }
debug() {
let { target } = this.props;
window.open("about:devtools-toolbox?type=tab&id=" + target.outerWindowID);
- },
+ }
render() {
let { target } = this.props;
return dom.div({ className: "target-container" },
dom.img({
className: "target-icon",
role: "presentation",
@@ -45,9 +50,11 @@ module.exports = createClass({
target.title || target.url)
),
dom.button({
className: "debug-button",
onClick: this.debug,
}, Strings.GetStringFromName("debug"))
);
}
-});
+}
+
+module.exports = TabTarget;
--- a/devtools/client/aboutdebugging/components/workers/MultiE10sWarning.js
+++ b/devtools/client/aboutdebugging/components/workers/MultiE10sWarning.js
@@ -3,43 +3,46 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env browser */
"use strict";
loader.lazyImporter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
-const { createClass, DOM: dom } =
+const { Component, DOM: dom } =
require("devtools/client/shared/vendor/react");
const Services = require("Services");
const { Ci } = require("chrome");
loader.lazyImporter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
loader.lazyRequireGetter(this, "DebuggerClient",
"devtools/shared/client/debugger-client", true);
const Strings = Services.strings.createBundle("chrome://devtools/locale/aboutdebugging.properties");
const MULTI_OPT_OUT_PREF = "dom.ipc.multiOptOut";
-module.exports = createClass({
- displayName: "multiE10SWarning",
+class multiE10SWarning extends Component {
+ constructor(props) {
+ super(props);
+ this.onUpdatePreferenceClick = this.onUpdatePreferenceClick.bind(this);
+ }
onUpdatePreferenceClick() {
let message = Strings.GetStringFromName("multiProcessWarningConfirmUpdate2");
if (window.confirm(message)) {
// Disable multi until at least the next experiment.
Services.prefs.setIntPref(MULTI_OPT_OUT_PREF,
Services.appinfo.E10S_MULTI_EXPERIMENT);
// Restart the browser.
Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
}
- },
+ }
render() {
return dom.div(
{
className: "service-worker-multi-process"
},
dom.div(
{},
@@ -53,10 +56,12 @@ module.exports = createClass({
dom.button(
{
className: "update-button",
onClick: this.onUpdatePreferenceClick,
},
Strings.GetStringFromName("multiProcessWarningUpdateLink2")
)
);
- },
-});
+ }
+}
+
+module.exports = multiE10SWarning;
--- a/devtools/client/aboutdebugging/components/workers/Panel.js
+++ b/devtools/client/aboutdebugging/components/workers/Panel.js
@@ -3,17 +3,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* globals window */
"use strict";
loader.lazyImporter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
const { Ci } = require("chrome");
-const { createClass, createFactory, DOM: dom, PropTypes } =
+const { Component, createFactory, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { getWorkerForms } = require("../../modules/worker");
const Services = require("Services");
const PanelHeader = createFactory(require("../PanelHeader"));
const TargetList = createFactory(require("../TargetList"));
const WorkerTarget = createFactory(require("./Target"));
const MultiE10SWarning = createFactory(require("./MultiE10sWarning"));
@@ -29,34 +29,35 @@ const Strings = Services.strings.createB
"chrome://devtools/locale/aboutdebugging.properties");
const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
const MORE_INFO_URL = "https://developer.mozilla.org/en-US/docs/Tools/about%3Adebugging" +
"#Service_workers_not_compatible";
const PROCESS_COUNT_PREF = "dom.ipc.processCount";
const MULTI_OPTOUT_PREF = "dom.ipc.multiOptOut";
-module.exports = createClass({
- displayName: "WorkersPanel",
-
- propTypes: {
- client: PropTypes.instanceOf(DebuggerClient).isRequired,
- id: PropTypes.string.isRequired
- },
+class WorkersPanel extends Component {
+ static get propTypes() {
+ return {
+ client: PropTypes.instanceOf(DebuggerClient).isRequired,
+ id: PropTypes.string.isRequired
+ };
+ }
- getInitialState() {
- return {
- workers: {
- service: [],
- shared: [],
- other: []
- },
- processCount: 1,
- };
- },
+ constructor(props) {
+ super(props);
+
+ this.updateMultiE10S = this.updateMultiE10S.bind(this);
+ this.updateWorkers = this.updateWorkers.bind(this);
+ this.getRegistrationForWorker = this.getRegistrationForWorker.bind(this);
+ this.isE10S = this.isE10S.bind(this);
+ this.renderServiceWorkersError = this.renderServiceWorkersError.bind(this);
+
+ this.state = this.initialState;
+ }
componentDidMount() {
let client = this.props.client;
client.addListener("workerListChanged", this.updateWorkers);
client.addListener("serviceWorkerRegistrationListChanged", this.updateWorkers);
client.addListener("processListChanged", this.updateWorkers);
client.addListener("registration-changed", this.updateWorkers);
@@ -72,38 +73,49 @@ module.exports = createClass({
// - In all cases, we don't have to manually check which pref changed to
// what. The platform code in nsIXULRuntime.maxWebProcessCount does all
// of that for us.
Services.prefs.addObserver(PROCESS_COUNT_PREF, this.updateMultiE10S);
Services.prefs.addObserver(MULTI_OPTOUT_PREF, this.updateMultiE10S);
this.updateMultiE10S();
this.updateWorkers();
- },
+ }
componentWillUnmount() {
let client = this.props.client;
client.removeListener("processListChanged", this.updateWorkers);
client.removeListener("serviceWorkerRegistrationListChanged", this.updateWorkers);
client.removeListener("workerListChanged", this.updateWorkers);
client.removeListener("registration-changed", this.updateWorkers);
Services.prefs.removeObserver(PROCESS_COUNT_PREF, this.updateMultiE10S);
Services.prefs.removeObserver(MULTI_OPTOUT_PREF, this.updateMultiE10S);
- },
+ }
+
+ get initialState() {
+ return {
+ workers: {
+ service: [],
+ shared: [],
+ other: []
+ },
+ processCount: 1,
+ };
+ }
updateMultiE10S() {
// We watch the pref but set the state based on
// nsIXULRuntime.maxWebProcessCount.
let processCount = Services.appinfo.maxWebProcessCount;
this.setState({ processCount });
- },
+ }
updateWorkers() {
- let workers = this.getInitialState().workers;
+ let workers = this.initialState.workers;
getWorkerForms(this.props.client).then(forms => {
forms.registrations.forEach(form => {
workers.service.push({
icon: WorkerIcon,
name: form.url,
url: form.url,
scope: form.scope,
@@ -151,30 +163,30 @@ module.exports = createClass({
});
// 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 });
});
- },
+ }
getRegistrationForWorker(form, registrations) {
for (let registration of registrations) {
if (registration.scope === form.scope) {
return registration;
}
}
return null;
- },
+ }
isE10S() {
return Services.appinfo.browserTabsRemoteAutostart;
- },
+ }
renderServiceWorkersError() {
let isWindowPrivate = PrivateBrowsingUtils.isContentWindowPrivate(window);
let isPrivateBrowsingMode = PrivateBrowsingUtils.permanentPrivateBrowsing;
let isServiceWorkerDisabled = !Services.prefs
.getBoolPref("dom.serviceWorkers.enabled");
let isDisabled = isWindowPrivate || isPrivateBrowsingMode || isServiceWorkerDisabled;
@@ -195,17 +207,17 @@ module.exports = createClass({
dom.a(
{
href: MORE_INFO_URL,
target: "_blank"
},
Strings.GetStringFromName("configurationIsNotCompatible.learnMore")
),
);
- },
+ }
render() {
let { client, id } = this.props;
let { workers, processCount } = this.state;
let isE10S = Services.appinfo.browserTabsRemoteAutostart;
let isMultiE10S = isE10S && processCount > 1;
@@ -250,9 +262,11 @@ module.exports = createClass({
name: Strings.GetStringFromName("otherWorkers"),
sort: true,
targetClass: WorkerTarget,
targets: workers.other
})
)
);
}
-});
+}
+
+module.exports = WorkersPanel;
--- a/devtools/client/aboutdebugging/components/workers/ServiceWorkerTarget.js
+++ b/devtools/client/aboutdebugging/components/workers/ServiceWorkerTarget.js
@@ -1,161 +1,175 @@
/* 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 { createClass, DOM: dom, PropTypes } =
+const { Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { debugWorker } = require("../../modules/worker");
const Services = require("Services");
loader.lazyRequireGetter(this, "DebuggerClient",
"devtools/shared/client/debugger-client", true);
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
-module.exports = createClass({
- displayName: "ServiceWorkerTarget",
+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,
+ workerActor: PropTypes.string
+ }).isRequired
+ };
+ }
- propTypes: {
- 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,
- workerActor: PropTypes.string
- }).isRequired
- },
+ constructor(props) {
+ super(props);
- getInitialState() {
- return {
+ 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() {
let { client } = this.props;
client.addListener("push-subscription-modified", this.onPushSubscriptionModified);
this.updatePushSubscription();
- },
+ }
componentDidUpdate(oldProps, oldState) {
let 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() {
let { 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;
}
let { client, target } = this.props;
debugWorker(client, target.workerActor);
- },
+ }
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;
}
let { client, target } = this.props;
client.request({
to: target.workerActor,
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;
}
let { client, target } = this.props;
client.request({
to: target.registrationActor,
type: "start"
});
- },
+ }
unregister() {
let { client, target } = this.props;
client.request({
to: target.registrationActor,
type: "unregister"
});
- },
+ }
onPushSubscriptionModified(type, data) {
let { 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;
}
let { 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.workerActor;
- },
+ }
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() {
let pushButton = dom.button({
className: "push-button",
onClick: this.push,
disabled: this.props.debugDisabled
}, Strings.GetStringFromName("push"));
@@ -174,29 +188,29 @@ module.exports = createClass({
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() {
let { target } = this.props;
let { pushSubscription } = this.state;
let status = this.getServiceWorkerStatus();
let fetch = target.fetch ? Strings.GetStringFromName("listeningForFetchEvents") :
Strings.GetStringFromName("notListeningForFetchEvents");
@@ -235,9 +249,11 @@ module.exports = createClass({
}, target.scope),
this.renderUnregisterLink()
)
)
),
this.renderButtons()
);
}
-});
+}
+
+module.exports = ServiceWorkerTarget;
--- a/devtools/client/aboutdebugging/components/workers/Target.js
+++ b/devtools/client/aboutdebugging/components/workers/Target.js
@@ -1,44 +1,49 @@
/* 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 { createClass, DOM: dom, PropTypes } =
+const { Component, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { debugWorker } = require("../../modules/worker");
const Services = require("Services");
loader.lazyRequireGetter(this, "DebuggerClient",
"devtools/shared/client/debugger-client", true);
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
-module.exports = createClass({
- displayName: "WorkerTarget",
+class WorkerTarget extends Component {
+ static get propTypes() {
+ return {
+ client: PropTypes.instanceOf(DebuggerClient).isRequired,
+ debugDisabled: PropTypes.bool,
+ target: PropTypes.shape({
+ icon: PropTypes.string,
+ name: PropTypes.string.isRequired,
+ workerActor: PropTypes.string
+ }).isRequired
+ };
+ }
- propTypes: {
- client: PropTypes.instanceOf(DebuggerClient).isRequired,
- debugDisabled: PropTypes.bool,
- target: PropTypes.shape({
- icon: PropTypes.string,
- name: PropTypes.string.isRequired,
- workerActor: PropTypes.string
- }).isRequired
- },
+ constructor(props) {
+ super(props);
+ this.debug = this.debug.bind(this);
+ }
debug() {
let { client, target } = this.props;
debugWorker(client, target.workerActor);
- },
+ }
render() {
let { target, debugDisabled } = this.props;
return dom.li({ className: "target-container" },
dom.img({
className: "target-icon",
role: "presentation",
@@ -49,9 +54,11 @@ module.exports = createClass({
),
dom.button({
className: "debug-button",
onClick: this.debug,
disabled: debugDisabled
}, Strings.GetStringFromName("debug"))
);
}
-});
+}
+
+module.exports = WorkerTarget;