Backed out changeset b43d8eb6e6c9 (bug 1335691) for build bustage. r=backout on a CLOSED TREE
authorSebastian Hengst <archaeopteryx@coole-files.de>
Mon, 13 Mar 2017 18:33:11 +0100
changeset 347355 13b05e58f420c64c047ea14cc74c467c632f11a1
parent 347354 19a4d023dd560867bfe434d05a239a440c873927
child 347356 d983cb91c5a48243adcd13187f4ae9f623f3d0d0
push id31496
push usercbook@mozilla.com
push dateTue, 14 Mar 2017 13:21:57 +0000
treeherdermozilla-central@9a26ed658fdc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1335691
milestone55.0a1
backs outb43d8eb6e6c9f3e0a512fbde2c0a992009689f34
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset b43d8eb6e6c9 (bug 1335691) for build bustage. r=backout on a CLOSED TREE
devtools/client/inspector/test/browser.ini
devtools/client/inspector/test/browser_inspector_highlighter-rect_01.js
devtools/client/inspector/test/browser_inspector_highlighter-rect_02.js
devtools/server/actors/highlighters.js
devtools/server/actors/highlighters/rect.js
--- a/devtools/client/inspector/test/browser.ini
+++ b/devtools/client/inspector/test/browser.ini
@@ -99,16 +99,18 @@ skip-if = (os == 'linux' && bits == 32 &
 [browser_inspector_highlighter-keybinding_01.js]
 [browser_inspector_highlighter-keybinding_02.js]
 [browser_inspector_highlighter-keybinding_03.js]
 [browser_inspector_highlighter-keybinding_04.js]
 [browser_inspector_highlighter-measure_01.js]
 [browser_inspector_highlighter-measure_02.js]
 [browser_inspector_highlighter-options.js]
 [browser_inspector_highlighter-preview.js]
+[browser_inspector_highlighter-rect_01.js]
+[browser_inspector_highlighter-rect_02.js]
 [browser_inspector_highlighter-rulers_01.js]
 [browser_inspector_highlighter-rulers_02.js]
 [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]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-rect_01.js
@@ -0,0 +1,121 @@
+/* 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";
+
+// Test that the custom rect highlighter provides the right API, ensures that
+// the input is valid and that it does create a box with the right dimensions,
+// at the right position.
+
+const TEST_URL = "data:text/html;charset=utf-8,Rect Highlighter Test";
+
+add_task(function* () {
+  let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
+  let front = inspector.inspector;
+  let highlighter = yield front.getHighlighterByType("RectHighlighter");
+  let body = yield getNodeFront("body", inspector);
+
+  info("Make sure the highlighter returned is correct");
+
+  ok(highlighter, "The RectHighlighter custom type was created");
+  is(highlighter.typeName, "customhighlighter",
+    "The RectHighlighter has the right type");
+  ok(highlighter.show && highlighter.hide,
+    "The RectHighlighter has the expected show/hide methods");
+
+  info("Check that the highlighter is hidden by default");
+
+  let hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  is(hidden, "true", "The highlighter is hidden by default");
+
+  info("Check that nothing is shown if no rect is passed");
+
+  yield highlighter.show(body);
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  is(hidden, "true", "The highlighter is hidden when no rect is passed");
+
+  info("Check that nothing is shown if rect is incomplete or invalid");
+
+  yield highlighter.show(body, {
+    rect: {x: 0, y: 0}
+  });
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  is(hidden, "true", "The highlighter is hidden when the rect is incomplete");
+
+  yield highlighter.show(body, {
+    rect: {x: 0, y: 0, width: -Infinity, height: 0}
+  });
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  is(hidden, "true", "The highlighter is hidden when the rect is invalid (1)");
+
+  yield highlighter.show(body, {
+    rect: {x: 0, y: 0, width: 5, height: -45}
+  });
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  is(hidden, "true", "The highlighter is hidden when the rect is invalid (2)");
+
+  yield highlighter.show(body, {
+    rect: {x: "test", y: 0, width: 5, height: 5}
+  });
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  is(hidden, "true", "The highlighter is hidden when the rect is invalid (3)");
+
+  info("Check that the highlighter is displayed when valid options are passed");
+
+  yield highlighter.show(body, {
+    rect: {x: 5, y: 5, width: 50, height: 50}
+  });
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  ok(!hidden, "The highlighter is displayed");
+  let style = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "style", highlighter);
+  is(style, "left:5px;top:5px;width:50px;height:50px;",
+    "The highlighter is positioned correctly");
+
+  info("Check that the highlighter can be displayed at x=0 y=0");
+
+  yield highlighter.show(body, {
+    rect: {x: 0, y: 0, width: 50, height: 50}
+  });
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  ok(!hidden, "The highlighter is displayed when x=0 and y=0");
+  style = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "style", highlighter);
+  is(style, "left:0px;top:0px;width:50px;height:50px;",
+    "The highlighter is positioned correctly");
+
+  info("Check that the highlighter is hidden when dimensions are 0");
+
+  yield highlighter.show(body, {
+    rect: {x: 0, y: 0, width: 0, height: 0}
+  });
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  is(hidden, "true", "The highlighter is hidden width and height are 0");
+
+  info("Check that a fill color can be passed");
+
+  yield highlighter.show(body, {
+    rect: {x: 100, y: 200, width: 500, height: 200},
+    fill: "red"
+  });
+  hidden = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "hidden", highlighter);
+  ok(!hidden, "The highlighter is displayed");
+  style = yield testActor.getHighlighterNodeAttribute(
+    "highlighted-rect", "style", highlighter);
+  is(style, "left:100px;top:200px;width:500px;height:200px;background:red;",
+    "The highlighter has the right background color");
+
+  yield highlighter.hide();
+  yield highlighter.finalize();
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-rect_02.js
@@ -0,0 +1,37 @@
+/* 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";
+
+// Test that the custom rect highlighter positions the rectangle relative to the
+// viewport of the context node we pass to it.
+
+const TEST_URL = URL_ROOT + "doc_inspector_highlighter_rect.html";
+
+add_task(function* () {
+  let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
+  let front = inspector.inspector;
+  let highlighter = yield front.getHighlighterByType("RectHighlighter");
+
+  info("Showing the rect highlighter in the context of the iframe");
+
+  // Get the reference to a context node inside the iframe
+  let childBody = yield getNodeFrontInFrame("body", "iframe", inspector);
+  yield highlighter.show(childBody, {
+    rect: {x: 50, y: 50, width: 100, height: 100}
+  });
+
+  let style = yield testActor.getHighlighterNodeAttribute("highlighted-rect",
+    "style", highlighter);
+
+  // The parent body has margin=50px and border=10px
+  // The parent iframe also has margin=50px and border=10px
+  // = 50 + 10 + 50 + 10 = 120px
+  // The rect is aat x=50 and y=50, so left and top should be 170px
+  is(style, "left:170px;top:170px;width:100px;height:100px;",
+    "The highlighter is correctly positioned");
+
+  yield highlighter.hide();
+  yield highlighter.finalize();
+});
--- a/devtools/server/actors/highlighters.js
+++ b/devtools/server/actors/highlighters.js
@@ -476,18 +476,19 @@ exports.CustomHighlighterActor = protoco
    * Show the highlighter.
    * This calls through to the highlighter instance's |show(node, options)|
    * method.
    *
    * Most custom highlighters are made to highlight DOM nodes, hence the first
    * NodeActor argument (NodeActor as in
    * devtools/server/actor/inspector).
    * Note however that some highlighters use this argument merely as a context
-   * node: The SelectHighlighter for instance uses it as a base node to run the
-   * provided CSS selector on.
+   * node: the RectHighlighter for instance uses it to calculate the absolute
+   * position of the provided rect. The SelectHighlighter uses it as a base node
+   * to run the provided CSS selector on.
    *
    * @param {NodeActor} The node to be highlighted
    * @param {Object} Options for the custom highlighter
    * @return {Boolean} True, if the highlighter has been successfully shown
    * (FF41+)
    */
   show: function (node, options) {
     if (!node || !this._highlighter) {
@@ -696,16 +697,20 @@ exports.CssGridHighlighter = CssGridHigh
 const { CssTransformHighlighter } = require("./highlighters/css-transform");
 register(CssTransformHighlighter);
 exports.CssTransformHighlighter = CssTransformHighlighter;
 
 const { SelectorHighlighter } = require("./highlighters/selector");
 register(SelectorHighlighter);
 exports.SelectorHighlighter = SelectorHighlighter;
 
+const { RectHighlighter } = require("./highlighters/rect");
+register(RectHighlighter);
+exports.RectHighlighter = RectHighlighter;
+
 const { GeometryEditorHighlighter } = require("./highlighters/geometry-editor");
 register(GeometryEditorHighlighter);
 exports.GeometryEditorHighlighter = GeometryEditorHighlighter;
 
 const { RulersHighlighter } = require("./highlighters/rulers");
 register(RulersHighlighter);
 exports.RulersHighlighter = RulersHighlighter;
 
new file mode 100644
--- /dev/null
+++ b/devtools/server/actors/highlighters/rect.js
@@ -0,0 +1,102 @@
+/* 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 { CanvasFrameAnonymousContentHelper } = require("./utils/markup");
+const { getAdjustedQuads } = require("devtools/shared/layout/utils");
+/**
+ * The RectHighlighter is a class that draws a rectangle highlighter at specific
+ * coordinates.
+ * It does *not* highlight DOM nodes, but rects.
+ * It also does *not* update dynamically, it only highlights a rect and remains
+ * there as long as it is shown.
+ */
+function RectHighlighter(highlighterEnv) {
+  this.win = highlighterEnv.window;
+  this.markup = new CanvasFrameAnonymousContentHelper(highlighterEnv,
+    this._buildMarkup.bind(this));
+}
+
+RectHighlighter.prototype = {
+  typeName: "RectHighlighter",
+
+  _buildMarkup: function () {
+    let doc = this.win.document;
+
+    let container = doc.createElement("div");
+    container.className = "highlighter-container";
+    container.innerHTML = "<div id=\"highlighted-rect\" " +
+                          "class=\"highlighted-rect\" hidden=\"true\">";
+
+    return container;
+  },
+
+  destroy: function () {
+    this.win = null;
+    this.markup.destroy();
+  },
+
+  getElement: function (id) {
+    return this.markup.getElement(id);
+  },
+
+  _hasValidOptions: function (options) {
+    let isValidNb = n => typeof n === "number" && n >= 0 && isFinite(n);
+    return options && options.rect &&
+           isValidNb(options.rect.x) &&
+           isValidNb(options.rect.y) &&
+           options.rect.width && isValidNb(options.rect.width) &&
+           options.rect.height && isValidNb(options.rect.height);
+  },
+
+  /**
+   * @param {DOMNode} node The highlighter rect is relatively positioned to the
+   * viewport this node is in. Using the provided node, the highligther will get
+   * the parent documentElement and use it as context to position the
+   * highlighter correctly.
+   * @param {Object} options Accepts the following options:
+   * - rect: mandatory object that should have the x, y, width, height
+   *   properties
+   * - fill: optional fill color for the rect
+   */
+  show: function (node, options) {
+    if (!this._hasValidOptions(options) || !node || !node.ownerDocument) {
+      this.hide();
+      return false;
+    }
+
+    let contextNode = node.ownerDocument.documentElement;
+
+    // Caculate the absolute rect based on the context node's adjusted quads.
+    let quads = getAdjustedQuads(this.win, contextNode);
+    if (!quads.length) {
+      this.hide();
+      return false;
+    }
+
+    let {bounds} = quads[0];
+    let x = "left:" + (bounds.x + options.rect.x) + "px;";
+    let y = "top:" + (bounds.y + options.rect.y) + "px;";
+    let width = "width:" + options.rect.width + "px;";
+    let height = "height:" + options.rect.height + "px;";
+
+    let style = x + y + width + height;
+    if (options.fill) {
+      style += "background:" + options.fill + ";";
+    }
+
+    // Set the coordinates of the highlighter and show it
+    let rect = this.getElement("highlighted-rect");
+    rect.setAttribute("style", style);
+    rect.removeAttribute("hidden");
+
+    return true;
+  },
+
+  hide: function () {
+    this.getElement("highlighted-rect").setAttribute("hidden", "true");
+  }
+};
+exports.RectHighlighter = RectHighlighter;