Backed out 4 changesets (bug 1456680) for failing dt at devtools/client/inspector/grids/test/browser_grids_grid-outline-highlight-area.js CLOSED TREE
authorBogdan Tara <btara@mozilla.com>
Tue, 01 May 2018 09:31:16 +0300
changeset 472518 7134ec98560255d2c6ffa8b47a1fd78f04d29851
parent 472517 5bf7bfe1db79fc344db9fa64dbae539771a8db75
child 472519 d2a4720d1c334b64d88a51678758c27ba8f03c89
child 472556 03130e40886bf76d8d0de4ce16b7a042fd54b4f4
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1456680
milestone61.0a1
backs out232bed10f4d8f36466070a58ae5a37156e24d894
cfa4b6d2be06b3a6efd558fc0d00c86c71f6ac25
aef2d7d27ff141adefee8583504c20496de07d6f
80f9a47393edf19de2941b295b315df7ac0110b6
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
Backed out 4 changesets (bug 1456680) for failing dt at devtools/client/inspector/grids/test/browser_grids_grid-outline-highlight-area.js CLOSED TREE Backed out changeset 232bed10f4d8 (bug 1456680) Backed out changeset cfa4b6d2be06 (bug 1456680) Backed out changeset aef2d7d27ff1 (bug 1456680) Backed out changeset 80f9a47393ed (bug 1456680)
devtools/client/inspector/grids/components/Grid.js
devtools/client/inspector/grids/components/GridOutline.js
devtools/client/inspector/grids/grid-inspector.js
devtools/client/inspector/inspector.js
devtools/client/inspector/layout/layout.js
devtools/client/inspector/markup/markup.js
devtools/client/inspector/shared/highlighters-overlay.js
--- a/devtools/client/inspector/grids/components/Grid.js
+++ b/devtools/client/inspector/grids/components/Grid.js
@@ -20,34 +20,37 @@ class Grid extends PureComponent {
     return {
       getSwatchColorPickerTooltip: PropTypes.func.isRequired,
       grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
       highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
       setSelectedNode: PropTypes.func.isRequired,
       onHideBoxModelHighlighter: PropTypes.func.isRequired,
       onSetGridOverlayColor: PropTypes.func.isRequired,
       onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
-      onShowGridOutlineHighlight: PropTypes.func.isRequired,
+      onShowGridAreaHighlight: PropTypes.func.isRequired,
+      onShowGridCellHighlight: PropTypes.func.isRequired,
+      onShowGridLineNamesHighlight: PropTypes.func.isRequired,
       onToggleGridHighlighter: PropTypes.func.isRequired,
       onToggleShowGridAreas: PropTypes.func.isRequired,
       onToggleShowGridLineNumbers: PropTypes.func.isRequired,
       onToggleShowInfiniteLines: PropTypes.func.isRequired,
     };
   }
 
   render() {
     let {
       getSwatchColorPickerTooltip,
       grids,
       highlighterSettings,
       setSelectedNode,
       onHideBoxModelHighlighter,
       onSetGridOverlayColor,
       onShowBoxModelHighlighterForNode,
-      onShowGridOutlineHighlight,
+      onShowGridAreaHighlight,
+      onShowGridCellHighlight,
       onToggleShowGridAreas,
       onToggleGridHighlighter,
       onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines,
     } = this.props;
 
     return grids.length ?
       dom.div(
@@ -71,17 +74,18 @@ class Grid extends PureComponent {
             highlighterSettings,
             onToggleShowGridAreas,
             onToggleShowGridLineNumbers,
             onToggleShowInfiniteLines,
           })
         ),
         GridOutline({
           grids,
-          onShowGridOutlineHighlight,
+          onShowGridAreaHighlight,
+          onShowGridCellHighlight,
         })
       )
       :
       dom.div(
         {
           className: "devtools-sidepanel-no-result",
         },
         getStr("layout.noGridsOnThisPage")
--- a/devtools/client/inspector/grids/components/GridOutline.js
+++ b/devtools/client/inspector/grids/components/GridOutline.js
@@ -35,17 +35,18 @@ const GRID_CELL_SCALE_FACTOR = 50;
 
 const VIEWPORT_MIN_HEIGHT = 100;
 const VIEWPORT_MAX_HEIGHT = 150;
 
 class GridOutline extends PureComponent {
   static get propTypes() {
     return {
       grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired,
-      onShowGridOutlineHighlight: PropTypes.func.isRequired,
+      onShowGridAreaHighlight: PropTypes.func.isRequired,
+      onShowGridCellHighlight: PropTypes.func.isRequired,
     };
   }
 
   constructor(props) {
     super(props);
 
     this.state = {
       height: 0,
@@ -88,38 +89,41 @@ class GridOutline extends PureComponent 
     }
 
     this.setState({ height, width, selectedGrid, showOutline });
   }
 
   doHighlightCell(target, hide) {
     const {
       grids,
-      onShowGridOutlineHighlight,
+      onShowGridAreaHighlight,
+      onShowGridCellHighlight,
     } = this.props;
     const name = target.dataset.gridAreaName;
     const id = target.dataset.gridId;
-    const gridFragmentIndex = target.dataset.gridFragmentIndex;
+    const fragmentIndex = target.dataset.gridFragmentIndex;
+    const color = target.closest(".grid-outline-group").dataset.gridLineColor;
     const rowNumber = target.dataset.gridRow;
     const columnNumber = target.dataset.gridColumn;
 
-    onShowGridOutlineHighlight(grids[id].nodeFront);
+    onShowGridAreaHighlight(grids[id].nodeFront, null, color);
+    onShowGridCellHighlight(grids[id].nodeFront, color);
 
     if (hide) {
       return;
     }
 
-    onShowGridOutlineHighlight(grids[id].nodeFront, {
-      showGridArea: name,
-      showGridCell: {
-        gridFragmentIndex,
-        rowNumber,
-        columnNumber,
-      }
-    });
+    if (name) {
+      onShowGridAreaHighlight(grids[id].nodeFront, name, color);
+    }
+
+    if (fragmentIndex && rowNumber && columnNumber) {
+      onShowGridCellHighlight(grids[id].nodeFront, color, fragmentIndex,
+        rowNumber, columnNumber);
+    }
   }
 
   /**
    * Returns the grid area name if the given grid cell is part of a grid area, otherwise
    * null.
    *
    * @param  {Number} columnNumber
    *         The column number of the grid cell.
@@ -318,16 +322,17 @@ class GridOutline extends PureComponent 
 
   renderGridOutline(grid) {
     let { color } = grid;
 
     return dom.g(
       {
         id: "grid-outline-group",
         className: "grid-outline-group",
+        "data-grid-line-color": color,
         style: { color }
       },
       this.renderGrid(grid)
     );
   }
 
   renderGridOutlineBorder(borderWidth, borderHeight, color) {
     return dom.rect(
--- a/devtools/client/inspector/grids/grid-inspector.js
+++ b/devtools/client/inspector/grids/grid-inspector.js
@@ -57,17 +57,19 @@ class GridInspector {
     this.getSwatchColorPickerTooltip = this.getSwatchColorPickerTooltip.bind(this);
     this.updateGridPanel = this.updateGridPanel.bind(this);
 
     this.onHighlighterShown = this.onHighlighterShown.bind(this);
     this.onHighlighterHidden = this.onHighlighterHidden.bind(this);
     this.onNavigate = this.onNavigate.bind(this);
     this.onReflow = throttle(this.onReflow, 500, this);
     this.onSetGridOverlayColor = this.onSetGridOverlayColor.bind(this);
-    this.onShowGridOutlineHighlight = this.onShowGridOutlineHighlight.bind(this);
+    this.onShowGridAreaHighlight = this.onShowGridAreaHighlight.bind(this);
+    this.onShowGridCellHighlight = this.onShowGridCellHighlight.bind(this);
+    this.onShowGridLineNamesHighlight = this.onShowGridLineNamesHighlight.bind(this);
     this.onSidebarSelect = this.onSidebarSelect.bind(this);
     this.onToggleGridHighlighter = this.onToggleGridHighlighter.bind(this);
     this.onToggleShowGridAreas = this.onToggleShowGridAreas.bind(this);
     this.onToggleShowGridLineNumbers = this.onToggleShowGridLineNumbers.bind(this);
     this.onToggleShowInfiniteLines = this.onToggleShowInfiniteLines.bind(this);
 
     this.init();
   }
@@ -84,16 +86,18 @@ class GridInspector {
     try {
       this.layoutInspector = await this.inspector.walker.getLayoutInspector();
     } catch (e) {
       // This call might fail if called asynchrously after the toolbox is finished
       // closing.
       return;
     }
 
+    this.loadHighlighterSettings();
+
     // Create a shared SwatchColorPicker instance to be reused by all GridItem components.
     this.swatchColorPickerTooltip = new SwatchColorPickerTooltip(
       this.inspector.toolbox.doc,
       this.inspector,
       {
         supportsCssColor4ColorFunction: () => false
       }
     );
@@ -132,17 +136,19 @@ class GridInspector {
     this.swatchColorPickerTooltip = null;
     this.walker = null;
   }
 
   getComponentProps() {
     return {
       getSwatchColorPickerTooltip: this.getSwatchColorPickerTooltip,
       onSetGridOverlayColor: this.onSetGridOverlayColor,
-      onShowGridOutlineHighlight: this.onShowGridOutlineHighlight,
+      onShowGridAreaHighlight: this.onShowGridAreaHighlight,
+      onShowGridCellHighlight: this.onShowGridCellHighlight,
+      onShowGridLineNamesHighlight: this.onShowGridLineNamesHighlight,
       onToggleGridHighlighter: this.onToggleGridHighlighter,
       onToggleShowGridAreas: this.onToggleShowGridAreas,
       onToggleShowGridLineNumbers: this.onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines: this.onToggleShowInfiniteLines,
     };
   }
 
   /**
@@ -191,16 +197,34 @@ class GridInspector {
         return grid.color;
       }
     }
 
     return null;
   }
 
   /**
+   * Create a highlighter settings object for the provided nodeFront.
+   *
+   * @param  {NodeFront} nodeFront
+   *         The NodeFront for which we need highlighter settings.
+   */
+  getGridHighlighterSettings(nodeFront) {
+    let { highlighterSettings } = this.store.getState();
+
+    // Get the grid color for the provided nodeFront.
+    let color = this.getGridColorForNodeFront(nodeFront);
+
+    // Merge the grid color to the generic highlighter settings.
+    return Object.assign({}, highlighterSettings, {
+      color
+    });
+  }
+
+  /**
    * Retrieve the shared SwatchColorPicker instance.
    */
   getSwatchColorPickerTooltip() {
     return this.swatchColorPickerTooltip;
   }
 
   /**
    * Given a list of new grid fronts, and if we have a currently highlighted grid, check
@@ -233,16 +257,47 @@ class GridInspector {
    */
   isPanelVisible() {
     return this.inspector && this.inspector.toolbox && this.inspector.sidebar &&
            this.inspector.toolbox.currentToolId === "inspector" &&
            this.inspector.sidebar.getCurrentTabID() === "layoutview";
   }
 
   /**
+   * Load the grid highligher display settings into the store from the stored preferences.
+   */
+  loadHighlighterSettings() {
+    let { dispatch } = this.store;
+
+    let showGridAreas = Services.prefs.getBoolPref(SHOW_GRID_AREAS);
+    let showGridLineNumbers = Services.prefs.getBoolPref(SHOW_GRID_LINE_NUMBERS);
+    let showInfinteLines = Services.prefs.getBoolPref(SHOW_INFINITE_LINES_PREF);
+
+    dispatch(updateShowGridAreas(showGridAreas));
+    dispatch(updateShowGridLineNumbers(showGridLineNumbers));
+    dispatch(updateShowInfiniteLines(showInfinteLines));
+  }
+
+  showGridHighlighter(node, settings) {
+    this.lastHighlighterColor = settings.color;
+    this.lastHighlighterNode = node;
+    this.lastHighlighterState = true;
+
+    this.highlighters.showGridHighlighter(node, settings);
+  }
+
+  toggleGridHighlighter(node, settings) {
+    this.lastHighlighterColor = settings.color;
+    this.lastHighlighterNode = node;
+    this.lastHighlighterState = node !== this.highlighters.gridHighlighterShown;
+
+    this.highlighters.toggleGridHighlighter(node, settings, "grid");
+  }
+
+  /**
    * Updates the grid panel 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.
    */
   async updateGridPanel() {
     // Stop refreshing if the inspector or store is already destroyed.
     if (!this.inspector || !this.store) {
       return;
     }
@@ -308,65 +363,70 @@ class GridInspector {
     this.inspector.emit("grid-panel-updated");
   }
   /**
    * Handler for "grid-highlighter-shown" events emitted from the
    * HighlightersOverlay. Passes nodefront and event name to handleHighlighterChange.
    * Required since on and off events need the same reference object.
    *
    * @param  {NodeFront} nodeFront
-   *         The NodeFront of the grid container element for which the grid
+   *         The NodeFront of the flex container element for which the flexbox
    *         highlighter is shown for.
    * @param  {Object} options
    *         The highlighter options used for the highlighter being shown/hidden.
    */
   onHighlighterShown(nodeFront, options) {
-    this.onHighlighterChange(nodeFront, true, options);
+    return this.onHighlighterChange(true, nodeFront, options);
   }
 
   /**
    * Handler for "grid-highlighter-hidden" events emitted from the
    * HighlightersOverlay. Passes nodefront and event name to handleHighlighterChange.
    * Required since on and off events need the same reference object.
    *
    * @param  {NodeFront} nodeFront
-   *         The NodeFront of the grid container element for which the grid highlighter
-   *         is hidden for.
+   *         The NodeFront of the flex container element for which the flexbox
+   *         highlighter is shown for.
    * @param  {Object} options
    *         The highlighter options used for the highlighter being shown/hidden.
    */
   onHighlighterHidden(nodeFront, options) {
-    this.onHighlighterChange(nodeFront, false, options);
+    return this.onHighlighterChange(false, nodeFront, options);
   }
 
   /**
    * Handler for "grid-highlighter-shown" and "grid-highlighter-hidden" events emitted
    * from the HighlightersOverlay. Updates the NodeFront's grid highlighted state.
    *
+   * @param  {Boolean} highlighted
+   *         If the grid should be updated to highlight or hide.
    * @param  {NodeFront} nodeFront
    *         The NodeFront of the grid container element for which the grid highlighter
    *         is shown for.
-   * @param  {Boolean} highlighted
-   *         If the grid should be updated to highlight or hide.
    * @param  {Object} options
    *         The highlighter options used for the highlighter being shown/hidden.
    */
-  onHighlighterChange(nodeFront, highlighted, options = {}) {
-    if (!this.isPanelVisible()) {
-      return;
+  onHighlighterChange(highlighted, nodeFront, options = {}) {
+    let { color } = options;
+
+    // Only tell the store that the highlighter changed if it did change.
+    // If we're still highlighting the same node, with the same color, no need to force
+    // a refresh.
+    if (this.lastHighlighterState !== highlighted ||
+        this.lastHighlighterNode !== nodeFront) {
+      this.store.dispatch(updateGridHighlighted(nodeFront, highlighted));
     }
 
-    const { grids } = this.store.getState();
-    const grid = grids.find(g => g.nodeFront === nodeFront);
-
-    if (!grid || grid.highlighted === highlighted) {
-      return;
+    if (this.lastHighlighterColor !== color || this.lastHighlighterNode !== nodeFront) {
+      this.store.dispatch(updateGridColor(nodeFront, color));
     }
 
-    this.store.dispatch(updateGridHighlighted(nodeFront, highlighted));
+    this.lastHighlighterColor = null;
+    this.lastHighlighterNode = null;
+    this.lastHighlighterState = null;
   }
 
   /**
    * Handler for "new-root" event fired by the inspector, which indicates a page
    * navigation. Updates grid panel contents.
    */
   onNavigate() {
     if (this.isPanelVisible()) {
@@ -440,17 +500,16 @@ class GridInspector {
    * @param  {NodeFront} node
    *         The NodeFront of the grid container element for which the grid color is
    *         being updated.
    * @param  {String} color
    *         A hex string representing the color to use.
    */
   async onSetGridOverlayColor(node, color) {
     this.store.dispatch(updateGridColor(node, color));
-
     let { grids } = this.store.getState();
     let currentUrl = this.inspector.target.url;
     // Get the hostname, if there is no hostname, fall back on protocol
     // ex: `data:` uri, and `about:` pages
     let hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
     let customGridColors = await asyncStorage.getItem("gridInspectorHostColors") || {};
 
     for (let grid of grids) {
@@ -460,44 +519,108 @@ class GridInspector {
         }
         // Update the custom color for the grid in this position.
         customGridColors[hostname][grid.id] = color;
         await asyncStorage.setItem("gridInspectorHostColors", customGridColors);
 
         // If the grid for which the color was updated currently has a highlighter, update
         // the color.
         if (grid.highlighted) {
-          this.highlighters.showGridHighlighter(node);
+          let highlighterSettings = this.getGridHighlighterSettings(node);
+          this.showGridHighlighter(node, highlighterSettings);
         }
       }
     }
   }
 
   /**
-   * Highlights the grid area and cell in the CSS Grid Highlighter for the given grid
-   * container element and selected grid area and cell options.
+   * Highlights the grid area in the CSS Grid Highlighter for the given grid.
+   *
+   * @param  {NodeFront} node
+   *         The NodeFront of the grid container element for which the grid
+   *         highlighter is highlighted for.
+   * @param  {String} gridAreaName
+   *         The name of the grid area for which the grid highlighter
+   *         is highlighted for.
+   * @param  {String} color
+   *         The color of the grid area for which the grid highlighter
+   *         is highlighted for.
+   */
+  onShowGridAreaHighlight(node, gridAreaName, color) {
+    let { highlighterSettings } = this.store.getState();
+
+    highlighterSettings.showGridArea = gridAreaName;
+    highlighterSettings.color = color;
+
+    this.showGridHighlighter(node, highlighterSettings);
+
+    this.store.dispatch(updateGridHighlighted(node, true));
+  }
+
+  /**
+   * Highlights the grid cell in the CSS Grid Highlighter for the given grid.
    *
    * @param  {NodeFront} node
-   *         The NodeFront of the grid container element for which the grid highlighter
+   *         The NodeFront of the grid container element for which the grid
+   *         highlighter is highlighted for.
+   * @param  {String} color
+   *         The color of the grid cell for which the grid highlighter
+   *         is highlighted for.
+   * @param  {Number|null} gridFragmentIndex
+   *         The index of the grid fragment for which the grid highlighter
+   *         is highlighted for.
+   * @param  {Number|null} rowNumber
+   *         The row number of the grid cell for which the grid highlighter
+   *         is highlighted for.
+   * @param  {Number|null} columnNumber
+   *         The column number of the grid cell for which the grid highlighter
    *         is highlighted for.
-   * @param  {Object} options
-   *         The options object has the following properties which corresponds to the
-   *         required parameters for showing the grid cell or area highlights.
-   *         See css-grid.js.
-   *         {
-   *           showGridCell: {
-   *             gridFragmentIndex: Number,
-   *             rowNumber: Number,
-   *             columnNumber: Number,
-   *           },
-   *           showGridArea: String,
-   *         }
    */
-  onShowGridOutlineHighlight(node, options) {
-    this.highlighters.showGridHighlighter(node, options);
+  onShowGridCellHighlight(node, color, gridFragmentIndex, rowNumber, columnNumber) {
+    let { highlighterSettings } = this.store.getState();
+
+    highlighterSettings.showGridCell = { gridFragmentIndex, rowNumber, columnNumber };
+    highlighterSettings.color = color;
+
+    this.showGridHighlighter(node, highlighterSettings);
+
+    this.store.dispatch(updateGridHighlighted(node, true));
+  }
+
+  /**
+   * Highlights the grid line in the CSS Grid Highlighter for the given grid.
+   *
+   * @param  {NodeFront} node
+   *         The NodeFront of the grid container element for which the grid
+   *         highlighter is highlighted for.
+   * @param  {Number|null} gridFragmentIndex
+   *         The index of the grid fragment for which the grid highlighter
+   *         is highlighted for.
+   * @param  {String} color
+   *         The color of the grid line for which the grid highlighter
+   *         is highlighted for.
+   * @param  {Number|null} lineNumber
+   *         The line number of the grid for which the grid highlighter
+   *         is highlighted for.
+   * @param  {String|null} type
+   *         The type of line for which the grid line is being highlighted for.
+   */
+  onShowGridLineNamesHighlight(node, gridFragmentIndex, color, lineNumber, type) {
+    let { highlighterSettings } = this.store.getState();
+
+    highlighterSettings.showGridLineNames = {
+      gridFragmentIndex,
+      lineNumber,
+      type
+    };
+    highlighterSettings.color = color;
+
+    this.showGridHighlighter(node, highlighterSettings);
+
+    this.store.dispatch(updateGridHighlighted(node, true));
   }
 
   /**
    * Handler for the inspector sidebar "select" event. Starts tracking reflows
    * if the layout panel is visible. Otherwise, stop tracking reflows.
    * Finally, refresh the layout view if it is visible.
    */
   onSidebarSelect() {
@@ -514,17 +637,21 @@ class GridInspector {
    * 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, "grid");
+    let highlighterSettings = this.getGridHighlighterSettings(node);
+    this.toggleGridHighlighter(node, highlighterSettings);
+
+    this.store.dispatch(updateGridHighlighted(node,
+      node !== this.highlighters.gridHighlighterShown));
   }
 
   /**
     * Handler for a change in the show grid areas checkbox in the GridDisplaySettings
     * component. Toggles on/off the option to show the grid areas in the grid highlighter.
     * Refreshes the shown grid highlighter for the grids currently highlighted.
     *
     * @param  {Boolean} enabled
@@ -537,17 +664,18 @@ class GridInspector {
     if (enabled) {
       this.telemetry.toolOpened("gridInspectorShowGridAreasOverlayChecked");
     }
 
     let { grids } = this.store.getState();
 
     for (let grid of grids) {
       if (grid.highlighted) {
-        this.highlighters.showGridHighlighter(grid.nodeFront);
+        let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront);
+        this.highlighters.showGridHighlighter(grid.nodeFront, highlighterSettings);
       }
     }
   }
 
   /**
    * Handler for a change in the show grid line numbers checkbox in the
    * GridDisplaySettings component. Toggles on/off the option to show the grid line
    * numbers in the grid highlighter. Refreshes the shown grid highlighter for the
@@ -563,17 +691,18 @@ class GridInspector {
     if (enabled) {
       this.telemetry.toolOpened("gridInspectorShowGridLineNumbersChecked");
     }
 
     let { grids } = this.store.getState();
 
     for (let grid of grids) {
       if (grid.highlighted) {
-        this.highlighters.showGridHighlighter(grid.nodeFront);
+        let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront);
+        this.showGridHighlighter(grid.nodeFront, 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
@@ -589,15 +718,16 @@ class GridInspector {
     if (enabled) {
       this.telemetry.toolOpened("gridInspectorShowInfiniteLinesChecked");
     }
 
     let { grids } = this.store.getState();
 
     for (let grid of grids) {
       if (grid.highlighted) {
-        this.highlighters.showGridHighlighter(grid.nodeFront);
+        let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront);
+        this.showGridHighlighter(grid.nodeFront, highlighterSettings);
       }
     }
   }
 }
 
 module.exports = GridInspector;
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -99,26 +99,25 @@ function Inspector(toolbox) {
   EventEmitter.decorate(this);
 
   this._toolbox = toolbox;
   this._target = toolbox.target;
   this.panelDoc = window.document;
   this.panelWin = window;
   this.panelWin.inspector = this;
 
-  this.store = Store();
-
   // Map [panel id => panel instance]
   // Stores all the instances of sidebar panels like rule view, computed view, ...
   this._panels = new Map();
 
   this.highlighters = new HighlightersOverlay(this);
   this.prefsObserver = new PrefObserver("devtools.");
   this.reflowTracker = new ReflowTracker(this._target);
   this.styleChangeTracker = new InspectorStyleChangeTracker(this);
+  this.store = Store();
   this.telemetry = new Telemetry();
 
   // Store the URL of the target page prior to navigation in order to ensure
   // telemetry counts in the Grid Inspector are not double counted on reload.
   this.previousURL = this.target.url;
 
   this.show3PaneToggle = Services.prefs.getBoolPref(SHOW_THREE_PANE_TOGGLE_PREF);
   this.is3PaneModeEnabled = Services.prefs.getBoolPref(THREE_PANE_ENABLED_PREF);
--- a/devtools/client/inspector/layout/layout.js
+++ b/devtools/client/inspector/layout/layout.js
@@ -47,17 +47,19 @@ class LayoutView {
     let {
       onToggleFlexboxHighlighter,
     } = this.flexboxInspector.getComponentProps();
 
     this.gridInspector = new GridInspector(this.inspector, this.inspector.panelWin);
     let {
       getSwatchColorPickerTooltip,
       onSetGridOverlayColor,
-      onShowGridOutlineHighlight,
+      onShowGridAreaHighlight,
+      onShowGridCellHighlight,
+      onShowGridLineNamesHighlight,
       onToggleGridHighlighter,
       onToggleShowGridAreas,
       onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines,
     } = this.gridInspector.getComponentProps();
 
     let layoutApp = LayoutApp({
       getSwatchColorPickerTooltip,
@@ -67,17 +69,19 @@ class LayoutView {
        * default.
        */
       showBoxModelProperties: true,
       onHideBoxModelHighlighter,
       onSetGridOverlayColor,
       onShowBoxModelEditor,
       onShowBoxModelHighlighter,
       onShowBoxModelHighlighterForNode,
-      onShowGridOutlineHighlight,
+      onShowGridAreaHighlight,
+      onShowGridCellHighlight,
+      onShowGridLineNamesHighlight,
       onToggleFlexboxHighlighter,
       onToggleGeometryEditor,
       onToggleGridHighlighter,
       onToggleShowGridAreas,
       onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines,
     });
 
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -57,30 +57,30 @@ const ATTR_COLLAPSE_LENGTH_PREF = "devto
  * updating based on mutations, and the undo/redo bindings.
  *
  * @param  {Inspector} inspector
  *         The inspector we're watching.
  * @param  {iframe} frame
  *         An iframe in which the caller has kindly loaded markup.xhtml.
  */
 function MarkupView(inspector, frame, controllerWindow) {
-  EventEmitter.decorate(this);
-
   this.inspector = inspector;
   this.walker = this.inspector.walker;
   this._frame = frame;
   this.win = this._frame.contentWindow;
   this.doc = this._frame.contentDocument;
   this._elt = this.doc.querySelector("#root");
 
   this.maxChildren = Services.prefs.getIntPref("devtools.markup.pagesize",
                                                DEFAULT_MAX_CHILDREN);
 
-  this.collapseAttributes = Services.prefs.getBoolPref(ATTR_COLLAPSE_ENABLED_PREF);
-  this.collapseAttributeLength = Services.prefs.getIntPref(ATTR_COLLAPSE_LENGTH_PREF);
+  this.collapseAttributes =
+    Services.prefs.getBoolPref(ATTR_COLLAPSE_ENABLED_PREF);
+  this.collapseAttributeLength =
+    Services.prefs.getIntPref(ATTR_COLLAPSE_LENGTH_PREF);
 
   // Creating the popup to be used to show CSS suggestions.
   // The popup will be attached to the toolbox document.
   this.popup = new AutocompletePopup(inspector.toolbox.doc, {
     autoSelect: true,
     theme: "auto",
   });
 
@@ -89,51 +89,56 @@ function MarkupView(inspector, frame, co
 
   this._containers = new Map();
   // This weakmap will hold keys used with the _containers map, in order to retrieve the
   // slotted container for a given node front.
   this._slottedContainerKeys = new WeakMap();
 
   // Binding functions that need to be called in scope.
   this._handleRejectionIfNotDestroyed = this._handleRejectionIfNotDestroyed.bind(this);
-  this._isImagePreviewTarget = this._isImagePreviewTarget.bind(this);
   this._mutationObserver = this._mutationObserver.bind(this);
-  this._onBlur = this._onBlur.bind(this);
+  this._onDisplayChange = this._onDisplayChange.bind(this);
+  this._onMouseClick = this._onMouseClick.bind(this);
+  this._onMouseUp = this._onMouseUp.bind(this);
+  this._onNewSelection = this._onNewSelection.bind(this);
   this._onCopy = this._onCopy.bind(this);
-  this._onCollapseAttributesPrefChange = this._onCollapseAttributesPrefChange.bind(this);
-  this._onDisplayChange = this._onDisplayChange.bind(this);
   this._onFocus = this._onFocus.bind(this);
-  this._onMouseClick = this._onMouseClick.bind(this);
   this._onMouseMove = this._onMouseMove.bind(this);
   this._onMouseOut = this._onMouseOut.bind(this);
-  this._onMouseUp = this._onMouseUp.bind(this);
-  this._onNewSelection = this._onNewSelection.bind(this);
   this._onToolboxPickerCanceled = this._onToolboxPickerCanceled.bind(this);
   this._onToolboxPickerHover = this._onToolboxPickerHover.bind(this);
+  this._onCollapseAttributesPrefChange =
+    this._onCollapseAttributesPrefChange.bind(this);
+  this._isImagePreviewTarget = this._isImagePreviewTarget.bind(this);
+  this._onBlur = this._onBlur.bind(this);
+
+  EventEmitter.decorate(this);
 
   // Listening to various events.
-  this._elt.addEventListener("blur", this._onBlur, true);
   this._elt.addEventListener("click", this._onMouseClick);
   this._elt.addEventListener("mousemove", this._onMouseMove);
   this._elt.addEventListener("mouseout", this._onMouseOut);
+  this._elt.addEventListener("blur", this._onBlur, true);
+  this.win.addEventListener("mouseup", this._onMouseUp);
+  this.win.addEventListener("copy", this._onCopy);
   this._frame.addEventListener("focus", this._onFocus);
-  this.inspector.selection.on("new-node-front", this._onNewSelection);
+  this.walker.on("mutations", this._mutationObserver);
   this.walker.on("display-change", this._onDisplayChange);
-  this.walker.on("mutations", this._mutationObserver);
-  this.win.addEventListener("copy", this._onCopy);
-  this.win.addEventListener("mouseup", this._onMouseUp);
+  this.inspector.selection.on("new-node-front", this._onNewSelection);
   this.toolbox.on("picker-canceled", this._onToolboxPickerCanceled);
   this.toolbox.on("picker-node-hovered", this._onToolboxPickerHover);
 
   this._onNewSelection();
   this._initTooltips();
 
   this._prefObserver = new PrefObserver("devtools.markup");
-  this._prefObserver.on(ATTR_COLLAPSE_ENABLED_PREF, this._onCollapseAttributesPrefChange);
-  this._prefObserver.on(ATTR_COLLAPSE_LENGTH_PREF, this._onCollapseAttributesPrefChange);
+  this._prefObserver.on(ATTR_COLLAPSE_ENABLED_PREF,
+                        this._onCollapseAttributesPrefChange);
+  this._prefObserver.on(ATTR_COLLAPSE_LENGTH_PREF,
+                        this._onCollapseAttributesPrefChange);
 
   this._initShortcuts();
 }
 
 MarkupView.prototype = {
   /**
    * How long does a node flash when it mutates (in ms).
    */
@@ -1869,27 +1874,28 @@ MarkupView.prototype = {
     }
 
     this.undo.destroy();
     this.undo = null;
 
     this.popup.destroy();
     this.popup = null;
 
-    this._elt.removeEventListener("blur", this._onBlur, true);
     this._elt.removeEventListener("click", this._onMouseClick);
     this._elt.removeEventListener("mousemove", this._onMouseMove);
     this._elt.removeEventListener("mouseout", this._onMouseOut);
+    this._elt.removeEventListener("blur", this._onBlur, true);
+    this.win.removeEventListener("mouseup", this._onMouseUp);
+    this.win.removeEventListener("copy", this._onCopy);
     this._frame.removeEventListener("focus", this._onFocus);
-    this.inspector.selection.off("new-node-front", this._onNewSelection);
-    this.toolbox.off("picker-node-hovered", this._onToolboxPickerHover);
+    this.walker.off("mutations", this._mutationObserver);
     this.walker.off("display-change", this._onDisplayChange);
-    this.walker.off("mutations", this._mutationObserver);
-    this.win.removeEventListener("copy", this._onCopy);
-    this.win.removeEventListener("mouseup", this._onMouseUp);
+    this.inspector.selection.off("new-node-front", this._onNewSelection);
+    this.toolbox.off("picker-node-hovered",
+                                this._onToolboxPickerHover);
 
     this._prefObserver.off(ATTR_COLLAPSE_ENABLED_PREF,
                            this._onCollapseAttributesPrefChange);
     this._prefObserver.off(ATTR_COLLAPSE_LENGTH_PREF,
                            this._onCollapseAttributesPrefChange);
     this._prefObserver.destroy();
 
     this._elt = null;
@@ -1900,18 +1906,18 @@ MarkupView.prototype = {
     this._containers = null;
 
     this.eventDetailsTooltip.destroy();
     this.eventDetailsTooltip = null;
 
     this.imagePreviewTooltip.destroy();
     this.imagePreviewTooltip = null;
 
+    this.win = null;
     this.doc = null;
-    this.win = null;
 
     this._lastDropTarget = null;
     this._lastDragTarget = null;
 
     return this._destroyer;
   },
 
   /**
--- a/devtools/client/inspector/shared/highlighters-overlay.js
+++ b/devtools/client/inspector/shared/highlighters-overlay.js
@@ -7,27 +7,17 @@
 "use strict";
 
 const Services = require("Services");
 const EventEmitter = require("devtools/shared/event-emitter");
 const {
   VIEW_NODE_VALUE_TYPE,
   VIEW_NODE_SHAPE_POINT_TYPE
 } = require("devtools/client/inspector/shared/node-types");
-
-const {
-  updateShowGridAreas,
-  updateShowGridLineNumbers,
-  updateShowInfiniteLines,
-} = require("devtools/client/inspector/grids/actions/highlighter-settings");
-
 const DEFAULT_GRID_COLOR = "#4B0082";
-const SHOW_GRID_AREAS = "devtools.gridinspector.showGridAreas";
-const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers";
-const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
 
 /**
  * Highlighters overlay is a singleton managing all highlighters in the Inspector.
  */
 class HighlightersOverlay {
   /**
    * @param  {Inspector} inspector
    *         Inspector toolbox panel.
@@ -41,17 +31,16 @@ class HighlightersOverlay {
     /*
     * Collection of instantiated in-context editors, like ShapesInContextEditor, which
     * behave like highlighters but with added editing capabilities that need to map value
     * changes to properties in the Rule view.
     */
     this.editors = {};
     this.inspector = inspector;
     this.highlighterUtils = this.inspector.toolbox.highlighterUtils;
-    this.store = this.inspector.store;
 
     // Only initialize the overlay if at least one of the highlighter types is supported.
     this.supportsHighlighters = this.highlighterUtils.supportsCustomHighlighters();
 
     // NodeFront of the flexbox container that is highlighted.
     this.flexboxHighlighterShown = null;
     // NodeFront of element that is highlighted by the geometry editor.
     this.geometryEditorHighlighterShown = null;
@@ -84,18 +73,16 @@ class HighlightersOverlay {
     this._handleRejection = this._handleRejection.bind(this);
     this.onShapesHighlighterShown = this.onShapesHighlighterShown.bind(this);
     this.onShapesHighlighterHidden = this.onShapesHighlighterHidden.bind(this);
 
     // Add inspector events, not specific to a given view.
     this.inspector.on("markupmutation", this.onMarkupMutation);
     this.inspector.target.on("will-navigate", this.onWillNavigate);
 
-    this.loadGridHighlighterSettings();
-
     EventEmitter.decorate(this);
   }
 
   /**
    * Returns whether `node` is somewhere inside the DOM of the rule view.
    *
    * @param {DOMNode} node
    * @return {Boolean}
@@ -138,31 +125,16 @@ class HighlightersOverlay {
 
     let el = view.element;
     el.removeEventListener("click", this.onClick, true);
     el.removeEventListener("mousemove", this.onMouseMove);
     el.removeEventListener("mouseout", this.onMouseOut);
   }
 
   /**
-   * Load the grid highligher display settings into the store from the stored preferences.
-   */
-  loadGridHighlighterSettings() {
-    const { dispatch } = this.inspector.store;
-
-    const showGridAreas = Services.prefs.getBoolPref(SHOW_GRID_AREAS);
-    const showGridLineNumbers = Services.prefs.getBoolPref(SHOW_GRID_LINE_NUMBERS);
-    const showInfinteLines = Services.prefs.getBoolPref(SHOW_INFINITE_LINES_PREF);
-
-    dispatch(updateShowGridAreas(showGridAreas));
-    dispatch(updateShowGridLineNumbers(showGridLineNumbers));
-    dispatch(updateShowInfiniteLines(showInfinteLines));
-  }
-
-  /**
    * Toggle the shapes highlighter for the given node.
 
    * @param  {NodeFront} node
    *         The NodeFront of the element with a shape to highlight.
    * @param  {Object} options
    *         Object used for passing options to the shapes highlighter.
    * @param {TextProperty} textProperty
    *        TextProperty where to write changes.
@@ -325,29 +297,16 @@ class HighlightersOverlay {
     this.emit("flexbox-highlighter-hidden", this.flexboxHighlighterShown);
     this.flexboxHighlighterShown = null;
 
     // Erase flexbox highlighter state.
     this.state.flexbox = null;
   }
 
   /**
-   * Create a grid highlighter settings object for the provided nodeFront.
-   *
-   * @param  {NodeFront} nodeFront
-   *         The NodeFront for which we need highlighter settings.
-   */
-  getGridHighlighterSettings(nodeFront) {
-    const { grids, highlighterSettings } = this.store.getState();
-    const grid = grids.find(g => g.nodeFront === nodeFront);
-    const color = grid ? grid.color : DEFAULT_GRID_COLOR;
-    return Object.assign({}, highlighterSettings, { color });
-  }
-
-  /**
    * Toggle the grid highlighter for the given grid container element.
    *
    * @param  {NodeFront} node
    *         The NodeFront of the grid container element to highlight.
    * @param  {Object} options
    *         Object used for passing options to the grid highlighter.
    * @param. {String|null} trigger
    *         String name matching "grid" or "rule" to indicate where the
@@ -365,29 +324,23 @@ class HighlightersOverlay {
 
   /**
    * Show the grid highlighter for the given grid container element.
    *
    * @param  {NodeFront} node
    *         The NodeFront of the grid container element to highlight.
    * @param  {Object} options
    *         Object used for passing options to the grid highlighter.
-   * @param. {String|null} trigger
-   *         String name matching "grid" or "rule" to indicate where the
-   *         grid highlighter was toggled on from. "grid" represents the grid view
-   *         "rule" represents the rule view.
    */
   async showGridHighlighter(node, options, trigger) {
     let highlighter = await this._getHighlighter("CssGridHighlighter");
     if (!highlighter) {
       return;
     }
 
-    options = Object.assign({}, options, this.getGridHighlighterSettings(node));
-
     let isShown = await highlighter.show(node, options);
     if (!isShown) {
       return;
     }
 
     this._toggleRuleViewIcon(node, true, ".ruleview-grid");
 
     if (trigger == "grid") {
@@ -422,19 +375,19 @@ class HighlightersOverlay {
     }
 
     this._toggleRuleViewIcon(node, false, ".ruleview-grid");
 
     await this.highlighters.CssGridHighlighter.hide();
 
     // Emit the NodeFront of the grid container element that the grid highlighter was
     // hidden for.
-    const nodeFront = this.gridHighlighterShown;
+    this.emit("grid-highlighter-hidden", this.gridHighlighterShown,
+      this.state.grid.options);
     this.gridHighlighterShown = null;
-    this.emit("grid-highlighter-hidden", nodeFront, this.state.grid.options);
 
     // Erase grid highlighter state.
     this.state.grid = {};
   }
 
   /**
    * Show the box model highlighter for the given node.
    *
@@ -829,21 +782,30 @@ class HighlightersOverlay {
                     !nodeInfo.value.pseudoElement;
     return isShape && isEnabled && nodeInfo.value.toggleActive &&
            !this.state.shapes.options.transformMode;
   }
 
   onClick(event) {
     if (this._isRuleViewDisplayGrid(event.target)) {
       event.stopPropagation();
-      this.toggleGridHighlighter(this.inspector.selection.nodeFront, "rule");
+
+      let { store } = this.inspector;
+      let { grids, highlighterSettings } = store.getState();
+      let grid = grids.find(g => g.nodeFront == this.inspector.selection.nodeFront);
+
+      highlighterSettings.color = grid ? grid.color : DEFAULT_GRID_COLOR;
+
+      this.toggleGridHighlighter(this.inspector.selection.nodeFront, highlighterSettings,
+        "rule");
     }
 
     if (this._isRuleViewDisplayFlex(event.target)) {
       event.stopPropagation();
+
       this.toggleFlexboxHighlighter(this.inspector.selection.nodeFront);
     }
 
     if (this._isRuleViewShapeSwatch(event.target)) {
       event.stopPropagation();
 
       const view = this.inspector.getPanel("ruleview").view;
       const nodeInfo = view.getNodeInfo(event.target);
@@ -993,17 +955,16 @@ class HighlightersOverlay {
     this.inspector.target.off("will-navigate", this.onWillNavigate);
 
     this._lastHovered = null;
 
     this.inspector = null;
     this.highlighterUtils = null;
     this.supportsHighlighters = null;
     this.state = null;
-    this.store = null;
 
     this.boxModelHighlighterShown = null;
     this.flexboxHighlighterShown = null;
     this.geometryEditorHighlighterShown = null;
     this.gridHighlighterShown = null;
     this.hoveredHighlighterShown = null;
     this.selectorHighlighterShown = null;
     this.shapesHighlighterShown = null;