Bug 1456680 - Part 3: Show an active state for the grid markup badge if its grid container is highlighted. r=pbro draft
authorGabriel Luong <gabriel.luong@gmail.com>
Fri, 08 Jun 2018 23:21:06 -0400
changeset 806334 1d432313c040f7cb3ad30cfeae0482f646bcbe8e
parent 806333 ad337f9e2fcf85ddff068a4a1afe0739ef8a6220
push id112862
push userbmo:gl@mozilla.com
push dateSat, 09 Jun 2018 03:24:40 +0000
reviewerspbro
bugs1456680
milestone62.0a1
Bug 1456680 - Part 3: Show an active state for the grid markup badge if its grid container is highlighted. r=pbro highlighted. MozReview-Commit-ID: 5WgwbI453a4
devtools/client/inspector/markup/markup.js
devtools/client/inspector/markup/test/browser_markup_display_node_01.js
devtools/client/inspector/markup/test/browser_markup_display_node_02.js
devtools/client/inspector/markup/test/browser_markup_events-overflow.js
devtools/client/inspector/markup/test/browser_markup_events-windowed-host.js
devtools/client/inspector/markup/test/browser_markup_events_click_to_close.js
devtools/client/inspector/markup/test/helper_events_test_runner.js
devtools/client/inspector/markup/views/element-container.js
devtools/client/inspector/markup/views/element-editor.js
devtools/client/themes/markup.css
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -60,16 +60,17 @@ const ATTR_COLLAPSE_LENGTH_PREF = "devto
  *         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.highlighters = inspector.highlighters;
   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.telemetry = this.inspector.telemetry;
 
   this.maxChildren = Services.prefs.getIntPref("devtools.markup.pagesize",
@@ -1909,16 +1910,17 @@ MarkupView.prototype = {
 
     this.eventDetailsTooltip.destroy();
     this.eventDetailsTooltip = null;
 
     this.imagePreviewTooltip.destroy();
     this.imagePreviewTooltip = null;
 
     this.doc = null;
+    this.highlighters = null;
     this.win = null;
 
     this._lastDropTarget = null;
     this._lastDragTarget = null;
 
     return this._destroyer;
   },
 
--- a/devtools/client/inspector/markup/test/browser_markup_display_node_01.js
+++ b/devtools/client/inspector/markup/test/browser_markup_display_node_01.js
@@ -35,42 +35,46 @@ add_task(async function() {
   await pushPref("layout.css.grid-template-subgrid-value.enabled", true);
 
   const {inspector} = await openInspectorForURL("data:text/html;charset=utf-8," +
     encodeURIComponent(TEST_URI));
 
   info("Check the display node is shown and the value of #grid.");
   await selectNode("#grid", inspector);
   const gridContainer = await getContainerForSelector("#grid", inspector);
-  const gridDisplayNode = gridContainer.elt.querySelector(".markupview-display-badge");
+  const gridDisplayNode = gridContainer.elt.querySelector(
+    ".markup-badge[data-display]");
   is(gridDisplayNode.textContent, "grid", "Got the correct display type for #grid.");
   is(gridDisplayNode.style.display, "inline-block", "#grid display node is shown.");
 
   info("Check the display node is shown and the value of #subgrid.");
   await selectNode("#subgrid", inspector);
   const subgridContainer = await getContainerForSelector("#subgrid", inspector);
   const subgridDisplayNode = subgridContainer.elt.querySelector(
-    ".markupview-display-badge");
+    ".markup-badge[data-display]");
   is(subgridDisplayNode.textContent, "subgrid",
     "Got the correct display type for #subgrid");
   is(subgridDisplayNode.style.display, "inline-block", "#subgrid display node is shown");
 
   info("Check the display node is shown and the value of #flex.");
   await selectNode("#flex", inspector);
   const flexContainer = await getContainerForSelector("#flex", inspector);
-  const flexDisplayNode = flexContainer.elt.querySelector(".markupview-display-badge");
+  const flexDisplayNode = flexContainer.elt.querySelector(
+    ".markup-badge[data-display]");
   is(flexDisplayNode.textContent, "flex", "Got the correct display type for #flex");
   is(flexDisplayNode.style.display, "inline-block", "#flex display node is shown.");
 
   info("Check the display node is shown and the value of #block.");
   await selectNode("#block", inspector);
   const blockContainer = await getContainerForSelector("#block", inspector);
-  const blockDisplayNode = blockContainer.elt.querySelector(".markupview-display-badge");
+  const blockDisplayNode = blockContainer.elt.querySelector(
+    ".markup-badge[data-display]");
   is(blockDisplayNode.textContent, "block", "Got the correct display type for #block");
   is(blockDisplayNode.style.display, "none", "#block display node is hidden.");
 
   info("Check the display node is shown and the value of span.");
   await selectNode("span", inspector);
   const spanContainer = await getContainerForSelector("span", inspector);
-  const spanDisplayNode = spanContainer.elt.querySelector(".markupview-display-badge");
+  const spanDisplayNode = spanContainer.elt.querySelector(
+    ".markup-badge[data-display]");
   is(spanDisplayNode.textContent, "inline", "Got the correct display type for #span");
   is(spanDisplayNode.style.display, "none", "span display node is hidden.");
 });
--- a/devtools/client/inspector/markup/test/browser_markup_display_node_02.js
+++ b/devtools/client/inspector/markup/test/browser_markup_display_node_02.js
@@ -92,17 +92,17 @@ add_task(async function() {
     await runTestData(inspector, testActor, data);
   }
 });
 
 async function runTestData(inspector, testActor,
                       {selector, before, changeStyle, after}) {
   await selectNode(selector, inspector);
   const container = await getContainerForSelector(selector, inspector);
-  const displayNode = container.elt.querySelector(".markupview-display-badge");
+  const displayNode = container.elt.querySelector(".markup-badge[data-display]");
 
   is(displayNode.textContent, before.textContent,
     `Got the correct before display type for ${selector}: ${displayNode.textContent}`);
   is(displayNode.style.display, before.display,
     `Got the correct before display style for ${selector}: ${displayNode.style.display}`);
 
   info("Listening for the display-change event");
   const onDisplayChanged = inspector.markup.walker.once("display-change");
--- a/devtools/client/inspector/markup/test/browser_markup_events-overflow.js
+++ b/devtools/client/inspector/markup/test/browser_markup_events-overflow.js
@@ -29,17 +29,17 @@ const TEST_DATA = [
     alignTop: false,
   },
 ];
 
 add_task(async function() {
   const { inspector } = await openInspectorForURL(TEST_URL);
 
   const markupContainer = await getContainerForSelector("#events", inspector);
-  const evHolder = markupContainer.elt.querySelector(".markupview-event-badge");
+  const evHolder = markupContainer.elt.querySelector(".markup-badge[data-event]");
   const tooltip = inspector.markup.eventDetailsTooltip;
 
   info("Clicking to open event tooltip.");
   EventUtils.synthesizeMouseAtCenter(evHolder, {},
     inspector.markup.doc.defaultView);
   await tooltip.once("shown");
   info("EventTooltip visible.");
 
--- a/devtools/client/inspector/markup/test/browser_markup_events-windowed-host.js
+++ b/devtools/client/inspector/markup/test/browser_markup_events-windowed-host.js
@@ -27,17 +27,17 @@ add_task(async function() {
   await toolbox.switchHost("bottom");
   await runTests(inspector);
 
   await toolbox.destroy();
 });
 
 async function runTests(inspector) {
   const markupContainer = await getContainerForSelector("#events", inspector);
-  const evHolder = markupContainer.elt.querySelector(".markupview-event-badge");
+  const evHolder = markupContainer.elt.querySelector(".markup-badge[data-event]");
   const tooltip = inspector.markup.eventDetailsTooltip;
 
   info("Clicking to open event tooltip.");
 
   let onInspectorUpdated = inspector.once("inspector-updated");
   const onTooltipShown = tooltip.once("shown");
   EventUtils.synthesizeMouseAtCenter(evHolder, {}, inspector.markup.doc.defaultView);
 
--- a/devtools/client/inspector/markup/test/browser_markup_events_click_to_close.js
+++ b/devtools/client/inspector/markup/test/browser_markup_events_click_to_close.js
@@ -22,20 +22,20 @@ const TEST_URL = `
 
 add_task(async function() {
   const {inspector, toolbox} = await openInspectorForURL(
     "data:text/html;charset=utf-8," + encodeURI(TEST_URL));
 
   await inspector.markup.expandAll();
 
   const container1 = await getContainerForSelector("#d1", inspector);
-  const evHolder1 = container1.elt.querySelector(".markupview-event-badge");
+  const evHolder1 = container1.elt.querySelector(".markup-badge[data-event]");
 
   const container2 = await getContainerForSelector("#d2", inspector);
-  const evHolder2 = container2.elt.querySelector(".markupview-event-badge");
+  const evHolder2 = container2.elt.querySelector(".markup-badge[data-event]");
 
   const tooltip = inspector.markup.eventDetailsTooltip;
 
   info("Click the event icon for the first element");
   let onShown = tooltip.once("shown");
   EventUtils.synthesizeMouseAtCenter(evHolder1, {},
     inspector.markup.doc.defaultView);
   await onShown;
--- a/devtools/client/inspector/markup/test/helper_events_test_runner.js
+++ b/devtools/client/inspector/markup/test/helper_events_test_runner.js
@@ -50,17 +50,17 @@ async function runEventPopupTests(url, t
 async function checkEventsForNode(test, inspector, testActor) {
   const {selector, expected, beforeTest, isSourceMapped} = test;
   const container = await getContainerForSelector(selector, inspector);
 
   if (typeof beforeTest === "function") {
     await beforeTest(inspector, testActor);
   }
 
-  const evHolder = container.elt.querySelector(".markupview-event-badge");
+  const evHolder = container.elt.querySelector(".markup-badge[data-event]");
 
   if (expected.length === 0) {
     // if no event is expected, simply check that the event bubble is hidden
     is(evHolder.style.display, "none", "event bubble should be hidden");
     return;
   }
 
   const tooltip = inspector.markup.eventDetailsTooltip;
--- a/devtools/client/inspector/markup/views/element-container.js
+++ b/devtools/client/inspector/markup/views/element-container.js
@@ -29,34 +29,56 @@ loader.lazyRequireGetter(this, "setEvent
  *         The markup view that owns this container.
  * @param  {NodeFront} node
  *         The node to display.
  */
 function MarkupElementContainer(markupView, node) {
   MarkupContainer.prototype.initialize.call(this, markupView, node,
     "elementcontainer");
 
+  this.onGridHighlighterChange = this.onGridHighlighterChange.bind(this);
+
+  this.markup.highlighters.on("grid-highlighter-hidden", this.onGridHighlighterChange);
+  this.markup.highlighters.on("grid-highlighter-shown", this.onGridHighlighterChange);
+
   if (node.nodeType === nodeConstants.ELEMENT_NODE) {
     this.editor = new ElementEditor(this, node);
   } else {
     throw new Error("Invalid node for MarkupElementContainer");
   }
 
   this.tagLine.appendChild(this.editor.elt);
 }
 
 MarkupElementContainer.prototype = extend(MarkupContainer.prototype, {
+  destroy: function() {
+    this.markup.highlighters.off("grid-highlighter-hidden", this.onGridHighlighterChange);
+    this.markup.highlighters.off("grid-highlighter-shown", this.onGridHighlighterChange);
+
+    MarkupContainer.prototype.destroy.call(this);
+  },
+
   onContainerClick: function(event) {
     if (!event.target.hasAttribute("data-event")) {
       return;
     }
 
     this._buildEventTooltipContent(event.target);
   },
 
+  /**
+   * Handler for "grid-highlighter-hidden" and "grid-highlighter-shown" event emitted from
+   * the HighlightersOverlay. Toggles the active state of the display badge if it matches
+   * the highlighted grid node.
+   */
+  onGridHighlighterChange: function() {
+    this.editor.displayNode.classList.toggle("active",
+      this.markup.highlighters.gridHighlighterShown === this.node);
+  },
+
   async _buildEventTooltipContent(target) {
     const tooltip = this.markup.eventDetailsTooltip;
 
     await tooltip.hide();
 
     const listenerInfo = await this.node.getEventListenerInfo();
 
     const toolbox = this.markup.toolbox;
--- a/devtools/client/inspector/markup/views/element-editor.js
+++ b/devtools/client/inspector/markup/views/element-editor.js
@@ -167,24 +167,24 @@ ElementEditor.prototype = {
 
     this.closeTag = this.doc.createElement("span");
     this.closeTag.classList.add("tag", "theme-fg-color3");
     close.appendChild(this.closeTag);
 
     close.appendChild(this.doc.createTextNode(">"));
 
     this.eventNode = this.doc.createElement("div");
-    this.eventNode.classList.add("markupview-event-badge");
+    this.eventNode.classList.add("markup-badge");
     this.eventNode.dataset.event = "true";
     this.eventNode.textContent = "event";
     this.eventNode.title = INSPECTOR_L10N.getStr("markupView.event.tooltiptext");
     this.elt.appendChild(this.eventNode);
 
     this.displayNode = this.doc.createElement("div");
-    this.displayNode.classList.add("markupview-display-badge");
+    this.displayNode.classList.add("markup-badge");
     this.elt.appendChild(this.displayNode);
   },
 
   set selected(value) {
     if (this.textEditor) {
       this.textEditor.selected = value;
     }
   },
--- a/devtools/client/themes/markup.css
+++ b/devtools/client/themes/markup.css
@@ -1,25 +1,27 @@
 /* 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/. */
 
 :root {
+  --markup-badge-active-background-color: var(--blue-50);
   --markup-badge-background-color: var(--grey-20);
   --markup-badge-border-color: #CACAD1;
   --markup-badge-color: var(--grey-90);
   --markup-badge-hover-background-color: #DFDFE8;
   --markup-hidden-attr-name-color: #BA89B8;
   --markup-hidden-attr-value-color: #5C6D87;
   --markup-hidden-punctuation-color: #909090;
   --markup-hidden-tag-color: #97A4B3;
   --markup-outline: var(--theme-splitter-color);
 }
 
 .theme-dark:root {
+  --markup-badge-active-background-color: var(--blue-60);
   --markup-badge-background-color: var(--grey-70);
   --markup-badge-border-color: var(--grey-50);
   --markup-badge-color: var(--grey-30);
   --markup-badge-hover-background-color: var(--grey-80);
   --markup-hidden-attr-name-color: #B07EB3;
   --markup-hidden-attr-value-color: #9893A3;
   --markup-hidden-punctuation-color: #909090;
   --markup-hidden-tag-color: #AFB5BF;
@@ -389,33 +391,41 @@ ul.children + .tag-line::before {
   color: var(--theme-selection-color);
 }
 
 /* Applicable to the DOCTYPE */
 .doctype {
   font-style: italic;
 }
 
-/* Display and Event Badges */
-.markupview-display-badge,
-.markupview-event-badge {
+/* Markup Badges */
+.markup-badge {
   display: none;
   font-size: 9px;
   font-weight: normal;
   line-height: 11px;
   vertical-align: 1px;
   border: 1px solid var(--markup-badge-border-color);
   border-radius: 3px;
   padding: 0px 2px;
   margin-inline-start: 5px;
   -moz-user-select: none;
   background-color: var(--markup-badge-background-color);
   color: var(--markup-badge-color);
 }
 
-.markupview-event-badge {
+.markup-badge.active {
+  background-color: var(--markup-badge-active-background-color);
+  border-color: var(--theme-selection-color);
+  color: var(--theme-selection-color);
+}
+
+.markup-badge[data-display="grid"],
+.markup-badge[data-event] {
   cursor: pointer;
 }
 
-.markupview-event-badge:focus,
-.markupview-event-badge:hover {
+.markup-badge[data-display="grid"]:focus,
+.markup-badge[data-display="grid"]:hover,
+.markup-badge[data-event]:focus,
+.markup-badge[data-event]:hover {
   background-color: var(--markup-badge-hover-background-color);
 }