Bug 1305786 - Add initial react/redux boilerplate for creating a new layout panel r=honza
authorGabriel Luong <gabriel.luong@gmail.com>
Mon, 03 Oct 2016 10:22:26 -0400
changeset 420163 7aeb526759fe3a57a87f0af96a35d64b4f23f4ab
parent 420053 2a14359213efbbe5b8ea31cbba0cd8ba8fa16550
child 420164 6619a470dcb905afc7c9c63d7e2da05c57d6964b
push id31118
push userbgrinstead@mozilla.com
push dateMon, 03 Oct 2016 15:59:53 +0000
reviewershonza
bugs1305786
milestone52.0a1
Bug 1305786 - Add initial react/redux boilerplate for creating a new layout panel r=honza
devtools/client/framework/toolbox.js
devtools/client/inspector/inspector.js
devtools/client/inspector/inspector.xhtml
devtools/client/inspector/layout/actions/index.js
devtools/client/inspector/layout/actions/moz.build
devtools/client/inspector/layout/components/App.js
devtools/client/inspector/layout/components/moz.build
devtools/client/inspector/layout/layout.js
devtools/client/inspector/layout/moz.build
devtools/client/inspector/layout/reducers/grids.js
devtools/client/inspector/layout/reducers/index.js
devtools/client/inspector/layout/reducers/moz.build
devtools/client/inspector/layout/store.js
devtools/client/inspector/layout/types.js
devtools/client/inspector/moz.build
devtools/client/locales/en-US/inspector.properties
devtools/client/preferences/devtools.js
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -481,16 +481,20 @@ Toolbox.prototype = {
   get React() {
     return this.browserRequire("devtools/client/shared/vendor/react");
   },
 
   get ReactDOM() {
     return this.browserRequire("devtools/client/shared/vendor/react-dom");
   },
 
+  get ReactRedux() {
+    return this.browserRequire("devtools/client/shared/vendor/react-redux");
+  },
+
   // Return HostType id for telemetry
   _getTelemetryHostId: function () {
     switch (this.hostType) {
       case Toolbox.HostType.BOTTOM: return 0;
       case Toolbox.HostType.SIDE: return 1;
       case Toolbox.HostType.WINDOW: return 2;
       case Toolbox.HostType.CUSTOM: return 3;
       default: return 9;
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -24,16 +24,17 @@ const Telemetry = require("devtools/clie
 const Menu = require("devtools/client/framework/menu");
 const MenuItem = require("devtools/client/framework/menu-item");
 
 const {CommandUtils} = require("devtools/client/shared/developer-toolbar");
 const {ComputedViewTool} = require("devtools/client/inspector/computed/computed");
 const {FontInspector} = require("devtools/client/inspector/fonts/fonts");
 const {HTMLBreadcrumbs} = require("devtools/client/inspector/breadcrumbs");
 const {InspectorSearch} = require("devtools/client/inspector/inspector-search");
+const {LayoutViewTool} = require("devtools/client/inspector/layout/layout");
 const {MarkupView} = require("devtools/client/inspector/markup/markup");
 const {RuleViewTool} = require("devtools/client/inspector/rules/rules");
 const {ToolSidebar} = require("devtools/client/inspector/toolsidebar");
 const {ViewHelpers} = require("devtools/client/shared/widgets/view-helpers");
 const clipboardHelper = require("devtools/shared/platform/clipboard");
 
 const {LocalizationHelper, localizeMarkup} = require("devtools/shared/l10n");
 const INSPECTOR_L10N = new LocalizationHelper("devtools/locale/inspector.properties");
@@ -412,16 +413,20 @@ Inspector.prototype = {
   get React() {
     return this._toolbox.React;
   },
 
   get ReactDOM() {
     return this._toolbox.ReactDOM;
   },
 
+  get ReactRedux() {
+    return this._toolbox.ReactRedux;
+  },
+
   get browserRequire() {
     return this._toolbox.browserRequire;
   },
 
   get InspectorTabPanel() {
     if (!this._InspectorTabPanel) {
       this._InspectorTabPanel =
         this.React.createFactory(this.browserRequire(
@@ -554,16 +559,26 @@ Inspector.prototype = {
       Services.prefs.setCharPref("devtools.inspector.activeSidebar", toolId);
     };
 
     this.sidebar.on("select", this._setDefaultSidebar);
 
     this.ruleview = new RuleViewTool(this, this.panelWin);
     this.computedview = new ComputedViewTool(this, this.panelWin);
 
+    if (Services.prefs.getBoolPref("devtools.layoutview.enabled")) {
+      this.sidebar.addExistingTab(
+        "layoutview",
+        INSPECTOR_L10N.getStr("inspector.sidebar.layoutViewTitle"),
+        defaultTab == "layoutview"
+      );
+
+      this.layoutview = new LayoutViewTool(this, this.panelWin);
+    }
+
     if (this.target.form.animationsActor) {
       this.sidebar.addFrameTab(
         "animationinspector",
         INSPECTOR_L10N.getStr("inspector.sidebar.animationInspectorTitle"),
         "chrome://devtools/content/animationinspector/animation-inspector.xhtml",
         defaultTab == "animationinspector");
     }
 
@@ -861,16 +876,20 @@ Inspector.prototype = {
     if (this.ruleview) {
       this.ruleview.destroy();
     }
 
     if (this.computedview) {
       this.computedview.destroy();
     }
 
+    if (this.layoutview) {
+      this.layoutview.destroy();
+    }
+
     if (this.fontInspector) {
       this.fontInspector.destroy();
     }
 
     let cssPropertiesDestroyer = this._cssPropertiesLoaded.then(({front}) => {
       if (front) {
         front.destroy();
       }
--- a/devtools/client/inspector/inspector.xhtml
+++ b/devtools/client/inspector/inspector.xhtml
@@ -179,16 +179,21 @@
             <div id="propertyContainer" class="theme-separator" tabindex="0">
             </div>
 
             <div id="computedview-no-results" hidden="" data-localization="content=inspector.noProperties"/>
           </div>
         </div>
       </div>
 
+      <div id="sidebar-panel-layoutview" class="devtools-monospace theme-sidebar inspector-tabpanel"
+           data-localization-bundle="devtools/locale/inspector.properties">
+        <div id="layout-root"></div>
+      </div>
+
       <div id="sidebar-panel-fontinspector" class="devtools-monospace theme-sidebar inspector-tabpanel"
                 data-localization-bundle="devtools/locale/font-inspector.properties">
         <div class="devtools-toolbar">
           <div class="devtools-searchbox">
             <input id="font-preview-text-input" class="devtools-textinput" type="search"
                         data-localization="placeholder=fontinspector.previewText"/>
           </div>
           <label id="font-showall" class="theme-link"
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/actions/index.js
@@ -0,0 +1,5 @@
+/* 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";
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/actions/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/components/App.js
@@ -0,0 +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/. */
+
+"use strict";
+
+const { createClass, DOM: dom } = require("devtools/client/shared/vendor/react");
+const { connect } = require("devtools/client/shared/vendor/react-redux");
+
+let App = createClass({
+
+  displayName: "App",
+
+  render() {
+    return dom.div(
+      {
+        id: "app",
+      }
+    );
+  },
+
+});
+
+module.exports = connect(state => state)(App);
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/components/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DevToolsModules(
+    'App.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/layout.js
@@ -0,0 +1,37 @@
+/* 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";
+
+function LayoutViewTool(inspector, window) {
+  this.inspector = inspector;
+  this.document = window.document;
+  this.store = null;
+
+  this.init();
+}
+
+LayoutViewTool.prototype = {
+
+  init() {
+    const { React, ReactDOM, ReactRedux, browserRequire } = this.inspector;
+
+    const Store = browserRequire("devtools/client/inspector/layout/store");
+    const App = React.createFactory(
+      browserRequire("devtools/client/inspector/layout/components/App"));
+
+    let store = this.store = Store();
+    let provider = React.createElement(ReactRedux.Provider, { store }, App());
+    ReactDOM.render(provider, this.document.querySelector("#layout-root"));
+  },
+
+  destroy() {
+    this.inspector = null;
+    this.document = null;
+    this.store = null;
+  },
+
+};
+
+exports.LayoutViewTool = LayoutViewTool;
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DIRS += [
+    'actions',
+    'components',
+    'reducers',
+]
+
+DevToolsModules(
+    'layout.js',
+    'store.js',
+    'types.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/reducers/grids.js
@@ -0,0 +1,21 @@
+/* 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 INITIAL_GRIDS = {
+
+};
+
+let reducers = {
+
+};
+
+module.exports = function (grids = INITIAL_GRIDS, action) {
+  let reducer = reducers[action.type];
+  if (!reducer) {
+    return grids;
+  }
+  return reducer(grids, action);
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/reducers/index.js
@@ -0,0 +1,7 @@
+/* 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";
+
+exports.grids = require("./grids");
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/reducers/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DevToolsModules(
+    'grids.js',
+    'index.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/store.js
@@ -0,0 +1,33 @@
+/* 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 { combineReducers } = require("devtools/client/shared/vendor/redux");
+const createStore = require("devtools/client/shared/redux/create-store");
+const reducers = require("./reducers/index");
+const flags = require("devtools/shared/flags");
+
+module.exports = function () {
+  let shouldLog = false;
+  let history;
+
+  // If testing, store the action history in an array
+  // we'll later attach to the store
+  if (flags.testing) {
+    history = [];
+    shouldLog = true;
+  }
+
+  let store = createStore({
+    log: shouldLog,
+    history
+  })(combineReducers(reducers), {});
+
+  if (history) {
+    store.history = history;
+  }
+
+  return store;
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/types.js
@@ -0,0 +1,5 @@
+/* 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";
--- a/devtools/client/inspector/moz.build
+++ b/devtools/client/inspector/moz.build
@@ -1,16 +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/.
 
 DIRS += [
     'components',
     'computed',
     'fonts',
+    'layout',
     'markup',
     'rules',
     'shared'
 ]
 
 DevToolsModules(
     'breadcrumbs.js',
     'inspector-commands.js',
--- a/devtools/client/locales/en-US/inspector.properties
+++ b/devtools/client/locales/en-US/inspector.properties
@@ -308,16 +308,21 @@ inspector.sidebar.fontInspectorTitle=Fon
 inspector.sidebar.ruleViewTitle=Rules
 
 # LOCALIZATION NOTE (inspector.sidebar.computedViewTitle):
 # This is the title shown in a tab in the side panel of the Inspector panel
 # that corresponds to the tool displaying the list of computed CSS values
 # used in the page.
 inspector.sidebar.computedViewTitle=Computed
 
+# LOCALIZATION NOTE (inspector.sidebar.computedViewTitle):
+# This is the title shown in a tab in the side panel of the Inspector panel
+# that corresponds to the tool displaying layout information defined in the page.
+inspector.sidebar.layoutViewTitle=Layout
+
 # LOCALIZATION NOTE (inspector.sidebar.animationInspectorTitle):
 # This is the title shown in a tab in the side panel of the Inspector panel
 # that corresponds to the tool displaying animations defined in the page.
 inspector.sidebar.animationInspectorTitle=Animations
 
 # LOCALIZATION NOTE (inspector.eyedropper.label): A string displayed as the tooltip of
 # a button in the inspector which toggles the Eyedropper tool
 inspector.eyedropper.label=Grab a color from the page
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -60,16 +60,25 @@ pref("devtools.inspector.show_pseudo_ele
 pref("devtools.inspector.imagePreviewTooltipSize", 300);
 // Enable user agent style inspection in rule-view
 pref("devtools.inspector.showUserAgentStyles", false);
 // Show all native anonymous content (like controls in <video> tags)
 pref("devtools.inspector.showAllAnonymousContent", false);
 // Enable the MDN docs tooltip
 pref("devtools.inspector.mdnDocsTooltip.enabled", true);
 
+// Enable the Font Inspector
+pref("devtools.fontinspector.enabled", true);
+
+// Enable the Layout View
+pref("devtools.layoutview.enabled", false);
+
+// By how many times eyedropper will magnify pixels
+pref("devtools.eyedropper.zoom", 6);
+
 // Enable to collapse attributes that are too long.
 pref("devtools.markup.collapseAttributes", true);
 
 // Length to collapse attributes
 pref("devtools.markup.collapseAttributeLength", 120);
 
 // DevTools default color unit
 pref("devtools.defaultColorUnit", "authored");
@@ -317,37 +326,31 @@ pref("devtools.hud.loglimit", 1000);
 // The number of lines that are displayed in the web console for the Net,
 // CSS, JS and Web Developer categories. These defaults should be kept in sync
 // with DEFAULT_LOG_LIMIT in the webconsole frontend.
 pref("devtools.hud.loglimit.network", 1000);
 pref("devtools.hud.loglimit.cssparser", 1000);
 pref("devtools.hud.loglimit.exception", 1000);
 pref("devtools.hud.loglimit.console", 1000);
 
-// By how many times eyedropper will magnify pixels
-pref("devtools.eyedropper.zoom", 6);
-
 // The developer tools editor configuration:
 // - tabsize: how many spaces to use when a Tab character is displayed.
 // - expandtab: expand Tab characters to spaces.
 // - keymap: which keymap to use (can be 'default', 'emacs' or 'vim')
 // - autoclosebrackets: whether to permit automatic bracket/quote closing.
 // - detectindentation: whether to detect the indentation from the file
 // - enableCodeFolding: Whether to enable code folding or not.
 pref("devtools.editor.tabsize", 2);
 pref("devtools.editor.expandtab", true);
 pref("devtools.editor.keymap", "default");
 pref("devtools.editor.autoclosebrackets", true);
 pref("devtools.editor.detectindentation", true);
 pref("devtools.editor.enableCodeFolding", true);
 pref("devtools.editor.autocomplete", true);
 
-// Enable the Font Inspector
-pref("devtools.fontinspector.enabled", true);
-
 // Pref to store the browser version at the time of a telemetry ping for an
 // opened developer tool. This allows us to ping telemetry just once per browser
 // version for each user.
 pref("devtools.telemetry.tools.opened.version", "{}");
 
 // Enable the JSON View tool (an inspector for application/json documents) on
 // Nightly and Dev. Edition.
 #ifdef RELEASE_BUILD