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: DPW4dqlDY0j
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -60,22 +60,28 @@ 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 = this.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");
+ // Stores a reference to the MarkupElementContainer of a highlighted grid.
+ // This is used to track when a MarkupElementContainer needs to be updated to
+ // inactivate its grid diplay markup badge on a grid highlighter change.
+ this.highlightedGridContainer = null;
+
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);
// Creating the popup to be used to show CSS suggestions.
// The popup will be attached to the toolbox document.
@@ -96,30 +102,34 @@ function MarkupView(inspector, frame, co
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._onCopy = this._onCopy.bind(this);
this._onCollapseAttributesPrefChange = this._onCollapseAttributesPrefChange.bind(this);
this._onDisplayChange = this._onDisplayChange.bind(this);
this._onFocus = this._onFocus.bind(this);
+ this._onGridHighlighterHidden = this._onGridHighlighterHidden.bind(this);
+ this._onGridHighlighterShown = this._onGridHighlighterShown.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);
// 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._frame.addEventListener("focus", this._onFocus);
+ this.highlighters.on("grid-highlighter-hidden", this._onGridHighlighterHidden);
+ this.highlighters.on("grid-highlighter-shown", this._onGridHighlighterShown);
this.inspector.selection.on("new-node-front", this._onNewSelection);
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.toolbox.on("picker-canceled", this._onToolboxPickerCanceled);
this.toolbox.on("picker-node-hovered", this._onToolboxPickerHover);
@@ -1874,16 +1884,18 @@ MarkupView.prototype = {
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._frame.removeEventListener("focus", this._onFocus);
+ this.highlighters.off("grid-highlighter-hidden", this._onGridHighlighterHidden);
+ this.highlighters.off("grid-highlighter-shown", this._onGridHighlighterShown);
this.inspector.selection.off("new-node-front", this._onNewSelection);
this.toolbox.off("picker-node-hovered", this._onToolboxPickerHover);
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._prefObserver.off(ATTR_COLLAPSE_ENABLED_PREF,
@@ -1901,16 +1913,18 @@ MarkupView.prototype = {
this.eventDetailsTooltip.destroy();
this.eventDetailsTooltip = null;
this.imagePreviewTooltip.destroy();
this.imagePreviewTooltip = null;
this.doc = null;
+ this.highlighters = null;
+ this.highlightedGridContainer = null;
this.win = null;
this._lastDropTarget = null;
this._lastDragTarget = null;
return this._destroyer;
},
@@ -1996,16 +2010,56 @@ MarkupView.prototype = {
nextSibling = null;
}
if (parent.nodeType !== nodeConstants.ELEMENT_NODE) {
return null;
}
return {parent, nextSibling};
+ },
+
+ /**
+ * Handler for "grid-highlighter-hidden" event emitted from the HighlightersOverlay.
+ * Updates the markup view to show an inactive grid display badge for the given
+ * nodeFront.
+ *
+ * @param {NodeFront} nodeFront
+ * The NodeFront of the grid container element for which the grid highlighter
+ * is hidden for.
+ */
+ _onGridHighlighterHidden(nodeFront) {
+ const container = this.getContainer(nodeFront);
+
+ if (container) {
+ container.update();
+ }
+
+ this.highlightedGridContainer = null;
+ },
+
+ /**
+ * Handler for "grid-highlighter-shown" event emitted from the HighlightersOverlay.
+ * Updates the markup view to show an active grid display badge for the given nodeFront.
+ *
+ * @param {NodeFront} nodeFront
+ * The NodeFront of the grid container element for which the grid highlighter
+ * is shown for.
+ */
+ _onGridHighlighterShown(nodeFront) {
+ const container = this.getContainer(nodeFront);
+
+ // Update the last highlighted grid element container to inactivate its badge.
+ if (this.highlightedGridContainer) {
+ this.highlightedGridContainer.update();
+ }
+
+ if (container) {
+ container.update();
+ }
}
};
/**
* Map a number from one range to another.
*/
function map(value, oldMin, oldMax, newMin, newMax) {
let ratio = oldMax - oldMin;
--- a/devtools/client/inspector/markup/test/browser_markup_display_node_01.js
+++ b/devtools/client/inspector/markup/test/browser_markup_display_node_01.js
@@ -26,33 +26,33 @@ const TEST_URI = `
add_task(async function() {
let {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);
let gridContainer = await getContainerForSelector("#grid", inspector);
- let gridDisplayNode = gridContainer.elt.querySelector(".markupview-display-badge");
+ let 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 #flex.");
await selectNode("#flex", inspector);
let flexContainer = await getContainerForSelector("#flex", inspector);
- let flexDisplayNode = flexContainer.elt.querySelector(".markupview-display-badge");
+ let 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);
let blockContainer = await getContainerForSelector("#block", inspector);
- let blockDisplayNode = blockContainer.elt.querySelector(".markupview-display-badge");
+ let 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);
let spanContainer = await getContainerForSelector("span", inspector);
- let spanDisplayNode = spanContainer.elt.querySelector(".markupview-display-badge");
+ let 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);
let container = await getContainerForSelector(selector, inspector);
- let displayNode = container.elt.querySelector(".markupview-display-badge");
+ let 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");
let 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() {
let { inspector } = await openInspectorForURL(TEST_URL);
let markupContainer = await getContainerForSelector("#events", inspector);
- let evHolder = markupContainer.elt.querySelector(".markupview-event-badge");
+ let evHolder = markupContainer.elt.querySelector(".markup-badge[data-event]");
let 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
@@ -25,17 +25,17 @@ add_task(async function() {
await toolbox.switchHost("bottom");
await runTests(inspector);
await toolbox.destroy();
});
async function runTests(inspector) {
let markupContainer = await getContainerForSelector("#events", inspector);
- let evHolder = markupContainer.elt.querySelector(".markupview-event-badge");
+ let evHolder = markupContainer.elt.querySelector(".markup-badge[data-event]");
let tooltip = inspector.markup.eventDetailsTooltip;
info("Clicking to open event tooltip.");
let onInspectorUpdated = inspector.once("inspector-updated");
let 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() {
let {inspector, toolbox} = await openInspectorForURL(
"data:text/html;charset=utf-8," + encodeURI(TEST_URL));
await inspector.markup.expandAll();
let container1 = await getContainerForSelector("#d1", inspector);
- let evHolder1 = container1.elt.querySelector(".markupview-event-badge");
+ let evHolder1 = container1.elt.querySelector(".markup-badge[data-event]");
let container2 = await getContainerForSelector("#d2", inspector);
- let evHolder2 = container2.elt.querySelector(".markupview-event-badge");
+ let evHolder2 = container2.elt.querySelector(".markup-badge[data-event]");
let 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) {
let {selector, expected, beforeTest, isSourceMapped} = test;
let container = await getContainerForSelector(selector, inspector);
if (typeof beforeTest === "function") {
await beforeTest(inspector, testActor);
}
- let evHolder = container.elt.querySelector(".markupview-event-badge");
+ let 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;
}
let tooltip = inspector.markup.eventDetailsTooltip;
--- a/devtools/client/inspector/markup/views/element-editor.js
+++ b/devtools/client/inspector/markup/views/element-editor.js
@@ -53,16 +53,17 @@ const DISPLAY_TYPES = {
* The container owning this editor.
* @param {Element} node
* The node being edited.
*/
function ElementEditor(container, node) {
this.container = container;
this.node = node;
this.markup = this.container.markup;
+ this.highlighters = this.markup.highlighters;
this.doc = this.markup.doc;
this._cssProperties = getCssProperties(this.markup.toolbox);
this.attrElements = new Map();
this.animationTimers = {};
this.elt = null;
this.tag = null;
@@ -166,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;
}
},
@@ -271,20 +272,29 @@ ElementEditor.prototype = {
}
// Update the event bubble display
this.eventNode.style.display = this.node.hasEventListeners ? "inline-block" : "none";
// Update the display type node
let showDisplayNode = this.node.displayType in DISPLAY_TYPES;
this.displayNode.textContent = this.node.displayType;
- this.displayNode.dataset.display = showDisplayNode ? this.node.displayType : "";
+ this.displayNode.dataset.display = this.node.displayType;
this.displayNode.style.display = showDisplayNode ? "inline-block" : "none";
this.displayNode.title = showDisplayNode ? DISPLAY_TYPES[this.node.displayType] : "";
+ if (this.highlighters.gridHighlighterShown === this.node) {
+ this.displayNode.classList.add("active");
+
+ // Store the MarkupElementContainer of the highlighted grid.
+ this.markup.highlightedGridContainer = this.container;
+ } else {
+ this.displayNode.classList.remove("active");
+ }
+
this.updateTextEditor();
},
/**
* Update the inline text editor in case of a single text child node.
*/
updateTextEditor: function() {
let node = this.node.inlineTextChild;
--- a/devtools/client/inspector/shared/highlighters-overlay.js
+++ b/devtools/client/inspector/shared/highlighters-overlay.js
@@ -402,19 +402,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.
- this.emit("grid-highlighter-hidden", this.gridHighlighterShown,
- this.state.grid.options);
+ const nodeFront = this.gridHighlighterShown;
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.
*
--- 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);
}