Bug 1469877 - XUL accessible highlighter position is incorrect at different zoom levels. r?pbro draft
authorMicah Tigley <mtigley@mozilla.com>
Thu, 21 Jun 2018 15:47:45 -0400
changeset 809695 4ce808d7697ca3fa93ba4a94e8df8484a1b18d81
parent 808763 77b8ddea1fbd524f0917844f43c21c186262de5b
push id113767
push userbmo:mtigley@mozilla.com
push dateFri, 22 Jun 2018 18:21:31 +0000
reviewerspbro
bugs1469877
milestone62.0a1
Bug 1469877 - XUL accessible highlighter position is incorrect at different zoom levels. r?pbro MozReview-Commit-ID: JifRFqv5oGE
devtools/server/actors/highlighters/utils/accessibility.js
devtools/server/actors/highlighters/xul-accessible.js
--- a/devtools/server/actors/highlighters/utils/accessibility.js
+++ b/devtools/server/actors/highlighters/utils/accessibility.js
@@ -17,33 +17,45 @@ const { getCurrentZoom } = require("devt
  *         - {Number} x
  *           x coordinate of the top left corner of the accessible object
  *         - {Number} y
  *           y coordinate of the top left corner of the accessible object
  *         - {Number} w
  *           width of the the accessible object
  *         - {Number} h
  *           height of the the accessible object
+ *         - {Number} zoom
+ *           zoom level of the accessible object's parent window
  * @return {Object|null} Returns, if available, positioning and bounds information for
  *                 the accessible object.
  */
-function getBounds(win, { x, y, w, h }) {
-  const { mozInnerScreenX, mozInnerScreenY, scrollX, scrollY } = win;
-  const zoom = getCurrentZoom(win);
+function getBounds(win, { x, y, w, h, zoom }) {
+  let { mozInnerScreenX, mozInnerScreenY, scrollX, scrollY } = win;
+  let zoomFactor = getCurrentZoom(win);
   let left = x, right = x + w, top = y, bottom = y + h;
 
+  // For a XUL accessible, normalize the top-level window with its current zoom level.
+  // We need to do this because top-level browser content does not allow zooming.
+  if (zoom) {
+    zoomFactor = zoom;
+    mozInnerScreenX /= zoomFactor;
+    mozInnerScreenY /= zoomFactor;
+    scrollX /= zoomFactor;
+    scrollY /= zoomFactor;
+  }
+
   left -= mozInnerScreenX - scrollX;
   right -= mozInnerScreenX - scrollX;
   top -= mozInnerScreenY - scrollY;
   bottom -= mozInnerScreenY - scrollY;
 
-  left *= zoom;
-  right *= zoom;
-  top *= zoom;
-  bottom *= zoom;
+  left *= zoomFactor;
+  right *= zoomFactor;
+  top *= zoomFactor;
+  bottom *= zoomFactor;
 
   const width = right - left;
   const height = bottom - top;
 
   return { left, right, top, bottom, width, height };
 }
 
 exports.getBounds = getBounds;
--- a/devtools/server/actors/highlighters/xul-accessible.js
+++ b/devtools/server/actors/highlighters/xul-accessible.js
@@ -1,17 +1,17 @@
 /* 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 { getBounds } = require("./utils/accessibility");
 const { createNode, isNodeValid } = require("./utils/markup");
-const { loadSheet } = require("devtools/shared/layout/utils");
+const { getCurrentZoom, loadSheet } = require("devtools/shared/layout/utils");
 
 /**
  * Stylesheet used for highlighter styling of accessible objects in chrome. It
  * is consistent with the styling of an in-content accessible highlighter.
  */
 const ACCESSIBLE_BOUNDS_SHEET = "data:text/css;charset=utf-8," + encodeURIComponent(`
   .accessible-bounds {
     position: fixed;
@@ -75,17 +75,21 @@ class XULWindowAccessibleHighlighter {
 
   /**
    * Get current accessible bounds.
    *
    * @return {Object|null} Returns, if available, positioning and bounds
    *                       information for the accessible object.
    */
   get _bounds() {
-    return getBounds(this.win, this.options);
+    // Zoom level for the top level browser window does not change and only inner frames
+    // do. So we need to get the zoom level of the current node's parent window.
+    const zoom = getCurrentZoom(this.currentNode);
+
+    return getBounds(this.win, { ...this.options, zoom });
   }
 
   /**
    * Show the highlighter on a given accessible.
    *
    * @param {DOMNode} node
    *        A dom node that corresponds to the accessible object.
    * @param {Object} options