Bug 1207997 - about:debugging use factories/dom helpers instead of createElement;r=janx
authorJulian Descottes <jdescottes@mozilla.com>
Sun, 21 Feb 2016 01:58:00 +0100
changeset 285782 1e55f160b4ae5237c3bd8053acba9ff434c1b609
parent 285781 a96f17e627e5b86e1d6d603e10751edb37d1601d
child 285783 23ee4ba3d9275b2f3720ba6d3fba234b70e2a144
push id30035
push usercbook@mozilla.com
push dateMon, 29 Feb 2016 10:16:00 +0000
treeherdermozilla-central@4972f77869de [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjanx
bugs1207997
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1207997 - about:debugging use factories/dom helpers instead of createElement;r=janx Make about:debugging code less verbose: - use component factories to avoid having to remove calls to createElement - use React.DOM helpers - components only module.export their class (require('my-component.js').MyComponent -> require('my-component.js')) MozReview-Commit-ID: CBWLgcPUkMf
devtools/client/aboutdebugging/components/aboutdebugging.js
devtools/client/aboutdebugging/components/addons-controls.js
devtools/client/aboutdebugging/components/addons-tab.js
devtools/client/aboutdebugging/components/tab-header.js
devtools/client/aboutdebugging/components/tab-menu-entry.js
devtools/client/aboutdebugging/components/tab-menu.js
devtools/client/aboutdebugging/components/target-list.js
devtools/client/aboutdebugging/components/target.js
devtools/client/aboutdebugging/components/workers-tab.js
devtools/client/aboutdebugging/initializer.js
--- a/devtools/client/aboutdebugging/components/aboutdebugging.js
+++ b/devtools/client/aboutdebugging/components/aboutdebugging.js
@@ -3,36 +3,43 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* eslint-env browser */
 
 "use strict";
 
 const Services = require("Services");
 
-const React = require("devtools/client/shared/vendor/react");
-const { TabMenu } = require("./tab-menu");
+const { createFactory, createClass, DOM: dom } =
+  require("devtools/client/shared/vendor/react");
 
-loader.lazyRequireGetter(this, "AddonsTab", "./components/addons-tab", true);
-loader.lazyRequireGetter(this, "WorkersTab", "./components/workers-tab", true);
+const TabMenu = createFactory(require("./tab-menu"));
+loader.lazyGetter(this, "AddonsTab",
+  () => createFactory(require("./addons-tab")));
+loader.lazyGetter(this, "WorkersTab",
+  () => createFactory(require("./workers-tab")));
 
 const Strings = Services.strings.createBundle(
   "chrome://devtools/locale/aboutdebugging.properties");
 
-const tabs = [
-  { id: "addons", name: Strings.GetStringFromName("addons"),
-    icon: "chrome://devtools/skin/images/debugging-addons.svg",
-    component: AddonsTab },
-  { id: "workers", name: Strings.GetStringFromName("workers"),
-    icon: "chrome://devtools/skin/images/debugging-workers.svg",
-    component: WorkersTab },
-];
+const tabs = [{
+  id: "addons",
+  name: Strings.GetStringFromName("addons"),
+  icon: "chrome://devtools/skin/images/debugging-addons.svg",
+  component: AddonsTab
+}, {
+  id: "workers",
+  name: Strings.GetStringFromName("workers"),
+  icon: "chrome://devtools/skin/images/debugging-workers.svg",
+  component: WorkersTab
+}];
+
 const defaultTabId = "addons";
 
-exports.AboutDebuggingApp = React.createClass({
+module.exports = createClass({
   displayName: "AboutDebuggingApp",
 
   getInitialState() {
     return {
       selectedTabId: defaultTabId
     };
   },
 
@@ -50,22 +57,21 @@ exports.AboutDebuggingApp = React.create
 
   render() {
     let { client } = this.props;
     let { selectedTabId } = this.state;
     let selectTab = this.selectTab;
 
     let selectedTab = tabs.find(t => t.id == selectedTabId);
 
-    return React.createElement(
-      "div", { className: "app"},
-        React.createElement(TabMenu, { tabs, selectedTabId, selectTab }),
-        React.createElement("div", { className: "main-content" },
-          React.createElement(selectedTab.component, { client }))
-        );
+    return dom.div({ className: "app" },
+      TabMenu({ tabs, selectedTabId, selectTab }),
+      dom.div({ className: "main-content" },
+        selectedTab.component({ client }))
+      );
   },
 
   onHashChange() {
     let tabId = window.location.hash.substr(1);
 
     let isValid = tabs.some(t => t.id == tabId);
     if (isValid) {
       this.setState({ selectedTabId: tabId });
--- a/devtools/client/aboutdebugging/components/addons-controls.js
+++ b/devtools/client/aboutdebugging/components/addons-controls.js
@@ -7,50 +7,49 @@
 "use strict";
 
 loader.lazyImporter(this, "AddonManager",
   "resource://gre/modules/AddonManager.jsm");
 
 const { Cc, Ci } = require("chrome");
 const Services = require("Services");
 
-const React = require("devtools/client/shared/vendor/react");
+const { createClass, DOM: dom } = require("devtools/client/shared/vendor/react");
 
 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";
 
-exports.AddonsControls = React.createClass({
+module.exports = createClass({
   displayName: "AddonsControls",
 
   render() {
     let { debugDisabled } = this.props;
 
-    return React.createElement(
-      "div", { className: "addons-controls" }, React.createElement(
-        "div", { className: "addons-options" },
-          React.createElement("input", {
+    return dom.div({ className: "addons-controls" },
+        dom.div({ className: "addons-options" },
+          dom.input({
             id: "enable-addon-debugging",
             type: "checkbox",
             checked: !debugDisabled,
             onChange: this.onEnableAddonDebuggingChange,
           }),
-          React.createElement("label", {
+          dom.label({
             className: "addons-debugging-label",
             htmlFor: "enable-addon-debugging",
             title: Strings.GetStringFromName("addonDebugging.tooltip")
           }, Strings.GetStringFromName("addonDebugging.label")),
           "(",
-          React.createElement("a", { href: MORE_INFO_URL, target: "_blank" },
+          dom.a({ href: MORE_INFO_URL, target: "_blank" },
             Strings.GetStringFromName("addonDebugging.moreInfo")),
           ")"
         ),
-        React.createElement("button", {
+        dom.button({
           id: "load-addon-from-file",
           onClick: this.loadAddonFromFile,
         }, Strings.GetStringFromName("loadTemporaryAddon"))
       );
   },
 
   onEnableAddonDebuggingChange(event) {
     let enabled = event.target.checked;
--- a/devtools/client/aboutdebugging/components/addons-tab.js
+++ b/devtools/client/aboutdebugging/components/addons-tab.js
@@ -1,32 +1,31 @@
 /* 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/. */
 
-/* global React */
-
 "use strict";
 
 const { AddonManager } = require("resource://gre/modules/AddonManager.jsm");
 const Services = require("Services");
 
-const React = require("devtools/client/shared/vendor/react");
-const { AddonsControls } = require("./addons-controls");
-const { TabHeader } = require("./tab-header");
-const { TargetList } = require("./target-list");
+const { createFactory, createClass, DOM: dom } =
+  require("devtools/client/shared/vendor/react");
+const AddonsControls = createFactory(require("./addons-controls"));
+const TabHeader = createFactory(require("./tab-header"));
+const TargetList = createFactory(require("./target-list"));
 
 const ExtensionIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
 const Strings = Services.strings.createBundle(
   "chrome://devtools/locale/aboutdebugging.properties");
 
 const CHROME_ENABLED_PREF = "devtools.chrome.enabled";
 const REMOTE_ENABLED_PREF = "devtools.debugger.remote-enabled";
 
-exports.AddonsTab = React.createClass({
+module.exports = createClass({
   displayName: "AddonsTab",
 
   getInitialState() {
     return {
       extensions: [],
       debugDisabled: false,
     };
   },
@@ -51,29 +50,27 @@ exports.AddonsTab = React.createClass({
       this.updateDebugStatus);
   },
 
   render() {
     let { client } = this.props;
     let { debugDisabled, extensions: targets } = this.state;
     let name = Strings.GetStringFromName("extensions");
 
-    return React.createElement(
-      "div", { id: "tab-addons", className: "tab", role: "tabpanel",
-        "aria-labelledby": "tab-addons-header-name" },
-        React.createElement(TabHeader, {
-          id: "tab-addons-header-name",
-          name: Strings.GetStringFromName("addons")}),
-        React.createElement(AddonsControls, { debugDisabled }),
-        React.createElement(
-          "div", { id: "addons" },
-          React.createElement(TargetList,
-            { name, targets, client, debugDisabled })
-      )
-    );
+    return dom.div({
+      id: "tab-addons",
+      className: "tab",
+      role: "tabpanel",
+      "aria-labelledby": "tab-addons-header-name" },
+    TabHeader({
+      id: "tab-addons-header-name",
+      name: Strings.GetStringFromName("addons") }),
+    AddonsControls({ debugDisabled }),
+    dom.div({ id: "addons" },
+      TargetList({ name, targets, client, debugDisabled })));
   },
 
   updateDebugStatus() {
     let debugDisabled =
       !Services.prefs.getBoolPref(CHROME_ENABLED_PREF) ||
       !Services.prefs.getBoolPref(REMOTE_ENABLED_PREF);
 
     this.setState({ debugDisabled });
--- a/devtools/client/aboutdebugging/components/tab-header.js
+++ b/devtools/client/aboutdebugging/components/tab-header.js
@@ -1,19 +1,19 @@
 /* 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 React = require("devtools/client/shared/vendor/react");
+const { createClass, DOM: dom } =
+  require("devtools/client/shared/vendor/react");
 
-exports.TabHeader = React.createClass({
+module.exports = createClass({
   displayName: "TabHeader",
 
   render() {
     let { name, id } = this.props;
 
-    return React.createElement(
-      "div", { className: "header" }, React.createElement(
-        "h1", { id, className: "header-name" }, name));
+    return dom.div({ className: "header" },
+      dom.h1({ id, className: "header-name" }, name));
   },
 });
--- a/devtools/client/aboutdebugging/components/tab-menu-entry.js
+++ b/devtools/client/aboutdebugging/components/tab-menu-entry.js
@@ -1,30 +1,31 @@
 /* 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 React = require("devtools/client/shared/vendor/react");
+const { createClass, DOM: dom } =
+  require("devtools/client/shared/vendor/react");
 
-exports.TabMenuEntry = React.createClass({
+module.exports = createClass({
   displayName: "TabMenuEntry",
 
   render() {
     let { icon, name, selected } = this.props;
 
     // Here .category, .category-icon, .category-name classnames are used to
     // apply common styles defined.
     let className = "category" + (selected ? " selected" : "");
-    return React.createElement(
-      "div", { className, onClick: this.onClick,
-        "aria-selected": selected, role: "tab" },
-        React.createElement("img", { className: "category-icon", src: icon,
-          role: "presentation" }),
-        React.createElement("div", { className: "category-name" }, name)
-      );
+    return dom.div({
+      "aria-selected": selected,
+      className,
+      onClick: this.onClick,
+      role: "tab" },
+    dom.img({ className: "category-icon", src: icon, role: "presentation" }),
+    dom.div({ className: "category-name" }, name));
   },
 
   onClick() {
     this.props.selectTab(this.props.tabId);
   }
 });
--- a/devtools/client/aboutdebugging/components/tab-menu.js
+++ b/devtools/client/aboutdebugging/components/tab-menu.js
@@ -1,26 +1,24 @@
 /* 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/. */
 
-/* global React */
-
 "use strict";
 
-const React = require("devtools/client/shared/vendor/react");
-const { TabMenuEntry } = require("./tab-menu-entry");
+const { createClass, createFactory, DOM: dom } =
+  require("devtools/client/shared/vendor/react");
+const TabMenuEntry = createFactory(require("./tab-menu-entry"));
 
-exports.TabMenu = React.createClass({
+module.exports = createClass({
   displayName: "TabMenu",
 
   render() {
     let { tabs, selectedTabId, selectTab } = this.props;
     let tabLinks = tabs.map(({ id, name, icon }) => {
       let selected = id == selectedTabId;
-      return React.createElement(TabMenuEntry,
-        { tabId: id, name, icon, selected, selectTab });
+      return TabMenuEntry({ tabId: id, name, icon, selected, selectTab });
     });
 
     // "categories" id used for styling purposes
-    return React.createElement("div", { id: "categories" }, tabLinks);
+    return dom.div({ id: "categories" }, tabLinks);
   },
 });
--- a/devtools/client/aboutdebugging/components/target-list.js
+++ b/devtools/client/aboutdebugging/components/target-list.js
@@ -1,37 +1,38 @@
 /* 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/. */
 
-/* global React */
-
 "use strict";
 
 const Services = require("Services");
 
-const React = require("devtools/client/shared/vendor/react");
-const { Target } = require("./target");
+const { createClass, createFactory, DOM: dom } =
+  require("devtools/client/shared/vendor/react");
+const Target = createFactory(require("./target"));
 
 const Strings = Services.strings.createBundle(
   "chrome://devtools/locale/aboutdebugging.properties");
 
 const LocaleCompare = (a, b) => {
   return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
 };
 
-exports.TargetList = React.createClass({
+module.exports = createClass({
   displayName: "TargetList",
 
   render() {
     let { client, debugDisabled } = this.props;
     let targets = this.props.targets.sort(LocaleCompare).map(target => {
-      return React.createElement(Target, { client, target, debugDisabled });
+      return Target({ client, target, debugDisabled });
     });
+
     return (
-      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"))
+      dom.div({ id: this.props.id, className: "targets" },
+        dom.h4(null, this.props.name),
+        targets.length > 0 ?
+          targets :
+          dom.p(null, Strings.GetStringFromName("nothing"))
       )
     );
   },
 });
--- a/devtools/client/aboutdebugging/components/target.js
+++ b/devtools/client/aboutdebugging/components/target.js
@@ -12,38 +12,39 @@ loader.lazyRequireGetter(this, "gDevTool
       "devtools/client/framework/devtools", true);
 loader.lazyRequireGetter(this, "Toolbox",
       "devtools/client/framework/toolbox", true);
 
 loader.lazyImporter(this, "BrowserToolboxProcess",
       "resource://devtools/client/framework/ToolboxProcess.jsm");
 
 const Services = require("Services");
-const React = require("devtools/client/shared/vendor/react");
+const { createClass, DOM: dom } =
+  require("devtools/client/shared/vendor/react");
 
 const Strings = Services.strings.createBundle(
   "chrome://devtools/locale/aboutdebugging.properties");
 
-exports.Target = React.createClass({
+module.exports = createClass({
   displayName: "Target",
 
   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", {
+    return dom.div({ className: "target" },
+      dom.img({
         className: "target-icon",
         role: "presentation",
         src: target.icon }),
-      React.createElement("div", { className: "target-details" },
-        React.createElement("div", { className: "target-name" }, target.name)
+      dom.div({ className: "target-details" },
+        dom.div({ className: "target-name" }, target.name)
       ),
       (isRunning ?
-        React.createElement("button", {
+        dom.button({
           className: "debug-button",
           onClick: this.debug,
           disabled: debugDisabled,
         }, Strings.GetStringFromName("debug")) :
         null
       )
     );
   },
--- a/devtools/client/aboutdebugging/components/workers-tab.js
+++ b/devtools/client/aboutdebugging/components/workers-tab.js
@@ -3,25 +3,26 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Ci } = require("chrome");
 const { Task } = require("resource://gre/modules/Task.jsm");
 const Services = require("Services");
 
-const React = require("devtools/client/shared/vendor/react");
-const { TargetList } = require("./target-list");
-const { TabHeader } = require("./tab-header");
+const { createClass, createFactory, DOM: dom } =
+  require("devtools/client/shared/vendor/react");
+const TabHeader = createFactory(require("./tab-header"));
+const TargetList = createFactory(require("./target-list"));
 
 const Strings = Services.strings.createBundle(
   "chrome://devtools/locale/aboutdebugging.properties");
 const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
 
-exports.WorkersTab = React.createClass({
+module.exports = createClass({
   displayName: "WorkersTab",
 
   getInitialState() {
     return {
       workers: {
         service: [],
         shared: [],
         other: []
@@ -43,37 +44,40 @@ exports.WorkersTab = React.createClass({
     client.removeListener("serviceWorkerRegistrationListChanged", this.update);
     client.removeListener("workerListChanged", this.update);
   },
 
   render() {
     let { client } = this.props;
     let { workers } = this.state;
 
-    return React.createElement(
-      "div", { id: "tab-workers", className: "tab", role: "tabpanel",
-        "aria-labelledby": "tab-workers-header-name" },
-        React.createElement(TabHeader, {
-          id: "tab-workers-header-name",
-          name: Strings.GetStringFromName("workers")}),
-        React.createElement(
-          "div", { id: "workers", className: "inverted-icons" },
-          React.createElement(TargetList, {
-            id: "service-workers",
-            name: Strings.GetStringFromName("serviceWorkers"),
-            targets: workers.service, client }),
-          React.createElement(TargetList, {
-            id: "shared-workers",
-            name: Strings.GetStringFromName("sharedWorkers"),
-            targets: workers.shared, client }),
-          React.createElement(TargetList, {
-            id: "other-workers",
-            name: Strings.GetStringFromName("otherWorkers"),
-            targets: workers.other, client }))
-      );
+    return dom.div({
+      id: "tab-workers",
+      className: "tab",
+      role: "tabpanel",
+      "aria-labelledby": "tab-workers-header-name" },
+    TabHeader({
+      id: "tab-workers-header-name",
+      name: Strings.GetStringFromName("workers") }),
+    dom.div({ id: "workers", className: "inverted-icons" },
+      TargetList({
+        id: "service-workers",
+        name: Strings.GetStringFromName("serviceWorkers"),
+        targets: workers.service,
+        client }),
+      TargetList({
+        id: "shared-workers",
+        name: Strings.GetStringFromName("sharedWorkers"),
+        targets: workers.shared,
+        client }),
+      TargetList({
+        id: "other-workers",
+        name: Strings.GetStringFromName("otherWorkers"),
+        targets: workers.other,
+        client })));
   },
 
   update() {
     let workers = this.getInitialState().workers;
 
     this.getWorkerForms().then(forms => {
       forms.registrations.forEach(form => {
         workers.service.push({
--- a/devtools/client/aboutdebugging/initializer.js
+++ b/devtools/client/aboutdebugging/initializer.js
@@ -1,14 +1,13 @@
 /* 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 */
-/* global DebuggerClient, DebuggerServer */
 
 "use strict";
 
 const { loader } = Components.utils.import(
   "resource://devtools/shared/Loader.jsm", {});
 
 loader.lazyRequireGetter(this, "DebuggerClient",
   "devtools/shared/client/main", true);
@@ -17,39 +16,42 @@ loader.lazyRequireGetter(this, "Debugger
 loader.lazyRequireGetter(this, "Telemetry",
   "devtools/client/shared/telemetry");
 
 const { BrowserLoader } = Components.utils.import(
   "resource://devtools/client/shared/browser-loader.js", {});
 const { require } =
   BrowserLoader("resource://devtools/client/aboutdebugging/", window);
 
-const React = require("devtools/client/shared/vendor/react");
-const { AboutDebuggingApp } = require("./components/aboutdebugging");
+const {
+  createFactory,
+  render,
+  unmountComponentAtNode } = require("devtools/client/shared/vendor/react");
+const AboutDebuggingApp = createFactory(require("./components/aboutdebugging"));
 
 var AboutDebugging = {
   init() {
     if (!DebuggerServer.initialized) {
       DebuggerServer.init();
       DebuggerServer.addBrowserActors();
     }
     DebuggerServer.allowChromeProcess = true;
     this.client = new DebuggerClient(DebuggerServer.connectPipe());
 
     this.client.connect().then(() => {
       let client = this.client;
       let telemetry = new Telemetry();
 
-      let app = React.createElement(AboutDebuggingApp, { client, telemetry });
-      React.render(app, document.querySelector("#body"));
+      render(AboutDebuggingApp({ client, telemetry }),
+        document.querySelector("#body"));
     });
   },
 
   destroy() {
-    React.unmountComponentAtNode(document.querySelector("#body"));
+    unmountComponentAtNode(document.querySelector("#body"));
 
     this.client.close();
     this.client = null;
   },
 };
 
 window.addEventListener("DOMContentLoaded", function load() {
   window.removeEventListener("DOMContentLoaded", load);