Bug 1906123 - use a fixed AR for tab preview while preserving scroll position. r=tabbrowser-reviewers,dao

Differential Revision: https://phabricator.services.mozilla.com/D218085
This commit is contained in:
DJ 2024-07-31 18:47:40 +00:00
parent f339e845ec
commit f6616399f8
3 changed files with 86 additions and 6 deletions

View File

@ -101,12 +101,13 @@ export default class TabHoverPreviewPanel {
return;
}
let thumbnailCanvas = this._win.document.createElement("canvas");
thumbnailCanvas.width = 280 * this._win.devicePixelRatio;
thumbnailCanvas.height = 140 * this._win.devicePixelRatio;
this._win.PageThumbs.captureToCanvas(tab.linkedBrowser, thumbnailCanvas, {
fullViewport: true,
targetWidth: 280 * this._win.devicePixelRatio,
preserveAspectRatio: true,
})
this._win.PageThumbs.captureTabPreviewThumbnail(
tab.linkedBrowser,
thumbnailCanvas
)
.then(() => {
// in case we've changed tabs after capture started, ensure we still want to show the thumbnail
if (this._tab == tab && this._hasValidThumbnailState(tab)) {

View File

@ -16,7 +16,21 @@ export class ThumbnailsChild extends JSWindowActorChild {
let [width, height] = lazy.PageThumbUtils.getContentSize(
this.contentWindow
);
return { width, height };
let documentElement = this.document.documentElement;
let body = this.document.body;
return {
width,
height,
scrollY: this.contentWindow.scrollY,
documentHeight: Math.max(
documentElement.clientHeight,
documentElement.scrollHeight,
documentElement.offsetHeight,
body.clientHeight,
body.scrollHeight,
body.offsetHeight
),
};
}
case "Browser:Thumbnail:CheckState": {
/**

View File

@ -481,6 +481,71 @@ export var PageThumbs = {
return true;
},
/**
* Capture a thumbnail for tab previews and draw it to canvas
*
* @param aBrowser the content window of this browser will be captured.
* @param aCanvas the thumbnail will be rendered to this canvas.
*/
async captureTabPreviewThumbnail(aBrowser, aCanvas) {
let desiredAspectRatio = aCanvas.width / aCanvas.height;
let thumbnailsActor =
aBrowser.browsingContext.currentWindowGlobal.getActor("Thumbnails");
let contentInfo = await thumbnailsActor.sendQuery(
"Browser:Thumbnail:ContentInfo"
);
// capture vars
let captureX = 0;
let captureY = contentInfo.scrollY;
let captureWidth = contentInfo.width;
let captureHeight = captureWidth / desiredAspectRatio;
let captureScale = aCanvas.width / captureWidth;
// render vars
let renderX = 0;
let renderY = 0;
let renderWidth = aCanvas.width;
let renderHeight = aCanvas.height;
// We're scaling based on width, so when the window is really wide,
// the screenshot will be really small.
// Some pages might not have enough content to vertically fill our canvas.
// In this case, we scale the capture based on height instead and crop
// the horizontal edges when rendering.
if (contentInfo.documentHeight < captureHeight) {
captureY = 0;
captureHeight = contentInfo.documentHeight;
captureScale = aCanvas.height / captureHeight;
renderWidth = captureWidth * captureScale;
renderHeight = aCanvas.height;
//canvasY = (aCanvas.height - eventualHeight) / 2;
renderX = (aCanvas.width - renderWidth) / 2;
renderY = (aCanvas.height - renderHeight) / 2;
}
// Avoid showing a blank space at the bottom of the thumbnail
// when the scroll position is near the bottom of the document.
else if (contentInfo.documentHeight - captureY < captureHeight) {
captureY = contentInfo.documentHeight - captureHeight;
}
let snapshotResult = await aBrowser.drawSnapshot(
captureX,
captureY,
captureWidth,
captureHeight,
captureScale * 2,
"transparent",
false
);
aCanvas
.getContext("2d")
.drawImage(snapshotResult, renderX, renderY, renderWidth, renderHeight);
},
/**
* Stores data to disk for the given URLs.
*