Bug 1309212 - display highlighter infobar for #text nodes;r=pbro draft
authorJulian Descottes <jdescottes@mozilla.com>
Thu, 13 Oct 2016 19:28:34 +0200
changeset 426031 9398368334be3138ea37bb7f715d292784b58156
parent 425967 94b0fddf96b43942bdd851a3275042909ea37e09
child 426032 04915986442fda54dc4b6786f56546ba0c3b16c1
push id32590
push userjdescottes@mozilla.com
push dateMon, 17 Oct 2016 16:34:51 +0000
reviewerspbro
bugs1309212
milestone52.0a1
Bug 1309212 - display highlighter infobar for #text nodes;r=pbro MozReview-Commit-ID: HBaLSFyz6LR
devtools/client/inspector/test/browser.ini
devtools/client/inspector/test/browser_inspector_infobar_textnode.js
devtools/client/inspector/test/doc_inspector_infobar_textnode.html
devtools/server/actors/highlighters/box-model.js
devtools/server/actors/inspector.js
--- a/devtools/client/inspector/test/browser.ini
+++ b/devtools/client/inspector/test/browser.ini
@@ -20,16 +20,17 @@ support-files =
   doc_inspector_highlighter_inline.html
   doc_inspector_highlighter.html
   doc_inspector_highlighter_rect.html
   doc_inspector_highlighter_rect_iframe.html
   doc_inspector_highlighter_xbl.xul
   doc_inspector_infobar_01.html
   doc_inspector_infobar_02.html
   doc_inspector_infobar_03.html
+  doc_inspector_infobar_textnode.html
   doc_inspector_menu.html
   doc_inspector_outerhtml.html
   doc_inspector_remove-iframe-during-load.html
   doc_inspector_search.html
   doc_inspector_search-reserved.html
   doc_inspector_search-suggestions.html
   doc_inspector_search-svg.html
   doc_inspector_select-last-selected-01.html
@@ -104,16 +105,17 @@ subsuite = clipboard
 [browser_inspector_highlighter-selector_01.js]
 [browser_inspector_highlighter-selector_02.js]
 [browser_inspector_highlighter-xbl.js]
 [browser_inspector_highlighter-zoom.js]
 [browser_inspector_iframe-navigation.js]
 [browser_inspector_infobar_01.js]
 [browser_inspector_infobar_02.js]
 [browser_inspector_infobar_03.js]
+[browser_inspector_infobar_textnode.js]
 [browser_inspector_initialization.js]
 skip-if = (e10s && debug) # Bug 1250058 - Docshell leak on debug e10s
 [browser_inspector_inspect-object-element.js]
 [browser_inspector_invalidate.js]
 [browser_inspector_keyboard-shortcuts-copy-outerhtml.js]
 subsuite = clipboard
 [browser_inspector_keyboard-shortcuts.js]
 [browser_inspector_menu-01-sensitivity.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_infobar_textnode.js
@@ -0,0 +1,46 @@
+/* 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";
+
+// Bug 1309212 - Make sure info-bar is displayed with dimensions for text nodes.
+
+const TEST_URI = URL_ROOT + "doc_inspector_infobar_textnode.html";
+
+add_task(function* () {
+  let { inspector, testActor } = yield openInspectorForURL(TEST_URI);
+  let { walker } = inspector;
+
+  info("Retrieve the children of #textnode-container");
+  let div = yield walker.querySelector(walker.rootNode, "#textnode-container");
+  let { nodes } = yield inspector.walker.children(div);
+
+  // Children 0, 2 and 4 are text nodes, for which we expect to see an infobar containing
+  // dimensions.
+
+  // Regular text node.
+  info("Select the first text node");
+  yield selectNode(nodes[0], inspector, "test-highlight");
+  yield checkTextNodeInfoBar(testActor);
+
+  // Whitespace-only text node.
+  info("Select the second text node");
+  yield selectNode(nodes[2], inspector, "test-highlight");
+  yield checkTextNodeInfoBar(testActor);
+
+  // Regular text node.
+  info("Select the third text node");
+  yield selectNode(nodes[4], inspector, "test-highlight");
+  yield checkTextNodeInfoBar(testActor);
+});
+
+function* checkTextNodeInfoBar(testActor) {
+  let tag = yield testActor.getHighlighterNodeTextContent(
+    "box-model-infobar-tagname");
+  is(tag, "#text", "node display name is #text");
+  let dims = yield testActor.getHighlighterNodeTextContent(
+      "box-model-infobar-dimensions");
+  // Do not assert dimensions as they might be platform specific.
+  ok(!!dims, "node has dims");
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/doc_inspector_infobar_textnode.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+</head>
+<body>
+  <div id="textnode-container">
+    text
+    <span>content</span>
+    <span>content</span>
+    text
+  </div>
+</body>
+</html>
--- a/devtools/server/actors/highlighters/box-model.js
+++ b/devtools/server/actors/highlighters/box-model.js
@@ -344,19 +344,21 @@ BoxModelHighlighter.prototype = extend(A
    * passed as an argument to show(node)).
    * Should be called whenever node size or attributes change
    */
   _update: function () {
     let shown = false;
     setIgnoreLayoutChanges(true);
 
     if (this._updateBoxModel()) {
-      // Show the infobar only if configured to do so and the node is an element.
-      if (!this.options.hideInfoBar &&
-          this.currentNode.nodeType === this.currentNode.ELEMENT_NODE) {
+      // Show the infobar only if configured to do so and the node is an element or a text
+      // node.
+      if (!this.options.hideInfoBar && (
+          this.currentNode.nodeType === this.currentNode.ELEMENT_NODE ||
+          this.currentNode.nodeType === this.currentNode.TEXT_NODE)) {
         this._showInfobar();
       } else {
         this._hideInfobar();
       }
       this._showBoxModel();
       shown = true;
     } else {
       // Nothing to highlight (0px rectangle like a <script> tag for instance)
@@ -692,19 +694,17 @@ BoxModelHighlighter.prototype = extend(A
     let displayName = inspector.getNodeDisplayName(node);
 
     let id = node.id ? "#" + node.id : "";
 
     let classList = (node.classList || []).length
                     ? "." + [...node.classList].join(".")
                     : "";
 
-    let pseudos = PSEUDO_CLASSES.filter(pseudo => {
-      return hasPseudoClassLock(node, pseudo);
-    }, this).join("");
+    let pseudos = this._getPseudoClasses(node).join("");
     if (pseudo) {
       // Display :after as ::after
       pseudos += ":" + pseudo;
     }
 
     let rect = this._getOuterQuad("border").bounds;
     let dim = parseFloat(rect.width.toPrecision(6)) +
               " \u00D7 " +
@@ -714,16 +714,25 @@ BoxModelHighlighter.prototype = extend(A
     this.getElement("infobar-id").setTextContent(id);
     this.getElement("infobar-classes").setTextContent(classList);
     this.getElement("infobar-pseudo-classes").setTextContent(pseudos);
     this.getElement("infobar-dimensions").setTextContent(dim);
 
     this._moveInfobar();
   },
 
+  _getPseudoClasses: function (node) {
+    if (node.nodeType !== nodeConstants.ELEMENT_NODE) {
+      // hasPseudoClassLock can only be used on Elements.
+      return [];
+    }
+
+    return PSEUDO_CLASSES.filter(pseudo => hasPseudoClassLock(node, pseudo));
+  },
+
   /**
    * Move the Infobar to the right place in the highlighter.
    */
   _moveInfobar: function () {
     let bounds = this._getOuterBounds();
     let container = this.getElement("infobar-container");
 
     moveInfobar(container, bounds, this.win);
--- a/devtools/server/actors/inspector.js
+++ b/devtools/server/actors/inspector.js
@@ -185,16 +185,21 @@ exports.setInspectingNode = function (va
  * used when displaying said name in the UI.
  *
  * @param  {Node} rawNode
  *         Node for which we want the display name
  * @return {String}
  *         Properly cased version of the node tag name
  */
 const getNodeDisplayName = function (rawNode) {
+  if (rawNode.nodeName && !rawNode.localName) {
+    // The localName & prefix APIs have been moved from the Node interface to the Element
+    // interface. Use Node.nodeName as a fallback.
+    return rawNode.nodeName;
+  }
   return (rawNode.prefix ? rawNode.prefix + ":" : "") + rawNode.localName;
 };
 exports.getNodeDisplayName = getNodeDisplayName;
 
 /**
  * Server side of the node actor.
  */
 var NodeActor = exports.NodeActor = protocol.ActorClassWithSpec(nodeSpec, {