mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Backed out 3 changesets (bug 1875481) for basicWindowDotPrintTest related junit failures.
Backed out changeset cd024cb2768e (bug 1875481) Backed out changeset 6b7be15cd017 (bug 1875481) Backed out changeset d1da53c0673b (bug 1875481)
This commit is contained in:
parent
f268233fbd
commit
9879879814
@ -300,10 +300,10 @@ export const ContentAnalysis = {
|
||||
);
|
||||
return;
|
||||
}
|
||||
const analysisType = request.analysisType;
|
||||
const operation = request.analysisType;
|
||||
// For operations that block browser interaction, show the "slow content analysis"
|
||||
// dialog faster
|
||||
let slowTimeoutMs = this._shouldShowBlockingNotification(analysisType)
|
||||
let slowTimeoutMs = this._shouldShowBlockingNotification(operation)
|
||||
? this._SLOW_DLP_NOTIFICATION_BLOCKING_TIMEOUT_MS
|
||||
: this._SLOW_DLP_NOTIFICATION_NONBLOCKING_TIMEOUT_MS;
|
||||
let browsingContext = request.windowGlobalParent?.browsingContext;
|
||||
@ -333,7 +333,7 @@ export const ContentAnalysis = {
|
||||
timer: lazy.setTimeout(() => {
|
||||
this.dlpBusyViewsByTopBrowsingContext.setEntry(browsingContext, {
|
||||
notification: this._showSlowCAMessage(
|
||||
analysisType,
|
||||
operation,
|
||||
request,
|
||||
resourceNameOrOperationType,
|
||||
browsingContext
|
||||
@ -450,10 +450,7 @@ export const ContentAnalysis = {
|
||||
}
|
||||
|
||||
if (this._SHOW_NOTIFICATIONS) {
|
||||
let topWindow =
|
||||
aBrowsingContext.topChromeWindow ??
|
||||
aBrowsingContext.embedderWindowGlobal.browsingContext.topChromeWindow;
|
||||
const notification = new topWindow.Notification(
|
||||
const notification = new aBrowsingContext.topChromeWindow.Notification(
|
||||
this.l10n.formatValueSync("contentanalysis-notification-title"),
|
||||
{
|
||||
body: aMessage,
|
||||
@ -472,10 +469,10 @@ export const ContentAnalysis = {
|
||||
return null;
|
||||
},
|
||||
|
||||
_shouldShowBlockingNotification(aAnalysisType) {
|
||||
_shouldShowBlockingNotification(aOperation) {
|
||||
return !(
|
||||
aAnalysisType == Ci.nsIContentAnalysisRequest.eFileDownloaded ||
|
||||
aAnalysisType == Ci.nsIContentAnalysisRequest.ePrint
|
||||
aOperation == Ci.nsIContentAnalysisRequest.eFileDownloaded ||
|
||||
aOperation == Ci.nsIContentAnalysisRequest.ePrint
|
||||
);
|
||||
},
|
||||
|
||||
@ -491,9 +488,6 @@ export const ContentAnalysis = {
|
||||
case Ci.nsIContentAnalysisRequest.eDroppedText:
|
||||
l10nId = "contentanalysis-operationtype-dropped-text";
|
||||
break;
|
||||
case Ci.nsIContentAnalysisRequest.eOperationPrint:
|
||||
l10nId = "contentanalysis-operationtype-print";
|
||||
break;
|
||||
}
|
||||
if (!l10nId) {
|
||||
console.error(
|
||||
@ -602,14 +596,10 @@ export const ContentAnalysis = {
|
||||
case Ci.nsIContentAnalysisRequest.eDroppedText:
|
||||
l10nId = "contentanalysis-slow-agent-dialog-body-dropped-text";
|
||||
break;
|
||||
case Ci.nsIContentAnalysisRequest.eOperationPrint:
|
||||
l10nId = "contentanalysis-slow-agent-dialog-body-print";
|
||||
break;
|
||||
}
|
||||
if (!l10nId) {
|
||||
console.error(
|
||||
"Unknown operationTypeForDisplay: ",
|
||||
aResourceNameOrOperationType
|
||||
"Unknown operationTypeForDisplay: " + aResourceNameOrOperationType
|
||||
);
|
||||
return "";
|
||||
}
|
||||
|
@ -6,10 +6,8 @@
|
||||
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
|
||||
#include "ContentAnalysis.h"
|
||||
#include "ErrorList.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
@ -49,7 +47,6 @@
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsFrameLoaderOwner.h"
|
||||
#include "nsGlobalWindowOuter.h"
|
||||
#include "nsIContentAnalysis.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsNetUtil.h"
|
||||
@ -671,9 +668,6 @@ CanonicalBrowsingContext::ReplaceLoadingSessionHistoryEntryForLoad(
|
||||
|
||||
using PrintPromise = CanonicalBrowsingContext::PrintPromise;
|
||||
#ifdef NS_PRINTING
|
||||
// Clients must call StaticCloneForPrintingCreated or
|
||||
// NoStaticCloneForPrintingWillBeCreated before the underlying promise can
|
||||
// resolve.
|
||||
class PrintListenerAdapter final : public nsIWebProgressListener {
|
||||
public:
|
||||
explicit PrintListenerAdapter(PrintPromise::Private* aPromise)
|
||||
@ -684,14 +678,10 @@ class PrintListenerAdapter final : public nsIWebProgressListener {
|
||||
// NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_IMETHOD OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
|
||||
uint32_t aStateFlags, nsresult aStatus) override {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_STOP &&
|
||||
aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT && mPromise) {
|
||||
mPrintJobFinished = true;
|
||||
if (mHaveSetBrowsingContext) {
|
||||
mPromise->Resolve(mClonedStaticBrowsingContext, __func__);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
mPromise->Resolve(true, __func__);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -726,28 +716,10 @@ class PrintListenerAdapter final : public nsIWebProgressListener {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void StaticCloneForPrintingCreated(
|
||||
MaybeDiscardedBrowsingContext&& aClonedStaticBrowsingContext) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mClonedStaticBrowsingContext = std::move(aClonedStaticBrowsingContext);
|
||||
mHaveSetBrowsingContext = true;
|
||||
if (mPrintJobFinished && mPromise) {
|
||||
mPromise->Resolve(mClonedStaticBrowsingContext, __func__);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void NoStaticCloneForPrintingWillBeCreated() {
|
||||
StaticCloneForPrintingCreated(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
~PrintListenerAdapter() = default;
|
||||
|
||||
RefPtr<PrintPromise::Private> mPromise;
|
||||
MaybeDiscardedBrowsingContext mClonedStaticBrowsingContext = nullptr;
|
||||
bool mHaveSetBrowsingContext = false;
|
||||
bool mPrintJobFinished = false;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(PrintListenerAdapter, nsIWebProgressListener)
|
||||
@ -763,9 +735,7 @@ already_AddRefed<Promise> CanonicalBrowsingContext::PrintJS(
|
||||
Print(aPrintSettings)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[promise](MaybeDiscardedBrowsingContext) {
|
||||
promise->MaybeResolveWithUndefined();
|
||||
},
|
||||
[promise](bool) { promise->MaybeResolveWithUndefined(); },
|
||||
[promise](nsresult aResult) { promise->MaybeReject(aResult); });
|
||||
return promise.forget();
|
||||
}
|
||||
@ -775,72 +745,7 @@ RefPtr<PrintPromise> CanonicalBrowsingContext::Print(
|
||||
#ifndef NS_PRINTING
|
||||
return PrintPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
|
||||
#else
|
||||
// Content analysis is not supported on non-Windows platforms.
|
||||
# if defined(XP_WIN)
|
||||
bool needContentAnalysis = false;
|
||||
nsCOMPtr<nsIContentAnalysis> contentAnalysis =
|
||||
mozilla::components::nsIContentAnalysis::Service();
|
||||
Unused << NS_WARN_IF(!contentAnalysis);
|
||||
if (contentAnalysis) {
|
||||
nsresult rv = contentAnalysis->GetIsActive(&needContentAnalysis);
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
if (needContentAnalysis) {
|
||||
auto done = MakeRefPtr<PrintPromise::Private>(__func__);
|
||||
contentanalysis::ContentAnalysis::PrintToPDFToDetermineIfPrintAllowed(
|
||||
this, aPrintSettings)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[done, aPrintSettings = RefPtr{aPrintSettings},
|
||||
self = RefPtr{this}](
|
||||
contentanalysis::ContentAnalysis::PrintAllowedResult aResponse)
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA mutable {
|
||||
if (aResponse.mAllowed) {
|
||||
self->PrintWithNoContentAnalysis(
|
||||
aPrintSettings, false,
|
||||
aResponse.mCachedStaticDocumentBrowsingContext)
|
||||
->ChainTo(done.forget(), __func__);
|
||||
} else {
|
||||
// Since we are not doing the second print in this case,
|
||||
// release the clone that is no longer needed.
|
||||
self->ReleaseClonedPrint(
|
||||
aResponse.mCachedStaticDocumentBrowsingContext);
|
||||
done->Reject(NS_ERROR_CONTENT_BLOCKED, __func__);
|
||||
}
|
||||
},
|
||||
[done, self = RefPtr{this}](
|
||||
contentanalysis::ContentAnalysis::PrintAllowedError
|
||||
aErrorResponse) MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA {
|
||||
// Since we are not doing the second print in this case, release
|
||||
// the clone that is no longer needed.
|
||||
self->ReleaseClonedPrint(
|
||||
aErrorResponse.mCachedStaticDocumentBrowsingContext);
|
||||
done->Reject(aErrorResponse.mError, __func__);
|
||||
});
|
||||
return done;
|
||||
}
|
||||
# endif
|
||||
return PrintWithNoContentAnalysis(aPrintSettings, false, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::ReleaseClonedPrint(
|
||||
const MaybeDiscardedBrowsingContext& aClonedStaticBrowsingContext) {
|
||||
#ifdef NS_PRINTING
|
||||
auto* browserParent = GetBrowserParent();
|
||||
if (NS_WARN_IF(!browserParent)) {
|
||||
return;
|
||||
}
|
||||
Unused << browserParent->SendDestroyPrintClone(aClonedStaticBrowsingContext);
|
||||
#endif
|
||||
}
|
||||
|
||||
RefPtr<PrintPromise> CanonicalBrowsingContext::PrintWithNoContentAnalysis(
|
||||
nsIPrintSettings* aPrintSettings, bool aForceStaticDocument,
|
||||
const MaybeDiscardedBrowsingContext& aCachedStaticDocument) {
|
||||
#ifndef NS_PRINTING
|
||||
return PrintPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
|
||||
#else
|
||||
auto promise = MakeRefPtr<PrintPromise::Private>(__func__);
|
||||
auto listener = MakeRefPtr<PrintListenerAdapter>(promise);
|
||||
if (IsInProcess()) {
|
||||
@ -852,14 +757,12 @@ RefPtr<PrintPromise> CanonicalBrowsingContext::PrintWithNoContentAnalysis(
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
listener->NoStaticCloneForPrintingWillBeCreated();
|
||||
outerWindow->Print(aPrintSettings,
|
||||
/* aRemotePrintJob = */ nullptr, listener,
|
||||
/* aDocShellToCloneInto = */ nullptr,
|
||||
nsGlobalWindowOuter::IsPreview::No,
|
||||
nsGlobalWindowOuter::IsForWindowDotPrint::No,
|
||||
/* aPrintPreviewCallback = */ nullptr,
|
||||
/* aCachedBrowsingContext = */ nullptr, rv);
|
||||
/* aPrintPreviewCallback = */ nullptr, rv);
|
||||
if (rv.Failed()) {
|
||||
promise->Reject(rv.StealNSResult(), __func__);
|
||||
}
|
||||
@ -902,31 +805,12 @@ RefPtr<PrintPromise> CanonicalBrowsingContext::PrintWithNoContentAnalysis(
|
||||
printData.remotePrintJob() =
|
||||
browserParent->Manager()->SendPRemotePrintJobConstructor(remotePrintJob);
|
||||
|
||||
remotePrintJob->RegisterListener(listener);
|
||||
if (listener) {
|
||||
remotePrintJob->RegisterListener(listener);
|
||||
}
|
||||
|
||||
if (!aCachedStaticDocument.IsNullOrDiscarded()) {
|
||||
// There is no cloned static browsing context that
|
||||
// SendPrintClonedPage() will return, so indicate this
|
||||
// so listener can resolve its promise.
|
||||
listener->NoStaticCloneForPrintingWillBeCreated();
|
||||
if (NS_WARN_IF(!browserParent->SendPrintClonedPage(
|
||||
this, printData, aCachedStaticDocument))) {
|
||||
promise->Reject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
} else {
|
||||
RefPtr<PBrowserParent::PrintPromise> printPromise =
|
||||
browserParent->SendPrint(this, printData, aForceStaticDocument);
|
||||
printPromise->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[listener](MaybeDiscardedBrowsingContext cachedStaticDocument) {
|
||||
// promise will get resolved by the listener
|
||||
listener->StaticCloneForPrintingCreated(
|
||||
std::move(cachedStaticDocument));
|
||||
},
|
||||
[promise](ResponseRejectReason reason) {
|
||||
NS_WARNING("SendPrint() failed");
|
||||
promise->Reject(NS_ERROR_FAILURE, __func__);
|
||||
});
|
||||
if (NS_WARN_IF(!browserParent->SendPrint(this, printData))) {
|
||||
promise->Reject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
return promise.forget();
|
||||
#endif
|
||||
|
@ -136,16 +136,11 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||
UniquePtr<LoadingSessionHistoryInfo> ReplaceLoadingSessionHistoryEntryForLoad(
|
||||
LoadingSessionHistoryInfo* aInfo, nsIChannel* aNewChannel);
|
||||
|
||||
using PrintPromise =
|
||||
MozPromise<MaybeDiscardedBrowsingContext, nsresult, false>;
|
||||
using PrintPromise = MozPromise</* unused */ bool, nsresult, false>;
|
||||
MOZ_CAN_RUN_SCRIPT RefPtr<PrintPromise> Print(nsIPrintSettings*);
|
||||
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> PrintJS(nsIPrintSettings*,
|
||||
ErrorResult&);
|
||||
MOZ_CAN_RUN_SCRIPT RefPtr<PrintPromise> PrintWithNoContentAnalysis(
|
||||
nsIPrintSettings* aPrintSettings, bool aForceStaticDocument,
|
||||
const MaybeDiscardedBrowsingContext& aClonedStaticBrowsingContext);
|
||||
MOZ_CAN_RUN_SCRIPT void ReleaseClonedPrint(
|
||||
const MaybeDiscardedBrowsingContext& aClonedStaticBrowsingContext);
|
||||
|
||||
// Call the given callback on all top-level descendant BrowsingContexts.
|
||||
// Return Callstate::Stop from the callback to stop calling further children.
|
||||
//
|
||||
|
@ -3388,8 +3388,7 @@ already_AddRefed<Promise> nsFrameLoader::PrintPreview(
|
||||
/* aListener = */ nullptr, docShellToCloneInto,
|
||||
nsGlobalWindowOuter::IsPreview::Yes,
|
||||
nsGlobalWindowOuter::IsForWindowDotPrint::No,
|
||||
[resolve](const PrintPreviewResultInfo& aInfo) { resolve(aInfo); },
|
||||
nullptr, rv);
|
||||
[resolve](const PrintPreviewResultInfo& aInfo) { resolve(aInfo); }, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
promise->MaybeReject(std::move(rv));
|
||||
}
|
||||
|
@ -3752,7 +3752,7 @@ Nullable<WindowProxyHolder> nsGlobalWindowInner::PrintPreview(
|
||||
/* aRemotePrintJob = */ nullptr, aListener, aDocShellToCloneInto,
|
||||
nsGlobalWindowOuter::IsPreview::Yes,
|
||||
nsGlobalWindowOuter::IsForWindowDotPrint::No,
|
||||
/* aPrintPreviewCallback = */ nullptr, nullptr, aError),
|
||||
/* aPrintPreviewCallback = */ nullptr, aError),
|
||||
aError, nullptr);
|
||||
}
|
||||
|
||||
|
@ -5006,7 +5006,7 @@ void nsGlobalWindowOuter::PrintOuter(ErrorResult& aError) {
|
||||
|
||||
const bool forPreview = !StaticPrefs::print_always_print_silent();
|
||||
Print(nullptr, nullptr, nullptr, nullptr, IsPreview(forPreview),
|
||||
IsForWindowDotPrint::Yes, nullptr, nullptr, aError);
|
||||
IsForWindowDotPrint::Yes, nullptr, aError);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -5028,8 +5028,7 @@ Nullable<WindowProxyHolder> nsGlobalWindowOuter::Print(
|
||||
nsIPrintSettings* aPrintSettings, RemotePrintJobChild* aRemotePrintJob,
|
||||
nsIWebProgressListener* aListener, nsIDocShell* aDocShellToCloneInto,
|
||||
IsPreview aIsPreview, IsForWindowDotPrint aForWindowDotPrint,
|
||||
PrintPreviewResolver&& aPrintPreviewCallback,
|
||||
RefPtr<BrowsingContext>* aCachedBrowsingContext, ErrorResult& aError) {
|
||||
PrintPreviewResolver&& aPrintPreviewCallback, ErrorResult& aError) {
|
||||
#ifdef NS_PRINTING
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsService =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1");
|
||||
@ -5065,36 +5064,16 @@ Nullable<WindowProxyHolder> nsGlobalWindowOuter::Print(
|
||||
nsCOMPtr<nsIDocumentViewer> viewer;
|
||||
RefPtr<BrowsingContext> bc;
|
||||
bool hasPrintCallbacks = false;
|
||||
bool wasStaticDocument = docToPrint->IsStaticDocument();
|
||||
bool usingCachedBrowsingContext = false;
|
||||
if (aCachedBrowsingContext && *aCachedBrowsingContext) {
|
||||
MOZ_ASSERT(!wasStaticDocument,
|
||||
"Why pass in non-empty aCachedBrowsingContext if original "
|
||||
"document is already static?");
|
||||
if (!wasStaticDocument) {
|
||||
// The passed in document is not a static clone and the caller passed in a
|
||||
// static clone to reuse, so swap it in.
|
||||
docToPrint = (*aCachedBrowsingContext)->GetDocument();
|
||||
MOZ_ASSERT(docToPrint);
|
||||
MOZ_ASSERT(docToPrint->IsStaticDocument());
|
||||
wasStaticDocument = true;
|
||||
usingCachedBrowsingContext = true;
|
||||
}
|
||||
}
|
||||
if (wasStaticDocument) {
|
||||
if (docToPrint->IsStaticDocument()) {
|
||||
if (aForWindowDotPrint == IsForWindowDotPrint::Yes) {
|
||||
aError.ThrowNotSupportedError(
|
||||
"Calling print() from a print preview is unsupported, did you intend "
|
||||
"to call printPreview() instead?");
|
||||
return nullptr;
|
||||
}
|
||||
if (usingCachedBrowsingContext) {
|
||||
bc = docToPrint->GetBrowsingContext();
|
||||
} else {
|
||||
// We're already a print preview window, just reuse our browsing context /
|
||||
// content viewer.
|
||||
bc = sourceBC;
|
||||
}
|
||||
// We're already a print preview window, just reuse our browsing context /
|
||||
// content viewer.
|
||||
bc = sourceBC;
|
||||
nsCOMPtr<nsIDocShell> docShell = bc->GetDocShell();
|
||||
if (!docShell) {
|
||||
aError.ThrowNotSupportedError("No docshell");
|
||||
@ -5136,10 +5115,6 @@ Nullable<WindowProxyHolder> nsGlobalWindowOuter::Print(
|
||||
if (NS_WARN_IF(aError.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
if (aCachedBrowsingContext) {
|
||||
MOZ_ASSERT(!*aCachedBrowsingContext);
|
||||
*aCachedBrowsingContext = bc;
|
||||
}
|
||||
}
|
||||
if (!bc) {
|
||||
aError.ThrowNotAllowedError("No browsing context");
|
||||
@ -5195,24 +5170,6 @@ Nullable<WindowProxyHolder> nsGlobalWindowOuter::Print(
|
||||
"Content viewer didn't implement nsIWebBrowserPrint");
|
||||
return nullptr;
|
||||
}
|
||||
bool closeWindowAfterPrint;
|
||||
if (wasStaticDocument) {
|
||||
// Here the document was a static clone to begin with that this code did not
|
||||
// create, so we should not clean it up.
|
||||
// The exception is if we're using the passed-in aCachedBrowsingContext, in
|
||||
// which case this is the second print with this static document clone that
|
||||
// we created the first time through, and we are responsible for cleaning it
|
||||
// up.
|
||||
closeWindowAfterPrint = usingCachedBrowsingContext;
|
||||
} else {
|
||||
// In this case the document was not a static clone, so we made a static
|
||||
// clone for printing purposes and must clean it up after the print is done.
|
||||
// The exception is if aCachedBrowsingContext is non-NULL, meaning the
|
||||
// caller is intending to print this document again, so we need to defer the
|
||||
// cleanup until after the second print.
|
||||
closeWindowAfterPrint = !aCachedBrowsingContext;
|
||||
}
|
||||
webBrowserPrint->SetCloseWindowAfterPrint(closeWindowAfterPrint);
|
||||
|
||||
// For window.print(), we postpone making these calls until the round-trip to
|
||||
// the parent process (triggered by the OpenInternal call above) calls us
|
||||
|
@ -580,8 +580,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||
Print(nsIPrintSettings*,
|
||||
mozilla::layout::RemotePrintJobChild* aRemotePrintJob,
|
||||
nsIWebProgressListener*, nsIDocShell*, IsPreview, IsForWindowDotPrint,
|
||||
PrintPreviewResolver&&, RefPtr<mozilla::dom::BrowsingContext>*,
|
||||
mozilla::ErrorResult&);
|
||||
PrintPreviewResolver&&, mozilla::ErrorResult&);
|
||||
mozilla::dom::Selection* GetSelectionOuter();
|
||||
already_AddRefed<mozilla::dom::Selection> GetSelection() override;
|
||||
nsScreen* GetScreen();
|
||||
|
@ -2342,7 +2342,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview(
|
||||
/* aListener = */ nullptr, docShellToCloneInto,
|
||||
nsGlobalWindowOuter::IsPreview::Yes,
|
||||
nsGlobalWindowOuter::IsForWindowDotPrint::No,
|
||||
std::move(aCallback), nullptr, IgnoreErrors());
|
||||
std::move(aCallback), IgnoreErrors());
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -2359,9 +2359,8 @@ mozilla::ipc::IPCResult BrowserChild::RecvExitPrintPreview() {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::CommonPrint(
|
||||
const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData,
|
||||
RefPtr<BrowsingContext>* aCachedBrowsingContext) {
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvPrint(
|
||||
const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData) {
|
||||
#ifdef NS_PRINTING
|
||||
if (NS_WARN_IF(aBc.IsNullOrDiscarded())) {
|
||||
return IPC_OK();
|
||||
@ -2390,12 +2389,12 @@ mozilla::ipc::IPCResult BrowserChild::CommonPrint(
|
||||
IgnoredErrorResult rv;
|
||||
RefPtr printJob = static_cast<RemotePrintJobChild*>(
|
||||
aPrintData.remotePrintJob().AsChild());
|
||||
outerWindow->Print(
|
||||
printSettings, printJob,
|
||||
/* aListener = */ nullptr,
|
||||
/* aWindowToCloneInto = */ nullptr, nsGlobalWindowOuter::IsPreview::No,
|
||||
nsGlobalWindowOuter::IsForWindowDotPrint::No,
|
||||
/* aPrintPreviewCallback = */ nullptr, aCachedBrowsingContext, rv);
|
||||
outerWindow->Print(printSettings, printJob,
|
||||
/* aListener = */ nullptr,
|
||||
/* aWindowToCloneInto = */ nullptr,
|
||||
nsGlobalWindowOuter::IsPreview::No,
|
||||
nsGlobalWindowOuter::IsForWindowDotPrint::No,
|
||||
/* aPrintPreviewCallback = */ nullptr, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -2404,49 +2403,6 @@ mozilla::ipc::IPCResult BrowserChild::CommonPrint(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvPrint(
|
||||
const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData,
|
||||
bool aReturnStaticClone, PrintResolver&& aResolve) {
|
||||
#ifdef NS_PRINTING
|
||||
RefPtr<BrowsingContext> browsingContext;
|
||||
auto result = CommonPrint(aBc, aPrintData,
|
||||
aReturnStaticClone ? &browsingContext : nullptr);
|
||||
aResolve(browsingContext);
|
||||
return result;
|
||||
#else
|
||||
aResolve(nullptr);
|
||||
return IPC_OK();
|
||||
#endif
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvPrintClonedPage(
|
||||
const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData,
|
||||
const MaybeDiscardedBrowsingContext& aClonedBc) {
|
||||
#ifdef NS_PRINTING
|
||||
if (aClonedBc.IsNullOrDiscarded()) {
|
||||
return IPC_OK();
|
||||
}
|
||||
RefPtr<BrowsingContext> clonedBc = aClonedBc.get();
|
||||
return CommonPrint(aBc, aPrintData, &clonedBc);
|
||||
#else
|
||||
return IPC_OK();
|
||||
#endif
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvDestroyPrintClone(
|
||||
const MaybeDiscardedBrowsingContext& aCachedPage) {
|
||||
#ifdef NS_PRINTING
|
||||
if (aCachedPage) {
|
||||
RefPtr<nsPIDOMWindowOuter> window = aCachedPage->GetDOMWindow();
|
||||
if (NS_WARN_IF(!window)) {
|
||||
return IPC_OK();
|
||||
}
|
||||
window->Close();
|
||||
}
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvUpdateNativeWindowHandle(
|
||||
const uintptr_t& aNewHandle) {
|
||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||
|
@ -507,15 +507,7 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
||||
mozilla::ipc::IPCResult RecvExitPrintPreview();
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvPrint(
|
||||
const MaybeDiscardedBrowsingContext&, const PrintData&, bool,
|
||||
PrintResolver&&);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult RecvPrintClonedPage(
|
||||
const MaybeDiscardedBrowsingContext&, const PrintData&,
|
||||
const MaybeDiscardedBrowsingContext&);
|
||||
|
||||
mozilla::ipc::IPCResult RecvDestroyPrintClone(
|
||||
const MaybeDiscardedBrowsingContext&);
|
||||
const MaybeDiscardedBrowsingContext&, const PrintData&);
|
||||
|
||||
mozilla::ipc::IPCResult RecvUpdateNativeWindowHandle(
|
||||
const uintptr_t& aNewHandle);
|
||||
@ -720,11 +712,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
||||
|
||||
void InternalSetDocShellIsActive(bool aIsActive);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
mozilla::ipc::IPCResult CommonPrint(
|
||||
const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData,
|
||||
RefPtr<BrowsingContext>* aCachedBrowsingContext);
|
||||
|
||||
bool CreateRemoteLayerManager(
|
||||
mozilla::layers::PCompositorBridgeChild* aCompositorChild);
|
||||
|
||||
|
@ -960,33 +960,8 @@ child:
|
||||
*
|
||||
* @param aBrowsingContext the browsing context to print.
|
||||
* @param aPrintData the serialized settings to print with
|
||||
* @param aReturnStaticClone If the document in aBrowsingContext is not a static clone, whether
|
||||
* to return the static document clone created.
|
||||
* Note that if you call this with true but do not later call PrintClonedPage(),
|
||||
* you must call DestroyPrintCache() to avoid leaks.
|
||||
*/
|
||||
async Print(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData, bool aReturnStaticClone) returns(MaybeDiscardedBrowsingContext staticCloneBrowsingContext);
|
||||
|
||||
/**
|
||||
* Tell the child to print the passed in static clone browsing context with the given settings.
|
||||
*
|
||||
* @param aBrowsingContext the browsing context to print.
|
||||
* @param aPrintData the serialized settings to print with
|
||||
* @param aStaticCloneBrowsingContext The static clone of aBrowsingContext that
|
||||
* was created by an earlier call to Print(). This is the page that will actually be
|
||||
* printed.
|
||||
*/
|
||||
async PrintClonedPage(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData, MaybeDiscardedBrowsingContext aStaticCloneBrowsingContext);
|
||||
|
||||
/**
|
||||
* Destroy the static document clone for printing, if present. See Print() for details.
|
||||
* For callers' simplicity, it is safe to call this method even if aStaticCloneBrowsingContext
|
||||
* is null or has already been discarded.
|
||||
*
|
||||
* @param aStaticCloneBrowsingContext The static clone that was created by
|
||||
* an earlier call to Print().
|
||||
*/
|
||||
async DestroyPrintClone(MaybeDiscardedBrowsingContext aStaticCloneBrowsingContext);
|
||||
async Print(MaybeDiscardedBrowsingContext aBC, PrintData aPrintData);
|
||||
|
||||
/**
|
||||
* Update the child with the tab's current top-level native window handle.
|
||||
|
@ -20,6 +20,14 @@
|
||||
#include "mozilla/dom/TransformerBinding.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
// XXX: GCC somehow does not allow attributes before lambda return types, while
|
||||
// clang requires so. See also bug 1627007.
|
||||
#ifdef __clang__
|
||||
# define MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
#else
|
||||
# define MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA
|
||||
#endif
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
using namespace streams_abstract;
|
||||
|
@ -449,7 +449,6 @@ class nsDocumentViewer final : public nsIDocumentViewer,
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
unsigned mClosingWhilePrinting : 1;
|
||||
unsigned mCloseWindowAfterPrint : 1;
|
||||
|
||||
# if NS_PRINT_PREVIEW
|
||||
RefPtr<nsPrintJob> mPrintJob;
|
||||
@ -521,7 +520,6 @@ nsDocumentViewer::nsDocumentViewer()
|
||||
mInPermitUnloadPrompt(false),
|
||||
#ifdef NS_PRINTING
|
||||
mClosingWhilePrinting(false),
|
||||
mCloseWindowAfterPrint(false),
|
||||
#endif // NS_PRINTING
|
||||
mReloadEncodingSource(kCharsetUninitialized),
|
||||
mReloadEncoding(nullptr),
|
||||
@ -3141,20 +3139,6 @@ nsDocumentViewer::GetDoingPrintPreview(bool* aDoingPrintPreview) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentViewer::GetCloseWindowAfterPrint(bool* aCloseWindowAfterPrint) {
|
||||
NS_ENSURE_ARG_POINTER(aCloseWindowAfterPrint);
|
||||
|
||||
*aCloseWindowAfterPrint = mCloseWindowAfterPrint;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentViewer::SetCloseWindowAfterPrint(bool aCloseWindowAfterPrint) {
|
||||
mCloseWindowAfterPrint = aCloseWindowAfterPrint;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentViewer::ExitPrintPreview() {
|
||||
NS_ENSURE_TRUE(mPrintJob, NS_ERROR_FAILURE);
|
||||
@ -3319,15 +3303,13 @@ void nsDocumentViewer::OnDonePrinting() {
|
||||
|
||||
// We are done printing, now clean up.
|
||||
//
|
||||
// If the original document to print was not a static clone, we opened a new
|
||||
// window and are responsible for cleaning up the whole <browser> or window
|
||||
// (see the OPEN_PRINT_BROWSER code, specifically
|
||||
// handleStaticCloneCreatedForPrint()), so gotta run window.close(), which
|
||||
// will take care of this.
|
||||
// For non-print-preview jobs, we are actually responsible for cleaning up
|
||||
// our whole <browser> or window (see the OPEN_PRINT_BROWSER code), so gotta
|
||||
// run window.close(), which will take care of this.
|
||||
//
|
||||
// Otherwise the front-end code is responsible for cleaning the UI.
|
||||
bool closeWindowAfterPrint = GetCloseWindowAfterPrint();
|
||||
if (closeWindowAfterPrint) {
|
||||
// For print preview jobs the front-end code is responsible for cleaning the
|
||||
// UI.
|
||||
if (!printJob->CreatedForPrintPreview()) {
|
||||
if (mContainer) {
|
||||
if (nsCOMPtr<nsPIDOMWindowOuter> win = mContainer->GetWindow()) {
|
||||
win->Close();
|
||||
|
@ -1031,12 +1031,4 @@
|
||||
# define MOZ_EMPTY_BASES
|
||||
#endif
|
||||
|
||||
// XXX: GCC somehow does not allow attributes before lambda return types, while
|
||||
// clang requires so. See also bug 1627007.
|
||||
#ifdef __clang__
|
||||
# define MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
#else
|
||||
# define MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA
|
||||
#endif
|
||||
|
||||
#endif /* mozilla_Attributes_h */
|
||||
|
@ -30,7 +30,7 @@ native PrintPreviewResolver(std::function<void(const mozilla::dom::PrintPreviewR
|
||||
* nsIWebBrowserPrint corresponds to the main interface
|
||||
* for printing an embedded Gecko web browser window/document
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(c9a934ed-fff1-4971-bfba-6c25ad70e1e6)]
|
||||
[scriptable, uuid(c9a934ed-fff1-4971-bfba-6c25ad70e1e6)]
|
||||
interface nsIWebBrowserPrint : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -85,13 +85,6 @@ interface nsIWebBrowserPrint : nsISupports
|
||||
*/
|
||||
readonly attribute long printPreviewCurrentPageNumber;
|
||||
|
||||
/*
|
||||
* Whether the document to print needs to have its window closed after printing
|
||||
* is done - see OPEN_PRINT_BROWSER and specifically handleStaticCloneCreatedForPrint().
|
||||
* This is set if the document is not a static clone.
|
||||
*/
|
||||
[infallible] attribute boolean closeWindowAfterPrint;
|
||||
|
||||
/**
|
||||
* Print the specified DOM window
|
||||
*
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "base/process_util.h"
|
||||
#include "GMPUtils.h" // ToHexString
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/Logging.h"
|
||||
@ -25,9 +24,6 @@
|
||||
#include "nsIFile.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIStorageStream.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
@ -39,7 +35,6 @@
|
||||
# include <windows.h>
|
||||
# define SECURITY_WIN32 1
|
||||
# include <security.h>
|
||||
# include "mozilla/NativeNt.h"
|
||||
# include "mozilla/WinDllServices.h"
|
||||
#endif // XP_WIN
|
||||
|
||||
@ -119,11 +114,6 @@ nsIContentAnalysisAcknowledgement::FinalAction ConvertResult(
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla::contentanalysis {
|
||||
ContentAnalysisRequest::~ContentAnalysisRequest() {
|
||||
#ifdef XP_WIN
|
||||
CloseHandle(mPrintDataHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentAnalysisRequest::GetAnalysisType(AnalysisType* aAnalysisType) {
|
||||
@ -143,34 +133,6 @@ ContentAnalysisRequest::GetFilePath(nsAString& aFilePath) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentAnalysisRequest::GetPrintDataHandle(uint64_t* aPrintDataHandle) {
|
||||
#ifdef XP_WIN
|
||||
uintptr_t printDataHandle = reinterpret_cast<uintptr_t>(mPrintDataHandle);
|
||||
uint64_t printDataValue = static_cast<uint64_t>(printDataHandle);
|
||||
*aPrintDataHandle = printDataValue;
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentAnalysisRequest::GetPrinterName(nsAString& aPrinterName) {
|
||||
aPrinterName = mPrinterName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentAnalysisRequest::GetPrintDataSize(uint64_t* aPrintDataSize) {
|
||||
#ifdef XP_WIN
|
||||
*aPrintDataSize = mPrintDataSize;
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentAnalysisRequest::GetUrl(nsIURI** aUrl) {
|
||||
NS_ENSURE_ARG_POINTER(aUrl);
|
||||
@ -272,8 +234,6 @@ ContentAnalysisRequest::ContentAnalysisRequest(
|
||||
mUrl(std::move(aUrl)),
|
||||
mSha256Digest(std::move(aSha256Digest)),
|
||||
mWindowGlobalParent(aWindowGlobalParent) {
|
||||
MOZ_ASSERT(aAnalysisType != AnalysisType::ePrint,
|
||||
"Print should use other ContentAnalysisRequest constructor!");
|
||||
if (aStringIsFilePath) {
|
||||
mFilePath = std::move(aString);
|
||||
} else {
|
||||
@ -291,32 +251,6 @@ ContentAnalysisRequest::ContentAnalysisRequest(
|
||||
mRequestToken = GenerateRequestToken();
|
||||
}
|
||||
|
||||
ContentAnalysisRequest::ContentAnalysisRequest(
|
||||
const nsTArray<uint8_t> aPrintData, nsCOMPtr<nsIURI> aUrl,
|
||||
nsString aPrinterName, dom::WindowGlobalParent* aWindowGlobalParent)
|
||||
: mAnalysisType(AnalysisType::ePrint),
|
||||
mUrl(std::move(aUrl)),
|
||||
mPrinterName(std::move(aPrinterName)),
|
||||
mWindowGlobalParent(aWindowGlobalParent) {
|
||||
#ifdef XP_WIN
|
||||
LARGE_INTEGER dataContentLength;
|
||||
dataContentLength.QuadPart = static_cast<LONGLONG>(aPrintData.Length());
|
||||
mPrintDataHandle = ::CreateFileMappingW(
|
||||
INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, dataContentLength.HighPart,
|
||||
dataContentLength.LowPart, nullptr);
|
||||
if (mPrintDataHandle) {
|
||||
mozilla::nt::AutoMappedView view(mPrintDataHandle, FILE_MAP_ALL_ACCESS);
|
||||
memcpy(view.as<uint8_t>(), aPrintData.Elements(), aPrintData.Length());
|
||||
mPrintDataSize = aPrintData.Length();
|
||||
}
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"Content Analysis is not supported on non-Windows platforms");
|
||||
#endif
|
||||
mOperationTypeForDisplay = OperationType::eOperationPrint;
|
||||
mRequestToken = GenerateRequestToken();
|
||||
}
|
||||
|
||||
nsresult ContentAnalysisRequest::GetFileDigest(const nsAString& aFilePath,
|
||||
nsCString& aDigestString) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
@ -432,44 +366,22 @@ static nsresult ConvertToProtobuf(
|
||||
requestData->set_digest(sha256Digest.get());
|
||||
}
|
||||
|
||||
if (analysisType == nsIContentAnalysisRequest::AnalysisType::ePrint) {
|
||||
#if XP_WIN
|
||||
uint64_t printDataHandle;
|
||||
MOZ_TRY(aIn->GetPrintDataHandle(&printDataHandle));
|
||||
if (!printDataHandle) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsString filePath;
|
||||
rv = aIn->GetFilePath(filePath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!filePath.IsEmpty()) {
|
||||
std::string filePathStr = NS_ConvertUTF16toUTF8(filePath).get();
|
||||
aOut->set_file_path(filePathStr);
|
||||
auto filename = filePathStr.substr(filePathStr.find_last_of("/\\") + 1);
|
||||
if (!filename.empty()) {
|
||||
requestData->set_filename(filename);
|
||||
}
|
||||
aOut->mutable_print_data()->set_handle(printDataHandle);
|
||||
|
||||
uint64_t printDataSize;
|
||||
MOZ_TRY(aIn->GetPrintDataSize(&printDataSize));
|
||||
aOut->mutable_print_data()->set_size(printDataSize);
|
||||
|
||||
nsString printerName;
|
||||
MOZ_TRY(aIn->GetPrinterName(printerName));
|
||||
requestData->mutable_print_metadata()->set_printer_name(
|
||||
NS_ConvertUTF16toUTF8(printerName).get());
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
} else {
|
||||
nsString filePath;
|
||||
rv = aIn->GetFilePath(filePath);
|
||||
nsString textContent;
|
||||
rv = aIn->GetTextContent(textContent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!filePath.IsEmpty()) {
|
||||
std::string filePathStr = NS_ConvertUTF16toUTF8(filePath).get();
|
||||
aOut->set_file_path(filePathStr);
|
||||
auto filename = filePathStr.substr(filePathStr.find_last_of("/\\") + 1);
|
||||
if (!filename.empty()) {
|
||||
requestData->set_filename(filename);
|
||||
}
|
||||
} else {
|
||||
nsString textContent;
|
||||
rv = aIn->GetTextContent(textContent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_ASSERT(!textContent.IsEmpty());
|
||||
aOut->set_text_content(NS_ConvertUTF16toUTF8(textContent).get());
|
||||
}
|
||||
MOZ_ASSERT(!textContent.IsEmpty());
|
||||
aOut->set_text_content(NS_ConvertUTF16toUTF8(textContent).get());
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
@ -1306,9 +1218,7 @@ void ContentAnalysis::IssueResponse(RefPtr<ContentAnalysisResponse>& response) {
|
||||
|
||||
LOGD("Content analysis resolving response promise for token %s",
|
||||
responseRequestToken.get());
|
||||
nsIContentAnalysisResponse::Action action;
|
||||
DebugOnly<nsresult> rv = response->GetAction(&action);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
nsIContentAnalysisResponse::Action action = response->GetAction();
|
||||
nsCOMPtr<nsIObserverService> obsServ =
|
||||
mozilla::services::GetObserverService();
|
||||
if (action == nsIContentAnalysisResponse::Action::eWarn) {
|
||||
@ -1470,9 +1380,7 @@ ContentAnalysis::RespondToWarnDialog(const nsACString& aRequestToken,
|
||||
return;
|
||||
}
|
||||
entry->mResponse->ResolveWarnAction(aAllowContent);
|
||||
nsIContentAnalysisResponse::Action action;
|
||||
DebugOnly<nsresult> rv = entry->mResponse->GetAction(&action);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
auto action = entry->mResponse->GetAction();
|
||||
if (entry->mCallbackData.AutoAcknowledge()) {
|
||||
RefPtr<ContentAnalysisAcknowledgement> acknowledgement =
|
||||
new ContentAnalysisAcknowledgement(
|
||||
@ -1497,181 +1405,6 @@ ContentAnalysis::RespondToWarnDialog(const nsACString& aRequestToken,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
RefPtr<ContentAnalysis::PrintAllowedPromise>
|
||||
ContentAnalysis::PrintToPDFToDetermineIfPrintAllowed(
|
||||
dom::CanonicalBrowsingContext* aBrowsingContext,
|
||||
nsIPrintSettings* aPrintSettings) {
|
||||
// Note that the IsChrome() check here excludes a few
|
||||
// common about pages like about:config, about:preferences,
|
||||
// and about:support, but other about: pages may still
|
||||
// go through content analysis.
|
||||
if (aBrowsingContext->IsChrome()) {
|
||||
return PrintAllowedPromise::CreateAndResolve(PrintAllowedResult(true),
|
||||
__func__);
|
||||
}
|
||||
nsCOMPtr<nsIPrintSettings> contentAnalysisPrintSettings;
|
||||
if (NS_WARN_IF(NS_FAILED(aPrintSettings->Clone(
|
||||
getter_AddRefs(contentAnalysisPrintSettings)))) ||
|
||||
NS_WARN_IF(!aBrowsingContext->GetCurrentWindowGlobal())) {
|
||||
return PrintAllowedPromise::CreateAndReject(
|
||||
PrintAllowedError(NS_ERROR_FAILURE), __func__);
|
||||
}
|
||||
contentAnalysisPrintSettings->SetOutputDestination(
|
||||
nsIPrintSettings::OutputDestinationType::kOutputDestinationStream);
|
||||
contentAnalysisPrintSettings->SetOutputFormat(
|
||||
nsIPrintSettings::kOutputFormatPDF);
|
||||
nsCOMPtr<nsIStorageStream> storageStream =
|
||||
do_CreateInstance("@mozilla.org/storagestream;1");
|
||||
if (!storageStream) {
|
||||
return PrintAllowedPromise::CreateAndReject(
|
||||
PrintAllowedError(NS_ERROR_FAILURE), __func__);
|
||||
}
|
||||
// Use segment size of 512K
|
||||
nsresult rv = storageStream->Init(0x80000, UINT32_MAX);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return PrintAllowedPromise::CreateAndReject(PrintAllowedError(rv),
|
||||
__func__);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIOutputStream> outputStream;
|
||||
storageStream->QueryInterface(NS_GET_IID(nsIOutputStream),
|
||||
getter_AddRefs(outputStream));
|
||||
MOZ_ASSERT(outputStream);
|
||||
|
||||
contentAnalysisPrintSettings->SetOutputStream(outputStream.get());
|
||||
RefPtr<dom::CanonicalBrowsingContext> browsingContext = aBrowsingContext;
|
||||
auto promise = MakeRefPtr<PrintAllowedPromise::Private>(__func__);
|
||||
nsCOMPtr<nsIPrintSettings> finalPrintSettings(aPrintSettings);
|
||||
aBrowsingContext
|
||||
->PrintWithNoContentAnalysis(contentAnalysisPrintSettings, true, nullptr)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[browsingContext, contentAnalysisPrintSettings, finalPrintSettings,
|
||||
promise](
|
||||
dom::MaybeDiscardedBrowsingContext cachedStaticBrowsingContext)
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA mutable {
|
||||
nsCOMPtr<nsIOutputStream> outputStream;
|
||||
contentAnalysisPrintSettings->GetOutputStream(
|
||||
getter_AddRefs(outputStream));
|
||||
nsCOMPtr<nsIStorageStream> storageStream =
|
||||
do_QueryInterface(outputStream);
|
||||
MOZ_ASSERT(storageStream);
|
||||
nsTArray<uint8_t> printData;
|
||||
uint32_t length = 0;
|
||||
storageStream->GetLength(&length);
|
||||
if (!printData.SetLength(length, fallible)) {
|
||||
promise->Reject(
|
||||
PrintAllowedError(NS_ERROR_OUT_OF_MEMORY,
|
||||
cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
nsresult rv = storageStream->NewInputStream(
|
||||
0, getter_AddRefs(inputStream));
|
||||
if (NS_FAILED(rv)) {
|
||||
promise->Reject(
|
||||
PrintAllowedError(rv, cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
uint32_t currentPosition = 0;
|
||||
while (currentPosition < length) {
|
||||
uint32_t elementsRead = 0;
|
||||
// Make sure the reinterpret_cast<> below is safe
|
||||
static_assert(std::is_trivially_assignable_v<
|
||||
decltype(*printData.Elements()), char>);
|
||||
rv = inputStream->Read(
|
||||
reinterpret_cast<char*>(printData.Elements()) +
|
||||
currentPosition,
|
||||
length - currentPosition, &elementsRead);
|
||||
if (NS_WARN_IF(NS_FAILED(rv) || !elementsRead)) {
|
||||
promise->Reject(
|
||||
PrintAllowedError(NS_FAILED(rv) ? rv : NS_ERROR_FAILURE,
|
||||
cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
currentPosition += elementsRead;
|
||||
}
|
||||
|
||||
nsString printerName;
|
||||
rv = contentAnalysisPrintSettings->GetPrinterName(printerName);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
promise->Reject(
|
||||
PrintAllowedError(rv, cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* windowParent = browsingContext->GetCurrentWindowGlobal();
|
||||
if (!windowParent) {
|
||||
// The print window may have been closed by the user by now.
|
||||
// Cancel the print.
|
||||
promise->Reject(
|
||||
PrintAllowedError(NS_ERROR_ABORT,
|
||||
cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIURI> uri = windowParent->GetDocumentURI();
|
||||
nsCOMPtr<nsIContentAnalysisRequest> contentAnalysisRequest =
|
||||
new contentanalysis::ContentAnalysisRequest(
|
||||
std::move(printData), std::move(uri),
|
||||
std::move(printerName), windowParent);
|
||||
auto callback =
|
||||
MakeRefPtr<contentanalysis::ContentAnalysisCallback>(
|
||||
[browsingContext, cachedStaticBrowsingContext, promise,
|
||||
finalPrintSettings = std::move(finalPrintSettings)](
|
||||
nsIContentAnalysisResponse* aResponse)
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY_LAMBDA mutable {
|
||||
bool shouldAllow = false;
|
||||
DebugOnly<nsresult> rv =
|
||||
aResponse->GetShouldAllowContent(
|
||||
&shouldAllow);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
promise->Resolve(
|
||||
PrintAllowedResult(
|
||||
shouldAllow, cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
},
|
||||
[promise,
|
||||
cachedStaticBrowsingContext](nsresult aError) {
|
||||
promise->Reject(
|
||||
PrintAllowedError(aError,
|
||||
cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
});
|
||||
nsCOMPtr<nsIContentAnalysis> contentAnalysis =
|
||||
mozilla::components::nsIContentAnalysis::Service();
|
||||
if (NS_WARN_IF(!contentAnalysis)) {
|
||||
promise->Reject(
|
||||
PrintAllowedError(rv, cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
} else {
|
||||
bool isActive = false;
|
||||
nsresult rv = contentAnalysis->GetIsActive(&isActive);
|
||||
// Should not be called if content analysis is not active
|
||||
MOZ_ASSERT(isActive);
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
rv = contentAnalysis->AnalyzeContentRequestCallback(
|
||||
contentAnalysisRequest, /* aAutoAcknowledge */ true,
|
||||
callback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
promise->Reject(
|
||||
PrintAllowedError(rv, cachedStaticBrowsingContext),
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
},
|
||||
[promise](nsresult aError) {
|
||||
promise->Reject(PrintAllowedError(aError), __func__);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentAnalysisResponse::Acknowledge(
|
||||
nsIContentAnalysisAcknowledgement* aAcknowledgement) {
|
||||
|
@ -8,8 +8,6 @@
|
||||
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/MaybeDiscarded.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "nsIContentAnalysis.h"
|
||||
#include "nsProxyRelease.h"
|
||||
@ -20,16 +18,10 @@
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include <windows.h>
|
||||
#endif // XP_WIN
|
||||
|
||||
class nsIPrincipal;
|
||||
class nsIPrintSettings;
|
||||
class ContentAnalysisTest;
|
||||
|
||||
namespace mozilla::dom {
|
||||
class CanonicalBrowsingContext;
|
||||
class DataTransfer;
|
||||
class WindowGlobalParent;
|
||||
} // namespace mozilla::dom
|
||||
@ -72,15 +64,11 @@ class ContentAnalysisRequest final : public nsIContentAnalysisRequest {
|
||||
bool aStringIsFilePath, nsCString aSha256Digest,
|
||||
nsCOMPtr<nsIURI> aUrl, OperationType aOperationType,
|
||||
dom::WindowGlobalParent* aWindowGlobalParent);
|
||||
ContentAnalysisRequest(const nsTArray<uint8_t> aPrintData,
|
||||
nsCOMPtr<nsIURI> aUrl, nsString aPrinterName,
|
||||
dom::WindowGlobalParent* aWindowGlobalParent);
|
||||
static nsresult GetFileDigest(const nsAString& aFilePath,
|
||||
nsCString& aDigestString);
|
||||
|
||||
private:
|
||||
~ContentAnalysisRequest();
|
||||
|
||||
~ContentAnalysisRequest() = default;
|
||||
// Remove unneeded copy constructor/assignment
|
||||
ContentAnalysisRequest(const ContentAnalysisRequest&) = delete;
|
||||
ContentAnalysisRequest& operator=(ContentAnalysisRequest&) = delete;
|
||||
@ -117,16 +105,7 @@ class ContentAnalysisRequest final : public nsIContentAnalysisRequest {
|
||||
// OPERATION_CUSTOMDISPLAYSTRING
|
||||
nsString mOperationDisplayString;
|
||||
|
||||
// The name of the printer being printed to
|
||||
nsString mPrinterName;
|
||||
|
||||
RefPtr<dom::WindowGlobalParent> mWindowGlobalParent;
|
||||
#ifdef XP_WIN
|
||||
// The printed data to analyze, in PDF format
|
||||
HANDLE mPrintDataHandle = 0;
|
||||
// The size of the printed data in mPrintDataHandle
|
||||
uint64_t mPrintDataSize = 0;
|
||||
#endif
|
||||
|
||||
friend class ::ContentAnalysisTest;
|
||||
};
|
||||
@ -149,39 +128,6 @@ class ContentAnalysis final : public nsIContentAnalysis {
|
||||
nsCString GetUserActionId();
|
||||
void SetLastResult(nsresult aLastResult) { mLastResult = aLastResult; }
|
||||
|
||||
struct PrintAllowedResult final {
|
||||
bool mAllowed;
|
||||
dom::MaybeDiscarded<dom::BrowsingContext>
|
||||
mCachedStaticDocumentBrowsingContext;
|
||||
PrintAllowedResult(bool aAllowed, dom::MaybeDiscarded<dom::BrowsingContext>
|
||||
aCachedStaticDocumentBrowsingContext)
|
||||
: mAllowed(aAllowed),
|
||||
mCachedStaticDocumentBrowsingContext(
|
||||
aCachedStaticDocumentBrowsingContext) {}
|
||||
explicit PrintAllowedResult(bool aAllowed)
|
||||
: PrintAllowedResult(aAllowed, dom::MaybeDiscardedBrowsingContext()) {}
|
||||
};
|
||||
struct PrintAllowedError final {
|
||||
nsresult mError;
|
||||
dom::MaybeDiscarded<dom::BrowsingContext>
|
||||
mCachedStaticDocumentBrowsingContext;
|
||||
PrintAllowedError(nsresult aError, dom::MaybeDiscarded<dom::BrowsingContext>
|
||||
aCachedStaticDocumentBrowsingContext)
|
||||
: mError(aError),
|
||||
mCachedStaticDocumentBrowsingContext(
|
||||
aCachedStaticDocumentBrowsingContext) {}
|
||||
explicit PrintAllowedError(nsresult aError)
|
||||
: PrintAllowedError(aError, dom::MaybeDiscardedBrowsingContext()) {}
|
||||
};
|
||||
using PrintAllowedPromise =
|
||||
MozPromise<PrintAllowedResult, PrintAllowedError, true>;
|
||||
#if defined(XP_WIN)
|
||||
MOZ_CAN_RUN_SCRIPT static RefPtr<PrintAllowedPromise>
|
||||
PrintToPDFToDetermineIfPrintAllowed(
|
||||
dom::CanonicalBrowsingContext* aBrowsingContext,
|
||||
nsIPrintSettings* aPrintSettings);
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
private:
|
||||
~ContentAnalysis();
|
||||
// Remove unneeded copy constructor/assignment
|
||||
|
@ -87,11 +87,7 @@ class ContentAnalysisResult : public nsIContentAnalysisResult {
|
||||
|
||||
static RefPtr<ContentAnalysisResult> FromContentAnalysisResponse(
|
||||
nsIContentAnalysisResponse* aResponse) {
|
||||
bool shouldAllowContent = false;
|
||||
DebugOnly<nsresult> rv =
|
||||
aResponse->GetShouldAllowContent(&shouldAllowContent);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (shouldAllowContent) {
|
||||
if (aResponse->GetShouldAllowContent()) {
|
||||
return FromAction(nsIContentAnalysisResponse::Action::eAllow);
|
||||
} else {
|
||||
return FromAction(nsIContentAnalysisResponse::Action::eBlock);
|
||||
|
@ -11,6 +11,5 @@ Classes = [
|
||||
'contract_ids': ['@mozilla.org/contentanalysis;1'],
|
||||
'type': 'mozilla::contentanalysis::ContentAnalysis',
|
||||
'headers': ['/toolkit/components/contentanalysis/ContentAnalysis.h'],
|
||||
'overridable': True,
|
||||
},
|
||||
]
|
||||
|
@ -36,7 +36,7 @@ interface nsIContentAnalysisAcknowledgement : nsISupports
|
||||
readonly attribute nsIContentAnalysisAcknowledgement_FinalAction finalAction;
|
||||
};
|
||||
|
||||
[scriptable, uuid(89088c61-15f6-4ace-a880-a1b5ea47ca66)]
|
||||
[scriptable, builtinclass, uuid(89088c61-15f6-4ace-a880-a1b5ea47ca66)]
|
||||
interface nsIContentAnalysisResponse : nsISupports
|
||||
{
|
||||
// These values must stay synchronized with ContentAnalysisResponse
|
||||
@ -59,11 +59,11 @@ interface nsIContentAnalysisResponse : nsISupports
|
||||
eErrorOther = 3,
|
||||
};
|
||||
|
||||
readonly attribute nsIContentAnalysisResponse_Action action;
|
||||
readonly attribute boolean shouldAllowContent;
|
||||
[infallible] readonly attribute nsIContentAnalysisResponse_Action action;
|
||||
[infallible] readonly attribute boolean shouldAllowContent;
|
||||
// If action is eCanceled, this is the error explaining why the request was canceled,
|
||||
// or eUserInitiated if the user canceled it.
|
||||
readonly attribute nsIContentAnalysisResponse_CancelError cancelError;
|
||||
[infallible] readonly attribute nsIContentAnalysisResponse_CancelError cancelError;
|
||||
|
||||
// Identifier for the corresponding nsIContentAnalysisRequest
|
||||
readonly attribute ACString requestToken;
|
||||
@ -131,7 +131,6 @@ interface nsIContentAnalysisRequest : nsISupports
|
||||
eCustomDisplayString = 0,
|
||||
eClipboard = 1,
|
||||
eDroppedText = 2,
|
||||
eOperationPrint = 3,
|
||||
};
|
||||
readonly attribute nsIContentAnalysisRequest_OperationType operationTypeForDisplay;
|
||||
readonly attribute AString operationDisplayString;
|
||||
@ -142,15 +141,6 @@ interface nsIContentAnalysisRequest : nsISupports
|
||||
// Name of file to analyze. Only one of textContent or filePath is defined.
|
||||
readonly attribute AString filePath;
|
||||
|
||||
// HANDLE to the printed data in PDF format.
|
||||
readonly attribute unsigned long long printDataHandle;
|
||||
|
||||
// Size of the data stored in printDataHandle.
|
||||
readonly attribute unsigned long long printDataSize;
|
||||
|
||||
// Name of the printer being printed to.
|
||||
readonly attribute AString printerName;
|
||||
|
||||
// The URL containing the file download/upload or to which web content is
|
||||
// being uploaded.
|
||||
readonly attribute nsIURI url;
|
||||
@ -195,7 +185,7 @@ interface nsIContentAnalysisDiagnosticInfo : nsISupports
|
||||
[infallible] readonly attribute long long requestCount;
|
||||
};
|
||||
|
||||
[scriptable, uuid(61497587-2bba-4a88-acd3-3fbb2cedf163)]
|
||||
[scriptable, builtinclass, uuid(61497587-2bba-4a88-acd3-3fbb2cedf163)]
|
||||
interface nsIContentAnalysis : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -1,20 +1,3 @@
|
||||
[DEFAULT]
|
||||
run-if = ["os == 'win'"]
|
||||
support-files = [
|
||||
"head.js",
|
||||
]
|
||||
|
||||
["browser_content_analysis_policies.js"]
|
||||
|
||||
["browser_print_changing_page_content_analysis.js"]
|
||||
support-files = [
|
||||
"!/toolkit/components/printing/tests/head.js",
|
||||
"changing_page_for_print.html",
|
||||
]
|
||||
|
||||
["browser_print_content_analysis.js"]
|
||||
support-files = [
|
||||
"!/toolkit/components/printing/tests/head.js",
|
||||
"!/toolkit/components/printing/tests/longerArticle.html",
|
||||
"!/toolkit/components/printing/tests/simplifyArticleSample.html",
|
||||
]
|
||||
|
@ -1,339 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/toolkit/components/printing/tests/head.js",
|
||||
this
|
||||
);
|
||||
|
||||
const PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
|
||||
Ci.nsIPrintSettingsService
|
||||
);
|
||||
|
||||
let mockCA = {
|
||||
isActive: true,
|
||||
mightBeActive: true,
|
||||
errorValue: undefined,
|
||||
|
||||
setupForTest(shouldAllowRequest) {
|
||||
this.shouldAllowRequest = shouldAllowRequest;
|
||||
this.errorValue = undefined;
|
||||
this.calls = [];
|
||||
},
|
||||
|
||||
setupForTestWithError(errorValue) {
|
||||
this.errorValue = errorValue;
|
||||
this.calls = [];
|
||||
},
|
||||
|
||||
getAction() {
|
||||
if (this.shouldAllowRequest === undefined) {
|
||||
this.shouldAllowRequest = true;
|
||||
}
|
||||
return this.shouldAllowRequest
|
||||
? Ci.nsIContentAnalysisResponse.eAllow
|
||||
: Ci.nsIContentAnalysisResponse.eBlock;
|
||||
},
|
||||
|
||||
// nsIContentAnalysis methods
|
||||
async analyzeContentRequest(request, _autoAcknowledge) {
|
||||
info(
|
||||
"Mock ContentAnalysis service: analyzeContentRequest, this.shouldAllowRequest=" +
|
||||
this.shouldAllowRequest +
|
||||
", this.errorValue=" +
|
||||
this.errorValue
|
||||
);
|
||||
this.calls.push(request);
|
||||
if (this.errorValue) {
|
||||
throw this.errorValue;
|
||||
}
|
||||
// Use setTimeout to simulate an async activity
|
||||
await new Promise(res => setTimeout(res, 0));
|
||||
return makeContentAnalysisResponse(this.getAction(), request.requestToken);
|
||||
},
|
||||
|
||||
analyzeContentRequestCallback(request, autoAcknowledge, callback) {
|
||||
info(
|
||||
"Mock ContentAnalysis service: analyzeContentRequestCallback, this.shouldAllowRequest=" +
|
||||
this.shouldAllowRequest +
|
||||
", this.errorValue=" +
|
||||
this.errorValue
|
||||
);
|
||||
this.calls.push(request);
|
||||
if (this.errorValue) {
|
||||
throw this.errorValue;
|
||||
}
|
||||
let response = makeContentAnalysisResponse(
|
||||
this.getAction(),
|
||||
request.requestToken
|
||||
);
|
||||
// Use setTimeout to simulate an async activity
|
||||
setTimeout(() => {
|
||||
callback.contentResult(response);
|
||||
}, 0);
|
||||
},
|
||||
};
|
||||
|
||||
add_setup(async function test_setup() {
|
||||
mockCA = mockContentAnalysisService(mockCA);
|
||||
});
|
||||
|
||||
const TEST_PAGE_URL = PrintHelper.getTestPageUrlHTTPS(
|
||||
"changing_page_for_print.html"
|
||||
);
|
||||
|
||||
function addUniqueSuffix(prefix) {
|
||||
return `${prefix}-${Services.uuid
|
||||
.generateUUID()
|
||||
.toString()
|
||||
.slice(1, -1)}.pdf`;
|
||||
}
|
||||
|
||||
async function printToDestination(aBrowser, aDestination) {
|
||||
let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
|
||||
let fileName = addUniqueSuffix(`printDestinationTest-${aDestination}`);
|
||||
let filePath = PathUtils.join(tmpDir.path, fileName);
|
||||
|
||||
info(`Printing to ${filePath}`);
|
||||
|
||||
let settings = PSSVC.createNewPrintSettings();
|
||||
settings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
|
||||
settings.outputDestination = aDestination;
|
||||
|
||||
settings.headerStrCenter = "";
|
||||
settings.headerStrLeft = "";
|
||||
settings.headerStrRight = "";
|
||||
settings.footerStrCenter = "";
|
||||
settings.footerStrLeft = "";
|
||||
settings.footerStrRight = "";
|
||||
|
||||
settings.unwriteableMarginTop = 1; /* Just to ensure settings are respected on both */
|
||||
let outStream = null;
|
||||
if (aDestination == Ci.nsIPrintSettings.kOutputDestinationFile) {
|
||||
settings.toFileName = PathUtils.join(tmpDir.path, fileName);
|
||||
} else {
|
||||
is(aDestination, Ci.nsIPrintSettings.kOutputDestinationStream);
|
||||
outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
||||
Ci.nsIFileOutputStream
|
||||
);
|
||||
let tmpFile = tmpDir.clone();
|
||||
tmpFile.append(fileName);
|
||||
outStream.init(tmpFile, -1, 0o666, 0);
|
||||
settings.outputStream = outStream;
|
||||
}
|
||||
|
||||
await aBrowser.browsingContext.print(settings);
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
function assertContentAnalysisRequest(request) {
|
||||
is(request.url.spec, TEST_PAGE_URL, "request has correct URL");
|
||||
is(
|
||||
request.analysisType,
|
||||
Ci.nsIContentAnalysisRequest.ePrint,
|
||||
"request has print analysisType"
|
||||
);
|
||||
is(
|
||||
request.operationTypeForDisplay,
|
||||
Ci.nsIContentAnalysisRequest.eOperationPrint,
|
||||
"request has print operationTypeForDisplay"
|
||||
);
|
||||
is(request.textContent, "", "request textContent should be empty");
|
||||
is(request.filePath, "", "request filePath should be empty");
|
||||
isnot(request.printDataHandle, 0, "request printDataHandle should not be 0");
|
||||
isnot(request.printDataSize, 0, "request printDataSize should not be 0");
|
||||
ok(!!request.requestToken.length, "request requestToken should not be empty");
|
||||
}
|
||||
|
||||
add_task(
|
||||
async function testPrintToStreamWithContentAnalysisActiveAndAllowing() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(true);
|
||||
|
||||
let filePath = await printToDestination(
|
||||
helper.sourceBrowser,
|
||||
Ci.nsIPrintSettings.kOutputDestinationFile
|
||||
);
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
|
||||
// This effectively tests that the PDF content sent to Content Analysis
|
||||
// and the content that is actually printed matches. This is necessary
|
||||
// because a previous iteration of the Content Analysis code didn't use
|
||||
// a static Document clone for this and so the content would differ. (since
|
||||
// the .html file in question adds content to the page when print events
|
||||
// happen)
|
||||
await waitForFileToAlmostMatchSize(
|
||||
filePath,
|
||||
mockCA.calls[0].printDataSize
|
||||
);
|
||||
|
||||
await IOUtils.remove(filePath);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
add_task(
|
||||
async function testPrintToStreamWithContentAnalysisActiveAndBlocking() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(false);
|
||||
|
||||
try {
|
||||
await printToDestination(
|
||||
helper.sourceBrowser,
|
||||
Ci.nsIPrintSettings.kOutputDestinationFile
|
||||
);
|
||||
ok(false, "Content analysis should make this fail to print");
|
||||
} catch (e) {
|
||||
ok(
|
||||
/NS_ERROR_CONTENT_BLOCKED/.test(e.toString()),
|
||||
"Got content blocked error"
|
||||
);
|
||||
}
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
add_task(async function testPrintToStreamWithContentAnalysisReturningError() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
expectUncaughtException();
|
||||
mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
try {
|
||||
await printToDestination(
|
||||
helper.sourceBrowser,
|
||||
Ci.nsIPrintSettings.kOutputDestinationFile
|
||||
);
|
||||
ok(false, "Content analysis should make this fail to print");
|
||||
} catch (e) {
|
||||
ok(
|
||||
/NS_ERROR_NOT_AVAILABLE/.test(e.toString()),
|
||||
"Error in mock CA was propagated out"
|
||||
);
|
||||
}
|
||||
is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis");
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function testPrintThroughDialogWithContentAnalysisActive() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(true);
|
||||
|
||||
let fileName = addUniqueSuffix(`printDialogTest`);
|
||||
let file = helper.mockFilePicker(fileName);
|
||||
info(`Printing to ${file.path}`);
|
||||
await helper.startPrint();
|
||||
await helper.assertPrintToFile(file, () => {
|
||||
EventUtils.sendKey("return", helper.win);
|
||||
});
|
||||
|
||||
is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis");
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
|
||||
await waitForFileToAlmostMatchSize(
|
||||
file.path,
|
||||
mockCA.calls[0].printDataSize
|
||||
);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
add_task(
|
||||
async function testPrintThroughDialogWithContentAnalysisActiveAndBlocking() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(false);
|
||||
|
||||
await helper.startPrint();
|
||||
let fileName = addUniqueSuffix(`printDialogTest`);
|
||||
let file = helper.mockFilePicker(fileName);
|
||||
info(`Printing to ${file.path}`);
|
||||
try {
|
||||
await helper.assertPrintToFile(file, () => {
|
||||
EventUtils.sendKey("return", helper.win);
|
||||
});
|
||||
} catch (e) {
|
||||
ok(
|
||||
/Wait for target file to get created/.test(e.toString()),
|
||||
"Target file should not get created"
|
||||
);
|
||||
}
|
||||
ok(!file.exists(), "File should not exist");
|
||||
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
add_task(
|
||||
async function testPrintThroughDialogWithContentAnalysisReturningError() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
expectUncaughtException();
|
||||
mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
await helper.startPrint();
|
||||
let fileName = addUniqueSuffix(`printDialogTest`);
|
||||
let file = helper.mockFilePicker(fileName);
|
||||
info(`Printing to ${file.path}`);
|
||||
try {
|
||||
await helper.assertPrintToFile(file, () => {
|
||||
EventUtils.sendKey("return", helper.win);
|
||||
});
|
||||
} catch (e) {
|
||||
ok(
|
||||
/Wait for target file to get created/.test(e.toString()),
|
||||
"Target file should not get created"
|
||||
);
|
||||
}
|
||||
ok(!file.exists(), "File should not exist");
|
||||
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
@ -1,390 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/toolkit/components/printing/tests/head.js",
|
||||
this
|
||||
);
|
||||
|
||||
const PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
|
||||
Ci.nsIPrintSettingsService
|
||||
);
|
||||
|
||||
let mockCA = {
|
||||
isActive: true,
|
||||
mightBeActive: true,
|
||||
errorValue: undefined,
|
||||
|
||||
setupForTest(shouldAllowRequest) {
|
||||
this.shouldAllowRequest = shouldAllowRequest;
|
||||
this.errorValue = undefined;
|
||||
this.calls = [];
|
||||
},
|
||||
|
||||
setupForTestWithError(errorValue) {
|
||||
this.errorValue = errorValue;
|
||||
this.calls = [];
|
||||
},
|
||||
|
||||
clearCalls() {
|
||||
this.calls = [];
|
||||
},
|
||||
|
||||
getAction() {
|
||||
if (this.shouldAllowRequest === undefined) {
|
||||
this.shouldAllowRequest = true;
|
||||
}
|
||||
return this.shouldAllowRequest
|
||||
? Ci.nsIContentAnalysisResponse.eAllow
|
||||
: Ci.nsIContentAnalysisResponse.eBlock;
|
||||
},
|
||||
|
||||
// nsIContentAnalysis methods
|
||||
async analyzeContentRequest(request, _autoAcknowledge) {
|
||||
info(
|
||||
"Mock ContentAnalysis service: analyzeContentRequest, this.shouldAllowRequest=" +
|
||||
this.shouldAllowRequest +
|
||||
", this.errorValue=" +
|
||||
this.errorValue
|
||||
);
|
||||
this.calls.push(request);
|
||||
if (this.errorValue) {
|
||||
throw this.errorValue;
|
||||
}
|
||||
// Use setTimeout to simulate an async activity
|
||||
await new Promise(res => setTimeout(res, 0));
|
||||
return makeContentAnalysisResponse(this.getAction(), request.requestToken);
|
||||
},
|
||||
|
||||
analyzeContentRequestCallback(request, autoAcknowledge, callback) {
|
||||
info(
|
||||
"Mock ContentAnalysis service: analyzeContentRequestCallback, this.shouldAllowRequest=" +
|
||||
this.shouldAllowRequest +
|
||||
", this.errorValue=" +
|
||||
this.errorValue
|
||||
);
|
||||
this.calls.push(request);
|
||||
if (this.errorValue) {
|
||||
throw this.errorValue;
|
||||
}
|
||||
let response = makeContentAnalysisResponse(
|
||||
this.getAction(),
|
||||
request.requestToken
|
||||
);
|
||||
// Use setTimeout to simulate an async activity
|
||||
setTimeout(() => {
|
||||
callback.contentResult(response);
|
||||
}, 0);
|
||||
},
|
||||
};
|
||||
|
||||
add_setup(async function test_setup() {
|
||||
mockCA = mockContentAnalysisService(mockCA);
|
||||
});
|
||||
|
||||
const TEST_PAGE_URL =
|
||||
"https://example.com/browser/toolkit/components/printing/tests/simplifyArticleSample.html";
|
||||
const TEST_PAGE_URL_2 =
|
||||
"https://example.com/browser/toolkit/components/printing/tests/longerArticle.html";
|
||||
|
||||
function addUniqueSuffix(prefix) {
|
||||
return `${prefix}-${Services.uuid
|
||||
.generateUUID()
|
||||
.toString()
|
||||
.slice(1, -1)}.pdf`;
|
||||
}
|
||||
|
||||
async function printToDestination(aBrowser, aDestination) {
|
||||
let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
|
||||
let fileName = addUniqueSuffix(`printDestinationTest-${aDestination}`);
|
||||
let filePath = PathUtils.join(tmpDir.path, fileName);
|
||||
|
||||
info(`Printing to ${filePath}`);
|
||||
|
||||
let settings = PSSVC.createNewPrintSettings();
|
||||
settings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
|
||||
settings.outputDestination = aDestination;
|
||||
|
||||
settings.headerStrCenter = "";
|
||||
settings.headerStrLeft = "";
|
||||
settings.headerStrRight = "";
|
||||
settings.footerStrCenter = "";
|
||||
settings.footerStrLeft = "";
|
||||
settings.footerStrRight = "";
|
||||
|
||||
settings.unwriteableMarginTop = 1; /* Just to ensure settings are respected on both */
|
||||
let outStream = null;
|
||||
if (aDestination == Ci.nsIPrintSettings.kOutputDestinationFile) {
|
||||
settings.toFileName = PathUtils.join(tmpDir.path, fileName);
|
||||
} else {
|
||||
is(aDestination, Ci.nsIPrintSettings.kOutputDestinationStream);
|
||||
outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
||||
Ci.nsIFileOutputStream
|
||||
);
|
||||
let tmpFile = tmpDir.clone();
|
||||
tmpFile.append(fileName);
|
||||
outStream.init(tmpFile, -1, 0o666, 0);
|
||||
settings.outputStream = outStream;
|
||||
}
|
||||
|
||||
await aBrowser.browsingContext.print(settings);
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
function assertContentAnalysisRequest(request, expectedUrl) {
|
||||
is(request.url.spec, expectedUrl ?? TEST_PAGE_URL, "request has correct URL");
|
||||
is(
|
||||
request.analysisType,
|
||||
Ci.nsIContentAnalysisRequest.ePrint,
|
||||
"request has print analysisType"
|
||||
);
|
||||
is(
|
||||
request.operationTypeForDisplay,
|
||||
Ci.nsIContentAnalysisRequest.eOperationPrint,
|
||||
"request has print operationTypeForDisplay"
|
||||
);
|
||||
is(request.textContent, "", "request textContent should be empty");
|
||||
is(request.filePath, "", "request filePath should be empty");
|
||||
isnot(request.printDataHandle, 0, "request printDataHandle should not be 0");
|
||||
isnot(request.printDataSize, 0, "request printDataSize should not be 0");
|
||||
ok(!!request.requestToken.length, "request requestToken should not be empty");
|
||||
}
|
||||
|
||||
// Printing to a stream is different than going through the print preview dialog because it
|
||||
// doesn't make a static clone of the document before the print, which causes the
|
||||
// Content Analysis code to go through a different code path. This is similar to what
|
||||
// happens when various preferences are set to skip the print preview dialog, for example
|
||||
// print.prefer_system_dialog.
|
||||
add_task(
|
||||
async function testPrintToStreamWithContentAnalysisActiveAndAllowing() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(true);
|
||||
|
||||
let filePath = await printToDestination(
|
||||
helper.sourceBrowser,
|
||||
Ci.nsIPrintSettings.kOutputDestinationFile
|
||||
);
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
|
||||
await waitForFileToAlmostMatchSize(
|
||||
filePath,
|
||||
mockCA.calls[0].printDataSize
|
||||
);
|
||||
|
||||
await IOUtils.remove(filePath);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
add_task(
|
||||
async function testPrintToStreamAfterNavigationWithContentAnalysisActiveAndAllowing() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(true);
|
||||
|
||||
let filePath = await printToDestination(
|
||||
helper.sourceBrowser,
|
||||
Ci.nsIPrintSettings.kOutputDestinationFile
|
||||
);
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
mockCA.clearCalls();
|
||||
|
||||
await IOUtils.remove(filePath);
|
||||
|
||||
BrowserTestUtils.startLoadingURIString(
|
||||
helper.sourceBrowser,
|
||||
TEST_PAGE_URL_2
|
||||
);
|
||||
await BrowserTestUtils.browserLoaded(helper.sourceBrowser);
|
||||
|
||||
filePath = await printToDestination(
|
||||
helper.sourceBrowser,
|
||||
Ci.nsIPrintSettings.kOutputDestinationFile
|
||||
);
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0], TEST_PAGE_URL_2);
|
||||
await waitForFileToAlmostMatchSize(
|
||||
filePath,
|
||||
mockCA.calls[0].printDataSize
|
||||
);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
add_task(
|
||||
async function testPrintToStreamWithContentAnalysisActiveAndBlocking() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(false);
|
||||
|
||||
try {
|
||||
await printToDestination(
|
||||
helper.sourceBrowser,
|
||||
Ci.nsIPrintSettings.kOutputDestinationFile
|
||||
);
|
||||
ok(false, "Content analysis should make this fail to print");
|
||||
} catch (e) {
|
||||
ok(
|
||||
/NS_ERROR_CONTENT_BLOCKED/.test(e.toString()),
|
||||
"Got content blocked error"
|
||||
);
|
||||
}
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
add_task(async function testPrintToStreamWithContentAnalysisReturningError() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
expectUncaughtException();
|
||||
mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
try {
|
||||
await printToDestination(
|
||||
helper.sourceBrowser,
|
||||
Ci.nsIPrintSettings.kOutputDestinationFile
|
||||
);
|
||||
ok(false, "Content analysis should make this fail to print");
|
||||
} catch (e) {
|
||||
ok(
|
||||
/NS_ERROR_NOT_AVAILABLE/.test(e.toString()),
|
||||
"Error in mock CA was propagated out"
|
||||
);
|
||||
}
|
||||
is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis");
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function testPrintThroughDialogWithContentAnalysisActive() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(true);
|
||||
|
||||
await helper.startPrint();
|
||||
let fileName = addUniqueSuffix(`printDialogTest`);
|
||||
let file = helper.mockFilePicker(fileName);
|
||||
info(`Printing to ${file.path}`);
|
||||
await helper.assertPrintToFile(file, () => {
|
||||
EventUtils.sendKey("return", helper.win);
|
||||
});
|
||||
|
||||
is(mockCA.calls.length, 1, "Correct number of calls to Content Analysis");
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
|
||||
await waitForFileToAlmostMatchSize(
|
||||
file.path,
|
||||
mockCA.calls[0].printDataSize
|
||||
);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
add_task(
|
||||
async function testPrintThroughDialogWithContentAnalysisActiveAndBlocking() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
mockCA.setupForTest(false);
|
||||
|
||||
await helper.startPrint();
|
||||
let fileName = addUniqueSuffix(`printDialogTest`);
|
||||
let file = helper.mockFilePicker(fileName);
|
||||
info(`Printing to ${file.path}`);
|
||||
try {
|
||||
await helper.assertPrintToFile(file, () => {
|
||||
EventUtils.sendKey("return", helper.win);
|
||||
});
|
||||
} catch (e) {
|
||||
ok(
|
||||
/Wait for target file to get created/.test(e.toString()),
|
||||
"Target file should not get created"
|
||||
);
|
||||
}
|
||||
ok(!file.exists(), "File should not exist");
|
||||
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
add_task(
|
||||
async function testPrintThroughDialogWithContentAnalysisReturningError() {
|
||||
await PrintHelper.withTestPage(
|
||||
async helper => {
|
||||
expectUncaughtException();
|
||||
mockCA.setupForTestWithError(Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
await helper.startPrint();
|
||||
let fileName = addUniqueSuffix(`printDialogTest`);
|
||||
let file = helper.mockFilePicker(fileName);
|
||||
info(`Printing to ${file.path}`);
|
||||
try {
|
||||
await helper.assertPrintToFile(file, () => {
|
||||
EventUtils.sendKey("return", helper.win);
|
||||
});
|
||||
} catch (e) {
|
||||
ok(
|
||||
/Wait for target file to get created/.test(e.toString()),
|
||||
"Target file should not get created"
|
||||
);
|
||||
}
|
||||
ok(!file.exists(), "File should not exist");
|
||||
|
||||
is(
|
||||
mockCA.calls.length,
|
||||
1,
|
||||
"Correct number of calls to Content Analysis"
|
||||
);
|
||||
assertContentAnalysisRequest(mockCA.calls[0]);
|
||||
},
|
||||
TEST_PAGE_URL,
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
@ -1,12 +0,0 @@
|
||||
<!doctype html>
|
||||
<p>Some random text</p>
|
||||
<button onclick="print()">Print the page</button>
|
||||
<pre id="log"></pre>
|
||||
<script>
|
||||
let i = 0;
|
||||
for (let t of ["beforeprint", "afterprint"]) {
|
||||
addEventListener(t, () => {
|
||||
document.getElementById("log").appendChild(document.createTextNode(`[${i++}] ${t}\n`));
|
||||
});
|
||||
}
|
||||
</script>
|
@ -1,114 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { MockRegistrar } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/MockRegistrar.sys.mjs"
|
||||
);
|
||||
|
||||
// Wraps the given object in an XPConnect wrapper and, if an interface
|
||||
// is passed, queries the result to that interface.
|
||||
function xpcWrap(obj, iface) {
|
||||
let ifacePointer = Cc[
|
||||
"@mozilla.org/supports-interface-pointer;1"
|
||||
].createInstance(Ci.nsISupportsInterfacePointer);
|
||||
|
||||
ifacePointer.data = obj;
|
||||
if (iface) {
|
||||
return ifacePointer.data.QueryInterface(iface);
|
||||
}
|
||||
return ifacePointer.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock a (set of) service(s) as the object mockService.
|
||||
*
|
||||
* @param {[string]} serviceNames
|
||||
* array of services names that mockService will be
|
||||
* allowed to QI to. Must include the name of the
|
||||
* service referenced by contractId.
|
||||
* @param {string} contractId
|
||||
* the component ID that will reference the mock object
|
||||
* instead of the original service
|
||||
* @param {object} interfaceObj
|
||||
* interface object for the component
|
||||
* @param {object} mockService
|
||||
* object that satisfies the contract well
|
||||
* enough to use as a mock of it
|
||||
* @returns {object} The newly-mocked service
|
||||
*/
|
||||
function mockService(serviceNames, contractId, interfaceObj, mockService) {
|
||||
// xpcWrap allows us to mock [implicit_jscontext] methods.
|
||||
let newService = {
|
||||
...mockService,
|
||||
QueryInterface: ChromeUtils.generateQI(serviceNames),
|
||||
};
|
||||
let o = xpcWrap(newService, interfaceObj);
|
||||
let cid = MockRegistrar.register(contractId, o);
|
||||
registerCleanupFunction(() => {
|
||||
MockRegistrar.unregister(cid);
|
||||
});
|
||||
return newService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock the nsIContentAnalysis service with the object mockCAService.
|
||||
*
|
||||
* @param {object} mockCAService
|
||||
* the service to mock for nsIContentAnalysis
|
||||
* @returns {object} The newly-mocked service
|
||||
*/
|
||||
function mockContentAnalysisService(mockCAService) {
|
||||
return mockService(
|
||||
["nsIContentAnalysis"],
|
||||
"@mozilla.org/contentanalysis;1",
|
||||
Ci.nsIContentAnalysis,
|
||||
mockCAService
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an nsIContentAnalysisResponse.
|
||||
*
|
||||
* @param {number} action The action to take, from the
|
||||
* nsIContentAnalysisResponse.Action enum.
|
||||
* @param {string} token The requestToken.
|
||||
* @returns {object} An object that conforms to nsIContentAnalysisResponse.
|
||||
*/
|
||||
function makeContentAnalysisResponse(action, token) {
|
||||
return {
|
||||
action,
|
||||
shouldAllowContent: action != Ci.nsIContentAnalysisResponse.eBlock,
|
||||
requestToken: token,
|
||||
acknowledge: _acknowledgement => {},
|
||||
};
|
||||
}
|
||||
|
||||
async function waitForFileToAlmostMatchSize(filePath, expectedSize) {
|
||||
// In Cocoa the CGContext adds a hash, plus there are other minor
|
||||
// non-user-visible differences, so we need to be a bit more sloppy there.
|
||||
//
|
||||
// We see one byte difference in Windows and Linux on automation sometimes,
|
||||
// though files are consistently the same locally, that needs
|
||||
// investigation, but it's probably harmless.
|
||||
// Note that this is copied from browser_print_stream.js.
|
||||
const maxSizeDifference = AppConstants.platform == "macosx" ? 100 : 3;
|
||||
|
||||
// Buffering shenanigans? Wait for sizes to match... There's no great
|
||||
// IOUtils methods to force a flush without writing anything...
|
||||
// Note that this means if this results in a timeout this is exactly
|
||||
// the same as a test failure.
|
||||
// This is taken from toolkit/components/printing/tests/browser_print_stream.js
|
||||
await TestUtils.waitForCondition(async function () {
|
||||
let fileStat = await IOUtils.stat(filePath);
|
||||
|
||||
info("got size: " + fileStat.size + " expected: " + expectedSize);
|
||||
Assert.greater(
|
||||
fileStat.size,
|
||||
0,
|
||||
"File should not be empty: " + fileStat.size
|
||||
);
|
||||
return Math.abs(fileStat.size - expectedSize) <= maxSizeDifference;
|
||||
}, "Sizes should (almost) match");
|
||||
}
|
@ -60,9 +60,6 @@ class PrintHelper {
|
||||
}
|
||||
|
||||
static getTestPageUrl(pathName) {
|
||||
if (pathName.startsWith("http://")) {
|
||||
return pathName;
|
||||
}
|
||||
const testPath = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"http://example.com"
|
||||
@ -71,9 +68,6 @@ class PrintHelper {
|
||||
}
|
||||
|
||||
static getTestPageUrlHTTPS(pathName) {
|
||||
if (pathName.startsWith("https://")) {
|
||||
return pathName;
|
||||
}
|
||||
const testPath = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://example.com"
|
||||
|
@ -20,12 +20,8 @@ contentanalysis-slow-agent-dialog-body-clipboard = { $agent } is reviewing what
|
||||
# Variables:
|
||||
# $agent - The name of the DLP agent doing the analysis
|
||||
contentanalysis-slow-agent-dialog-body-dropped-text = { $agent } is reviewing the text you dropped against your organization’s data policies. This may take a moment.
|
||||
# Variables:
|
||||
# $agent - The name of the DLP agent doing the analysis
|
||||
contentanalysis-slow-agent-dialog-body-print = { $agent } is reviewing what you printed against your organization’s data policies. This may take a moment.
|
||||
contentanalysis-operationtype-clipboard = clipboard
|
||||
contentanalysis-operationtype-dropped-text = dropped text
|
||||
contentanalysis-operationtype-print = print
|
||||
# $filename - The filename associated with the request, such as "aFile.txt"
|
||||
contentanalysis-customdisplaystring-description = upload of “{ $filename }”
|
||||
|
||||
|
@ -335,7 +335,7 @@ interface nsIPrintSettings : nsISupports
|
||||
*/
|
||||
attribute AString toFileName;
|
||||
|
||||
attribute nsIOutputStream outputStream; /* for kOutputDestinationStream */
|
||||
attribute nsIOutputStream outputStream; /* for kOutputDestinationPrinter */
|
||||
|
||||
[infallible] attribute long printPageDelay; /* in milliseconds */
|
||||
|
||||
|
@ -735,11 +735,7 @@ nsFilePicker::CheckContentAnalysisService() {
|
||||
auto contentAnalysisCallback =
|
||||
mozilla::MakeRefPtr<mozilla::contentanalysis::ContentAnalysisCallback>(
|
||||
[promise](nsIContentAnalysisResponse* aResponse) {
|
||||
bool shouldAllow = false;
|
||||
mozilla::DebugOnly<nsresult> rv =
|
||||
aResponse->GetShouldAllowContent(&shouldAllow);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
promise->Resolve(shouldAllow, __func__);
|
||||
promise->Resolve(aResponse->GetShouldAllowContent(), __func__);
|
||||
},
|
||||
[promise](nsresult aError) { promise->Reject(aError, __func__); });
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user