Bug 1053898 - Update SlottedNodeEditor to show a reveal link on hover;r=bgrins draft
authorJulian Descottes <jdescottes@mozilla.com>
Wed, 07 Mar 2018 11:50:21 +0100
changeset 774748 d6723178568df5ebb736292851622e1e345ec365
parent 773678 426fa586e9fa6212c7f9283946d3242b2296543f
child 774749 2ea9757d0335b4eec4ca3bc4b416a68cff457822
child 774775 620b1eba4d234b1333672f31862f6f349f962e2c
push id104491
push userjdescottes@mozilla.com
push dateThu, 29 Mar 2018 14:09:04 +0000
reviewersbgrins
bugs1053898
milestone61.0a1
Bug 1053898 - Update SlottedNodeEditor to show a reveal link on hover;r=bgrins MozReview-Commit-ID: 7j7zmApH5h6
devtools/client/inspector/markup/views/slotted-node-container.js
devtools/client/inspector/markup/views/slotted-node-editor.js
devtools/client/locales/en-US/inspector.properties
devtools/client/themes/markup.css
--- a/devtools/client/inspector/markup/views/slotted-node-container.js
+++ b/devtools/client/inspector/markup/views/slotted-node-container.js
@@ -13,16 +13,44 @@ function SlottedNodeContainer(markupView
     "slottednodecontainer");
 
   this.editor = new SlottedNodeEditor(this, node);
   this.tagLine.appendChild(this.editor.elt);
   this.hasChildren = false;
 }
 
 SlottedNodeContainer.prototype = extend(MarkupContainer.prototype, {
+  _onMouseDown: function(event) {
+    if (event.target.classList.contains("reveal-link")) {
+      event.stopPropagation();
+      event.preventDefault();
+      return;
+    }
+    MarkupContainer.prototype._onMouseDown.call(this, event);
+  },
+
+  /**
+   * Slotted node containers never display children and should not react to toggle.
+   */
+  _onToggle: function(event) {
+    event.stopPropagation();
+  },
+
+  onContainerClick: async function(event) {
+    if (!event.target.classList.contains("reveal-link")) {
+      return;
+    }
+
+    let selection = this.markup.inspector.selection;
+    if (selection.nodeFront != this.node || selection.isSlotted()) {
+      let reason = "reveal-from-slot";
+      this.markup.inspector.selection.setNodeFront(this.node, { reason });
+    }
+  },
+
   isDraggable: function() {
     return false;
   },
 
   isSlotted: function() {
     return true;
   }
 });
--- a/devtools/client/inspector/markup/views/slotted-node-editor.js
+++ b/devtools/client/inspector/markup/views/slotted-node-editor.js
@@ -1,45 +1,55 @@
 /* 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 {LocalizationHelper} = require("devtools/shared/l10n");
+const INSPECTOR_L10N =
+      new LocalizationHelper("devtools/client/locales/inspector.properties");
+
 function SlottedNodeEditor(container, node) {
   this.container = container;
   this.markup = this.container.markup;
   this.buildMarkup();
-  this.tag.textContent = "<" + node.nodeName.toLowerCase() + ">";
+  this.tag.textContent = "→ <" + node.nodeName.toLowerCase() + ">";
 
   // Make the "tag" part of this editor focusable.
   this.tag.setAttribute("tabindex", "-1");
 }
 
 SlottedNodeEditor.prototype = {
   buildMarkup: function() {
     let doc = this.markup.doc;
 
     this.elt = doc.createElement("span");
     this.elt.classList.add("editor");
 
     this.tag = doc.createElement("span");
     this.tag.classList.add("tag");
     this.elt.appendChild(this.tag);
+
+    this.revealLink = doc.createElement("span");
+    this.revealLink.classList.add("reveal-link");
+    this.revealLink.textContent = INSPECTOR_L10N.getStr("markupView.revealLink.label");
+    this.elt.appendChild(this.revealLink);
   },
 
   destroy: function() {
     // We might be already destroyed.
     if (!this.elt) {
       return;
     }
 
     this.elt.remove();
     this.elt = null;
     this.tag = null;
+    this.revealLink = null;
   },
 
   /**
    * Stub method for consistency with ElementEditor.
    */
   getInfoAtNode: function() {
     return null;
   }
--- a/devtools/client/locales/en-US/inspector.properties
+++ b/devtools/client/locales/en-US/inspector.properties
@@ -73,16 +73,22 @@ markupView.display.contents.tooltiptext2=This element doesn’t produce a specific box by itself, but renders its contents.
 # the markup view.
 markupView.event.tooltiptext=Event listener
 
 # LOCALIZATION NOTE (markupView.newAttribute.label)
 # This is used to speak the New Attribute button when editing a tag
 # and a screen reader user tabs to it. This string is not visible onscreen.
 markupView.newAttribute.label=New attribute
 
+# LOCALIZATION NOTE (markupView.revealLink.label)
+# Used in the markup view when displaying elements inserted in <slot> nodes in a custom
+# component. On hover, a link with this label will be shown to select the corresponding
+# non-slotted container. (test with dom.webcomponents.shadowdom.enabled set to true)
+markupView.revealLink.label=reveal
+
 #LOCALIZATION NOTE: Used in the image preview tooltip when the image could not be loaded
 previewTooltip.image.brokenImage=Could not load the image
 
 # LOCALIZATION NOTE: Used in color picker tooltip when the eyedropper is disabled for
 # non-HTML documents
 eyedropper.disabled.title=Unavailable in non-HTML documents
 
 #LOCALIZATION NOTE: Used in the event tooltip to allow the debugger to be opened
--- a/devtools/client/themes/markup.css
+++ b/devtools/client/themes/markup.css
@@ -316,16 +316,30 @@ ul.children + .tag-line::before {
 .more-nodes {
   padding-left: 16px;
 }
 
 .styleinspector-propertyeditor {
   border: 1px solid #CCC;
 }
 
+.reveal-link {
+  margin-inline-start: 10px;
+  cursor: pointer;
+  display: none;
+}
+
+.reveal-link:hover {
+  text-decoration: underline
+}
+
+.tag-line:hover .reveal-link {
+  display: inline;
+}
+
 /* Draw a circle next to nodes that have a pseudo class lock.
    Center vertically with the 1.4em line height on .tag-line */
 .child.pseudoclass-locked::before {
   content: "";
   background: var(--theme-highlight-lightorange);
   border-radius: 50%;
   width: .8em;
   height: .8em;