Bug 1708403 - Make resetting of scroll position for drawSnapshot opt-in. r=mstange,kmag

Differential Revision: https://phabricator.services.mozilla.com/D117613
This commit is contained in:
Matt Woodrow 2021-08-25 00:21:01 +00:00
Родитель e9dfbfe231
Коммит bb02f9029f
11 изменённых файлов: 37 добавлений и 8 удалений

Просмотреть файл

@ -40,6 +40,7 @@ this.takeshot = (function() {
height: pos.height,
};
options.rect = rectangle;
options.resetScrollPosition = true;
// To avoid creating extremely large images (which causes
// performance problems), we set the devicePixelRatio to 1.

Просмотреть файл

@ -118,7 +118,8 @@ async function captureScreenshot(args, browsingContext) {
const snapshot = await browsingContext.currentWindowGlobal.drawSnapshot(
rect,
actualRatio,
"rgb(255,255,255)"
"rgb(255,255,255)",
args.fullpage
);
const fileScale = args.fileScale || actualRatio;

Просмотреть файл

@ -43,7 +43,7 @@
// be visually in the middle of the root scroll frame, but should still be at the
// top of the snapshot (since snapshots with a rect are taken relative to the document).
var rect = new window.DOMRect(0, 0, 500, 2000);
let image = await SpecialPowers.snapshotContext(window, rect, "rgb(255, 255, 255)");
let image = await SpecialPowers.snapshotContext(window, rect, "rgb(255, 255, 255)", true);
testWrapCx.drawImage(image, 0, 0);
var refCanvas = make_canvas();

Просмотреть файл

@ -128,6 +128,10 @@ interface WindowGlobalParent : WindowContext {
* @param scale The scale to render the window at. Use devicePixelRatio
* to have comparable rendering to the OS.
* @param backgroundColor The background color to use.
* @param resetScrollPosition If true, temporarily resets the scroll position
* of the root scroll frame to 0, such that position:fixed elements are drawn
* at their initial position. This parameter only takes effect when passing a
* non-null rect.
*
* This API can only be used in the parent process, as content processes
* cannot access the rendering of out of process iframes. This API works
@ -136,7 +140,8 @@ interface WindowGlobalParent : WindowContext {
[Throws]
Promise<ImageBitmap> drawSnapshot(DOMRect? rect,
double scale,
UTF8String backgroundColor);
UTF8String backgroundColor,
optional boolean resetScrollPosition = false);
/**
* Fetches the securityInfo object for this window. This function will

Просмотреть файл

@ -930,7 +930,7 @@ void WindowGlobalParent::PermitUnload(std::function<void(bool)>&& aResolver) {
already_AddRefed<mozilla::dom::Promise> WindowGlobalParent::DrawSnapshot(
const DOMRect* aRect, double aScale, const nsACString& aBackgroundColor,
mozilla::ErrorResult& aRv) {
bool aResetScrollPosition, mozilla::ErrorResult& aRv) {
nsIGlobalObject* global = GetParentObject();
RefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
@ -949,6 +949,8 @@ already_AddRefed<mozilla::dom::Promise> WindowGlobalParent::DrawSnapshot(
if (!aRect) {
// If no explicit Rect was passed, we want the currently visible viewport.
flags = gfx::CrossProcessPaintFlags::DrawView;
} else if (aResetScrollPosition) {
flags = gfx::CrossProcessPaintFlags::ResetScrollPosition;
}
if (!gfx::CrossProcessPaint::Start(this, aRect, (float)aScale, color, flags,

Просмотреть файл

@ -160,7 +160,7 @@ class WindowGlobalParent final : public WindowContext,
already_AddRefed<mozilla::dom::Promise> DrawSnapshot(
const DOMRect* aRect, double aScale, const nsACString& aBackgroundColor,
mozilla::ErrorResult& aRv);
bool aResetScrollPosition, mozilla::ErrorResult& aRv);
already_AddRefed<Promise> GetSecurityInfo(ErrorResult& aRv);

Просмотреть файл

@ -178,7 +178,7 @@ void TabCapturer::CaptureFrameNow() {
// XXX This would be more efficient if it returned a MozPromise, and
// even more if we used CrossProcessPaint directly and returned a surface.
RefPtr<dom::Promise> promise =
wgp->DrawSnapshot(nullptr, 1.0, "white"_ns, IgnoreErrors());
wgp->DrawSnapshot(nullptr, 1.0, "white"_ns, false, IgnoreErrors());
if (!promise) {
return;
}

Просмотреть файл

@ -122,8 +122,10 @@ PaintFragment PaintFragment::Record(dom::BrowsingContext* aBc,
RenderDocumentFlags renderDocFlags = RenderDocumentFlags::None;
if (!(aFlags & CrossProcessPaintFlags::DrawView)) {
renderDocFlags = (RenderDocumentFlags::IgnoreViewportScrolling |
RenderDocumentFlags::ResetViewportScrolling |
RenderDocumentFlags::DocumentRelative);
if (aFlags & CrossProcessPaintFlags::ResetScrollPosition) {
renderDocFlags |= RenderDocumentFlags::ResetViewportScrolling;
}
}
// Perform the actual rendering

Просмотреть файл

@ -43,6 +43,7 @@ class CrossProcessPaint;
enum class CrossProcessPaintFlags {
None = 0,
DrawView = 1 << 1,
ResetScrollPosition = 1 << 2,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CrossProcessPaintFlags)

Просмотреть файл

@ -132,8 +132,20 @@ class TabBase {
let scale = options?.scale || win.devicePixelRatio;
let rect = options?.rect && win.DOMRect.fromRect(options.rect);
// We only allow mozilla addons to use the resetScrollPosition option,
// since it's not standardized.
let resetScrollPosition = false;
if (!context.extension.restrictSchemes) {
resetScrollPosition = !!options?.resetScrollPosition;
}
let wgp = this.browsingContext.currentWindowGlobal;
let image = await wgp.drawSnapshot(rect, scale * zoom, "white");
let image = await wgp.drawSnapshot(
rect,
scale * zoom,
"white",
resetScrollPosition
);
let doc = Services.appShell.hiddenDOMWindow.document;
let canvas = doc.createElement("canvas");

Просмотреть файл

@ -45,6 +45,11 @@
"type": "number",
"optional": true,
"description": "The scale of the resulting image. Defaults to <code>devicePixelRatio</code>."
},
"resetScrollPosition": {
"type": "boolean",
"optional": true,
"description": "If true, temporarily resets the scroll position of the document to 0. Only takes effect if rect is also specified."
}
}
},