Bug 1383870 - CSS shapes highlighter incorrectly handles mouse events on elements in iframe. r=gl draft
authorMike Park <mikeparkms@gmail.com>
Tue, 25 Jul 2017 10:33:51 -0400
changeset 678655 6148721ecbe50b2318b623ef591120a9fa19bedf
parent 674243 6edf1a28df0e57d6299ec255f554f135b0bea8f0
child 735399 4e6d8fe045e9724c669a1aa6c1c613157781207d
push id84000
push userbmo:mpark@mozilla.com
push dateWed, 11 Oct 2017 18:41:03 +0000
reviewersgl
bugs1383870
milestone58.0a1
Bug 1383870 - CSS shapes highlighter incorrectly handles mouse events on elements in iframe. r=gl MozReview-Commit-ID: HAHop7hSPxs
devtools/server/actors/highlighters/shapes.js
--- a/devtools/server/actors/highlighters/shapes.js
+++ b/devtools/server/actors/highlighters/shapes.js
@@ -1,27 +1,28 @@
 /* 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, getCSSStyleRules,
         createSVGNode, createNode, getComputedStyle } = require("./utils/markup");
-const { setIgnoreLayoutChanges, getCurrentZoom } = require("devtools/shared/layout/utils");
+const { setIgnoreLayoutChanges, getCurrentZoom,
+        getAdjustedQuads } = require("devtools/shared/layout/utils");
 const { AutoRefreshHighlighter } = require("./auto-refresh");
 const {
   getDistance,
   clickedOnEllipseEdge,
   distanceToLine,
   projection,
   clickedOnPoint,
   roundTo
 } = require("devtools/server/actors/utils/shapes-utils");
-const EventEmitter = require("devtools/shared/event-emitter");
+const EventEmitter = require("devtools/shared/old-event-emitter");
 
 const BASE_MARKER_SIZE = 5;
 // the width of the area around highlighter lines that can be clicked, in px
 const LINE_CLICK_WIDTH = 5;
 const DOM_EVENTS = ["mousedown", "mousemove", "mouseup", "dblclick"];
 const UNITS = ["px", "%", "em", "rem", "in", "cm", "mm", "pt",
                "pc", "vh", "vw", "vmin", "vmax"];
 const _dragging = Symbol("shapes/dragging");
@@ -175,16 +176,37 @@ class ShapesHighlighter extends AutoRefr
     return {
       top: top / zoom,
       left: left / zoom,
       width: width / zoom,
       height: height / zoom
     };
   }
 
+  get frameDimensions() {
+    // In an iframe, we get the node's quads relative to the frame,
+    // instead of the parent document.
+    let dims = getAdjustedQuads(this.currentNode.ownerGlobal,
+      this.currentNode, this.referenceBox)[0].bounds;
+    let zoom = getCurrentZoom(this.win);
+
+    if (this.currentNode.getBBox &&
+        getComputedStyle(this.currentNode).stroke !== "none" && !this.useStrokeBox) {
+      dims = getObjectBoundingBox(dims.top, dims.left,
+        dims.width, dims.height, this.currentNode);
+    }
+
+    return {
+      top: dims.top / zoom,
+      left: dims.left / zoom,
+      width: dims.width / zoom,
+      height: dims.height / zoom
+    };
+  }
+
   handleEvent(event, id) {
     // No event handling if the highlighter is hidden
     if (this.areShapesHidden()) {
       return;
     }
 
     const { target, type, pageX, pageY } = event;
 
@@ -701,17 +723,20 @@ class ShapesHighlighter extends AutoRefr
    * Convert the given coordinates on the page to percentages relative to the current
    * element.
    * @param {Number} pageX the x coordinate on the page
    * @param {Number} pageY the y coordinate on the page
    * @returns {Object} object of form {percentX, percentY}, which are the x/y coords
    *          in percentages relative to the element.
    */
   convertPageCoordsToPercent(pageX, pageY) {
-    let { top, left, width, height } = this.zoomAdjustedDimensions;
+    // If the current node is in an iframe, we get dimensions relative to the frame.
+    let dims = (this.highlighterEnv.window.document === this.currentNode.ownerDocument) ?
+               this.zoomAdjustedDimensions : this.frameDimensions;
+    let { top, left, width, height } = dims;
     pageX -= left;
     pageY -= top;
     let percentX = pageX * 100 / width;
     let percentY = pageY * 100 / height;
     return { percentX, percentY };
   }
 
   /**