Bug 1412555 - Update canvas position on scroll in the css grid highlighter. r=pbro
authorGabriel Luong <gabriel.luong@gmail.com>
Thu, 02 Nov 2017 09:46:30 -0400
changeset 389829 de37bff8b0337070fa89ff0f15f01a2e516eae0a
parent 389828 35fc92e75cf75947444747ca5b279cbaf34e051e
child 389830 2aa956f09d3e1ba236b8bc3f08cd9b1fcaacabe6
push id96924
push usergabriel.luong@gmail.com
push dateThu, 02 Nov 2017 13:47:05 +0000
treeherdermozilla-inbound@de37bff8b033 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbro
bugs1412555
milestone58.0a1
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
Bug 1412555 - Update canvas position on scroll in the css grid highlighter. r=pbro
devtools/server/actors/highlighters/css-grid.js
devtools/server/actors/highlighters/flexbox.js
devtools/server/actors/highlighters/utils/canvas.js
--- a/devtools/server/actors/highlighters/css-grid.js
+++ b/devtools/server/actors/highlighters/css-grid.js
@@ -8,21 +8,21 @@ const Services = require("Services");
 const { AutoRefreshHighlighter } = require("./auto-refresh");
 const {
   CANVAS_SIZE,
   drawBubbleRect,
   drawLine,
   drawRect,
   drawRoundedRect,
   getBoundsFromPoints,
-  getCanvasPosition,
   getCurrentMatrix,
   getPathDescriptionFromPoints,
   getPointsFromDiagonal,
   updateCanvasElement,
+  updateCanvasPosition,
 } = require("./utils/canvas");
 const {
   CanvasFrameAnonymousContentHelper,
   createNode,
   createSVGNode,
   moveInfobar,
 } = require("./utils/markup");
 const { apply } = require("devtools/shared/layout/dom-matrix-2d");
@@ -171,22 +171,20 @@ class CssGridHighlighter extends AutoRef
     pageListenerTarget.addEventListener("pagehide", this.onPageHide);
 
     // Initialize the <canvas> position to the top left corner of the page
     this._canvasPosition = {
       x: 0,
       y: 0
     };
 
-    // Calling `getCanvasPosition` anyway since the highlighter could be initialized
+    // Calling `updateCanvasPosition` anyway since the highlighter could be initialized
     // on a page that has scrolled already.
-    let { canvasX, canvasY } = getCanvasPosition(this._canvasPosition, this._scroll,
-      this.win, this._winDimensions);
-    this._canvasPosition.x = canvasX;
-    this._canvasPosition.y = canvasY;
+    updateCanvasPosition(this._canvasPosition, this._scroll, this.win,
+      this._winDimensions);
   }
 
   _buildMarkup() {
     let container = createNode(this.win, {
       attributes: {
         "class": "highlighter-container"
       }
     });
@@ -767,17 +765,17 @@ class CssGridHighlighter extends AutoRef
       getBoundsFromPoints([{x, y}, {x, y}, {x, y}, {x, y}]), this.win);
   }
 
   /**
    * The <canvas>'s position needs to be updated if the page scrolls too much, in order
    * to give the illusion that it always covers the viewport.
    */
   _scrollUpdate() {
-    let { hasUpdated } = getCanvasPosition(this._canvasPosition, this._scroll, this.win,
+    let hasUpdated = updateCanvasPosition(this._canvasPosition, this._scroll, this.win,
       this._winDimensions);
 
     if (hasUpdated) {
       this._update();
     }
   }
 
   getFirstRowLinePos(fragment) {
--- a/devtools/server/actors/highlighters/flexbox.js
+++ b/devtools/server/actors/highlighters/flexbox.js
@@ -2,19 +2,19 @@
  * 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 { AutoRefreshHighlighter } = require("./auto-refresh");
 const {
   CANVAS_SIZE,
-  getCanvasPosition,
   getCurrentMatrix,
   updateCanvasElement,
+  updateCanvasPosition,
 } = require("./utils/canvas");
 const {
   CanvasFrameAnonymousContentHelper,
   createNode,
 } = require("./utils/markup");
 const {
   setIgnoreLayoutChanges,
 } = require("devtools/shared/layout/utils");
@@ -37,22 +37,20 @@ class FlexboxHighlighter extends AutoRef
     pageListenerTarget.addEventListener("pagehide", this.onPageHide);
 
     // Initialize the <canvas> position to the top left corner of the page
     this._canvasPosition = {
       x: 0,
       y: 0
     };
 
-    // Calling `getCanvasPosition` anyway since the highlighter could be initialized
+    // Calling `updateCanvasPosition` anyway since the highlighter could be initialized
     // on a page that has scrolled already.
-    let { canvasX, canvasY } = getCanvasPosition(this._canvasPosition, this._scroll,
-      this.win, this._winDimensions);
-    this._canvasPosition.x = canvasX;
-    this._canvasPosition.y = canvasY;
+    updateCanvasPosition(this._canvasPosition, this._scroll, this.win,
+      this._winDimensions);
   }
 
   _buildMarkup() {
     let container = createNode(this.win, {
       attributes: {
         "class": "highlighter-container"
       }
     });
@@ -121,17 +119,17 @@ class FlexboxHighlighter extends AutoRef
     this.getElement("canvas").setAttribute("hidden", "true");
   }
 
   /**
    * The <canvas>'s position needs to be updated if the page scrolls too much, in order
    * to give the illusion that it always covers the viewport.
    */
   _scrollUpdate() {
-    let { hasUpdated } = getCanvasPosition(this._canvasPosition, this._scroll, this.win,
+    let hasUpdated = updateCanvasPosition(this._canvasPosition, this._scroll, this.win,
       this._winDimensions);
 
     if (hasUpdated) {
       this._update();
     }
   }
 
   _show() {
--- a/devtools/server/actors/highlighters/utils/canvas.js
+++ b/devtools/server/actors/highlighters/utils/canvas.js
@@ -224,89 +224,16 @@ function getBoundsFromPoints(points) {
   bounds.y = bounds.top;
   bounds.width = bounds.right - bounds.left;
   bounds.height = bounds.bottom - bounds.top;
 
   return bounds;
 }
 
 /**
- * Calculates and returns the <canvas>'s position in accordance with the page's scroll,
- * document's size, canvas size, and viewport's size. This is called when a page's scroll
- * is detected.
- *
- * @param  {Object} canvasPosition
- *         A pointer object {x, y} representing the <canvas> position to the top left
- *         corner of the page.
- * @param  {Object} scrollPosition
- *         A pointer object {x, y} representing the window's pageXOffset and pageYOffset.
- * @param  {Window} window
- *         The window object.
- * @param  {Object} windowDimensions
- *         An object {width, height} representing the window's dimensions for the
- *         `window` given.
- * @return {Object} An object with the following properties:
- *         - {Boolean} hasUpdated
- *           true if the <canvas> position was updated and false otherwise.
- *         - {Number} canvasX
- *           The canvas' x position.
- *         - {Number} canvasY
- *           The canvas' y position.
- */
-function getCanvasPosition(canvasPosition, scrollPosition, window, windowDimensions) {
-  let { x: canvasX, y: canvasY } = canvasPosition;
-  let { x: scrollX, y: scrollY } = scrollPosition;
-  let cssCanvasSize = CANVAS_SIZE / window.devicePixelRatio;
-  let viewportSize = getViewportDimensions(window);
-  let { height, width } = windowDimensions;
-  let canvasWidth = cssCanvasSize;
-  let canvasHeight = cssCanvasSize;
-  let hasUpdated = false;
-
-  // Those values indicates the relative horizontal and vertical space the page can
-  // scroll before we have to reposition the <canvas>; they're 1/4 of the delta between
-  // the canvas' size and the viewport's size: that's because we want to consider both
-  // sides (top/bottom, left/right; so 1/2 for each side) and also we don't want to
-  // shown the edges of the canvas in case of fast scrolling (to avoid showing undraw
-  // areas, therefore another 1/2 here).
-  let bufferSizeX = (canvasWidth - viewportSize.width) >> 2;
-  let bufferSizeY = (canvasHeight - viewportSize.height) >> 2;
-
-  // Defines the boundaries for the canvas.
-  let leftBoundary = 0;
-  let rightBoundary = width - canvasWidth;
-  let topBoundary = 0;
-  let bottomBoundary = height - canvasHeight;
-
-  // Defines the thresholds that triggers the canvas' position to be updated.
-  let leftThreshold = scrollX - bufferSizeX;
-  let rightThreshold = scrollX - canvasWidth + viewportSize.width + bufferSizeX;
-  let topThreshold = scrollY - bufferSizeY;
-  let bottomThreshold = scrollY - canvasHeight + viewportSize.height + bufferSizeY;
-
-  if (canvasX < rightBoundary && canvasX < rightThreshold) {
-    canvasX = Math.min(leftThreshold, rightBoundary);
-    hasUpdated = true;
-  } else if (canvasX > leftBoundary && canvasX > leftThreshold) {
-    canvasX = Math.max(rightThreshold, leftBoundary);
-    hasUpdated = true;
-  }
-
-  if (canvasY < bottomBoundary && canvasY < bottomThreshold) {
-    canvasY = Math.min(topThreshold, bottomBoundary);
-    hasUpdated = true;
-  } else if (canvasY > topBoundary && canvasY > topThreshold) {
-    canvasY = Math.max(bottomThreshold, topBoundary);
-    hasUpdated = true;
-  }
-
-  return { canvasX, canvasY, hasUpdated };
-}
-
-/**
  * Returns the current matrices for both canvas drawing and SVG taking into account the
  * following transformations, in this order:
  *   1. The scale given by the display pixel ratio.
  *   2. The translation to the top left corner of the element.
  *   3. The scale given by the current zoom.
  *   4. The translation given by the top and left padding of the element.
  *   5. Any CSS transformation applied directly to the element (only 2D
  *      transformation; the 3D transformation are flattened, see `dom-matrix-2d` module
@@ -422,19 +349,90 @@ function updateCanvasElement(canvas, can
 
   // Resize the canvas taking the dpr into account so as to have crisp lines, and
   // translating it to give the perception that it always covers the viewport.
   canvas.setAttribute("style",
     `width: ${size}px; height: ${size}px; transform: translate(${x}px, ${y}px);`);
   canvas.getCanvasContext("2d").clearRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
 }
 
+/**
+ * Calculates and returns the <canvas>'s position in accordance with the page's scroll,
+ * document's size, canvas size, and viewport's size. This is called when a page's scroll
+ * is detected.
+ *
+ * @param  {Object} canvasPosition
+ *         A pointer object {x, y} representing the <canvas> position to the top left
+ *         corner of the page.
+ * @param  {Object} scrollPosition
+ *         A pointer object {x, y} representing the window's pageXOffset and pageYOffset.
+ * @param  {Window} window
+ *         The window object.
+ * @param  {Object} windowDimensions
+ *         An object {width, height} representing the window's dimensions for the
+ *         `window` given.
+ * @return {Boolean} true if the <canvas> position was updated and false otherwise.
+ */
+function updateCanvasPosition(canvasPosition, scrollPosition, window, windowDimensions) {
+  let { x: canvasX, y: canvasY } = canvasPosition;
+  let { x: scrollX, y: scrollY } = scrollPosition;
+  let cssCanvasSize = CANVAS_SIZE / window.devicePixelRatio;
+  let viewportSize = getViewportDimensions(window);
+  let { height, width } = windowDimensions;
+  let canvasWidth = cssCanvasSize;
+  let canvasHeight = cssCanvasSize;
+  let hasUpdated = false;
+
+  // Those values indicates the relative horizontal and vertical space the page can
+  // scroll before we have to reposition the <canvas>; they're 1/4 of the delta between
+  // the canvas' size and the viewport's size: that's because we want to consider both
+  // sides (top/bottom, left/right; so 1/2 for each side) and also we don't want to
+  // shown the edges of the canvas in case of fast scrolling (to avoid showing undraw
+  // areas, therefore another 1/2 here).
+  let bufferSizeX = (canvasWidth - viewportSize.width) >> 2;
+  let bufferSizeY = (canvasHeight - viewportSize.height) >> 2;
+
+  // Defines the boundaries for the canvas.
+  let leftBoundary = 0;
+  let rightBoundary = width - canvasWidth;
+  let topBoundary = 0;
+  let bottomBoundary = height - canvasHeight;
+
+  // Defines the thresholds that triggers the canvas' position to be updated.
+  let leftThreshold = scrollX - bufferSizeX;
+  let rightThreshold = scrollX - canvasWidth + viewportSize.width + bufferSizeX;
+  let topThreshold = scrollY - bufferSizeY;
+  let bottomThreshold = scrollY - canvasHeight + viewportSize.height + bufferSizeY;
+
+  if (canvasX < rightBoundary && canvasX < rightThreshold) {
+    canvasX = Math.min(leftThreshold, rightBoundary);
+    hasUpdated = true;
+  } else if (canvasX > leftBoundary && canvasX > leftThreshold) {
+    canvasX = Math.max(rightThreshold, leftBoundary);
+    hasUpdated = true;
+  }
+
+  if (canvasY < bottomBoundary && canvasY < bottomThreshold) {
+    canvasY = Math.min(topThreshold, bottomBoundary);
+    hasUpdated = true;
+  } else if (canvasY > topBoundary && canvasY > topThreshold) {
+    canvasY = Math.max(bottomThreshold, topBoundary);
+    hasUpdated = true;
+  }
+
+  // Update the canvas position with the calculated canvasX and canvasY positions.
+  canvasPosition.x = canvasX;
+  canvasPosition.y = canvasY;
+
+  return hasUpdated;
+}
+
 exports.CANVAS_SIZE = CANVAS_SIZE;
 exports.drawBubbleRect = drawBubbleRect;
 exports.drawLine = drawLine;
 exports.drawRect = drawRect;
 exports.drawRoundedRect = drawRoundedRect;
 exports.getBoundsFromPoints = getBoundsFromPoints;
-exports.getCanvasPosition = getCanvasPosition;
 exports.getCurrentMatrix = getCurrentMatrix;
 exports.getPathDescriptionFromPoints = getPathDescriptionFromPoints;
 exports.getPointsFromDiagonal = getPointsFromDiagonal;
 exports.updateCanvasElement = updateCanvasElement;
+exports.updateCanvasPosition = updateCanvasPosition;