Bug 1408468 - Shapes highlighter handles for shapes in iframe cannot be clicked outside iframe. r=gl draft
authorMike Park <mikeparkms@gmail.com>
Fri, 13 Oct 2017 13:19:50 -0400
changeset 680980 bfbc93a9aebdbfa5004ff06ed02cff79610dba18
parent 680024 196dadb2fe500e75c6fbddcac78106648676cf10
child 736042 60bb2d8df5c040a8411b95ea3b983e3db8aa1464
push id84707
push userbmo:mpark@mozilla.com
push dateMon, 16 Oct 2017 18:48:38 +0000
reviewersgl
bugs1408468
milestone58.0a1
Bug 1408468 - Shapes highlighter handles for shapes in iframe cannot be clicked outside iframe. r=gl MozReview-Commit-ID: 3J4J6vM96sj
devtools/client/inspector/test/browser.ini
devtools/client/inspector/test/browser_inspector_highlighter-cssshape_iframe_01.js
devtools/client/inspector/test/doc_inspector_highlighter_cssshapes_iframe.html
devtools/client/inspector/test/head.js
devtools/server/actors/highlighters/shapes.js
--- a/devtools/client/inspector/test/browser.ini
+++ b/devtools/client/inspector/test/browser.ini
@@ -11,16 +11,17 @@ support-files =
   doc_inspector_delete-selected-node-02.html
   doc_inspector_embed.html
   doc_inspector_gcli-inspect-command.html
   doc_inspector_highlight_after_transition.html
   doc_inspector_highlighter-comments.html
   doc_inspector_highlighter-geometry_01.html
   doc_inspector_highlighter-geometry_02.html
   doc_inspector_highlighter_cssshapes.html
+  doc_inspector_highlighter_cssshapes_iframe.html
   doc_inspector_highlighter_csstransform.html
   doc_inspector_highlighter_dom.html
   doc_inspector_highlighter_inline.html
   doc_inspector_highlighter.html
   doc_inspector_highlighter_rect.html
   doc_inspector_highlighter_rect_iframe.html
   doc_inspector_highlighter_scroll.html
   doc_inspector_highlighter_xbl.xul
@@ -77,16 +78,17 @@ skip-if = os == "mac" # Full keyboard na
 [browser_inspector_highlighter-comments.js]
 [browser_inspector_highlighter-cssgrid_01.js]
 [browser_inspector_highlighter-cssgrid_02.js]
 [browser_inspector_highlighter-cssshape_01.js]
 [browser_inspector_highlighter-cssshape_02.js]
 [browser_inspector_highlighter-cssshape_03.js]
 [browser_inspector_highlighter-cssshape_04.js]
 [browser_inspector_highlighter-cssshape_05.js]
+[browser_inspector_highlighter-cssshape_iframe_01.js]
 [browser_inspector_highlighter-csstransform_01.js]
 [browser_inspector_highlighter-csstransform_02.js]
 [browser_inspector_highlighter-embed.js]
 [browser_inspector_highlighter-eyedropper-clipboard.js]
 subsuite = clipboard
 skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
 [browser_inspector_highlighter-eyedropper-csp.js]
 [browser_inspector_highlighter-eyedropper-events.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/browser_inspector_highlighter-cssshape_iframe_01.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";
+
+// Test that shapes in iframes are updated correctly on mouse events.
+
+const TEST_URL = URL_ROOT + "doc_inspector_highlighter_cssshapes_iframe.html";
+const HIGHLIGHTER_TYPE = "ShapesHighlighter";
+
+add_task(function* () {
+  let inspector = yield openInspectorForURL(TEST_URL);
+  let helper = yield getHighlighterHelperFor(HIGHLIGHTER_TYPE)(inspector);
+  let {testActor} = inspector;
+
+  yield testPolygonIframeMovePoint(testActor, helper);
+
+  yield helper.finalize();
+});
+
+function* testPolygonIframeMovePoint(testActor, helper) {
+  info("Displaying polygon");
+  yield helper.show("#polygon", {mode: "cssClipPath"}, "#frame");
+  let { mouse, highlightedNode } = helper;
+
+  info("Moving polygon point visible in iframe");
+  yield mouse.down(10, 10);
+  yield mouse.move(20, 20);
+  yield mouse.up();
+  yield testActor.reflow();
+
+  let computedStyle = yield highlightedNode.getComputedStyle();
+  let definition = computedStyle["clip-path"].value;
+  ok(definition.includes("10px 10px"), "Point moved to 10px 10px");
+
+  info("Moving polygon point not visible in iframe");
+  yield mouse.down(110, 410);
+  yield mouse.move(120, 420);
+  yield mouse.up();
+  yield testActor.reflow();
+
+  computedStyle = yield highlightedNode.getComputedStyle();
+  definition = computedStyle["clip-path"].value;
+  ok(definition.includes("110px 51.25%"), "Point moved to 110px 51.25%");
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/test/doc_inspector_highlighter_cssshapes_iframe.html
@@ -0,0 +1,11 @@
+<!-- Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+  html, body {
+    height: 100%;
+    margin: 10px;
+  }
+</style>
+<iframe id="frame" src="doc_inspector_highlighter_cssshapes.html"></iframe>
\ No newline at end of file
--- a/devtools/client/inspector/test/head.js
+++ b/devtools/client/inspector/test/head.js
@@ -442,18 +442,22 @@ const getHighlighterHelperFor = (type) =
       get actorID() {
         if (!highlighter) {
           return null;
         }
 
         return highlighter.actorID;
       },
 
-      show: function* (selector = ":root", options) {
-        highlightedNode = yield getNodeFront(selector, inspector);
+      show: function* (selector = ":root", options, frameSelector = null) {
+        if (frameSelector) {
+          highlightedNode = yield getNodeFrontInFrame(selector, frameSelector, inspector);
+        } else {
+          highlightedNode = yield getNodeFront(selector, inspector);
+        }
         return yield highlighter.show(highlightedNode, options);
       },
 
       hide: function* () {
         yield highlighter.hide();
       },
 
       isElementHidden: function* (id) {
--- a/devtools/server/actors/highlighters/shapes.js
+++ b/devtools/server/actors/highlighters/shapes.js
@@ -2,17 +2,17 @@
  * 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, getCSSStyleRules,
         createSVGNode, createNode, getComputedStyle } = require("./utils/markup");
 const { setIgnoreLayoutChanges, getCurrentZoom,
-        getAdjustedQuads } = require("devtools/shared/layout/utils");
+        getAdjustedQuads, getFrameOffsets } = require("devtools/shared/layout/utils");
 const { AutoRefreshHighlighter } = require("./auto-refresh");
 const {
   getDistance,
   clickedOnEllipseEdge,
   distanceToLine,
   projection,
   clickedOnPoint
 } = require("devtools/server/actors/utils/shapes-geometry-utils");
@@ -199,17 +199,30 @@ class ShapesHighlighter extends AutoRefr
   }
 
   handleEvent(event, id) {
     // No event handling if the highlighter is hidden
     if (this.areShapesHidden()) {
       return;
     }
 
-    const { target, type, pageX, pageY } = event;
+    let { target, type, pageX, pageY } = event;
+
+    // For events on highlighted nodes in an iframe, when the event takes place
+    // outside the iframe. Check if event target belongs to the iframe. If it doesn't,
+    // adjust pageX/pageY to be relative to the iframe rather than the parent.
+    if (target.ownerDocument !== this.currentNode.ownerDocument) {
+      let [xOffset, yOffset] = getFrameOffsets(target.ownerGlobal, this.currentNode);
+      // xOffset/yOffset are relative to the viewport, so first find the top/left
+      // edges of the viewport relative to the page.
+      let viewportLeft = pageX - event.clientX;
+      let viewportTop = pageY - event.clientY;
+      pageX -= viewportLeft + xOffset;
+      pageY -= viewportTop + yOffset;
+    }
 
     switch (type) {
       case "pagehide":
         // If a page hide event is triggered for current window's highlighter, hide the
         // highlighter.
         if (target.defaultView === this.win) {
           this.destroy();
         }