forked from mirrors/gecko-dev
Bug 1878038 - show entire viewport in tab preview. a=RyanVM
Original Revision: https://phabricator.services.mozilla.com/D212709 Differential Revision: https://phabricator.services.mozilla.com/D214432
This commit is contained in:
parent
0ac701f376
commit
2361bd68c9
5 changed files with 148 additions and 14 deletions
|
|
@ -74,12 +74,12 @@ export default class TabHoverPreviewPanel {
|
|||
if (!this._prefDisplayThumbnail || !this._hasValidThumbnailState(tab)) {
|
||||
return;
|
||||
}
|
||||
let thumbnailCanvas = this._win.PageThumbs.createCanvas(this._win);
|
||||
thumbnailCanvas.width = 280;
|
||||
thumbnailCanvas.height = 125;
|
||||
let thumbnailCanvas = this._win.document.createElement("canvas");
|
||||
|
||||
this._win.PageThumbs.captureToCanvas(tab.linkedBrowser, thumbnailCanvas, {
|
||||
fullViewport: true,
|
||||
targetWidth: 280,
|
||||
preserveAspectRatio: true,
|
||||
})
|
||||
.then(() => {
|
||||
// in case we've changed tabs after capture started, ensure we still want to show the thumbnail
|
||||
|
|
|
|||
|
|
@ -223,6 +223,17 @@ export var PageThumbUtils = {
|
|||
aDestCanvas.width = contentWidth;
|
||||
aDestCanvas.height = contentHeight;
|
||||
}
|
||||
} else if (contentHeight && aArgs.preserveAspectRatio) {
|
||||
// Calculate the thumbnail height based on thumbnail width
|
||||
// and content aspect ratio
|
||||
if (aArgs.targetWidth) {
|
||||
thumbnailWidth = aArgs.targetWidth;
|
||||
}
|
||||
thumbnailHeight = thumbnailWidth / (contentWidth / contentHeight);
|
||||
if (aDestCanvas) {
|
||||
aDestCanvas.width = thumbnailWidth;
|
||||
aDestCanvas.height = thumbnailHeight;
|
||||
}
|
||||
}
|
||||
|
||||
let intermediateWidth = thumbnailWidth * 2;
|
||||
|
|
@ -254,13 +265,17 @@ export var PageThumbUtils = {
|
|||
// content dims.
|
||||
// Also by default, canvas does not draw the scrollbars, so no need to
|
||||
// remove the scrollbar sizes.
|
||||
let scale = Math.min(
|
||||
Math.max(
|
||||
let targetScale;
|
||||
if (aArgs.preserveAspectRatio) {
|
||||
// always scale based on width, as we resize height to accommodate
|
||||
targetScale = intermediateWidth / contentWidth;
|
||||
} else {
|
||||
targetScale = Math.max(
|
||||
intermediateWidth / contentWidth,
|
||||
intermediateHeight / contentHeight
|
||||
),
|
||||
1
|
||||
);
|
||||
);
|
||||
}
|
||||
let scale = Math.min(targetScale, 1);
|
||||
|
||||
let snapshotCtx = snapshotCanvas.getContext("2d");
|
||||
snapshotCtx.save();
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ export var PageThumbs = {
|
|||
* isImage - indicate that this should be treated as an image url.
|
||||
* backgroundColor - background color to draw behind images.
|
||||
* targetWidth - desired width for images.
|
||||
* preserveAspectRatio - resize image height based on targetWidth
|
||||
* isBackgroundThumb - true if request is from the background thumb service.
|
||||
* fullViewport - request that a screenshot for the viewport be
|
||||
* captured. This makes it possible to get a screenshot that reflects
|
||||
|
|
@ -228,6 +229,7 @@ export var PageThumbs = {
|
|||
aArgs?.backgroundColor ?? lazy.PageThumbUtils.THUMBNAIL_BG_COLOR,
|
||||
targetWidth:
|
||||
aArgs?.targetWidth ?? lazy.PageThumbUtils.THUMBNAIL_DEFAULT_SIZE,
|
||||
preserveAspectRatio: aArgs?.preserveAspectRatio ?? false,
|
||||
isBackgroundThumb: aArgs ? aArgs.isBackgroundThumb : false,
|
||||
fullViewport: aArgs?.fullViewport ?? false,
|
||||
};
|
||||
|
|
@ -313,6 +315,7 @@ export var PageThumbs = {
|
|||
* isImage - indicate that this should be treated as an image url.
|
||||
* backgroundColor - background color to draw behind images.
|
||||
* targetWidth - desired width for images.
|
||||
* preserveAspectRatio - resize image height based on targetWidth
|
||||
* isBackgroundThumb - true if request is from the background thumb service.
|
||||
* fullViewport - request that a screenshot for the viewport be
|
||||
* captured. This makes it possible to get a screenshot that reflects
|
||||
|
|
@ -341,6 +344,7 @@ export var PageThumbs = {
|
|||
if (contentWidth == 0 || contentHeight == 0) {
|
||||
throw new Error("IMAGE_ZERO_DIMENSION");
|
||||
}
|
||||
let aspectRatio = contentWidth / contentHeight;
|
||||
|
||||
if (!aBrowser.isConnected) {
|
||||
return null;
|
||||
|
|
@ -363,9 +367,21 @@ export var PageThumbs = {
|
|||
});
|
||||
} else {
|
||||
let fullScale = aArgs ? aArgs.fullScale : false;
|
||||
let scale = fullScale
|
||||
? 1
|
||||
: Math.min(Math.max(aWidth / contentWidth, aHeight / contentHeight), 1);
|
||||
let targetWidth = aArgs.targetWidth ? aArgs.targetWidth : aWidth;
|
||||
let preserveAspectRatio = aArgs ? aArgs.preserveAspectRatio : false;
|
||||
let scale = 1;
|
||||
if (!fullScale) {
|
||||
let targetScale;
|
||||
if (preserveAspectRatio) {
|
||||
targetScale = targetWidth / contentWidth;
|
||||
} else {
|
||||
targetScale = Math.max(
|
||||
aWidth / contentWidth,
|
||||
aHeight / contentHeight
|
||||
);
|
||||
}
|
||||
scale = Math.min(targetScale, 1);
|
||||
}
|
||||
|
||||
image = await aBrowser.drawSnapshot(
|
||||
0,
|
||||
|
|
@ -380,8 +396,13 @@ export var PageThumbs = {
|
|||
return null;
|
||||
}
|
||||
|
||||
thumbnail.width = fullScale ? contentWidth : aWidth;
|
||||
thumbnail.height = fullScale ? contentHeight : aHeight;
|
||||
if (preserveAspectRatio) {
|
||||
thumbnail.width = targetWidth;
|
||||
thumbnail.height = targetWidth / aspectRatio;
|
||||
} else {
|
||||
thumbnail.width = fullScale ? contentWidth : aWidth;
|
||||
thumbnail.height = fullScale ? contentHeight : aHeight;
|
||||
}
|
||||
}
|
||||
|
||||
thumbnail.getContext("2d").drawImage(image, 0, 0);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ support-files = [
|
|||
|
||||
["browser_thumbnails_bg_crash_during_capture.js"]
|
||||
run-if = ["crashreporter"]
|
||||
skip-if = ["apple_silicon"] # Disabled due to bleedover with other tests when run in regular suites; passes in "failures" jobs
|
||||
skip-if = [
|
||||
"apple_silicon",
|
||||
] # Disabled due to bleedover with other tests when run in regular suites; passes in "failures" jobs
|
||||
|
||||
["browser_thumbnails_bg_crash_while_idle.js"]
|
||||
run-if = ["crashreporter"]
|
||||
|
|
@ -66,6 +68,8 @@ skip-if = ["true"] # bug 1314039 # Bug 1345418
|
|||
|
||||
["browser_thumbnails_fullViewport.js"]
|
||||
|
||||
["browser_thumbnails_preserveAspectRatio.js"]
|
||||
|
||||
["browser_thumbnails_privacy.js"]
|
||||
|
||||
["browser_thumbnails_redirect.js"]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PageThumbUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/PageThumbUtils.sys.mjs"
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the width & height of the content area for a given browser
|
||||
*
|
||||
* @param browser the browser to get dimensions for
|
||||
*/
|
||||
async function getContentDimensions(browser) {
|
||||
let thumbnailsActor =
|
||||
browser.browsingContext.currentWindowGlobal.getActor("Thumbnails");
|
||||
let contentInfo = await thumbnailsActor.sendQuery(
|
||||
"Browser:Thumbnail:ContentInfo"
|
||||
);
|
||||
return [contentInfo.width, contentInfo.height];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that preserveAspectRatio generates a sized canvas
|
||||
* that matches the window's aspect ratio
|
||||
*
|
||||
* @param windowWidth width of the browser window
|
||||
* @param windowHeight height of the browser window
|
||||
* @param useRemote Whether to use a remote or local browser (these use different PageThumbs APIs)
|
||||
* @param win the window to test
|
||||
*/
|
||||
async function testPreserveAspectRatio(
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
useRemote,
|
||||
win
|
||||
) {
|
||||
let resizeComplete = BrowserTestUtils.waitForEvent(win, "resize");
|
||||
win.resizeTo(windowWidth, windowHeight);
|
||||
await resizeComplete;
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{
|
||||
gBrowser: win.gBrowser,
|
||||
url: useRemote ? "https://example.com" : "about:about",
|
||||
},
|
||||
async browser => {
|
||||
let canvas = PageThumbUtils.createCanvas(win);
|
||||
let [, defaultThumbnailHeight] = PageThumbUtils.getThumbnailSize(win);
|
||||
|
||||
await PageThumbs.captureToCanvas(browser, canvas, {
|
||||
targetWidth: 300,
|
||||
preserveAspectRatio: false,
|
||||
});
|
||||
|
||||
Assert.equal(
|
||||
canvas.height,
|
||||
defaultThumbnailHeight,
|
||||
"canvas uses default thumbnail height"
|
||||
);
|
||||
|
||||
await PageThumbs.captureToCanvas(browser, canvas, {
|
||||
targetWidth: 300,
|
||||
preserveAspectRatio: true,
|
||||
});
|
||||
|
||||
let [contentWidth, contentHeight] = await getContentDimensions(browser);
|
||||
|
||||
let aspectRatio = contentWidth / contentHeight;
|
||||
let expectedHeight = canvas.width / aspectRatio;
|
||||
|
||||
// Calculation may be off by a pixel here and there due to floating point math;
|
||||
// assume it's correct if error is within 1%
|
||||
let deviation = Math.abs(expectedHeight - canvas.height) / expectedHeight;
|
||||
Assert.ok(deviation < 0.01, "canvas height within 1% of expected height");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests PageThumbs' preserveAspectRatio option for a variety
|
||||
* of window aspect ratios.
|
||||
*/
|
||||
add_task(async function thumbnails_preserveAspectRatio() {
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await testPreserveAspectRatio(600, 900, true, win);
|
||||
await testPreserveAspectRatio(900, 600, true, win);
|
||||
await testPreserveAspectRatio(450, 1000, true, win);
|
||||
await testPreserveAspectRatio(600, 900, false, win);
|
||||
await testPreserveAspectRatio(900, 600, false, win);
|
||||
await testPreserveAspectRatio(450, 1000, false, win);
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
Loading…
Reference in a new issue