Bug 1412555 - Update canvas position on scroll in the css grid highlighter. r=pbro
MozReview-Commit-ID: GKAQ8LRfLau
--- 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;