diff options
Diffstat (limited to '')
23 files changed, 265 insertions, 237 deletions
diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index 84f2d2960a..4c92988c9b 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -6,8 +6,10 @@ #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" @@ -47,6 +49,7 @@ #include "nsFrameLoader.h" #include "nsFrameLoaderOwner.h" #include "nsGlobalWindowOuter.h" +#include "nsIContentAnalysis.h" #include "nsIWebBrowserChrome.h" #include "nsIXULRuntime.h" #include "nsNetUtil.h" @@ -668,6 +671,9 @@ 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) @@ -678,10 +684,14 @@ 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) { - mPromise->Resolve(true, __func__); - mPromise = nullptr; + mPrintJobFinished = true; + if (mHaveSetBrowsingContext) { + mPromise->Resolve(mClonedStaticBrowsingContext, __func__); + mPromise = nullptr; + } } return NS_OK; } @@ -716,10 +726,28 @@ 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) @@ -735,7 +763,9 @@ already_AddRefed<Promise> CanonicalBrowsingContext::PrintJS( Print(aPrintSettings) ->Then( GetCurrentSerialEventTarget(), __func__, - [promise](bool) { promise->MaybeResolveWithUndefined(); }, + [promise](MaybeDiscardedBrowsingContext) { + promise->MaybeResolveWithUndefined(); + }, [promise](nsresult aResult) { promise->MaybeReject(aResult); }); return promise.forget(); } @@ -745,7 +775,72 @@ 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()) { @@ -757,12 +852,14 @@ RefPtr<PrintPromise> CanonicalBrowsingContext::Print( } ErrorResult rv; + listener->NoStaticCloneForPrintingWillBeCreated(); outerWindow->Print(aPrintSettings, /* aRemotePrintJob = */ nullptr, listener, /* aDocShellToCloneInto = */ nullptr, nsGlobalWindowOuter::IsPreview::No, nsGlobalWindowOuter::IsForWindowDotPrint::No, - /* aPrintPreviewCallback = */ nullptr, rv); + /* aPrintPreviewCallback = */ nullptr, + /* aCachedBrowsingContext = */ nullptr, rv); if (rv.Failed()) { promise->Reject(rv.StealNSResult(), __func__); } @@ -805,12 +902,31 @@ RefPtr<PrintPromise> CanonicalBrowsingContext::Print( printData.remotePrintJob() = browserParent->Manager()->SendPRemotePrintJobConstructor(remotePrintJob); - if (listener) { - remotePrintJob->RegisterListener(listener); - } + remotePrintJob->RegisterListener(listener); - if (NS_WARN_IF(!browserParent->SendPrint(this, printData))) { - promise->Reject(NS_ERROR_FAILURE, __func__); + 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__); + }); } return promise.forget(); #endif @@ -2245,9 +2361,19 @@ bool CanonicalBrowsingContext::SupportsLoadingInParent( return false; } } - // If the current document has a beforeunload listener, then we need to - // start the load in that process after we fire the event. - if (global->HasBeforeUnload()) { + + // If unloading the current document will cause a beforeunload listener to + // run, then we need to start the load in that process after we fire the + // event. + if (PreOrderWalkFlag([&](BrowsingContext* aBC) { + WindowContext* wc = aBC->GetCurrentWindowContext(); + if (wc && wc->HasBeforeUnload()) { + // We can stop as soon as we know at least one beforeunload listener + // exists. + return WalkFlag::Stop; + } + return WalkFlag::Next; + }) == WalkFlag::Stop) { return false; } diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h index 132c9f2157..ccbdf9ed96 100644 --- a/docshell/base/CanonicalBrowsingContext.h +++ b/docshell/base/CanonicalBrowsingContext.h @@ -136,11 +136,16 @@ class CanonicalBrowsingContext final : public BrowsingContext { UniquePtr<LoadingSessionHistoryInfo> ReplaceLoadingSessionHistoryEntryForLoad( LoadingSessionHistoryInfo* aInfo, nsIChannel* aNewChannel); - using PrintPromise = MozPromise</* unused */ bool, nsresult, false>; + using PrintPromise = + MozPromise<MaybeDiscardedBrowsingContext, 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. // diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index fdae228b90..56efb7aed7 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -108,6 +108,12 @@ static const RedirEntry kRedirMap[] = { {"credits", "https://www.mozilla.org/credits/", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::URI_MUST_LOAD_IN_CHILD}, + {"fingerprinting", + "chrome://global/content/usercharacteristics/usercharacteristics.html", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT | nsIAboutModule::ALLOW_SCRIPT | + nsIAboutModule::URI_MUST_LOAD_IN_CHILD | + nsIAboutModule::URI_CAN_LOAD_IN_PRIVILEGEDABOUT_PROCESS}, {"httpsonlyerror", "chrome://global/content/httpsonlyerror/errorpage.html", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::URI_CAN_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT | diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 3404597343..87a34cf5b2 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -144,6 +144,7 @@ #include "nsIScriptChannel.h" #include "nsIScriptObjectPrincipal.h" #include "nsIScriptSecurityManager.h" +#include "nsScriptSecurityManager.h" #include "nsIScrollableFrame.h" #include "nsIScrollObserver.h" #include "nsISupportsPrimitives.h" @@ -332,7 +333,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext, mAppType(nsIDocShell::APP_TYPE_UNKNOWN), mLoadType(0), mFailedLoadType(0), - mMetaViewportOverride(nsIDocShell::META_VIEWPORT_OVERRIDE_NONE), mChannelToDisconnectOnPageHide(0), mCreatingDocument(false), #ifdef DEBUG @@ -2376,37 +2376,6 @@ nsDocShell::ClearCachedUserAgent() { return NS_OK; } -NS_IMETHODIMP -nsDocShell::GetMetaViewportOverride( - MetaViewportOverride* aMetaViewportOverride) { - NS_ENSURE_ARG_POINTER(aMetaViewportOverride); - - *aMetaViewportOverride = mMetaViewportOverride; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::SetMetaViewportOverride( - MetaViewportOverride aMetaViewportOverride) { - // We don't have a way to verify this coming from Javascript, so this check is - // still needed. - if (!(aMetaViewportOverride == META_VIEWPORT_OVERRIDE_NONE || - aMetaViewportOverride == META_VIEWPORT_OVERRIDE_ENABLED || - aMetaViewportOverride == META_VIEWPORT_OVERRIDE_DISABLED)) { - return NS_ERROR_INVALID_ARG; - } - - mMetaViewportOverride = aMetaViewportOverride; - - // Inform our presShell that it needs to re-check its need for a viewport - // override. - if (RefPtr<PresShell> presShell = GetPresShell()) { - presShell->MaybeRecreateMobileViewportManager(true); - } - - return NS_OK; -} - /* virtual */ int32_t nsDocShell::ItemType() { return mItemType; } @@ -2586,10 +2555,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) { value = false; } SetAllowDNSPrefetch(mAllowDNSPrefetch && value); - - // We don't need to inherit metaViewportOverride, because the viewport - // is only relevant for the outermost nsDocShell, not for any iframes - // like this that might be embedded within it. } nsCOMPtr<nsIURIContentListener> parentURIListener(do_GetInterface(parent)); @@ -8689,24 +8654,18 @@ nsresult nsDocShell::HandleSameDocumentNavigation( } } - auto isLoadableViaInternet = [](nsIURI* uri) { - return (uri && (net::SchemeIsHTTP(uri) || net::SchemeIsHTTPS(uri))); - }; - - if (isLoadableViaInternet(principalURI) && - isLoadableViaInternet(mCurrentURI) && isLoadableViaInternet(newURI)) { - nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); - if (!NS_SUCCEEDED( - ssm->CheckSameOriginURI(newURI, principalURI, false, false)) || - !NS_SUCCEEDED(ssm->CheckSameOriginURI(mCurrentURI, principalURI, - false, false))) { - MOZ_LOG(gSHLog, LogLevel::Debug, - ("nsDocShell[%p]: possible violation of the same origin policy " - "during same document navigation", - this)); - aSameDocument = false; - return NS_OK; - } + if (nsScriptSecurityManager::IsHttpOrHttpsAndCrossOrigin(principalURI, + newURI) || + nsScriptSecurityManager::IsHttpOrHttpsAndCrossOrigin(principalURI, + mCurrentURI) || + nsScriptSecurityManager::IsHttpOrHttpsAndCrossOrigin(mCurrentURI, + newURI)) { + aSameDocument = false; + MOZ_LOG(gSHLog, LogLevel::Debug, + ("nsDocShell[%p]: possible violation of the same origin policy " + "during same document navigation", + this)); + return NS_OK; } } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 82ac6c9ab9..f01e3426c4 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -1267,10 +1267,6 @@ class nsDocShell final : public nsDocLoader, uint32_t mLoadType; uint32_t mFailedLoadType; - // Whether or not handling of the <meta name="viewport"> tag is overridden. - // Possible values are defined as constants in nsIDocShell.idl. - MetaViewportOverride mMetaViewportOverride; - // See WindowGlobalParent::mSingleChannelId. mozilla::Maybe<uint64_t> mSingleChannelId; uint32_t mRequestForBlockingFromBFCacheCount = 0; diff --git a/docshell/base/nsDocShellLoadState.cpp b/docshell/base/nsDocShellLoadState.cpp index 587617e73d..b3812eedd3 100644 --- a/docshell/base/nsDocShellLoadState.cpp +++ b/docshell/base/nsDocShellLoadState.cpp @@ -901,6 +901,14 @@ void nsDocShellLoadState::SetFileName(const nsAString& aFileName) { mFileName = aFileName; } +void nsDocShellLoadState::SetRemoteTypeOverride( + const nsCString& aRemoteTypeOverride) { + MOZ_DIAGNOSTIC_ASSERT( + NS_IsAboutBlank(mURI), + "Should only have aRemoteTypeOverride for about:blank URIs"); + mRemoteTypeOverride = mozilla::Some(aRemoteTypeOverride); +} + const nsCString& nsDocShellLoadState::GetEffectiveTriggeringRemoteType() const { // Consider non-errorpage loads from session history as being triggred by the // parent process, as we'll validate them against the history entry. diff --git a/docshell/base/nsDocShellLoadState.h b/docshell/base/nsDocShellLoadState.h index a34ca1b54b..8a8aad5a2c 100644 --- a/docshell/base/nsDocShellLoadState.h +++ b/docshell/base/nsDocShellLoadState.h @@ -323,9 +323,7 @@ class nsDocShellLoadState final { return mRemoteTypeOverride; } - void SetRemoteTypeOverride(const nsCString& aRemoteTypeOverride) { - mRemoteTypeOverride = mozilla::Some(aRemoteTypeOverride); - } + void SetRemoteTypeOverride(const nsCString& aRemoteTypeOverride); void SetWasSchemelessInput(bool aWasSchemelessInput) { mWasSchemelessInput = aWasSchemelessInput; diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 21f09a517e..024c0f544c 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -279,7 +279,7 @@ interface nsIDocShell : nsIDocShellTreeItem * next element in the parent should be returned. Returns true if focus was * successfully taken by the tree owner. */ - bool tabToTreeOwner(in boolean forward, in boolean forDocumentNavigation); + boolean tabToTreeOwner(in boolean forward, in boolean forDocumentNavigation); /** * Current busy state for DocShell @@ -522,7 +522,7 @@ interface nsIDocShell : nsIDocShellTreeItem * @param end timestamp when reflow ended, in milliseconds since * navigationStart (accurate to 1/1000 of a ms) */ - [noscript] void notifyReflowObservers(in bool interruptible, + [noscript] void notifyReflowObservers(in boolean interruptible, in DOMHighResTimeStamp start, in DOMHighResTimeStamp end); @@ -553,7 +553,7 @@ interface nsIDocShell : nsIDocShellTreeItem * True iff asynchronous panning and zooming is enabled for this * docshell. */ - readonly attribute bool asyncPanZoomEnabled; + readonly attribute boolean asyncPanZoomEnabled; /** * Indicates whether the UI may enable the character encoding menu. The UI @@ -595,8 +595,8 @@ interface nsIDocShell : nsIDocShellTreeItem * without any actual visual representation. They have to be marked * at construction time, to avoid any painting activity. */ - [noscript, notxpcom] bool IsInvisible(); - [noscript, notxpcom] void SetInvisible(in bool aIsInvisibleDocshell); + [noscript, notxpcom] boolean IsInvisible(); + [noscript, notxpcom] void SetInvisible(in boolean aIsInvisibleDocshell); /** * Get the script global for the document in this docshell. @@ -646,31 +646,6 @@ interface nsIDocShell : nsIDocShellTreeItem [noscript,nostdcall,notxpcom] nsCommandManager GetCommandManager(); - cenum MetaViewportOverride: 8 { - /** - * Override platform/pref default behaviour and force-disable support for - * <meta name="viewport">. - */ - META_VIEWPORT_OVERRIDE_DISABLED = 0, - /** - * Override platform/pref default behaviour and force-enable support for - * <meta name="viewport">. - */ - META_VIEWPORT_OVERRIDE_ENABLED = 1, - /** - * Don't override the platform/pref default behaviour for support for - * <meta name="viewport">. - */ - META_VIEWPORT_OVERRIDE_NONE = 2, - }; - - /** - * This allows chrome to override the default choice of whether the - * <meta name="viewport"> tag is respected in a specific docshell. - * Possible values are listed above. - */ - [infallible, setter_can_run_script] attribute nsIDocShell_MetaViewportOverride metaViewportOverride; - /** * Attribute that determines whether tracking protection is enabled. */ @@ -704,7 +679,7 @@ interface nsIDocShell : nsIDocShellTreeItem * Returns true if the current load is a forced reload, * e.g. started by holding shift whilst triggering reload. */ - readonly attribute bool isForceReloading; + readonly attribute boolean isForceReloading; Array<float> getColorMatrix(); diff --git a/docshell/base/nsIDocShellTreeOwner.idl b/docshell/base/nsIDocShellTreeOwner.idl index db6faa59c9..d16257f8a1 100644 --- a/docshell/base/nsIDocShellTreeOwner.idl +++ b/docshell/base/nsIDocShellTreeOwner.idl @@ -109,5 +109,5 @@ interface nsIDocShellTreeOwner : nsISupports Returns true if there is a primary content shell or a primary remote tab. */ - readonly attribute bool hasPrimaryContent; + readonly attribute boolean hasPrimaryContent; }; diff --git a/docshell/base/nsIPrivacyTransitionObserver.idl b/docshell/base/nsIPrivacyTransitionObserver.idl index c85d468d33..b0dbc74c77 100644 --- a/docshell/base/nsIPrivacyTransitionObserver.idl +++ b/docshell/base/nsIPrivacyTransitionObserver.idl @@ -7,5 +7,5 @@ [scriptable, function, uuid(b4b1449d-0ef0-47f5-b62e-adc57fd49702)] interface nsIPrivacyTransitionObserver : nsISupports { - void privateModeChanged(in bool enabled); + void privateModeChanged(in boolean enabled); }; diff --git a/docshell/base/nsIURIFixup.idl b/docshell/base/nsIURIFixup.idl index 2261c0cb40..23fa4ee296 100644 --- a/docshell/base/nsIURIFixup.idl +++ b/docshell/base/nsIURIFixup.idl @@ -200,5 +200,5 @@ interface nsIURIFixup : nsISupports * * @param aDomain A domain name to query. */ - bool isDomainKnown(in AUTF8String aDomain); + boolean isDomainKnown(in AUTF8String aDomain); }; diff --git a/docshell/build/components.conf b/docshell/build/components.conf index 691277a0bb..bcc6542d67 100644 --- a/docshell/build/components.conf +++ b/docshell/build/components.conf @@ -16,6 +16,7 @@ about_pages = [ 'crashgpu', 'crashextensions', 'credits', + 'fingerprinting', 'httpsonlyerror', 'license', 'logging', diff --git a/docshell/shistory/nsISHEntry.idl b/docshell/shistory/nsISHEntry.idl index 1d7427f581..6f682758d4 100644 --- a/docshell/shistory/nsISHEntry.idl +++ b/docshell/shistory/nsISHEntry.idl @@ -331,14 +331,14 @@ interface nsISHEntry : nsISupports in nsIURI originalURI, in nsIURI resultPrincipalURI, in nsIURI unstrippedURI, - in bool loadReplace, + in boolean loadReplace, in nsIReferrerInfo referrerInfo, in AString srcdoc, - in bool srcdocEntry, + in boolean srcdocEntry, in nsIURI baseURI, - in bool saveLayoutState, - in bool expired, - in bool userActivation); + in boolean saveLayoutState, + in boolean expired, + in boolean userActivation); nsISHEntry clone(); @@ -413,7 +413,7 @@ interface nsISHEntry : nsISupports * Add a new child SHEntry. If offset is -1 adds to the end of the list. */ void AddChild(in nsISHEntry aChild, in long aOffset, - [optional,default(false)] in bool aUseRemoteSubframes); + [optional,default(false)] in boolean aUseRemoteSubframes); /** * Remove a child SHEntry. diff --git a/docshell/shistory/nsISHistory.idl b/docshell/shistory/nsISHistory.idl index 9ca237c670..ffdd1ff788 100644 --- a/docshell/shistory/nsISHistory.idl +++ b/docshell/shistory/nsISHistory.idl @@ -273,19 +273,19 @@ interface nsISHistory: nsISupports [notxpcom] void EnsureCorrectEntryAtCurrIndex(in nsISHEntry aEntry); - [notxpcom] void EvictDocumentViewersOrReplaceEntry(in nsISHEntry aNewSHEntry, in bool aReplace); + [notxpcom] void EvictDocumentViewersOrReplaceEntry(in nsISHEntry aNewSHEntry, in boolean aReplace); nsISHEntry createEntry(); - [noscript] void AddToRootSessionHistory(in bool aCloneChildren, in nsISHEntry aOSHE, + [noscript] void AddToRootSessionHistory(in boolean aCloneChildren, in nsISHEntry aOSHE, in BrowsingContext aRootBC, in nsISHEntry aEntry, in unsigned long aLoadType, - in bool aShouldPersist, + in boolean aShouldPersist, out MaybeInt32 aPreviousEntryIndex, out MaybeInt32 aLoadedEntryIndex); [noscript] void AddChildSHEntryHelper(in nsISHEntry aCloneRef, in nsISHEntry aNewEntry, - in BrowsingContext aRootBC, in bool aCloneChildren); + in BrowsingContext aRootBC, in boolean aCloneChildren); [noscript, notxpcom] boolean isEmptyOrHasEntriesForSingleTopLevelPage(); }; diff --git a/docshell/test/browser/browser.toml b/docshell/test/browser/browser.toml index bcda46fd2e..ddea8bcc01 100644 --- a/docshell/test/browser/browser.toml +++ b/docshell/test/browser/browser.toml @@ -286,6 +286,12 @@ support-files = ["head_browser_onbeforeunload.js"] ["browser_onbeforeunload_navigation.js"] skip-if = ["os == 'win' && !debug"] # bug 1300351 +["browser_onbeforeunload_nested_with_delay.js"] +support-files = [ + "file_onbeforeunload_nested_inner.html", + "file_onbeforeunload_nested_outer.html", +] + ["browser_onbeforeunload_parent.js"] support-files = ["head_browser_onbeforeunload.js"] diff --git a/docshell/test/browser/browser_bug1673702.js b/docshell/test/browser/browser_bug1673702.js index c32c38fe45..f87a671900 100644 --- a/docshell/test/browser/browser_bug1673702.js +++ b/docshell/test/browser/browser_bug1673702.js @@ -18,7 +18,7 @@ add_task(async function test_backAndReload() { await BrowserTestUtils.browserStopped(browser); info("Reload."); - BrowserReload(); + BrowserCommands.reload(); await BrowserTestUtils.waitForLocationChange(gBrowser); is(browser.documentURI.spec, DUMMY); diff --git a/docshell/test/browser/browser_bug1769189.js b/docshell/test/browser/browser_bug1769189.js index 08cb4f9002..823f76c678 100644 --- a/docshell/test/browser/browser_bug1769189.js +++ b/docshell/test/browser/browser_bug1769189.js @@ -20,7 +20,7 @@ add_task(async function test_beforeUnload_and_replaceState() { browser, "pageshow" ); - BrowserReload(); + BrowserCommands.reload(); await awaitPageShow; let updatedState = await SpecialPowers.spawn(browser, [], () => { diff --git a/docshell/test/browser/browser_onbeforeunload_nested_with_delay.js b/docshell/test/browser/browser_onbeforeunload_nested_with_delay.js new file mode 100644 index 0000000000..409c73d0b7 --- /dev/null +++ b/docshell/test/browser/browser_onbeforeunload_nested_with_delay.js @@ -0,0 +1,58 @@ +"use strict"; + +add_task(async function () { + const outer = + "http://mochi.test:8888/browser/docshell/test/browser/file_onbeforeunload_nested_outer.html"; + await BrowserTestUtils.withNewTab(outer, async browser => { + let inner = browser.browsingContext.children[0]; + + // Install a beforeunload event handler that resolves a promise. + await SpecialPowers.spawn(inner, [], () => { + let { promise, resolve } = Promise.withResolvers(); + content.addEventListener( + "beforeunload", + e => { + e.preventDefault(); + resolve(); + }, + { + once: true, + } + ); + content.beforeunloadPromise = promise; + }); + + // Get the promise for the beforeunload handler so we can wait for it. + let beforeunloadFired = SpecialPowers.spawn( + browser.browsingContext.children[0], + [], + () => { + return content.beforeunloadPromise; + } + ); + + // Register whether a load has started. + let loaded = BrowserTestUtils.browserLoaded(browser).then(() => "loaded"); + + // This is rather fragile, but we need to make sure we don't start a + // speculative load in the parent so let's give it the time to be done. + let timeout = new Promise(resolve => + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(() => resolve("timeout"), 3000) + ); + + // Need to add some user interaction for beforeunload. + await BrowserTestUtils.synthesizeMouse("body", 0, 0, {}, inner, true); + + // Try to start a speculative load in the parent. + BrowserTestUtils.startLoadingURIString(browser, "https://example.com/"); + + await beforeunloadFired; + + is( + await Promise.race([loaded, timeout]), + "timeout", + "Timed out because the load was blocked by beforeunload." + ); + }); +}); diff --git a/docshell/test/browser/file_onbeforeunload_nested_inner.html b/docshell/test/browser/file_onbeforeunload_nested_inner.html new file mode 100644 index 0000000000..d9568d142b --- /dev/null +++ b/docshell/test/browser/file_onbeforeunload_nested_inner.html @@ -0,0 +1,3 @@ +<body> + <div>inner</div> +</body> diff --git a/docshell/test/browser/file_onbeforeunload_nested_outer.html b/docshell/test/browser/file_onbeforeunload_nested_outer.html new file mode 100644 index 0000000000..7689281eca --- /dev/null +++ b/docshell/test/browser/file_onbeforeunload_nested_outer.html @@ -0,0 +1,3 @@ +<body> +<iframe src="http://example.org/browser/docshell/test/browser/file_onbeforeunload_nested_inner.html"></iframe> +</body> diff --git a/docshell/test/iframesandbox/file_marquee_event_handlers.html b/docshell/test/iframesandbox/file_marquee_event_handlers.html deleted file mode 100644 index 13ee31ddb7..0000000000 --- a/docshell/test/iframesandbox/file_marquee_event_handlers.html +++ /dev/null @@ -1,17 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> -<meta charset="utf-8"> -<title>Test marquee attribute event handlers in iframe sandbox</title> -</head> -<body> - <!-- Note that the width here is slightly longer than the contents, to make - sure we bounce and finish very quickly. --> - <marquee loop="2" width="145" behavior="alternate" truespeed scrolldelay="1" - onstart="parent.postMessage(window.name + ' marquee onstart', '*');" - onbounce="parent.postMessage(window.name + ' marquee onbounce', '*');" - onfinish="parent.postMessage(window.name + ' marquee onfinish', '*');"> - Will bounce and finish - </marquee> -</body> -</html> diff --git a/docshell/test/iframesandbox/mochitest.toml b/docshell/test/iframesandbox/mochitest.toml index a8bf4b1d72..97e6f76170 100644 --- a/docshell/test/iframesandbox/mochitest.toml +++ b/docshell/test/iframesandbox/mochitest.toml @@ -1,7 +1,6 @@ [DEFAULT] support-files = [ "file_child_navigation_by_location.html", - "file_marquee_event_handlers.html", "file_other_auxiliary_navigation_by_location.html", "file_our_auxiliary_navigation_by_location.html", "file_parent_navigation_by_location.html", @@ -12,9 +11,6 @@ support-files = [ ["test_child_navigation_by_location.html"] -["test_marquee_event_handlers.html"] -skip-if = ["true"] # Bug 1455996 - ["test_other_auxiliary_navigation_by_location.html"] tags = "openwindow" diff --git a/docshell/test/iframesandbox/test_marquee_event_handlers.html b/docshell/test/iframesandbox/test_marquee_event_handlers.html deleted file mode 100644 index 80added8ab..0000000000 --- a/docshell/test/iframesandbox/test_marquee_event_handlers.html +++ /dev/null @@ -1,95 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=1277475 -html5 sandboxed iframe should not run marquee attribute event handlers without allow-scripts ---> -<head> -<meta charset="utf-8"> -<title>Test for Bug 1277475 - html5 sandboxed iframe should not run marquee attribute event handlers without allow-scripts</title> -<script src="/tests/SimpleTest/SimpleTest.js"></script> -<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1277475">Mozilla Bug 1277475</a> -<p id="display"></p> -<div id="content">Tests for Bug 1277475</div> - -<iframe id="if1" name="if1" src="file_marquee_event_handlers.html" - sandbox="allow-same-origin allow-forms allow-top-navigation allow-pointer-lock allow-orientation-lock allow-popups allow-modals allow-popups-to-escape-sandbox"> -</iframe> - -<iframe id="if2" name="if2" src="file_marquee_event_handlers.html" - sandbox="allow-scripts"></iframe> - -<script> - SimpleTest.waitForExplicitFinish(); - - var expectedMessages = new Set(); - var numberOfMessagesExpected = 4; - var unexpectedMessages = new Set(); - - window.onmessage = function(event) { - info(event.data + " message received"); - if (event.data.startsWith("if2") || event.data == "if1 chaser") { - expectedMessages.add(event.data); - if (expectedMessages.size == numberOfMessagesExpected) { - checkRecievedMessages(); - } - } else { - unexpectedMessages.add(event.data); - } - }; - - function checkRecievedMessages() { - // Check the expected messages explicitly as a cross-check. - ok(expectedMessages.has("if1 chaser"), - "if1 chaser message should have been received"); - ok(expectedMessages.has("if2 marquee onstart"), - "if2 marquee onstart should have run in iframe sandbox with allow-scripts"); - ok(expectedMessages.has("if2 marquee onbounce"), - "if2 marquee onbounce should have run in iframe sandbox with allow-scripts"); - ok(expectedMessages.has("if2 marquee onfinish"), - "if2 marquee onfinish should have run in iframe sandbox with allow-scripts"); - - unexpectedMessages.forEach( - (v) => { - ok(false, v + " should NOT have run in iframe sandbox without allow-scripts"); - } - ); - - SimpleTest.finish(); - } - - // If things are working properly the attribute event handlers won't run on - // the marquee in if1, so add our own capturing listeners on its window, so we - // know when they have fired. (These will run as we are not sandboxed.) - var if1FiredEvents = new Set(); - var if1NumberOfEventsExpected = 3; - var if1Win = document.getElementById("if1").contentWindow; - if1Win.addEventListener("start", () => { checkMarqueeEvent("start"); }, true); - if1Win.addEventListener("bounce", () => { checkMarqueeEvent("bounce"); }, true); - if1Win.addEventListener("finish", () => { checkMarqueeEvent("finish"); }, true); - - function checkMarqueeEvent(eventType) { - info("if1 event " + eventType + " fired"); - if1FiredEvents.add(eventType); - if (if1FiredEvents.size == if1NumberOfEventsExpected) { - // Only send the chasing message after a tick of the event loop to allow - // event handlers on the marquee to process. - SimpleTest.executeSoon(sendChasingMessage); - } - } - - function sendChasingMessage() { - // Add our own message listener to if1's window and echo back a chasing - // message to make sure that any messages from incorrectly run marquee - // attribute event handlers should have arrived before it. - if1Win.addEventListener("message", - (e) => { if1Win.parent.postMessage(e.data, "*"); }); - if1Win.postMessage("if1 chaser", "*"); - info("if1 chaser message sent"); - } -</script> -</body> -</html> |