Bug 1367627 - Show overlay of grid areas in Grid Highlighter. r=gl
authorMicah Tigley <tigleym@gmail.com>
Wed, 31 May 2017 18:37:43 -0600
changeset 361900 37a4d90166ba3efd9eea68ba98d1f5aa22384191
parent 361899 920a7465a372947b9b7ac096c6ae82a2449276e8
child 361901 11c66c13481d028d5a3ab76c4568316b643195c3
push id31948
push userkwierso@gmail.com
push dateFri, 02 Jun 2017 00:27:01 +0000
treeherdermozilla-central@1e229cf8933b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgl
bugs1367627
milestone55.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 1367627 - Show overlay of grid areas in Grid Highlighter. r=gl MozReview-Commit-ID: 9KWPltfpWlT
devtools/client/inspector/grids/actions/highlighter-settings.js
devtools/client/inspector/grids/actions/index.js
devtools/client/inspector/grids/components/Grid.js
devtools/client/inspector/grids/components/GridDisplaySettings.js
devtools/client/inspector/grids/grid-inspector.js
devtools/client/inspector/grids/reducers/highlighter-settings.js
devtools/client/inspector/grids/test/browser.ini
devtools/client/inspector/grids/test/browser_grids_display-setting-show-grid-areas.js
devtools/client/inspector/layout/layout.js
devtools/client/locales/en-US/layout.properties
devtools/client/preferences/devtools.js
devtools/server/actors/highlighters/css-grid.js
--- a/devtools/client/inspector/grids/actions/highlighter-settings.js
+++ b/devtools/client/inspector/grids/actions/highlighter-settings.js
@@ -1,22 +1,36 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {
+  UPDATE_SHOW_GRID_AREAS,
   UPDATE_SHOW_GRID_LINE_NUMBERS,
   UPDATE_SHOW_INFINITE_LINES,
 } = require("./index");
 
 module.exports = {
 
   /**
+   * Update the grid highlighter's show grid areas preference.
+   *
+   * @param  {Boolean} enabled
+   *         Whether or not the grid highlighter should show the grid areas.
+   */
+  updateShowGridAreas(enabled) {
+    return {
+      type: UPDATE_SHOW_GRID_AREAS,
+      enabled,
+    };
+  },
+
+  /**
    * Update the grid highlighter's show grid line numbers preference.
    *
    * @param  {Boolean} enabled
    *         Whether or not the grid highlighter should show the grid line numbers.
    */
   updateShowGridLineNumbers(enabled) {
     return {
       type: UPDATE_SHOW_GRID_LINE_NUMBERS,
--- a/devtools/client/inspector/grids/actions/index.js
+++ b/devtools/client/inspector/grids/actions/index.js
@@ -12,15 +12,18 @@ createEnum([
   "UPDATE_GRID_COLOR",
 
   // Update the grid highlighted state.
   "UPDATE_GRID_HIGHLIGHTED",
 
   // Update the entire grids state with the new list of grids.
   "UPDATE_GRIDS",
 
+  // Update the grid highlighter's show grid areas state.
+  "UPDATE_SHOW_GRID_AREAS",
+
   // Update the grid highlighter's show grid line numbers state.
   "UPDATE_SHOW_GRID_LINE_NUMBERS",
 
   // Update the grid highlighter's show infinite lines state.
   "UPDATE_SHOW_INFINITE_LINES",
 
 ], module.exports);
--- a/devtools/client/inspector/grids/components/Grid.js
+++ b/devtools/client/inspector/grids/components/Grid.js
@@ -26,37 +26,39 @@ module.exports = createClass({
     showGridOutline: PropTypes.bool.isRequired,
     onHideBoxModelHighlighter: PropTypes.func.isRequired,
     onSetGridOverlayColor: PropTypes.func.isRequired,
     onShowBoxModelHighlighterForNode: 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,
   },
 
   mixins: [ addons.PureRenderMixin ],
 
   render() {
     let {
       getSwatchColorPickerTooltip,
       grids,
       highlighterSettings,
       setSelectedNode,
       showGridOutline,
       onHideBoxModelHighlighter,
       onSetGridOverlayColor,
       onShowBoxModelHighlighterForNode,
+      onShowGridAreaHighlight,
+      onShowGridCellHighlight,
+      onToggleShowGridAreas,
       onToggleGridHighlighter,
       onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines,
-      onShowGridAreaHighlight,
-      onShowGridCellHighlight,
     } = this.props;
 
     return grids.length ?
       dom.div(
         {
           id: "layout-grid-container",
         },
         dom.div(
@@ -69,16 +71,17 @@ module.exports = createClass({
             setSelectedNode,
             onHideBoxModelHighlighter,
             onSetGridOverlayColor,
             onShowBoxModelHighlighterForNode,
             onToggleGridHighlighter,
           }),
           GridDisplaySettings({
             highlighterSettings,
+            onToggleShowGridAreas,
             onToggleShowGridLineNumbers,
             onToggleShowInfiniteLines,
           })
         ),
         showGridOutline ?
           GridOutline({
             grids,
             onShowGridAreaHighlight,
--- a/devtools/client/inspector/grids/components/GridDisplaySettings.js
+++ b/devtools/client/inspector/grids/components/GridDisplaySettings.js
@@ -11,22 +11,32 @@ const Types = require("../types");
 const { getStr } = require("../utils/l10n");
 
 module.exports = createClass({
 
   displayName: "GridDisplaySettings",
 
   propTypes: {
     highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired,
+    onToggleShowGridAreas: PropTypes.func.isRequired,
     onToggleShowGridLineNumbers: PropTypes.func.isRequired,
     onToggleShowInfiniteLines: PropTypes.func.isRequired,
   },
 
   mixins: [ addons.PureRenderMixin ],
 
+  onShowGridAreasCheckboxClick() {
+    let {
+      highlighterSettings,
+      onToggleShowGridAreas,
+    } = this.props;
+
+    onToggleShowGridAreas(!highlighterSettings.showGridAreasOverlay);
+  },
+
   onShowGridLineNumbersCheckboxClick() {
     let {
       highlighterSettings,
       onToggleShowGridLineNumbers,
     } = this.props;
 
     onToggleShowGridLineNumbers(!highlighterSettings.showGridLineNumbers);
   },
@@ -83,14 +93,31 @@ module.exports = createClass({
                 id: "grid-setting-show-grid-line-numbers",
                 type: "checkbox",
                 checked: highlighterSettings.showGridLineNumbers,
                 onChange: this.onShowGridLineNumbersCheckboxClick,
               }
             ),
             getStr("layout.displayNumbersOnLines")
           )
+        ),
+        dom.li(
+          {
+            className: "grid-settings-item",
+          },
+          dom.label(
+           {},
+           dom.input(
+             {
+               id: "grid-setting-show-grid-areas",
+               type: "checkbox",
+               checked: highlighterSettings.showGridAreasOverlay,
+               onChange: this.onShowGridAreasCheckboxClick,
+             }
+           ),
+           getStr("layout.displayGridAreas")
+          )
         )
       )
     );
   },
 
 });
--- a/devtools/client/inspector/grids/grid-inspector.js
+++ b/devtools/client/inspector/grids/grid-inspector.js
@@ -10,20 +10,22 @@ const { Task } = require("devtools/share
 const SwatchColorPickerTooltip = require("devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip");
 
 const {
   updateGridColor,
   updateGridHighlighted,
   updateGrids,
 } = require("./actions/grids");
 const {
+  updateShowGridAreas,
   updateShowGridLineNumbers,
   updateShowInfiniteLines,
 } = require("./actions/highlighter-settings");
 
+const SHOW_GRID_AREAS = "devtools.gridinspector.showGridAreas";
 const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers";
 const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
 
 // Default grid colors.
 const GRID_COLORS = [
   "#4B0082",
   "#BB9DFF",
   "#FFB53B",
@@ -49,16 +51,17 @@ function GridInspector(inspector, window
   this.onMarkupMutation = this.onMarkupMutation.bind(this);
   this.onReflow = this.onReflow.bind(this);
   this.onSetGridOverlayColor = this.onSetGridOverlayColor.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();
 }
 
 GridInspector.prototype = {
 
@@ -119,16 +122,17 @@ GridInspector.prototype = {
   getComponentProps() {
     return {
       getSwatchColorPickerTooltip: this.getSwatchColorPickerTooltip,
       onSetGridOverlayColor: this.onSetGridOverlayColor,
       onShowGridAreaHighlight: this.onShowGridAreaHighlight,
       onShowGridCellHighlight: this.onShowGridCellHighlight,
       onShowGridLineNamesHighlight: this.onShowGridLineNamesHighlight,
       onToggleGridHighlighter: this.onToggleGridHighlighter,
+      onToggleShowGridAreas: this.onToggleShowGridAreas,
       onToggleShowGridLineNumbers: this.onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines: this.onToggleShowInfiniteLines,
     };
   },
 
   /**
    * Returns the initial color linked to a grid container. Will attempt to check the
    * current grid highlighter state and the store.
@@ -210,19 +214,21 @@ GridInspector.prototype = {
   },
 
   /**
    * 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;
@@ -491,16 +497,38 @@ GridInspector.prototype = {
     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
+    *         Whether or not the grid highlighter should show the grid areas.
+    */
+  onToggleShowGridAreas(enabled) {
+    this.store.dispatch(updateShowGridAreas(enabled));
+    Services.prefs.setBoolPref(SHOW_GRID_AREAS, enabled);
+
+    let { grids } = this.store.getState();
+
+    for (let grid of grids) {
+      if (grid.highlighted) {
+        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
    * grids currently highlighted.
    *
    * @param  {Boolean} enabled
    *         Whether or not the grid highlighter should show the grid line numbers.
    */
--- a/devtools/client/inspector/grids/reducers/highlighter-settings.js
+++ b/devtools/client/inspector/grids/reducers/highlighter-settings.js
@@ -1,26 +1,34 @@
 /* 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 {
+  UPDATE_SHOW_GRID_AREAS,
   UPDATE_SHOW_GRID_LINE_NUMBERS,
   UPDATE_SHOW_INFINITE_LINES
 } = require("../actions/index");
 
 const INITIAL_HIGHLIGHTER_SETTINGS = {
+  showGridAreasOverlay: false,
   showGridLineNumbers: false,
   showInfiniteLines: false,
 };
 
 let reducers = {
 
+  [UPDATE_SHOW_GRID_AREAS](highlighterSettings, { enabled }) {
+    return Object.assign({}, highlighterSettings, {
+      showGridAreasOverlay: enabled,
+    });
+  },
+
   [UPDATE_SHOW_GRID_LINE_NUMBERS](highlighterSettings, { enabled }) {
     return Object.assign({}, highlighterSettings, {
       showGridLineNumbers: enabled,
     });
   },
 
   [UPDATE_SHOW_INFINITE_LINES](highlighterSettings, { enabled }) {
     return Object.assign({}, highlighterSettings, {
--- a/devtools/client/inspector/grids/test/browser.ini
+++ b/devtools/client/inspector/grids/test/browser.ini
@@ -8,16 +8,17 @@ support-files =
   !/devtools/client/inspector/test/head.js
   !/devtools/client/inspector/test/shared-head.js
   !/devtools/client/shared/test/test-actor.js
   !/devtools/client/shared/test/test-actor-registry.js
   !/devtools/client/framework/test/shared-redux-head.js
 
 [browser_grids_display-setting-extend-grid-lines.js]
 [browser_grids_display-setting-show-grid-line-numbers.js]
+[browser_grids_display-setting-show-grid-areas.js]
 [browser_grids_grid-list-color-picker-on-ESC.js]
 [browser_grids_grid-list-color-picker-on-RETURN.js]
 [browser_grids_grid-list-element-rep.js]
 [browser_grids_grid-list-no-grids.js]
 [browser_grids_grid-list-on-mutation-element-added.js]
 [browser_grids_grid-list-on-mutation-element-removed.js]
 [browser_grids_grid-list-toggle-multiple-grids.js]
 [browser_grids_grid-list-toggle-single-grid.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/grids/test/browser_grids_display-setting-show-grid-areas.js
@@ -0,0 +1,51 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests that the 'Display grid areas' grid highlighter setting will update
+// the redux store and pref setting.
+
+const TEST_URI = `
+  <style type='text/css'>
+    #grid {
+      display: grid;
+    }
+  </style>
+  <div id="grid">
+    <div id="cell1">cell1</div>
+    <div id="cell2">cell2</div>
+  </div>
+`;
+
+const SHOW_GRID_AREAS_PREF = "devtools.gridinspector.showGridAreas";
+
+add_task(function* () {
+  yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
+  let { inspector, gridInspector } = yield openLayoutView();
+  let { document: doc } = gridInspector;
+  let { store } = inspector;
+
+  yield selectNode("#grid", inspector);
+  let checkbox = doc.getElementById("grid-setting-show-grid-areas");
+
+  ok(!Services.prefs.getBoolPref(SHOW_GRID_AREAS_PREF),
+    "'Display grid areas' is pref off by default.");
+
+  info("Toggling ON the 'Display grid areas' setting.");
+  let onCheckboxChange = waitUntilState(store, state =>
+    state.highlighterSettings.showGridAreasOverlay);
+  checkbox.click();
+  yield onCheckboxChange;
+
+  info("Toggling OFF the 'Display grid areas' setting.");
+  onCheckboxChange = waitUntilState(store, state =>
+    !state.highlighterSettings.showGridAreasOverlay);
+  checkbox.click();
+  yield onCheckboxChange;
+
+  ok(!Services.prefs.getBoolPref(SHOW_GRID_AREAS_PREF),
+    "'Display grid areas' is pref off.");
+
+  Services.prefs.clearUserPref(SHOW_GRID_AREAS_PREF);
+});
--- a/devtools/client/inspector/layout/layout.js
+++ b/devtools/client/inspector/layout/layout.js
@@ -46,16 +46,17 @@ LayoutView.prototype = {
 
     let {
       getSwatchColorPickerTooltip,
       onSetGridOverlayColor,
       onShowGridAreaHighlight,
       onShowGridCellHighlight,
       onShowGridLineNamesHighlight,
       onToggleGridHighlighter,
+      onToggleShowGridAreas,
       onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines,
     } = this.inspector.gridInspector.getComponentProps();
 
     let app = App({
       getSwatchColorPickerTooltip,
       setSelectedNode,
       /**
@@ -75,16 +76,17 @@ LayoutView.prototype = {
       onShowBoxModelEditor,
       onShowBoxModelHighlighter,
       onShowBoxModelHighlighterForNode,
       onShowGridAreaHighlight,
       onShowGridCellHighlight,
       onShowGridLineNamesHighlight,
       onToggleGeometryEditor,
       onToggleGridHighlighter,
+      onToggleShowGridAreas,
       onToggleShowGridLineNumbers,
       onToggleShowInfiniteLines,
     });
 
     let provider = createElement(Provider, {
       store: this.store,
       id: "layoutview",
       title: INSPECTOR_L10N.getStr("inspector.sidebar.layoutViewTitle2"),
--- a/devtools/client/locales/en-US/layout.properties
+++ b/devtools/client/locales/en-US/layout.properties
@@ -7,16 +7,20 @@
 # The Layout Inspector may need to be enabled in about:config by setting
 # devtools.layoutview.enabled to true.
 
 # LOCALIZATION NOTE (layout.cannotShowGridOutline, layout.cannotSHowGridOutline.title):
 # In the case where the grid outline cannot be effectively displayed.
 layout.cannotShowGridOutline=Cannot show outline for this grid
 layout.cannotShowGridOutline.title=The selected grid’s outline cannot effectively fit inside the layout panel for it to be usable.
 
+# LOCALIZATION NOTE (layout.displayGridAreas): Label of the display grid areas setting
+# option in the CSS Grid pane.
+layout.displayGridAreas=Display grid areas
+
 # LOCALIZATION NOTE (layout.displayNumbersOnLines): Label of the display numbers on lines
 # setting option in the CSS Grid pane.
 layout.displayNumbersOnLines=Display numbers on lines
 
 # LOCALIZATION NOTE (layout.extendGridLinesInfinitely): Label of the extend grid lines
 # infinitely setting option in the CSS Grid pane.
 layout.extendGridLinesInfinitely=Extend grid lines infinitely
 
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -68,16 +68,17 @@ pref("devtools.inspector.colorWidget.ena
 
 // Enable the Font Inspector
 pref("devtools.fontinspector.enabled", true);
 
 // Enable the Layout View
 pref("devtools.layoutview.enabled", false);
 
 // Grid highlighter preferences
+pref("devtools.gridinspector.showGridAreas", false);
 pref("devtools.gridinspector.showGridLineNumbers", false);
 pref("devtools.gridinspector.showGridOutline", false);
 pref("devtools.gridinspector.showInfiniteLines", false);
 
 // By how many times eyedropper will magnify pixels
 pref("devtools.eyedropper.zoom", 6);
 
 // Enable to collapse attributes that are too long.
--- a/devtools/server/actors/highlighters/css-grid.js
+++ b/devtools/server/actors/highlighters/css-grid.js
@@ -35,29 +35,35 @@ const CSS_GRID_ENABLED_PREF = "layout.cs
 
 const DEFAULT_GRID_COLOR = "#4B0082";
 
 const COLUMNS = "cols";
 const ROWS = "rows";
 
 const GRID_FONT_SIZE = 10;
 const GRID_FONT_FAMILY = "sans-serif";
+const GRID_AREA_NAME_FONT_SIZE = "20";
 
 const GRID_LINES_PROPERTIES = {
   "edge": {
     lineDash: [0, 0],
     alpha: 1,
   },
   "explicit": {
     lineDash: [5, 3],
     alpha: 0.75,
   },
   "implicit": {
     lineDash: [2, 2],
     alpha: 0.5,
+  },
+  "areaEdge": {
+    lineDash: [0, 0],
+    alpha: 1,
+    lineWidth: 3,
   }
 };
 
 const GRID_GAP_PATTERN_WIDTH = 14; // px
 const GRID_GAP_PATTERN_HEIGHT = 14; // px
 const GRID_GAP_PATTERN_LINE_DASH = [5, 3]; // px
 const GRID_GAP_ALPHA = 0.5;
 
@@ -192,16 +198,20 @@ function drawRoundedRect(ctx, x, y, widt
  *     @param  {String} colorValue
  *     The color that should be used to draw the highlighter for this grid.
  * - showAllGridAreas(isShown)
  *     @param  {Boolean} isShown
  *     Shows all the grid area highlights for the current grid if isShown is true.
  * - showGridArea(areaName)
  *     @param  {String} areaName
  *     Shows the grid area highlight for the given area name.
+ * - showGridAreasOverlay(isShown)
+ *     @param  {Boolean} isShown
+ *     Displays an overlay of all the grid areas for the current grid container if
+ *     isShown is true.
  * - showGridCell({ gridFragmentIndex: Number, rowNumber: Number, columnNumber: Number })
  *     @param  {Object} { gridFragmentIndex: Number, rowNumber: Number,
  *                        columnNumber: Number }
  *     An object containing the grid fragment index, row and column numbers to the
  *     corresponding grid cell to highlight for the current grid.
  * - showGridLineNames({ gridFragmentIndex: Number, lineNumber: Number,
  *                       type: String })
  *     @param  {Object} { gridFragmentIndex: Number, lineNumber: Number }
@@ -946,17 +956,17 @@ CssGridHighlighter.prototype = extend(Au
       this._canvasPosition.x = Math.max(rightThreshold, leftBoundary);
       hasUpdated = true;
     }
 
     return hasUpdated;
   },
 
   /**
-   *  Updates the <canvas> element's style in accordance with the current window's
+   * Updates the <canvas> element's style in accordance with the current window's
    * devicePixelRatio, and the position calculated in `calculateCanvasPosition`; it also
    * clears the drawing context.
    */
   updateCanvasElement() {
     let ratio = parseFloat((this.win.devicePixelRatio || 1).toFixed(2));
     let size = CANVAS_SIZE / ratio;
     let { x, y } = this._canvasPosition;
 
@@ -1061,26 +1071,125 @@ CssGridHighlighter.prototype = extend(Au
 
     this.renderLines(fragment.cols, COLUMNS, "left", "top", "height",
                      this.getFirstRowLinePos(fragment),
                      this.getLastRowLinePos(fragment));
     this.renderLines(fragment.rows, ROWS, "top", "left", "width",
                      this.getFirstColLinePos(fragment),
                      this.getLastColLinePos(fragment));
 
+    if (this.options.showGridAreasOverlay) {
+      this.renderGridAreaOverlay();
+    }
+
     // Line numbers are rendered in a 2nd step to avoid overlapping with existing lines.
     if (this.options.showGridLineNumbers) {
       this.renderLineNumbers(fragment.cols, COLUMNS, "left", "top",
                        this.getFirstRowLinePos(fragment));
       this.renderLineNumbers(fragment.rows, ROWS, "top", "left",
                        this.getFirstColLinePos(fragment));
     }
   },
 
   /**
+   * Renders the grid area overlay on the css grid highlighter canvas.
+   */
+  renderGridAreaOverlay() {
+    let padding = 1;
+
+    for (let i = 0; i < this.gridData.length; i++) {
+      let fragment = this.gridData[i];
+
+      for (let area of fragment.areas) {
+        let { rowStart, rowEnd, columnStart, columnEnd } = area;
+
+        // Draw the line edges for the grid area
+        const areaColStart = fragment.cols.lines[columnStart - 1];
+        const areaColEnd = fragment.cols.lines[columnEnd - 1];
+
+        const areaRowStart = fragment.rows.lines[rowStart - 1];
+        const areaRowEnd = fragment.rows.lines[rowEnd - 1];
+
+        const areaColStartLinePos = areaColStart.start + areaColStart.breadth;
+        const areaRowStartLinePos = areaRowStart.start + areaRowStart.breadth;
+
+        this.renderLine(areaColStartLinePos + padding,
+                        areaRowStartLinePos, areaRowEnd.start,
+                        COLUMNS, "areaEdge");
+        this.renderLine(areaColEnd.start - padding,
+                        areaRowStartLinePos, areaRowEnd.start,
+                        COLUMNS, "areaEdge");
+
+        this.renderLine(areaRowStartLinePos + padding,
+                        areaColStartLinePos, areaColEnd.start,
+                        ROWS, "areaEdge");
+        this.renderLine(areaRowEnd.start - padding,
+                        areaColStartLinePos, areaColEnd.start,
+                        ROWS, "areaEdge");
+
+        this.renderGridAreaName(fragment, area);
+      }
+    }
+
+    this.ctx.restore();
+  },
+
+  /**
+   * Render grid area name on the containing grid area cell.
+   *
+   * @param  {Object} fragment
+   *         The grid fragment of the grid container.
+   * @param  {Object} area
+   *         The area overlay to render on the CSS highlighter canvas.
+   */
+  renderGridAreaName(fragment, area) {
+    let { rowStart, rowEnd, columnStart, columnEnd } = area;
+    let { devicePixelRatio } = this.win;
+    let displayPixelRatio = getDisplayPixelRatio(this.win);
+    let currentZoom = getCurrentZoom(this.win);
+    let offset = (displayPixelRatio / 2) % 1;
+    let fontSize = (GRID_AREA_NAME_FONT_SIZE * displayPixelRatio);
+
+    this.ctx.save();
+
+    let canvasX = Math.round(this._canvasPosition.x * devicePixelRatio);
+    let canvasY = Math.round(this._canvasPosition.y * devicePixelRatio);
+    this.ctx.translate(offset - canvasX, offset - canvasY);
+
+    this.ctx.font = (fontSize * currentZoom) + "px " + GRID_FONT_FAMILY;
+    this.ctx.strokeStyle = this.color;
+    this.ctx.fillStyle = this.color;
+    this.ctx.textAlign = "center";
+    this.ctx.textBaseline = "middle";
+
+    // Draw the text for the grid area name.
+    for (let rowNumber = rowStart; rowNumber < rowEnd; rowNumber++) {
+      for (let columnNumber = columnStart; columnNumber < columnEnd; columnNumber++) {
+        let row = fragment.rows.tracks[rowNumber - 1];
+        let column = fragment.cols.tracks[columnNumber - 1];
+
+        // Check if the font size is exceeds the bounds of the containing grid cell.
+        if (fontSize > column.breadth || fontSize > row.breadth) {
+          fontSize = (column.breadth + row.breadth) / 2;
+          this.ctx.font = (fontSize * currentZoom) + "px " + GRID_FONT_FAMILY;
+        }
+
+        let x = column.start + column.breadth / 2;
+        let y = row.start + row.breadth / 2;
+
+        [x, y] = apply(this.currentMatrix, [x, y]);
+
+        this.ctx.fillText(area.name, x, y);
+      }
+    }
+
+    this.ctx.restore();
+  },
+
+  /**
    * Render the grid lines given the grid dimension information of the
    * column or row lines.
    *
    * @param  {GridDimension} gridDimension
    *         Column or row grid dimension object.
    * @param  {Object} quad.bounds
    *         The content bounds of the box model region quads.
    * @param  {String} dimensionType
@@ -1175,17 +1284,16 @@ CssGridHighlighter.prototype = extend(Au
 
     linePos = Math.round(linePos);
     startPos = Math.round(startPos);
 
     this.ctx.save();
     this.ctx.setLineDash(GRID_LINES_PROPERTIES[lineType].lineDash);
     this.ctx.beginPath();
     this.ctx.translate(offset - x, offset - y);
-    this.ctx.lineWidth = lineWidth;
 
     if (dimensionType === COLUMNS) {
       if (isFinite(endPos)) {
         endPos = Math.round(endPos);
       } else {
         endPos = CANVAS_INFINITY;
         startPos = -endPos;
       }
@@ -1198,16 +1306,22 @@ CssGridHighlighter.prototype = extend(Au
         startPos = -endPos;
       }
       drawLine(this.ctx, startPos, linePos, endPos, linePos, this.currentMatrix);
     }
 
     this.ctx.strokeStyle = this.color;
     this.ctx.globalAlpha = GRID_LINES_PROPERTIES[lineType].alpha;
 
+    if (GRID_LINES_PROPERTIES[lineType].lineWidth) {
+      this.ctx.lineWidth = GRID_LINES_PROPERTIES[lineType].lineWidth * devicePixelRatio;
+    } else {
+      this.ctx.lineWidth = lineWidth;
+    }
+
     this.ctx.stroke();
     this.ctx.restore();
   },
 
   /**
    * Render the grid line number on the css grid highlighter canvas.
    *
    * @param  {Number} lineNumber