зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1705757 - Move FrameLoader.print to BrowsingContext.print. r=nika,remote-protocol-reviewers,marionette-reviewers,extension-reviewers,zombie
This makes it trivial to choose the right BrowserParent to print a browsing context, by removing the OuterWindowID / FrameLoader indirections. Differential Revision: https://phabricator.services.mozilla.com/D112412
This commit is contained in:
Родитель
6dae709f27
Коммит
9afefdd884
|
@ -1407,8 +1407,8 @@ this.tabs = class extends ExtensionAPI {
|
|||
printSettings.footerStrRight = pageSettings.footerRight;
|
||||
}
|
||||
|
||||
activeTab.linkedBrowser
|
||||
.print(activeTab.linkedBrowser.outerWindowID, printSettings)
|
||||
activeTab.linkedBrowser.browsingContext
|
||||
.print(printSettings)
|
||||
.then(() => resolve(retval == 0 ? "saved" : "replaced"))
|
||||
.catch(() =>
|
||||
resolve(retval == 0 ? "not_saved" : "not_replaced")
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
#include "nsIBrowser.h"
|
||||
#include "nsTHashSet.h"
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
# include "mozilla/embedding/printingui/PrintingParent.h"
|
||||
# include "nsIWebBrowserPrint.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
extern mozilla::LazyLogModule gAutoplayPermissionLog;
|
||||
|
@ -479,6 +484,120 @@ CanonicalBrowsingContext::ReplaceLoadingSessionHistoryEntryForLoad(
|
|||
return MakeUnique<LoadingSessionHistoryInfo>(newEntry, aInfo->mLoadId);
|
||||
}
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
class PrintListenerAdapter final : public nsIWebProgressListener {
|
||||
public:
|
||||
explicit PrintListenerAdapter(Promise* aPromise) : mPromise(aPromise) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_IMETHOD OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
|
||||
uint32_t aStateFlags, nsresult aStatus) override {
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_STOP &&
|
||||
aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT && mPromise) {
|
||||
mPromise->MaybeResolveWithUndefined();
|
||||
mPromise = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnStatusChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
const char16_t* aMessage) override {
|
||||
if (aStatus != NS_OK && mPromise) {
|
||||
mPromise->MaybeReject(ErrorResult(aStatus));
|
||||
mPromise = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnProgressChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, int32_t aCurSelfProgress,
|
||||
int32_t aMaxSelfProgress,
|
||||
int32_t aCurTotalProgress,
|
||||
int32_t aMaxTotalProgress) override {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, nsIURI* aLocation,
|
||||
uint32_t aFlags) override {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnSecurityChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, uint32_t aState) override {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnContentBlockingEvent(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aEvent) override {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~PrintListenerAdapter() = default;
|
||||
|
||||
RefPtr<Promise> mPromise;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(PrintListenerAdapter, nsIWebProgressListener)
|
||||
#endif
|
||||
|
||||
already_AddRefed<Promise> CanonicalBrowsingContext::Print(
|
||||
nsIPrintSettings* aPrintSettings, ErrorResult& aRv) {
|
||||
RefPtr<Promise> promise = Promise::Create(GetIncumbentGlobal(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
#ifndef NS_PRINTING
|
||||
promise->MaybeReject(ErrorResult(NS_ERROR_NOT_AVAILABLE));
|
||||
return promise.forget();
|
||||
#else
|
||||
|
||||
auto listener = MakeRefPtr<PrintListenerAdapter>(promise);
|
||||
if (IsInProcess()) {
|
||||
RefPtr<nsGlobalWindowOuter> outerWindow =
|
||||
nsGlobalWindowOuter::Cast(GetDOMWindow());
|
||||
if (NS_WARN_IF(!outerWindow)) {
|
||||
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
outerWindow->Print(aPrintSettings, listener,
|
||||
/* aDocShellToCloneInto = */ nullptr,
|
||||
nsGlobalWindowOuter::IsPreview::No,
|
||||
nsGlobalWindowOuter::IsForWindowDotPrint::No,
|
||||
/* aPrintPreviewCallback = */ nullptr, rv);
|
||||
if (rv.Failed()) {
|
||||
promise->MaybeReject(std::move(rv));
|
||||
}
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
auto* browserParent = GetBrowserParent();
|
||||
if (NS_WARN_IF(!browserParent)) {
|
||||
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RefPtr<embedding::PrintingParent> printingParent =
|
||||
browserParent->Manager()->GetPrintingParent();
|
||||
|
||||
embedding::PrintData printData;
|
||||
nsresult rv = printingParent->SerializeAndEnsureRemotePrintJob(
|
||||
aPrintSettings, listener, nullptr, &printData);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
promise->MaybeReject(ErrorResult(rv));
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!browserParent->SendPrint(this, printData))) {
|
||||
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
|
||||
}
|
||||
return promise.forget();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::CallOnAllTopDescendants(
|
||||
const std::function<mozilla::CallState(CanonicalBrowsingContext*)>&
|
||||
aCallback) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
class nsISHistory;
|
||||
class nsIWidget;
|
||||
class nsIPrintSettings;
|
||||
class nsSHistory;
|
||||
class nsBrowserStatusFilter;
|
||||
class nsSecureBrowserUI;
|
||||
|
@ -127,6 +128,9 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
|||
UniquePtr<LoadingSessionHistoryInfo> ReplaceLoadingSessionHistoryEntryForLoad(
|
||||
LoadingSessionHistoryInfo* aInfo, nsIChannel* aChannel);
|
||||
|
||||
already_AddRefed<Promise> Print(nsIPrintSettings* aPrintSettings,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// Call the given callback on all top-level descendant BrowsingContexts.
|
||||
// Return Callstate::Stop from the callback to stop calling
|
||||
// further children.
|
||||
|
|
|
@ -3252,64 +3252,6 @@ void nsFrameLoader::RequestSHistoryUpdate(bool aImmediately) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
class WebProgressListenerToPromise final : public nsIWebProgressListener {
|
||||
public:
|
||||
explicit WebProgressListenerToPromise(Promise* aPromise)
|
||||
: mPromise(aPromise) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_IMETHOD OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
|
||||
uint32_t aStateFlags, nsresult aStatus) override {
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_STOP &&
|
||||
aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT && mPromise) {
|
||||
mPromise->MaybeResolveWithUndefined();
|
||||
mPromise = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnStatusChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
const char16_t* aMessage) override {
|
||||
if (aStatus != NS_OK && mPromise) {
|
||||
mPromise->MaybeReject(ErrorResult(aStatus));
|
||||
mPromise = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnProgressChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, int32_t aCurSelfProgress,
|
||||
int32_t aMaxSelfProgress,
|
||||
int32_t aCurTotalProgress,
|
||||
int32_t aMaxTotalProgress) override {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, nsIURI* aLocation,
|
||||
uint32_t aFlags) override {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnSecurityChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, uint32_t aState) override {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD OnContentBlockingEvent(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aEvent) override {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~WebProgressListenerToPromise() = default;
|
||||
|
||||
RefPtr<Promise> mPromise;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebProgressListenerToPromise, nsIWebProgressListener)
|
||||
#endif
|
||||
|
||||
already_AddRefed<Promise> nsFrameLoader::PrintPreview(
|
||||
nsIPrintSettings* aPrintSettings,
|
||||
const Optional<uint64_t>& aSourceOuterWindowID, ErrorResult& aRv) {
|
||||
|
@ -3438,60 +3380,6 @@ void nsFrameLoader::ExitPrintPreview() {
|
|||
#endif
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> nsFrameLoader::Print(uint64_t aOuterWindowID,
|
||||
nsIPrintSettings* aPrintSettings,
|
||||
ErrorResult& aRv) {
|
||||
RefPtr<Promise> promise =
|
||||
Promise::Create(GetOwnerDoc()->GetOwnerGlobal(), aRv);
|
||||
|
||||
#ifndef NS_PRINTING
|
||||
promise->MaybeReject(ErrorResult(NS_ERROR_NOT_AVAILABLE));
|
||||
return promise.forget();
|
||||
#else
|
||||
|
||||
RefPtr<WebProgressListenerToPromise> listener(
|
||||
new WebProgressListenerToPromise(promise));
|
||||
|
||||
if (auto* browserParent = GetBrowserParent()) {
|
||||
RefPtr<embedding::PrintingParent> printingParent =
|
||||
browserParent->Manager()->GetPrintingParent();
|
||||
|
||||
embedding::PrintData printData;
|
||||
nsresult rv = printingParent->SerializeAndEnsureRemotePrintJob(
|
||||
aPrintSettings, listener, nullptr, &printData);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
promise->MaybeReject(ErrorResult(rv));
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
bool success = browserParent->SendPrint(aOuterWindowID, printData);
|
||||
if (!success) {
|
||||
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
|
||||
}
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RefPtr<nsGlobalWindowOuter> outerWindow =
|
||||
nsGlobalWindowOuter::GetOuterWindowWithId(aOuterWindowID);
|
||||
if (NS_WARN_IF(!outerWindow)) {
|
||||
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
outerWindow->Print(aPrintSettings, listener,
|
||||
/* aDocShellToCloneInto = */ nullptr,
|
||||
nsGlobalWindowOuter::IsPreview::No,
|
||||
nsGlobalWindowOuter::IsForWindowDotPrint::No,
|
||||
/* aPrintPreviewCallback = */ nullptr, rv);
|
||||
if (rv.Failed()) {
|
||||
promise->MaybeReject(std::move(rv));
|
||||
}
|
||||
|
||||
return promise.forget();
|
||||
#endif
|
||||
}
|
||||
|
||||
already_AddRefed<nsIRemoteTab> nsFrameLoader::GetRemoteTab() {
|
||||
if (!mRemoteBrowser) {
|
||||
return nullptr;
|
||||
|
|
|
@ -236,10 +236,6 @@ class nsFrameLoader final : public nsStubMutationObserver,
|
|||
|
||||
void ExitPrintPreview();
|
||||
|
||||
already_AddRefed<Promise> Print(uint64_t aOuterWindowID,
|
||||
nsIPrintSettings* aPrintSettings,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void StartPersistence(BrowsingContext* aContext,
|
||||
nsIWebBrowserPersistDocumentReceiver* aRecv,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
interface URI;
|
||||
interface nsIDocShell;
|
||||
interface nsISecureBrowserUI;
|
||||
interface nsIPrintSettings;
|
||||
interface nsIWebProgress;
|
||||
|
||||
interface mixin LoadContextMixin {
|
||||
|
@ -257,6 +258,17 @@ interface CanonicalBrowsingContext : BrowsingContext {
|
|||
[Throws]
|
||||
void loadURI(DOMString aURI, optional LoadURIOptions aOptions = {});
|
||||
|
||||
/**
|
||||
* Print the current document.
|
||||
*
|
||||
* @param aOuterWindowID the ID of the outer window to print
|
||||
* @param aPrintSettings print settings to use; printSilent can be
|
||||
* set to prevent prompting.
|
||||
* @return A Promise that resolves once printing is finished.
|
||||
*/
|
||||
[Throws]
|
||||
Promise<void> print(nsIPrintSettings aPrintSettings);
|
||||
|
||||
/**
|
||||
* These methods implement the nsIWebNavigation methods of the same names
|
||||
*/
|
||||
|
|
|
@ -141,18 +141,6 @@ interface FrameLoader {
|
|||
[ChromeOnly]
|
||||
void exitPrintPreview();
|
||||
|
||||
/**
|
||||
* Print the current document.
|
||||
*
|
||||
* @param aOuterWindowID the ID of the outer window to print
|
||||
* @param aPrintSettings optional print settings to use; printSilent can be
|
||||
* set to prevent prompting.
|
||||
* @return A Promise that resolves once printing is finished.
|
||||
*/
|
||||
[Throws]
|
||||
Promise<void> print(unsigned long long aOuterWindowID,
|
||||
nsIPrintSettings aPrintSettings);
|
||||
|
||||
/**
|
||||
* The element which owns this frame loader.
|
||||
*
|
||||
|
|
|
@ -552,8 +552,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||
|
||||
mozilla::ipc::IPCResult RecvExitPrintPreview();
|
||||
|
||||
mozilla::ipc::IPCResult RecvPrint(const uint64_t& aOuterWindowID,
|
||||
const PrintData& aPrintData);
|
||||
mozilla::ipc::IPCResult RecvPrint(const MaybeDiscardedBrowsingContext&,
|
||||
const PrintData&);
|
||||
|
||||
mozilla::ipc::IPCResult RecvUpdateNativeWindowHandle(
|
||||
const uintptr_t& aNewHandle);
|
||||
|
|
|
@ -982,10 +982,10 @@ child:
|
|||
/**
|
||||
* Tell the child to print the current page with the given settings.
|
||||
*
|
||||
* @param aOuterWindowID the ID of the outer window to print
|
||||
* @param aBrowsingContext the browsing context to print.
|
||||
* @param aPrintData the serialized settings to print with
|
||||
*/
|
||||
async Print(uint64_t aOuterWindowID, PrintData aPrintData);
|
||||
async Print(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData);
|
||||
|
||||
/**
|
||||
* Update the child with the tab's current top-level native window handle.
|
||||
|
|
|
@ -1697,7 +1697,7 @@ function RecvStartPrint(isPrintSelection, printRange)
|
|||
getService(Ci.nsIPrefBranch);
|
||||
ps.printInColor = prefs.getBoolPref("print.print_in_color", true);
|
||||
|
||||
g.browser.print(g.browser.outerWindowID, ps)
|
||||
g.browser.browsingContext.print(ps)
|
||||
.then(() => SendPrintDone(Cr.NS_OK, file.path))
|
||||
.catch(exception => SendPrintDone(exception.code, file.path));
|
||||
}
|
||||
|
|
|
@ -608,7 +608,7 @@ class Page extends Domain {
|
|||
|
||||
const { linkedBrowser } = this.session.target.tab;
|
||||
|
||||
await linkedBrowser.print(linkedBrowser.outerWindowID, printSettings);
|
||||
await linkedBrowser.browsingContext.print(printSettings);
|
||||
|
||||
// Bug 1603739 - With e10s enabled the promise returned by print() resolves
|
||||
// too early, which means the file hasn't been completely written.
|
||||
|
|
|
@ -3099,11 +3099,7 @@ GeckoDriver.prototype.print = async function(cmd) {
|
|||
assert.boolean(settings.printBackground);
|
||||
|
||||
const linkedBrowser = this.curBrowser.tab.linkedBrowser;
|
||||
const filePath = await print.printToFile(
|
||||
linkedBrowser,
|
||||
linkedBrowser.outerWindowID,
|
||||
settings
|
||||
);
|
||||
const filePath = await print.printToFile(linkedBrowser, settings);
|
||||
|
||||
// return all data as a base64 encoded string
|
||||
let bytes;
|
||||
|
|
|
@ -98,7 +98,7 @@ function getPrintSettings(settings, filePath) {
|
|||
return printSettings;
|
||||
}
|
||||
|
||||
print.printToFile = async function(browser, outerWindowID, settings) {
|
||||
print.printToFile = async function(browser, settings) {
|
||||
// Create a unique filename for the temporary PDF file
|
||||
const basePath = OS.Path.join(OS.Constants.Path.tmpDir, "marionette.pdf");
|
||||
const { file, path: filePath } = await OS.File.openUnique(basePath);
|
||||
|
@ -106,7 +106,7 @@ print.printToFile = async function(browser, outerWindowID, settings) {
|
|||
|
||||
let printSettings = getPrintSettings(settings, filePath);
|
||||
|
||||
await browser.print(outerWindowID, printSettings);
|
||||
await browser.browsingContext.print(printSettings);
|
||||
|
||||
// Bug 1603739 - With e10s enabled the promise returned by print() resolves
|
||||
// too early, which means the file hasn't been completely written.
|
||||
|
|
|
@ -785,11 +785,7 @@ browserRect.height: ${browserRect.height}`);
|
|||
printBackground: true,
|
||||
});
|
||||
|
||||
const filePath = await print.printToFile(
|
||||
win.gBrowser.frameLoader,
|
||||
win.gBrowser.outerWindowID,
|
||||
settings
|
||||
);
|
||||
const filePath = await print.printToFile(win.gBrowser, settings);
|
||||
|
||||
const fp = await OS.File.open(filePath, { read: true });
|
||||
try {
|
||||
|
|
|
@ -414,7 +414,7 @@ var PrintEventHandler = {
|
|||
this.printProgressIndicator.hidden = false;
|
||||
|
||||
let bc = this.currentPreviewBrowser.browsingContext;
|
||||
await this._doPrint(bc, settings);
|
||||
await bc.print(settings);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
@ -1013,17 +1013,6 @@ var PrintEventHandler = {
|
|||
Services.telemetry.keyedScalarAdd("printing.error", aMessage, 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Prints the window. This method has been abstracted into a helper for
|
||||
* testing purposes.
|
||||
*/
|
||||
_doPrint(aBrowsingContext, aSettings) {
|
||||
return aBrowsingContext.top.embedderElement.print(
|
||||
aBrowsingContext.currentWindowGlobal.outerWindowId,
|
||||
aSettings
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the system dialog. This method has been abstracted into a helper for
|
||||
* testing purposes. The showPrintDialog() call blocks until the dialog is
|
||||
|
|
|
@ -370,8 +370,7 @@ var PrintUtils = {
|
|||
* Optional print settings for the print operation
|
||||
*/
|
||||
printWindow(aBrowsingContext, aPrintSettings) {
|
||||
let windowID = aBrowsingContext.currentWindowGlobal.outerWindowId;
|
||||
let topBrowser = aBrowsingContext.top.embedderElement;
|
||||
let wg = aBrowsingContext.currentWindowGlobal;
|
||||
|
||||
const printPreviewIsOpen = !!document.getElementById(
|
||||
"print-preview-toolbar"
|
||||
|
@ -388,18 +387,18 @@ var PrintUtils = {
|
|||
|
||||
// Set the title so that the print dialog can pick it up and
|
||||
// use it to generate the filename for save-to-PDF.
|
||||
printSettings.title = this._originalTitle || topBrowser.contentTitle;
|
||||
printSettings.title = this._originalTitle || wg.documentTitle;
|
||||
|
||||
if (this._shouldSimplify) {
|
||||
// The generated document for simplified print preview has "about:blank"
|
||||
// as its URL. We need to set docURL here so that the print header/footer
|
||||
// can be given the original document's URL.
|
||||
printSettings.docURL = this._originalURL || topBrowser.currentURI.spec;
|
||||
printSettings.docURL = this._originalURL || wg.documentURI;
|
||||
}
|
||||
|
||||
// At some point we should handle the Promise that this returns (report
|
||||
// rejection to telemetry?)
|
||||
let promise = topBrowser.print(windowID, printSettings);
|
||||
let promise = aBrowsingContext.print(printSettings);
|
||||
|
||||
if (printPreviewIsOpen) {
|
||||
if (this._shouldSimplify) {
|
||||
|
|
|
@ -1731,14 +1731,6 @@
|
|||
};
|
||||
}
|
||||
|
||||
print(aOuterWindowID, aPrintSettings) {
|
||||
if (!this.frameLoader) {
|
||||
throw Components.Exception("No frame loader.", Cr.NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
return this.frameLoader.print(aOuterWindowID, aPrintSettings);
|
||||
}
|
||||
|
||||
async drawSnapshot(x, y, w, h, scale, backgroundColor) {
|
||||
let rect = new DOMRect(x, y, w, h);
|
||||
try {
|
||||
|
|
Загрузка…
Ссылка в новой задаче