Bug 1367627 - Show an overlay of grid areas in Grid Highlighter. r?gl draft
authorMicah Tigley <tigleym@gmail.com>
Tue, 30 May 2017 22:18:09 -0600
changeset 586819 801c93b670ec20eecfe425c5fa7981db83473390
parent 586775 9a5c710587f9e64bf044602d5e988b152ef4f40c
child 631110 fef93318069e0e3cb61695ac1449670a96571e3b
push id61535
push userbmo:tigleym@gmail.com
push dateWed, 31 May 2017 04:29:22 +0000
reviewersgl
bugs1367627
milestone55.0a1
Bug 1367627 - Show an overlay of grid areas in Grid Highlighter. r?gl MozReview-Commit-ID: 10a8nmjgWwr
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 'Extend grid lines infinitely' 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 }
@@ -1061,25 +1071,126 @@ 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.
@@ -1175,17 +1286,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 +1308,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