Bug 1308263 - Part 3: Add a grid display setting for extending the grid lines infinitely. r=jryans
authorGabriel Luong <gabriel.luong@gmail.com>
Tue, 29 Nov 2016 19:38:08 +0800
changeset 324694 49664db41b866ae46e185249ed61275fd1d94022
parent 324693 664ac68c497e4a93a1fba73d2d9fb75b197aad7c
child 324695 77eaeeade47ebbe695df5abb56f47bf4b57a9eaa
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersjryans
bugs1308263
milestone53.0a1
Bug 1308263 - Part 3: Add a grid display setting for extending the grid lines infinitely. r=jryans
devtools/client/inspector/layout/components/App.js
devtools/client/inspector/layout/components/Grid.js
devtools/client/inspector/layout/components/GridDisplaySettings.js
devtools/client/inspector/layout/components/GridList.js
devtools/client/inspector/layout/components/moz.build
devtools/client/inspector/layout/layout.js
devtools/client/locales/en-US/layout.properties
devtools/client/themes/layout.css
--- a/devtools/client/inspector/layout/components/App.js
+++ b/devtools/client/inspector/layout/components/App.js
@@ -15,17 +15,19 @@ const Types = require("../types");
 const { getStr } = require("../utils/l10n");
 
 const App = createClass({
 
   displayName: "App",
 
   propTypes: {
     grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
+    highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
     onToggleGridHighlighter: PropTypes.func.isRequired,
+    onToggleShowInfiniteLines: PropTypes.func.isRequired,
   },
 
   mixins: [ addons.PureRenderMixin ],
 
   render() {
     return dom.div(
       {
         id: "layout-container",
--- a/devtools/client/inspector/layout/components/Grid.js
+++ b/devtools/client/inspector/layout/components/Grid.js
@@ -2,46 +2,55 @@
  * 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 { addons, createClass, createFactory, DOM: dom, PropTypes } =
   require("devtools/client/shared/vendor/react");
 
+const GridDisplaySettings = createFactory(require("./GridDisplaySettings"));
 const GridList = createFactory(require("./GridList"));
 
 const Types = require("../types");
 const { getStr } = require("../utils/l10n");
 
 module.exports = createClass({
 
   displayName: "Grid",
 
   propTypes: {
     grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
+    highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
     onToggleGridHighlighter: PropTypes.func.isRequired,
+    onToggleShowInfiniteLines: PropTypes.func.isRequired,
   },
 
   mixins: [ addons.PureRenderMixin ],
 
   render() {
     let {
       grids,
+      highlighterSettings,
       onToggleGridHighlighter,
+      onToggleShowInfiniteLines,
     } = this.props;
 
     return grids.length ?
       dom.div(
         {
           id: "layout-grid-container",
         },
         GridList({
           grids,
           onToggleGridHighlighter,
+        }),
+        GridDisplaySettings({
+          highlighterSettings,
+          onToggleShowInfiniteLines,
         })
       )
       :
       dom.div(
         {
           className: "layout-no-grids",
         },
         getStr("layout.noGrids")
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/layout/components/GridDisplaySettings.js
@@ -0,0 +1,66 @@
+/* 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 { addons, createClass, DOM: dom, PropTypes } =
+  require("devtools/client/shared/vendor/react");
+
+const Types = require("../types");
+const { getStr } = require("../utils/l10n");
+
+module.exports = createClass({
+
+  displayName: "GridDisplaySettings",
+
+  propTypes: {
+    highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
+    onToggleShowInfiniteLines: PropTypes.func.isRequired,
+  },
+
+  mixins: [ addons.PureRenderMixin ],
+
+  onShowInfiniteLinesCheckboxClick() {
+    let {
+      highlighterSettings,
+      onToggleShowInfiniteLines,
+    } = this.props;
+
+    onToggleShowInfiniteLines(!highlighterSettings.showInfiniteLines);
+  },
+
+  render() {
+    let {
+      highlighterSettings,
+    } = this.props;
+
+    return dom.div(
+      {
+        className: "grid-container",
+      },
+      dom.span(
+        {},
+        getStr("layout.gridDisplaySettings")
+      ),
+      dom.ul(
+        {},
+        dom.li(
+          {},
+          dom.label(
+            {},
+            dom.input(
+              {
+                type: "checkbox",
+                checked: highlighterSettings.showInfiniteLines,
+                onChange: this.onShowInfiniteLinesCheckboxClick,
+              }
+            ),
+            getStr("layout.extendGridLinesInfinitely")
+          )
+        )
+      )
+    );
+  },
+
+});
--- a/devtools/client/inspector/layout/components/GridList.js
+++ b/devtools/client/inspector/layout/components/GridList.js
@@ -32,26 +32,24 @@ module.exports = createClass({
 
   render() {
     let {
       grids,
     } = this.props;
 
     return dom.div(
       {
-        className: "layout-grid-list-container",
+        className: "grid-container",
       },
       dom.span(
         {},
         getStr("layout.overlayMultipleGrids")
       ),
       dom.ul(
-        {
-          id: "layout-grid-list",
-        },
+        {},
         grids.map(grid => {
           let { nodeFront } = grid;
           let { displayName, attributes } = nodeFront;
 
           let gridName = displayName;
 
           let idIndex = attributes.findIndex(({ name }) => name === "id");
           if (idIndex > -1 && attributes[idIndex].value) {
--- a/devtools/client/inspector/layout/components/moz.build
+++ b/devtools/client/inspector/layout/components/moz.build
@@ -4,10 +4,11 @@
 # 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(
     'Accordion.css',
     'Accordion.js',
     'App.js',
     'Grid.js',
+    'GridDisplaySettings.js',
     'GridList.js',
 )
--- a/devtools/client/inspector/layout/layout.js
+++ b/devtools/client/inspector/layout/layout.js
@@ -8,23 +8,29 @@ const Services = require("Services");
 const { Task } = require("devtools/shared/task");
 const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
 const { Provider } = require("devtools/client/shared/vendor/react-redux");
 
 const {
   updateGridHighlighted,
   updateGrids,
 } = require("./actions/grids");
+const {
+  updateShowInfiniteLines,
+} = require("./actions/highlighter-settings");
+
 const App = createFactory(require("./components/App"));
 const Store = require("./store");
 
 const { LocalizationHelper } = require("devtools/shared/l10n");
 const INSPECTOR_L10N =
   new LocalizationHelper("devtools/client/locales/inspector.properties");
 
+const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
+
 function LayoutView(inspector, window) {
   this.document = window.document;
   this.highlighters = inspector.highlighters;
   this.inspector = inspector;
   this.store = null;
   this.walker = this.inspector.walker;
 
   this.onGridLayoutChange = this.onGridLayoutChange.bind(this);
@@ -47,28 +53,53 @@ LayoutView.prototype = {
   init: Task.async(function* () {
     if (!this.inspector) {
       return;
     }
 
     this.layoutInspector = yield this.inspector.walker.getLayoutInspector();
     let store = this.store = Store();
 
+    this.loadHighlighterSettings();
+
     let app = App({
 
       /**
        * Handler for a change in the input checkboxes in the GridList component.
        * Toggles on/off the grid highlighter for the provided grid container element.
        *
        * @param  {NodeFront} node
        *         The NodeFront of the grid container element for which the grid
        *         highlighter is toggled on/off for.
        */
       onToggleGridHighlighter: node => {
-        this.highlighters.toggleGridHighlighter(node);
+        let { highlighterSettings } = this.store.getState();
+        this.highlighters.toggleGridHighlighter(node, highlighterSettings);
+      },
+
+      /**
+       * Handler for a change in the extend grid lines infinitely checkbox in the
+       * GridDisplaySettings component. Toggles on/off the option to extend the grid
+       * lines infinitely in the grid highlighter. Refreshes the shown grid highlighter
+       * for grids currently highlighted.
+       *
+       * @param  {Boolean} enabled
+       *         Whether or not the grid highlighter should extend grid lines infinitely.
+       */
+      onToggleShowInfiniteLines: enabled => {
+        this.store.dispatch(updateShowInfiniteLines(enabled));
+        Services.prefs.setBoolPref(SHOW_INFINITE_LINES_PREF, enabled);
+
+        let { grids, highlighterSettings } = this.store.getState();
+
+        for (let grid of grids) {
+          if (grid.highlighted) {
+            this.highlighters.showGridHighlighter(grid.nodeFront, highlighterSettings);
+          }
+        }
       },
 
     });
 
     let provider = createElement(Provider, {
       store,
       id: "layoutview",
       title: INSPECTOR_L10N.getStr("inspector.sidebar.layoutViewTitle"),
@@ -107,16 +138,26 @@ LayoutView.prototype = {
    */
   isPanelVisible() {
     return this.inspector.toolbox.currentToolId === "inspector" &&
            this.inspector.sidebar &&
            this.inspector.sidebar.getCurrentTabID() === "layoutview";
   },
 
   /**
+   * Load the grid highligher display settings into the store from the stored preferences.
+   */
+  loadHighlighterSettings() {
+    let { dispatch } = this.store;
+
+    let showInfinteLines = Services.prefs.getBoolPref(SHOW_INFINITE_LINES_PREF);
+    dispatch(updateShowInfiniteLines(showInfinteLines));
+  },
+
+  /**
    * Refreshes the layout view by dispatching the new grid data. This is called when the
    * layout view becomes visible or the view needs to be updated with new grid data.
    *
    * @param {Array|null} gridFronts
    *        Optional array of all GridFront in the current page.
    */
   refresh: Task.async(function* (gridFronts) {
     // Stop refreshing if the inspector or store is already destroyed.
--- a/devtools/client/locales/en-US/layout.properties
+++ b/devtools/client/locales/en-US/layout.properties
@@ -5,15 +5,23 @@
 # LOCALIZATION NOTE This file contains the Layout Inspector strings.
 # The Layout Inspector is a panel accessible in the Inspector sidebar.
 # The Layout Inspector may need to be enabled in about:config by setting
 # devtools.layoutview.enabled to true.
 
 # LOCALIZATION NOTE (layout.header): The accordion header for the CSS Grid pane.
 layout.header=Grid
 
+# LOCALIZATION NOTE (layout.gridDisplaySettings): The header for the grid display
+# settings container in the CSS Grid pane.
+layout.gridDisplaySettings=Grid Display Settings
+
+# LOCALIZATION NOTE (layout.extendGridLinesInfinitely): Label of the extend grid lines
+# infinitely setting option in the CSS Grid pane.
+layout.extendGridLinesInfinitely=Extend grid lines infinitely
+
 # LOCALIZATION NOTE (layout.noGrids): In the case where there are no CSS grid
 # containers to display.
 layout.noGrids=No grids
 
 # LOCALIZATION NOTE (layout.overlayMultipleGrids): The header for the list of grid
 # container elements that can be highlighted in the CSS Grid pane.
 layout.overlayMultipleGrids=Overlay Multiple Grids
--- a/devtools/client/themes/layout.css
+++ b/devtools/client/themes/layout.css
@@ -4,49 +4,51 @@
 
 #layout-container {
   height: 100%;
   width: 100%;
   overflow: auto;
 }
 
 /**
- * Grid Container
+ * Common styles for shared components
  */
 
-#layout-grid-container {
-  margin: 5px;
-}
-
-/**
- * Grid List
- */
-
-.layout-grid-list-container {
+.grid-container {
   display: flex;
   flex-direction: column;
+  flex: 1;
   align-items: center;
 }
 
-.layout-grid-list-container > span {
+.grid-container > span {
   font-weight: bold;
   margin-bottom: 3px;
 }
 
-#layout-grid-list {
+.grid-container > ul {
   list-style: none;
   margin: 0;
   padding: 0;
 }
 
-#layout-grid-list li {
+.grid-container li {
   padding: 4px 0;
 }
 
 /**
+ * Grid Container
+ */
+
+#layout-grid-container {
+  display: flex;
+  margin: 5px;
+}
+
+/**
  * Container when no grids are present
  */
 
 .layout-no-grids {
   font-style: italic;
   text-align: center;
   padding: 0.5em;
 }