From b06a2c00a1a2f3bca10df3468c2f7beac06eca9e Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Mon, 24 Aug 2020 06:38:09 +0000 Subject: [PATCH 01/56] Bug 1620830 [Linux] Don't create DMABUFTextureData when dmabuf surface creation fails, r=sotaro Differential Revision: https://phabricator.services.mozilla.com/D87876 --- gfx/layers/opengl/DMABUFTextureClientOGL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gfx/layers/opengl/DMABUFTextureClientOGL.cpp b/gfx/layers/opengl/DMABUFTextureClientOGL.cpp index 816ec2f8cddd..00dca94b3879 100644 --- a/gfx/layers/opengl/DMABUFTextureClientOGL.cpp +++ b/gfx/layers/opengl/DMABUFTextureClientOGL.cpp @@ -35,6 +35,10 @@ DMABUFTextureData::~DMABUFTextureData() = default; } RefPtr surf = DMABufSurfaceRGBA::CreateDMABufSurface(aSize.width, aSize.height, flags); + if (!surf) { + NS_WARNING("DMABUFTextureData::Create() failed!"); + return nullptr; + } return new DMABUFTextureData(surf, aBackend); } From 4a9e44592e8b43a112ce1c0c8d4abf72e31ecbe3 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Thu, 20 Aug 2020 12:58:40 +0000 Subject: [PATCH 02/56] Bug 1649131 - Stop marking SessionHistoryInfo as moveonly. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D87036 --- docshell/base/nsDocShellLoadState.cpp | 2 +- dom/ipc/DOMTypes.ipdlh | 2 +- netwerk/ipc/NeckoChannelParams.ipdlh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docshell/base/nsDocShellLoadState.cpp b/docshell/base/nsDocShellLoadState.cpp index 7aab3c756cd3..475850f3647f 100644 --- a/docshell/base/nsDocShellLoadState.cpp +++ b/docshell/base/nsDocShellLoadState.cpp @@ -78,7 +78,7 @@ nsDocShellLoadState::nsDocShellLoadState( mChannelInitialized = aLoadState.ChannelInitialized(); if (aLoadState.loadingSessionHistoryInfo().isSome()) { mLoadingSessionHistoryInfo = MakeUnique( - aLoadState.loadingSessionHistoryInfo().value()); + aLoadState.loadingSessionHistoryInfo().ref()); } } diff --git a/dom/ipc/DOMTypes.ipdlh b/dom/ipc/DOMTypes.ipdlh index 56f36cea05db..aafdf79e313b 100644 --- a/dom/ipc/DOMTypes.ipdlh +++ b/dom/ipc/DOMTypes.ipdlh @@ -20,7 +20,7 @@ using struct mozilla::void_t using moveonly struct mozilla::SerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h"; -using moveonly mozilla::dom::LoadingSessionHistoryInfo +using class mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h"; using LayoutDeviceIntRect from "Units.h"; diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 1d58d9713184..7ba4fc4bfcb3 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -24,7 +24,7 @@ using class mozilla::TimeStamp from "mozilla/TimeStamp.h"; using refcounted class nsIPropertyBag2 from "mozilla/dom/PropertyBagUtils.h"; using refcounted class nsDOMNavigationTiming from "nsDOMNavigationTiming.h"; using nsILoadInfo::CrossOriginEmbedderPolicy from "nsILoadInfo.h"; -using moveonly mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h"; +using class mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h"; namespace mozilla { namespace net { From 1caf077d0b43820d33698f20f63983878c613a3b Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Sun, 23 Aug 2020 20:20:55 +0000 Subject: [PATCH 03/56] Bug 1649131 - Stop checking for an nsISHEntry in nsDocShellLoadState as a sign of a load from history. r=smaug Checking for an nsISHEntry doesn't work anymore with session history in the parent. For that we can check that the loading session history info's mIsLoadFromSessionHistory is true. If there is no loading session history info we can fall back to the old way of checking for a non-null nsISHEntry (which will only ever be true if session history in the parent is turned off). Differential Revision: https://phabricator.services.mozilla.com/D87037 --- docshell/base/nsDocShell.cpp | 108 +++++++++++----------- docshell/base/nsDocShellLoadState.cpp | 15 ++- docshell/base/nsDocShellLoadState.h | 3 + docshell/shistory/SessionHistoryEntry.cpp | 4 +- docshell/shistory/SessionHistoryEntry.h | 4 +- 5 files changed, 77 insertions(+), 57 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 4132d9e03ff3..a9babdd57bc0 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -801,7 +801,7 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) { ("nsDocShell[%p]: loading %s with flags 0x%08x", this, aLoadState->URI()->GetSpecOrDefault().get(), aLoadState->LoadFlags())); - if (!aLoadState->SHEntry() && + if (!aLoadState->LoadIsFromSessionHistory() && !LOAD_TYPE_HAS_FLAGS(aLoadState->LoadType(), LOAD_FLAGS_REPLACE_HISTORY)) { // This is possibly a subframe, so handle it accordingly. @@ -811,7 +811,7 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) { MaybeHandleSubframeHistory(aLoadState); } - if (aLoadState->SHEntry()) { + if (aLoadState->LoadIsFromSessionHistory()) { #ifdef DEBUG MOZ_LOG(gDocShellLog, LogLevel::Debug, ("nsDocShell[%p]: loading from session history", this)); @@ -849,8 +849,9 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) { "Typehint should be null when calling InternalLoad from LoadURI"); MOZ_ASSERT(aLoadState->FileName().IsVoid(), "FileName should be null when calling InternalLoad from LoadURI"); - MOZ_ASSERT(aLoadState->SHEntry() == nullptr, - "SHEntry should be null when calling InternalLoad from LoadURI"); + MOZ_ASSERT(!aLoadState->LoadIsFromSessionHistory(), + "Shouldn't be loading from an entry when calling InternalLoad " + "from LoadURI"); rv = InternalLoad(aLoadState); NS_ENSURE_SUCCESS(rv, rv); @@ -938,14 +939,14 @@ void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) { if (parentBusy & BUSY_FLAGS_BUSY || selfBusy & BUSY_FLAGS_BUSY) { aLoadState->SetLoadType(LOAD_NORMAL_REPLACE); - aLoadState->SetSHEntry(nullptr); + aLoadState->ClearLoadIsFromSessionHistory(); } return; } // This is a newly created frame. Check for exception cases first. // By default the subframe will inherit the parent's loadType. - if (aLoadState->SHEntry() && + if (aLoadState->LoadIsFromSessionHistory() && (parentLoadType == LOAD_NORMAL || parentLoadType == LOAD_LINK || parentLoadType == LOAD_NORMAL_EXTERNAL)) { // The parent was loaded normally. In this case, this *brand new* @@ -958,14 +959,14 @@ void nsDocShell::MaybeHandleSubframeHistory(nsDocShellLoadState* aLoadState) { parentDS->GetIsExecutingOnLoadHandler(&inOnLoadHandler); if (inOnLoadHandler) { aLoadState->SetLoadType(LOAD_NORMAL_REPLACE); - aLoadState->SetSHEntry(nullptr); + aLoadState->ClearLoadIsFromSessionHistory(); } } else if (parentLoadType == LOAD_REFRESH) { // Clear shEntry. For refresh loads, we have to load // what comes through the pipe, not what's in history. - aLoadState->SetSHEntry(nullptr); + aLoadState->ClearLoadIsFromSessionHistory(); } else if ((parentLoadType == LOAD_BYPASS_HISTORY) || - (aLoadState->SHEntry() && + (aLoadState->LoadIsFromSessionHistory() && ((parentLoadType & LOAD_CMD_HISTORY) || (parentLoadType == LOAD_RELOAD_NORMAL) || (parentLoadType == LOAD_RELOAD_CHARSET_CHANGE) || @@ -5432,7 +5433,7 @@ nsresult nsDocShell::Embed(nsIContentViewer* aContentViewer, } else { RefPtr rootSH = GetRootSessionHistory(); if (rootSH) { - if (!loadingEntry->mIsLoadFromSessionHistory) { + if (!loadingEntry->mLoadIsFromSessionHistory) { changeID = rootSH->AddPendingHistoryChange(); } else { // This is a load from session history, so we can update @@ -8229,7 +8230,7 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) { // LOAD_LINK. MOZ_ASSERT(aLoadState->LoadType() == LOAD_LINK || aLoadState->LoadType() == LOAD_NORMAL_REPLACE); - MOZ_ASSERT(!aLoadState->SHEntry()); + MOZ_ASSERT(!aLoadState->LoadIsFromSessionHistory()); MOZ_ASSERT(aLoadState->FirstParty()); // Windowwatcher will assume this. RefPtr loadState = @@ -8359,7 +8360,7 @@ bool nsDocShell::IsSameDocumentNavigation(nsDocShellLoadState* aLoadState, } } - if (mOSHE && aLoadState->SHEntry()) { + if (mOSHE && aLoadState->LoadIsFromSessionHistory()) { // We're doing a history load. mOSHE->SharesDocumentWith(aLoadState->SHEntry(), @@ -8499,7 +8500,7 @@ nsresult nsDocShell::HandleSameDocumentNavigation( // Link our new SHEntry to the old SHEntry's back/forward // cache data, since the two SHEntries correspond to the // same document. - if (mLoadingEntry && !mLoadingEntry->mIsLoadFromSessionHistory) { + if (mLoadingEntry && !mLoadingEntry->mLoadIsFromSessionHistory) { // If we're not doing a history load, scroll restoration // should be inherited from the previous session history entry. // XXX This needs most probably tweaks once fragment navigation is fixed @@ -8508,7 +8509,7 @@ nsresult nsDocShell::HandleSameDocumentNavigation( scrollRestorationIsManual); } if (mLSHE) { - if (!aLoadState->SHEntry()) { + if (!aLoadState->LoadIsFromSessionHistory()) { // If we're not doing a history load, scroll restoration // should be inherited from the previous session history entry. SetScrollRestorationIsManualOnHistoryEntry(mLSHE, @@ -8520,7 +8521,7 @@ nsresult nsDocShell::HandleSameDocumentNavigation( } // If we're doing a history load, use its scroll restoration state. - if (aLoadState->SHEntry()) { + if (aLoadState->LoadIsFromSessionHistory()) { DebugOnly rv = aLoadState->SHEntry()->GetScrollRestorationIsManual( &scrollRestorationIsManual); @@ -8910,7 +8911,8 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState) { if (mLoadType != LOAD_ERROR_PAGE) { SetHistoryEntryAndUpdateBC(Some(aLoadState->SHEntry()), Nothing()); - if (aLoadState->SHEntry()) { + if (aLoadState->LoadIsFromSessionHistory() && + !StaticPrefs::fission_sessionHistoryInParent()) { // We're making history navigation or a reload. Make sure our history ID // points to the same ID as SHEntry's docshell ID. aLoadState->SHEntry()->GetDocshellID(mHistoryID); @@ -8922,7 +8924,8 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState) { mSavingOldViewer = savePresentation; // If we have a saved content viewer in history, restore and show it now. - if (aLoadState->SHEntry() && (mLoadType & LOAD_CMD_HISTORY)) { + if (aLoadState->LoadIsFromSessionHistory() && + (mLoadType & LOAD_CMD_HISTORY)) { // https://html.spec.whatwg.org/#history-traversal: // To traverse the history // "If entry has a different Document object than the current entry, then @@ -8934,47 +8937,48 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState) { if (shistory) { shistory->RemovePendingHistoryNavigations(); } - - // It's possible that the previous viewer of mContentViewer is the - // viewer that will end up in aLoadState->SHEntry() when it gets closed. If - // that's the case, we need to go ahead and force it into its shentry so we - // can restore it. - if (mContentViewer) { - nsCOMPtr prevViewer = - mContentViewer->GetPreviousViewer(); - if (prevViewer) { + if (!StaticPrefs::fission_sessionHistoryInParent()) { + // It's possible that the previous viewer of mContentViewer is the + // viewer that will end up in aLoadState->SHEntry() when it gets closed. + // If that's the case, we need to go ahead and force it into its shentry + // so we can restore it. + if (mContentViewer) { + nsCOMPtr prevViewer = + mContentViewer->GetPreviousViewer(); + if (prevViewer) { #ifdef DEBUG - nsCOMPtr prevPrevViewer = - prevViewer->GetPreviousViewer(); - NS_ASSERTION(!prevPrevViewer, "Should never have viewer chain here"); + nsCOMPtr prevPrevViewer = + prevViewer->GetPreviousViewer(); + NS_ASSERTION(!prevPrevViewer, "Should never have viewer chain here"); #endif - nsCOMPtr viewerEntry; - prevViewer->GetHistoryEntry(getter_AddRefs(viewerEntry)); - if (viewerEntry == aLoadState->SHEntry()) { - // Make sure this viewer ends up in the right place - mContentViewer->SetPreviousViewer(nullptr); - prevViewer->Destroy(); + nsCOMPtr viewerEntry; + prevViewer->GetHistoryEntry(getter_AddRefs(viewerEntry)); + if (viewerEntry == aLoadState->SHEntry()) { + // Make sure this viewer ends up in the right place + mContentViewer->SetPreviousViewer(nullptr); + prevViewer->Destroy(); + } } } - } - nsCOMPtr oldEntry = mOSHE; - bool restoring; - rv = RestorePresentation(aLoadState->SHEntry(), &restoring); - if (restoring) { - Telemetry::Accumulate(Telemetry::BFCACHE_PAGE_RESTORED, true); - return rv; - } - Telemetry::Accumulate(Telemetry::BFCACHE_PAGE_RESTORED, false); - - // We failed to restore the presentation, so clean up. - // Both the old and new history entries could potentially be in - // an inconsistent state. - if (NS_FAILED(rv)) { - if (oldEntry) { - oldEntry->SyncPresentationState(); + nsCOMPtr oldEntry = mOSHE; + bool restoring; + rv = RestorePresentation(aLoadState->SHEntry(), &restoring); + if (restoring) { + Telemetry::Accumulate(Telemetry::BFCACHE_PAGE_RESTORED, true); + return rv; } + Telemetry::Accumulate(Telemetry::BFCACHE_PAGE_RESTORED, false); - aLoadState->SHEntry()->SyncPresentationState(); + // We failed to restore the presentation, so clean up. + // Both the old and new history entries could potentially be in + // an inconsistent state. + if (NS_FAILED(rv)) { + if (oldEntry) { + oldEntry->SyncPresentationState(); + } + + aLoadState->SHEntry()->SyncPresentationState(); + } } } diff --git a/docshell/base/nsDocShellLoadState.cpp b/docshell/base/nsDocShellLoadState.cpp index 475850f3647f..31a1fa543abd 100644 --- a/docshell/base/nsDocShellLoadState.cpp +++ b/docshell/base/nsDocShellLoadState.cpp @@ -530,12 +530,25 @@ nsDocShellLoadState::GetLoadingSessionHistoryInfo() const { void nsDocShellLoadState::SetLoadIsFromSessionHistory( int32_t aRequestedIndex, int32_t aSessionHistoryLength) { if (mLoadingSessionHistoryInfo) { - mLoadingSessionHistoryInfo->mIsLoadFromSessionHistory = true; + mLoadingSessionHistoryInfo->mLoadIsFromSessionHistory = true; mLoadingSessionHistoryInfo->mRequestedIndex = aRequestedIndex; mLoadingSessionHistoryInfo->mSessionHistoryLength = aSessionHistoryLength; } } +void nsDocShellLoadState::ClearLoadIsFromSessionHistory() { + if (mLoadingSessionHistoryInfo) { + mLoadingSessionHistoryInfo->mLoadIsFromSessionHistory = false; + } + mSHEntry = nullptr; +} + +bool nsDocShellLoadState::LoadIsFromSessionHistory() const { + return mLoadingSessionHistoryInfo + ? mLoadingSessionHistoryInfo->mLoadIsFromSessionHistory + : !!mSHEntry; +} + const nsString& nsDocShellLoadState::Target() const { return mTarget; } void nsDocShellLoadState::SetTarget(const nsAString& aTarget) { diff --git a/docshell/base/nsDocShellLoadState.h b/docshell/base/nsDocShellLoadState.h index 678919310a02..942d2c4ab7af 100644 --- a/docshell/base/nsDocShellLoadState.h +++ b/docshell/base/nsDocShellLoadState.h @@ -144,6 +144,8 @@ class nsDocShellLoadState final { void SetLoadingSessionHistoryInfo( const mozilla::dom::LoadingSessionHistoryInfo& aLoadingInfo); + bool LoadIsFromSessionHistory() const; + const nsString& Target() const; void SetTarget(const nsAString& aTarget); @@ -280,6 +282,7 @@ class nsDocShellLoadState final { void SetLoadIsFromSessionHistory(int32_t aRequestedIndex, int32_t aSessionHistoryLength); + void ClearLoadIsFromSessionHistory(); protected: // Destructor can't be defaulted or inlined, as header doesn't have all type diff --git a/docshell/shistory/SessionHistoryEntry.cpp b/docshell/shistory/SessionHistoryEntry.cpp index f218387ce465..ef368ee8a4d9 100644 --- a/docshell/shistory/SessionHistoryEntry.cpp +++ b/docshell/shistory/SessionHistoryEntry.cpp @@ -1010,7 +1010,7 @@ void IPDLParamTraits::Write( WriteIPDLParam(aMsg, aActor, info.mScrollRestorationIsManual); WriteIPDLParam(aMsg, aActor, info.mPersist); WriteIPDLParam(aMsg, aActor, aParam.mLoadId); - WriteIPDLParam(aMsg, aActor, aParam.mIsLoadFromSessionHistory); + WriteIPDLParam(aMsg, aActor, aParam.mLoadIsFromSessionHistory); WriteIPDLParam(aMsg, aActor, aParam.mRequestedIndex); WriteIPDLParam(aMsg, aActor, aParam.mSessionHistoryLength); } @@ -1041,7 +1041,7 @@ bool IPDLParamTraits::Read( !ReadIPDLParam(aMsg, aIter, aActor, &info.mPersist) || !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadId) || !ReadIPDLParam(aMsg, aIter, aActor, - &aResult->mIsLoadFromSessionHistory) || + &aResult->mLoadIsFromSessionHistory) || !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRequestedIndex) || !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSessionHistoryLength)) { aActor->FatalError("Error reading fields for SessionHistoryInfo"); diff --git a/docshell/shistory/SessionHistoryEntry.h b/docshell/shistory/SessionHistoryEntry.h index 340c82d653a4..cf6d661a65a2 100644 --- a/docshell/shistory/SessionHistoryEntry.h +++ b/docshell/shistory/SessionHistoryEntry.h @@ -111,9 +111,9 @@ struct LoadingSessionHistoryInfo { // an nsISHEntry in the nsDocShellLoadState and access to the nsISHistory, // but session-history-in-parent needs to pass needed information explicitly // to the relevant child process. - bool mIsLoadFromSessionHistory = false; + bool mLoadIsFromSessionHistory = false; // mRequestedIndex and mSessionHistoryLength are relevant - // only if mIsLoadFromSessionHistory is true. + // only if mLoadIsFromSessionHistory is true. int32_t mRequestedIndex = -1; int32_t mSessionHistoryLength = 0; }; From e08ef282076c7137cc0d429b01750b121c43d29d Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Sun, 23 Aug 2020 17:36:10 +0000 Subject: [PATCH 04/56] Bug 1649131 - Store some data in a pseudo shared state in the child process. r=smaug The entries in the parent process stores some data in a shared state for some of the entries that share a document. We also need to store some of this data in the info objects in the child process, but it doesn't make sense to have it be shared: the data shouldn't be mutated in the child process, and we probably only have one of the info objects anyway. This adds a structure that holds the shared data for an info object in the child process, but without actually sharing it. As we use info objects in both parent and child, we hold a void pointer that's a strong reference to a shared state in the parent process, and an owning pointer to the pseudo-shared state in the child process. Differential Revision: https://phabricator.services.mozilla.com/D87038 --- docshell/shistory/SessionHistoryEntry.cpp | 233 +++++++++++++++------- docshell/shistory/SessionHistoryEntry.h | 53 +++-- docshell/shistory/nsSHEntryShared.cpp | 18 +- docshell/shistory/nsSHEntryShared.h | 75 +++++-- docshell/shistory/nsSHistory.cpp | 1 - 5 files changed, 260 insertions(+), 120 deletions(-) diff --git a/docshell/shistory/SessionHistoryEntry.cpp b/docshell/shistory/SessionHistoryEntry.cpp index ef368ee8a4d9..b335503f8ad7 100644 --- a/docshell/shistory/SessionHistoryEntry.cpp +++ b/docshell/shistory/SessionHistoryEntry.cpp @@ -23,15 +23,16 @@ SessionHistoryInfo::SessionHistoryInfo(nsDocShellLoadState* aLoadState, mReferrerInfo(aLoadState->GetReferrerInfo()), mPostData(aLoadState->PostDataStream()), mLoadType(aLoadState->LoadType()), - mScrollPositionX(0), - mScrollPositionY(0), mSrcdocData(aLoadState->SrcdocData()), mBaseURI(aLoadState->BaseURI()), mLoadReplace(aLoadState->LoadReplace()), - mURIWasModified(false), /* FIXME Should this be aLoadState->IsSrcdocLoad()? */ mIsSrcdocEntry(!aLoadState->SrcdocData().IsEmpty()), - mScrollRestorationIsManual(false) { + mSharedState(SharedState::Create( + aLoadState->TriggeringPrincipal(), aLoadState->PrincipalToInherit(), + aLoadState->PartitionedPrincipalToInherit(), aLoadState->Csp(), + /* FIXME Is this correct? */ + aLoadState->TypeHint())) { MaybeUpdateTitleFromURI(); bool isNoStore = false; if (nsCOMPtr httpChannel = do_QueryInterface(aChannel)) { @@ -50,6 +51,79 @@ void SessionHistoryInfo::MaybeUpdateTitleFromURI() { } } +nsILayoutHistoryState* SessionHistoryInfo::GetLayoutHistoryState() { + return mSharedState.Get()->mLayoutHistoryState; +} + +void SessionHistoryInfo::SetLayoutHistoryState(nsILayoutHistoryState* aState) { + mSharedState.Get()->mLayoutHistoryState = aState; +} + +/* static */ +SessionHistoryInfo::SharedState SessionHistoryInfo::SharedState::Create( + nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, + nsIPrincipal* aPartitionedPrincipalToInherit, + nsIContentSecurityPolicy* aCsp, const nsACString& aContentType) { + if (XRE_IsParentProcess()) { + return SharedState(new SHEntrySharedParentState( + aTriggeringPrincipal, aPrincipalToInherit, + aPartitionedPrincipalToInherit, aCsp, aContentType)); + } + + // FIXME Pass the correct ID!!! + return SharedState(MakeUnique( + 0, aTriggeringPrincipal, aPrincipalToInherit, + aPartitionedPrincipalToInherit, aCsp, aContentType)); +} + +SessionHistoryInfo::SharedState::SharedState() { + if (XRE_IsParentProcess()) { + new (&mParent) + RefPtr(new SHEntrySharedParentState()); + } else { + new (&mChild) + UniquePtr(MakeUnique()); + } +} + +SessionHistoryInfo::SharedState::SharedState( + const SessionHistoryInfo::SharedState& aOther) { + if (XRE_IsParentProcess()) { + new (&mParent) RefPtr(aOther.mParent); + } else { + new (&mChild) UniquePtr( + MakeUnique(*aOther.mChild)); + } +} + +SessionHistoryInfo::SharedState::~SharedState() { + if (XRE_IsParentProcess()) { + mParent + .RefPtr::~RefPtr(); + } else { + mChild.UniquePtr::~UniquePtr(); + } +} + +SessionHistoryInfo::SharedState& SessionHistoryInfo::SharedState::operator=( + const SessionHistoryInfo::SharedState& aOther) { + if (this != &aOther) { + if (XRE_IsParentProcess()) { + mParent = aOther.mParent; + } else { + mChild = MakeUnique(*aOther.mChild); + } + } + return *this; +} + +SHEntrySharedState* SessionHistoryInfo::SharedState::Get() const { + if (XRE_IsParentProcess()) { + return mParent; + } + + return mChild.get(); +} static uint64_t gLoadingSessionHistoryInfoLoadId = 0; nsDataHashtable* @@ -86,22 +160,11 @@ void SessionHistoryEntry::RemoveLoadId(uint64_t aLoadId) { } SessionHistoryEntry::SessionHistoryEntry() - : mInfo(new SessionHistoryInfo()), - mSharedInfo(new SHEntrySharedParentState()), - mID(++gEntryID) {} + : mInfo(new SessionHistoryInfo()), mID(++gEntryID) {} SessionHistoryEntry::SessionHistoryEntry(nsDocShellLoadState* aLoadState, nsIChannel* aChannel) - : mInfo(new SessionHistoryInfo(aLoadState, aChannel)), - mSharedInfo(new SHEntrySharedParentState()), - mID(++gEntryID) { - mSharedInfo->mTriggeringPrincipal = aLoadState->TriggeringPrincipal(); - mSharedInfo->mPrincipalToInherit = aLoadState->PrincipalToInherit(); - mSharedInfo->mPartitionedPrincipalToInherit = - aLoadState->PartitionedPrincipalToInherit(); - mSharedInfo->mCsp = aLoadState->Csp(); - // FIXME Set remaining shared fields! -} + : mInfo(new SessionHistoryInfo(aLoadState, aChannel)), mID(++gEntryID) {} SessionHistoryEntry::~SessionHistoryEntry() { if (sLoadIdToEntry) { @@ -181,13 +244,13 @@ SessionHistoryEntry::SetTitle(const nsAString& aTitle) { NS_IMETHODIMP SessionHistoryEntry::GetIsSubFrame(bool* aIsSubFrame) { - *aIsSubFrame = mSharedInfo->mIsFrameNavigation; + *aIsSubFrame = SharedInfo()->mIsFrameNavigation; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::SetIsSubFrame(bool aIsSubFrame) { - mSharedInfo->mIsFrameNavigation = aIsSubFrame; + SharedInfo()->mIsFrameNavigation = aIsSubFrame; return NS_OK; } @@ -232,13 +295,13 @@ SessionHistoryEntry::SetContentViewer(nsIContentViewer* aContentViewer) { NS_IMETHODIMP SessionHistoryEntry::GetSticky(bool* aSticky) { - *aSticky = mSharedInfo->mSticky; + *aSticky = SharedInfo()->mSticky; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::SetSticky(bool aSticky) { - mSharedInfo->mSticky = aSticky; + SharedInfo()->mSticky = aSticky; return NS_OK; } @@ -283,7 +346,7 @@ NS_IMETHODIMP SessionHistoryEntry::GetLayoutHistoryState( nsILayoutHistoryState** aLayoutHistoryState) { nsCOMPtr layoutHistoryState = - mSharedInfo->mLayoutHistoryState; + SharedInfo()->mLayoutHistoryState; layoutHistoryState.forget(aLayoutHistoryState); return NS_OK; } @@ -291,7 +354,7 @@ SessionHistoryEntry::GetLayoutHistoryState( NS_IMETHODIMP SessionHistoryEntry::SetLayoutHistoryState( nsILayoutHistoryState* aLayoutHistoryState) { - mSharedInfo->mLayoutHistoryState = aLayoutHistoryState; + SharedInfo()->mLayoutHistoryState = aLayoutHistoryState; return NS_OK; } @@ -334,37 +397,37 @@ SessionHistoryEntry::SetID(uint32_t aID) { NS_IMETHODIMP SessionHistoryEntry::GetCacheKey(uint32_t* aCacheKey) { - *aCacheKey = mSharedInfo->mCacheKey; + *aCacheKey = SharedInfo()->mCacheKey; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::SetCacheKey(uint32_t aCacheKey) { - mSharedInfo->mCacheKey = aCacheKey; + SharedInfo()->mCacheKey = aCacheKey; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::GetSaveLayoutStateFlag(bool* aSaveLayoutStateFlag) { - *aSaveLayoutStateFlag = mSharedInfo->mSaveLayoutState; + *aSaveLayoutStateFlag = SharedInfo()->mSaveLayoutState; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::SetSaveLayoutStateFlag(bool aSaveLayoutStateFlag) { - mSharedInfo->mSaveLayoutState = aSaveLayoutStateFlag; + SharedInfo()->mSaveLayoutState = aSaveLayoutStateFlag; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::GetContentType(nsACString& aContentType) { - aContentType = mSharedInfo->mContentType; + aContentType = SharedInfo()->mContentType; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::SetContentType(const nsACString& aContentType) { - mSharedInfo->mContentType = aContentType; + SharedInfo()->mContentType = aContentType; return NS_OK; } @@ -384,7 +447,7 @@ NS_IMETHODIMP SessionHistoryEntry::GetTriggeringPrincipal( nsIPrincipal** aTriggeringPrincipal) { nsCOMPtr triggeringPrincipal = - mSharedInfo->mTriggeringPrincipal; + SharedInfo()->mTriggeringPrincipal; triggeringPrincipal.forget(aTriggeringPrincipal); return NS_OK; } @@ -392,20 +455,20 @@ SessionHistoryEntry::GetTriggeringPrincipal( NS_IMETHODIMP SessionHistoryEntry::SetTriggeringPrincipal( nsIPrincipal* aTriggeringPrincipal) { - mSharedInfo->mTriggeringPrincipal = aTriggeringPrincipal; + SharedInfo()->mTriggeringPrincipal = aTriggeringPrincipal; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit) { - nsCOMPtr principalToInherit = mSharedInfo->mPrincipalToInherit; + nsCOMPtr principalToInherit = SharedInfo()->mPrincipalToInherit; principalToInherit.forget(aPrincipalToInherit); return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit) { - mSharedInfo->mPrincipalToInherit = aPrincipalToInherit; + SharedInfo()->mPrincipalToInherit = aPrincipalToInherit; return NS_OK; } @@ -413,7 +476,7 @@ NS_IMETHODIMP SessionHistoryEntry::GetPartitionedPrincipalToInherit( nsIPrincipal** aPartitionedPrincipalToInherit) { nsCOMPtr partitionedPrincipalToInherit = - mSharedInfo->mPartitionedPrincipalToInherit; + SharedInfo()->mPartitionedPrincipalToInherit; partitionedPrincipalToInherit.forget(aPartitionedPrincipalToInherit); return NS_OK; } @@ -421,20 +484,20 @@ SessionHistoryEntry::GetPartitionedPrincipalToInherit( NS_IMETHODIMP SessionHistoryEntry::SetPartitionedPrincipalToInherit( nsIPrincipal* aPartitionedPrincipalToInherit) { - mSharedInfo->mPartitionedPrincipalToInherit = aPartitionedPrincipalToInherit; + SharedInfo()->mPartitionedPrincipalToInherit = aPartitionedPrincipalToInherit; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::GetCsp(nsIContentSecurityPolicy** aCsp) { - nsCOMPtr csp = mSharedInfo->mCsp; + nsCOMPtr csp = SharedInfo()->mCsp; csp.forget(aCsp); return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::SetCsp(nsIContentSecurityPolicy* aCsp) { - mSharedInfo->mCsp = aCsp; + SharedInfo()->mCsp = aCsp; return NS_OK; } @@ -452,7 +515,7 @@ SessionHistoryEntry::SetStateData(nsIStructuredCloneContainer* aStateData) { } const nsID& SessionHistoryEntry::DocshellID() const { - return mSharedInfo->mDocShellID; + return SharedInfo()->mDocShellID; } NS_IMETHODIMP @@ -463,7 +526,7 @@ SessionHistoryEntry::GetDocshellID(nsID& aDocshellID) { NS_IMETHODIMP SessionHistoryEntry::SetDocshellID(const nsID& aDocshellID) { - mSharedInfo->mDocShellID = aDocshellID; + SharedInfo()->mDocShellID = aDocshellID; return NS_OK; } @@ -521,7 +584,7 @@ SessionHistoryEntry::GetLoadedInThisProcess(bool* aLoadedInThisProcess) { NS_IMETHODIMP SessionHistoryEntry::GetShistory(nsISHistory** aShistory) { - nsCOMPtr sHistory = do_QueryReferent(mSharedInfo->mSHistory); + nsCOMPtr sHistory = do_QueryReferent(SharedInfo()->mSHistory); sHistory.forget(aShistory); return NS_OK; } @@ -530,20 +593,20 @@ NS_IMETHODIMP SessionHistoryEntry::SetShistory(nsISHistory* aShistory) { nsWeakPtr shistory = do_GetWeakReference(aShistory); // mSHistory can not be changed once it's set - MOZ_ASSERT(!mSharedInfo->mSHistory || (mSharedInfo->mSHistory == shistory)); - mSharedInfo->mSHistory = shistory; + MOZ_ASSERT(!SharedInfo()->mSHistory || (SharedInfo()->mSHistory == shistory)); + SharedInfo()->mSHistory = shistory; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::GetLastTouched(uint32_t* aLastTouched) { - *aLastTouched = mSharedInfo->mLastTouched; + *aLastTouched = SharedInfo()->mLastTouched; return NS_OK; } NS_IMETHODIMP SessionHistoryEntry::SetLastTouched(uint32_t aLastTouched) { - mSharedInfo->mLastTouched = aLastTouched; + SharedInfo()->mLastTouched = aLastTouched; return NS_OK; } @@ -581,12 +644,12 @@ SessionHistoryEntry::SetScrollPosition(int32_t aX, int32_t aY) { NS_IMETHODIMP_(void) SessionHistoryEntry::GetViewerBounds(nsIntRect& bounds) { - bounds = mSharedInfo->mViewerBounds; + bounds = SharedInfo()->mViewerBounds; } NS_IMETHODIMP_(void) SessionHistoryEntry::SetViewerBounds(const nsIntRect& bounds) { - mSharedInfo->mViewerBounds = bounds; + SharedInfo()->mViewerBounds = bounds; } NS_IMETHODIMP_(void) @@ -614,7 +677,7 @@ SessionHistoryEntry::SyncPresentationState() { NS_IMETHODIMP SessionHistoryEntry::InitLayoutHistoryState( nsILayoutHistoryState** aLayoutHistoryState) { - if (!mSharedInfo->mLayoutHistoryState) { + if (!SharedInfo()->mLayoutHistoryState) { nsCOMPtr historyState; historyState = NS_NewLayoutHistoryState(); SetLayoutHistoryState(historyState); @@ -662,7 +725,7 @@ SessionHistoryEntry::HasDetachedEditor() { NS_IMETHODIMP_(bool) SessionHistoryEntry::IsDynamicallyAdded() { - return mSharedInfo->mDynamicallyCreated; + return SharedInfo()->mDynamicallyCreated; } NS_IMETHODIMP @@ -910,12 +973,12 @@ SessionHistoryEntry::CreateLoadInfo(nsDocShellLoadState** aLoadState) { loadState->SetPostDataStream(mInfo->mPostData); loadState->SetReferrerInfo(mInfo->mReferrerInfo); - loadState->SetTypeHint(mSharedInfo->mContentType); - loadState->SetTriggeringPrincipal(mSharedInfo->mTriggeringPrincipal); - loadState->SetPrincipalToInherit(mSharedInfo->mPrincipalToInherit); + loadState->SetTypeHint(SharedInfo()->mContentType); + loadState->SetTriggeringPrincipal(SharedInfo()->mTriggeringPrincipal); + loadState->SetPrincipalToInherit(SharedInfo()->mPrincipalToInherit); loadState->SetPartitionedPrincipalToInherit( - mSharedInfo->mPartitionedPrincipalToInherit); - loadState->SetCsp(mSharedInfo->mCsp); + SharedInfo()->mPartitionedPrincipalToInherit); + loadState->SetCsp(SharedInfo()->mCsp); // Do not inherit principal from document (security-critical!); uint32_t flags = nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_NONE; @@ -946,7 +1009,7 @@ SessionHistoryEntry::CreateLoadInfo(nsDocShellLoadState** aLoadState) { NS_IMETHODIMP SessionHistoryEntry::GetBfcacheID(uint64_t* aBfcacheID) { - *aBfcacheID = mSharedInfo->mID; + *aBfcacheID = SharedInfo()->mId; return NS_OK; } @@ -957,15 +1020,8 @@ SessionHistoryEntry::SyncTreesForSubframeNavigation( NS_WARNING("Need to implement this"); } -void SessionHistoryEntry::MaybeSynchronizeSharedStateToInfo( - nsISHEntry* aEntry) { - nsCOMPtr entry = do_QueryInterface(aEntry); - if (!entry) { - return; - } - - entry->mInfo->mCacheKey = entry->mSharedInfo->mCacheKey; - // XXX Add other member variables which live in mSharedInfo. +SHEntrySharedParentState* SessionHistoryEntry::SharedInfo() const { + return static_cast(mInfo->mSharedState.Get()); } } // namespace dom @@ -1003,12 +1059,20 @@ void IPDLParamTraits::Write( WriteIPDLParam(aMsg, aActor, stateData); WriteIPDLParam(aMsg, aActor, info.mSrcdocData); WriteIPDLParam(aMsg, aActor, info.mBaseURI); - WriteIPDLParam(aMsg, aActor, info.mLayoutHistoryState); WriteIPDLParam(aMsg, aActor, info.mLoadReplace); WriteIPDLParam(aMsg, aActor, info.mURIWasModified); WriteIPDLParam(aMsg, aActor, info.mIsSrcdocEntry); WriteIPDLParam(aMsg, aActor, info.mScrollRestorationIsManual); WriteIPDLParam(aMsg, aActor, info.mPersist); + WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mId); + WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mTriggeringPrincipal); + WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mPrincipalToInherit); + WriteIPDLParam(aMsg, aActor, + info.mSharedState.Get()->mPartitionedPrincipalToInherit); + WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mCsp); + WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mContentType); + WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mLayoutHistoryState); + WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mCacheKey); WriteIPDLParam(aMsg, aActor, aParam.mLoadId); WriteIPDLParam(aMsg, aActor, aParam.mLoadIsFromSessionHistory); WriteIPDLParam(aMsg, aActor, aParam.mRequestedIndex); @@ -1021,6 +1085,7 @@ bool IPDLParamTraits::Read( Maybe stateData; dom::SessionHistoryInfo& info = aResult->mInfo; + uint64_t sharedId; if (!ReadIPDLParam(aMsg, aIter, aActor, &info.mURI) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mOriginalURI) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mResultPrincipalURI) || @@ -1033,20 +1098,38 @@ bool IPDLParamTraits::Read( !ReadIPDLParam(aMsg, aIter, aActor, &stateData) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mSrcdocData) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mBaseURI) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mLayoutHistoryState) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mLoadReplace) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mURIWasModified) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mIsSrcdocEntry) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mScrollRestorationIsManual) || !ReadIPDLParam(aMsg, aIter, aActor, &info.mPersist) || - !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadId) || - !ReadIPDLParam(aMsg, aIter, aActor, - &aResult->mLoadIsFromSessionHistory) || - !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRequestedIndex) || - !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSessionHistoryLength)) { + !ReadIPDLParam(aMsg, aIter, aActor, &sharedId)) { aActor->FatalError("Error reading fields for SessionHistoryInfo"); return false; } + + // FIXME If we're in the parent we should probably look up the sharedstate + // by id and reuse it, and only create a new one when there is no + // existing sharedstate. + info.mSharedState.Get()->mId = sharedId; + if (!ReadIPDLParam(aMsg, aIter, aActor, + &info.mSharedState.Get()->mTriggeringPrincipal) || + !ReadIPDLParam(aMsg, aIter, aActor, + &info.mSharedState.Get()->mPrincipalToInherit) || + !ReadIPDLParam( + aMsg, aIter, aActor, + &info.mSharedState.Get()->mPartitionedPrincipalToInherit) || + !ReadIPDLParam(aMsg, aIter, aActor, &info.mSharedState.Get()->mCsp) || + !ReadIPDLParam(aMsg, aIter, aActor, + &info.mSharedState.Get()->mContentType) || + !ReadIPDLParam(aMsg, aIter, aActor, + &info.mSharedState.Get()->mLayoutHistoryState) || + !ReadIPDLParam(aMsg, aIter, aActor, + &info.mSharedState.Get()->mCacheKey)) { + aActor->FatalError("Error reading fields for SessionHistoryInfo"); + return false; + } + if (stateData.isSome()) { info.mStateData = new nsStructuredCloneContainer(); if (aActor->GetSide() == ChildSide) { @@ -1056,6 +1139,16 @@ bool IPDLParamTraits::Read( } } MOZ_ASSERT_IF(stateData.isNothing(), !info.mStateData); + + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadId) || + !ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mLoadIsFromSessionHistory) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRequestedIndex) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSessionHistoryLength)) { + aActor->FatalError("Error reading fields for LoadingSessionHistoryInfo"); + return false; + } + return true; } diff --git a/docshell/shistory/SessionHistoryEntry.h b/docshell/shistory/SessionHistoryEntry.h index cf6d661a65a2..bdc074c4b5e8 100644 --- a/docshell/shistory/SessionHistoryEntry.h +++ b/docshell/shistory/SessionHistoryEntry.h @@ -10,6 +10,7 @@ #include "mozilla/UniquePtr.h" #include "nsILayoutHistoryState.h" #include "nsISHEntry.h" +#include "nsSHEntryShared.h" #include "nsStructuredCloneContainer.h" #include "nsDataHashtable.h" @@ -32,6 +33,7 @@ class SHEntrySharedParentState; class SessionHistoryInfo { public: SessionHistoryInfo() = default; + SessionHistoryInfo(const SessionHistoryInfo& aInfo) = default; SessionHistoryInfo(nsDocShellLoadState* aLoadState, nsIChannel* aChannel); bool operator==(const SessionHistoryInfo& aInfo) const { @@ -53,17 +55,12 @@ class SessionHistoryInfo { mScrollRestorationIsManual = aIsManual; } - void SetCacheKey(uint32_t aCacheKey) { mCacheKey = aCacheKey; } - nsIURI* GetURI() const { return mURI; } bool GetURIWasModified() const { return mURIWasModified; } - nsILayoutHistoryState* GetLayoutHistoryState() { return mLayoutHistoryState; } - - void SetLayoutHistoryState(nsILayoutHistoryState* aState) { - mLayoutHistoryState = aState; - } + nsILayoutHistoryState* GetLayoutHistoryState(); + void SetLayoutHistoryState(nsILayoutHistoryState* aState); private: friend class SessionHistoryEntry; @@ -83,19 +80,42 @@ class SessionHistoryInfo { RefPtr mStateData; nsString mSrcdocData; nsCOMPtr mBaseURI; - // mLayoutHistoryState is used to serialize layout history state across - // IPC. In the parent process this is then synchronized to - // SHEntrySharedParentState::mLayoutHistoryState - nsCOMPtr mLayoutHistoryState; - - // mCacheKey is handled similar way to mLayoutHistoryState. - uint32_t mCacheKey = 0; bool mLoadReplace = false; bool mURIWasModified = false; bool mIsSrcdocEntry = false; bool mScrollRestorationIsManual = false; bool mPersist = false; + + union SharedState { + SharedState(); + explicit SharedState(const SharedState& aOther); + ~SharedState(); + + SharedState& operator=(const SharedState& aOther); + + SHEntrySharedState* Get() const; + + static SharedState Create(nsIPrincipal* aTriggeringPrincipal, + nsIPrincipal* aPrincipalToInherit, + nsIPrincipal* aPartitionedPrincipalToInherit, + nsIContentSecurityPolicy* aCsp, + const nsACString& aContentType); + + private: + explicit SharedState(SHEntrySharedParentState* aParent) + : mParent(aParent) {} + explicit SharedState(UniquePtr&& aChild) + : mChild(std::move(aChild)) {} + + // In the parent process this holds a strong reference to the refcounted + // SHEntrySharedParentState. In the child processes this holds an owning + // pointer to a SHEntrySharedState. + RefPtr mParent; + UniquePtr mChild; + }; + + SharedState mSharedState; }; struct LoadingSessionHistoryInfo { @@ -139,6 +159,8 @@ class SessionHistoryEntry : public nsISHEntry { const SessionHistoryInfo& Info() const { return *mInfo; } + SHEntrySharedParentState* SharedInfo() const; + void AddChild(SessionHistoryEntry* aChild, int32_t aOffset, bool aUseRemoteSubframes); void RemoveChild(SessionHistoryEntry* aChild); @@ -152,8 +174,6 @@ class SessionHistoryEntry : public nsISHEntry { static SessionHistoryEntry* GetByLoadId(uint64_t aLoadId); static void RemoveLoadId(uint64_t aLoadId); - static void MaybeSynchronizeSharedStateToInfo(nsISHEntry* aEntry); - private: friend struct LoadingSessionHistoryInfo; virtual ~SessionHistoryEntry(); @@ -161,7 +181,6 @@ class SessionHistoryEntry : public nsISHEntry { const nsID& DocshellID() const; UniquePtr mInfo; - RefPtr mSharedInfo; nsISHEntry* mParent = nullptr; uint32_t mID; nsTArray> mChildren; diff --git a/docshell/shistory/nsSHEntryShared.cpp b/docshell/shistory/nsSHEntryShared.cpp index 68bd6d7744d9..f51265484086 100644 --- a/docshell/shistory/nsSHEntryShared.cpp +++ b/docshell/shistory/nsSHEntryShared.cpp @@ -28,17 +28,13 @@ uint64_t gSHEntrySharedID = 0; namespace mozilla { namespace dom { -SHEntrySharedParentState::SHEntrySharedParentState() - : mDocShellID({0}), - mViewerBounds(0, 0, 0, 0), - mCacheKey(0), - mLastTouched(0), - mID(++gSHEntrySharedID), - mIsFrameNavigation(false), - mSticky(true), - mDynamicallyCreated(false), - mExpired(false), - mSaveLayoutState(true) {} +SHEntrySharedParentState::SHEntrySharedParentState( + nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, + nsIPrincipal* aPartitionedPrincipalToInherit, + nsIContentSecurityPolicy* aCsp, const nsACString& aContentType) + : SHEntrySharedState(++gSHEntrySharedID, aTriggeringPrincipal, + aPrincipalToInherit, aPartitionedPrincipalToInherit, + aCsp, aContentType) {} SHEntrySharedParentState::~SHEntrySharedParentState() {} diff --git a/docshell/shistory/nsSHEntryShared.h b/docshell/shistory/nsSHEntryShared.h index b20d859166dc..90c9d80d3d08 100644 --- a/docshell/shistory/nsSHEntryShared.h +++ b/docshell/shistory/nsSHEntryShared.h @@ -43,17 +43,60 @@ namespace mozilla { namespace dom { class Document; +/** + * SHEntrySharedState holds shared state both in the child process and in the + * parent process. + */ +struct SHEntrySharedState { + SHEntrySharedState() = default; + SHEntrySharedState(const SHEntrySharedState& aState) = default; + SHEntrySharedState(uint64_t aId, nsIPrincipal* aTriggeringPrincipal, + nsIPrincipal* aPrincipalToInherit, + nsIPrincipal* aPartitionedPrincipalToInherit, + nsIContentSecurityPolicy* aCsp, + const nsACString& aContentType) + : mId(aId), + mTriggeringPrincipal(aTriggeringPrincipal), + mPrincipalToInherit(aPrincipalToInherit), + mPartitionedPrincipalToInherit(aPartitionedPrincipalToInherit), + mCsp(aCsp), + mContentType(aContentType) {} + + // These members aren't copied by SHEntrySharedParentState::CopyFrom() because + // they're specific to a particular content viewer. + uint64_t mId = 0; + + // These members are copied by SHEntrySharedParentState::CopyFrom(). If you + // add a member here, be sure to update the CopyFrom() implementation. + nsCOMPtr mTriggeringPrincipal; + nsCOMPtr mPrincipalToInherit; + nsCOMPtr mPartitionedPrincipalToInherit; + nsCOMPtr mCsp; + nsCString mContentType; + // Child side updates layout history state when page is being unloaded or + // moved to bfcache. + nsCOMPtr mLayoutHistoryState; + uint32_t mCacheKey = 0; +}; + /** * SHEntrySharedParentState holds the shared state that can live in the parent * process. */ -class SHEntrySharedParentState { +class SHEntrySharedParentState : public SHEntrySharedState { public: - uint64_t GetID() const { return mID; } + friend class SessionHistoryInfo; + + uint64_t GetID() const { return mId; } void NotifyListenersContentViewerEvicted(); - SHEntrySharedParentState(); + SHEntrySharedParentState() = default; + SHEntrySharedParentState(nsIPrincipal* aTriggeringPrincipal, + nsIPrincipal* aPrincipalToInherit, + nsIPrincipal* aPartitionedPrincipalToInherit, + nsIContentSecurityPolicy* aCsp, + const nsACString& aContentType); protected: virtual ~SHEntrySharedParentState(); @@ -66,34 +109,24 @@ class SHEntrySharedParentState { // These members are copied by SHEntrySharedParentState::CopyFrom(). If you // add a member here, be sure to update the CopyFrom() implementation. - nsID mDocShellID; - nsCOMPtr mTriggeringPrincipal; - nsCOMPtr mPrincipalToInherit; - nsCOMPtr mPartitionedPrincipalToInherit; - nsCOMPtr mCsp; - // Child side updates layout history state when page is being unloaded or - // moved to bfcache. - nsCOMPtr mLayoutHistoryState; - nsCString mContentType; + nsID mDocShellID{}; - nsIntRect mViewerBounds; + nsIntRect mViewerBounds{0, 0, 0, 0}; - uint32_t mCacheKey; - uint32_t mLastTouched; + uint32_t mLastTouched = 0; // These members aren't copied by SHEntrySharedParentState::CopyFrom() because // they're specific to a particular content viewer. - uint64_t mID; nsWeakPtr mSHistory; - bool mIsFrameNavigation; - bool mSticky; - bool mDynamicallyCreated; + bool mIsFrameNavigation = false; + bool mSticky = true; + bool mDynamicallyCreated = false; // This flag is about necko cache, not bfcache. - bool mExpired; + bool mExpired = false; - bool mSaveLayoutState; + bool mSaveLayoutState = true; }; /** diff --git a/docshell/shistory/nsSHistory.cpp b/docshell/shistory/nsSHistory.cpp index 4189996de54f..b526f9769ac3 100644 --- a/docshell/shistory/nsSHistory.cpp +++ b/docshell/shistory/nsSHistory.cpp @@ -1729,7 +1729,6 @@ void nsSHistory::InitiateLoad(nsISHEntry* aFrameEntry, loadState->SetLoadType(aLoadType); - SessionHistoryEntry::MaybeSynchronizeSharedStateToInfo(aFrameEntry); loadState->SetSHEntry(aFrameEntry); loadState->SetLoadIsFromSessionHistory(mRequestedIndex, Length()); From a4a8b3da89ee4b0c7b1d9c99f294a352e68c9c20 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Sun, 23 Aug 2020 17:41:03 +0000 Subject: [PATCH 05/56] Bug 1649131 - Implement history.pushState/.replaceState for session history in the parent. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D87039 --- docshell/base/BrowsingContext.cpp | 45 ++++ docshell/base/BrowsingContext.h | 22 ++ docshell/base/CanonicalBrowsingContext.cpp | 64 ++++- docshell/base/CanonicalBrowsingContext.h | 10 + docshell/base/nsDocShell.cpp | 257 ++++++++++++++------ docshell/base/nsDocShell.h | 13 +- docshell/base/nsDocShellLoadState.cpp | 5 +- docshell/base/nsDocShellLoadState.h | 3 +- docshell/shistory/SessionHistoryEntry.cpp | 268 ++++++++++++++------- docshell/shistory/SessionHistoryEntry.h | 59 ++++- docshell/shistory/nsSHistory.cpp | 16 +- dom/ipc/ContentParent.cpp | 35 ++- dom/ipc/ContentParent.h | 14 ++ dom/ipc/PContent.ipdl | 12 + 14 files changed, 642 insertions(+), 181 deletions(-) diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp index 160e180208b6..97046b872c2d 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp @@ -51,6 +51,7 @@ #include "nsFocusManager.h" #include "nsGlobalWindowOuter.h" #include "nsIObserverService.h" +#include "nsISHistory.h" #include "nsContentUtils.h" #include "nsQueryObject.h" #include "nsSandboxFlags.h" @@ -2595,6 +2596,50 @@ bool BrowsingContext::IsPopupAllowed() { return false; } +void BrowsingContext::SetActiveSessionHistoryEntryForTop( + const Maybe& aPreviousScrollPos, SessionHistoryInfo* aInfo, + uint32_t aLoadType) { + if (XRE_IsContentProcess()) { + nsID changeID = {}; + RefPtr shistory = GetChildSessionHistory(); + if (shistory) { + changeID = shistory->AddPendingHistoryChange(1, 1); + } + ContentChild::GetSingleton()->SendSetActiveSessionHistoryEntryForTop( + this, aPreviousScrollPos, *aInfo, aLoadType, changeID); + } else { + Canonical()->SetActiveSessionHistoryEntryForTop(aPreviousScrollPos, aInfo, + aLoadType, nsID()); + } +} + +void BrowsingContext::SetActiveSessionHistoryEntryForFrame( + const Maybe& aPreviousScrollPos, SessionHistoryInfo* aInfo, + int32_t aChildOffset) { + if (XRE_IsContentProcess()) { + nsID changeID = {}; + RefPtr shistory = GetChildSessionHistory(); + if (shistory) { + changeID = shistory->AddPendingHistoryChange(1, 1); + } + ContentChild::GetSingleton()->SendSetActiveSessionHistoryEntryForFrame( + this, aPreviousScrollPos, *aInfo, aChildOffset, changeID); + } else { + Canonical()->SetActiveSessionHistoryEntryForFrame(aPreviousScrollPos, aInfo, + aChildOffset, nsID()); + } +} + +void BrowsingContext::ReplaceActiveSessionHistoryEntry( + SessionHistoryInfo* aInfo) { + if (XRE_IsContentProcess()) { + ContentChild::GetSingleton()->SendReplaceActiveSessionHistoryEntry(this, + *aInfo); + } else { + Canonical()->ReplaceActiveSessionHistoryEntry(aInfo); + } +} + } // namespace dom namespace ipc { diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h index 29ed88705157..de283e99bae9 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h @@ -36,6 +36,7 @@ class nsGlobalWindowInner; class nsGlobalWindowOuter; class nsIPrincipal; class nsOuterWindowProxy; +struct nsPoint; class PickleIterator; namespace IPC { @@ -63,6 +64,9 @@ class ContentParent; class Element; template struct Nullable; +template +class Sequence; +class SessionHistoryInfo; class SessionStorageManager; class StructuredCloneHolder; class WindowContext; @@ -631,6 +635,24 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { // context or any of its ancestors. bool IsPopupAllowed(); + // Set a new active entry on this browsing context. Should only be called if + // IsTop() returns true. This is used for implementing + // history.pushState/replaceState. + void SetActiveSessionHistoryEntryForTop( + const Maybe& aPreviousScrollPos, SessionHistoryInfo* aInfo, + uint32_t aLoadType); + + // Set a new active entry on this browsing context. Should only be called if + // IsTop() returns false. This is used for implementing + // history.pushState/replaceState. + void SetActiveSessionHistoryEntryForFrame( + const Maybe& aPreviousScrollPos, SessionHistoryInfo* aInfo, + int32_t aChildOffset); + + // Replace the active entry for this browsing context. This is used for + // implementing history.replaceState. + void ReplaceActiveSessionHistoryEntry(SessionHistoryInfo* aInfo); + protected: virtual ~BrowsingContext(); BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup, diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp index e437c4aaac80..becf133f4c9c 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp @@ -403,12 +403,74 @@ void CanonicalBrowsingContext::NotifyOnHistoryReload( shistory->GetRequestedIndex(&requestedIndex); shistory->GetCount(&length); aLoadState.ref()->SetLoadIsFromSessionHistory( - requestedIndex >= 0 ? requestedIndex : index, length); + requestedIndex >= 0 ? requestedIndex : index, length, + aReloadActiveEntry.value()); } // If we don't have an active entry and we don't have a loading entry then // the nsDocShell will create a load state based on its document. } +void CanonicalBrowsingContext::SetActiveSessionHistoryEntryForTop( + const Maybe& aPreviousScrollPos, SessionHistoryInfo* aInfo, + uint32_t aLoadType, const nsID& aChangeID) { + RefPtr oldActiveEntry = mActiveEntry; + if (aPreviousScrollPos.isSome() && oldActiveEntry) { + oldActiveEntry->SetScrollPosition(aPreviousScrollPos.ref().x, + aPreviousScrollPos.ref().y); + } + RefPtr newEntry = new SessionHistoryEntry(aInfo); + mActiveEntry = newEntry; + Maybe previousEntryIndex, loadedEntryIndex; + nsISHistory* shistory = GetSessionHistory(); + if (shistory) { + shistory->AddToRootSessionHistory( + true, oldActiveEntry, this, newEntry, aLoadType, + nsDocShell::ShouldAddToSessionHistory(aInfo->GetURI(), nullptr), + &previousEntryIndex, &loadedEntryIndex); + // FIXME Need to do the equivalent of EvictContentViewersOrReplaceEntry. + Group()->EachParent([&](ContentParent* aParent) { + int32_t index = 0; + shistory->GetIndex(&index); + Unused << aParent->SendHistoryCommitIndexAndLength( + Top(), index, shistory->GetCount(), aChangeID); + }); + } +} + +void CanonicalBrowsingContext::SetActiveSessionHistoryEntryForFrame( + const Maybe& aPreviousScrollPos, SessionHistoryInfo* aInfo, + int32_t aChildOffset, const nsID& aChangeID) { + RefPtr oldActiveEntry = mActiveEntry; + if (aPreviousScrollPos.isSome() && oldActiveEntry) { + oldActiveEntry->SetScrollPosition(aPreviousScrollPos.ref().x, + aPreviousScrollPos.ref().y); + } + RefPtr newEntry = new SessionHistoryEntry(aInfo); + mActiveEntry = newEntry; + nsISHistory* shistory = GetSessionHistory(); + if (oldActiveEntry) { + if (shistory) { + shistory->AddChildSHEntryHelper(oldActiveEntry, newEntry, Top(), true); + } + } else if (GetParent() && GetParent()->mActiveEntry) { + GetParent()->mActiveEntry->AddChild(newEntry, aChildOffset, + UseRemoteSubframes()); + } + // FIXME Need to do the equivalent of EvictContentViewersOrReplaceEntry. + Group()->EachParent([&](ContentParent* aParent) { + int32_t index = 0; + shistory->GetIndex(&index); + Unused << aParent->SendHistoryCommitIndexAndLength( + Top(), index, shistory->GetCount(), aChangeID); + }); +} + +void CanonicalBrowsingContext::ReplaceActiveSessionHistoryEntry( + SessionHistoryInfo* aInfo) { + mActiveEntry->SetInfo(aInfo); + // FIXME Need to do the equivalent of EvictContentViewersOrReplaceEntry. +} + JSObject* CanonicalBrowsingContext::WrapObject( JSContext* aCx, JS::Handle aGivenProto) { return CanonicalBrowsingContext_Binding::Wrap(aCx, this, aGivenProto); diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h index 6eff2404f805..2df2d1fcf95b 100644 --- a/docshell/base/CanonicalBrowsingContext.h +++ b/docshell/base/CanonicalBrowsingContext.h @@ -112,6 +112,16 @@ class CanonicalBrowsingContext final : public BrowsingContext { Maybe>& aLoadState, Maybe& aReloadActiveEntry); + void SetActiveSessionHistoryEntryForTop( + const Maybe& aPreviousScrollPos, SessionHistoryInfo* aInfo, + uint32_t aLoadType, const nsID& aChangeID); + + void SetActiveSessionHistoryEntryForFrame( + const Maybe& aPreviousScrollPos, SessionHistoryInfo* aInfo, + int32_t aChildOffset, const nsID& aChangeID); + + void ReplaceActiveSessionHistoryEntry(SessionHistoryInfo* aInfo); + JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index a9babdd57bc0..5b72fdfed250 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -44,6 +44,7 @@ #include "mozilla/StartupTimeline.h" #include "mozilla/StorageAccess.h" #include "mozilla/Telemetry.h" +#include "mozilla/Tuple.h" #include "mozilla/Unused.h" #include "mozilla/WidgetUtils.h" @@ -8360,25 +8361,32 @@ bool nsDocShell::IsSameDocumentNavigation(nsDocShellLoadState* aLoadState, } } - if (mOSHE && aLoadState->LoadIsFromSessionHistory()) { - // We're doing a history load. + if (StaticPrefs::fission_sessionHistoryInParent()) { + if (mActiveEntry && aLoadState->LoadIsFromSessionHistory()) { + aState.mHistoryNavBetweenSameDoc = mActiveEntry->SharesDocumentWith( + aLoadState->GetLoadingSessionHistoryInfo()->mInfo); + } + } else { + if (mOSHE && aLoadState->LoadIsFromSessionHistory()) { + // We're doing a history load. - mOSHE->SharesDocumentWith(aLoadState->SHEntry(), - &aState.mHistoryNavBetweenSameDoc); + mOSHE->SharesDocumentWith(aLoadState->SHEntry(), + &aState.mHistoryNavBetweenSameDoc); + } + } #ifdef DEBUG - if (aState.mHistoryNavBetweenSameDoc) { - nsCOMPtr currentPostData; - if (StaticPrefs::fission_sessionHistoryInParent()) { - currentPostData = mActiveEntry->GetPostData(); - } else { - currentPostData = mOSHE->GetPostData(); - } - NS_ASSERTION(currentPostData == aLoadState->PostDataStream(), - "Different POST data for entries for the same page?"); + if (aState.mHistoryNavBetweenSameDoc) { + nsCOMPtr currentPostData; + if (StaticPrefs::fission_sessionHistoryInParent()) { + currentPostData = mActiveEntry->GetPostData(); + } else { + currentPostData = mOSHE->GetPostData(); } -#endif + NS_ASSERTION(currentPostData == aLoadState->PostDataStream(), + "Different POST data for entries for the same page?"); } +#endif // A same document navigation happens when we navigate between two SHEntries // for the same document. We do a same document navigation under two @@ -8394,12 +8402,23 @@ bool nsDocShell::IsSameDocumentNavigation(nsDocShellLoadState* aLoadState, // The restriction that the SHEntries in (a) must be different ensures // that history.go(0) and the like trigger full refreshes, rather than // same document navigations. - bool doSameDocumentNavigation = - (aState.mHistoryNavBetweenSameDoc && mOSHE != aLoadState->SHEntry()) || - (!aLoadState->SHEntry() && !aLoadState->PostDataStream() && - aState.mSameExceptHashes && aState.mNewURIHasRef); + if (!StaticPrefs::fission_sessionHistoryInParent()) { + bool doSameDocumentNavigation = + (aState.mHistoryNavBetweenSameDoc && mOSHE != aLoadState->SHEntry()) || + (!aLoadState->SHEntry() && !aLoadState->PostDataStream() && + aState.mSameExceptHashes && aState.mNewURIHasRef); - return doSameDocumentNavigation; + return doSameDocumentNavigation; + } + + if (aState.mHistoryNavBetweenSameDoc && + !aLoadState->GetLoadingSessionHistoryInfo()->mLoadingCurrentActiveEntry) { + return true; + } + + return !aLoadState->LoadIsFromSessionHistory() && + !aLoadState->PostDataStream() && aState.mSameExceptHashes && + aState.mNewURIHasRef; } nsresult nsDocShell::HandleSameDocumentNavigation( @@ -8522,10 +8541,12 @@ nsresult nsDocShell::HandleSameDocumentNavigation( // If we're doing a history load, use its scroll restoration state. if (aLoadState->LoadIsFromSessionHistory()) { - DebugOnly rv = - aLoadState->SHEntry()->GetScrollRestorationIsManual( - &scrollRestorationIsManual); - MOZ_ASSERT(NS_SUCCEEDED(rv), "Didn't expect this to fail."); + if (StaticPrefs::fission_sessionHistoryInParent()) { + scrollRestorationIsManual = mActiveEntry->GetScrollRestorationIsManual(); + } else { + scrollRestorationIsManual = + aLoadState->SHEntry()->GetScrollRestorationIsManual(); + } } /* Assign mLSHE to mOSHE. This will either be a new entry created @@ -10249,7 +10270,11 @@ bool nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel, (IsForceReloadType(aLoadType) && IsFrame())); // Create SH Entry (mLSHE) only if there is a SessionHistory object in the - // in the root browsing context. + // root browsing context. + // FIXME If session history in the parent is enabled then we only do this if + // the session history object is in process, otherwise we can't really + // use the mLSHE anyway. Once session history is only stored in the + // parent then this code will probably be removed anyway. RefPtr rootSH = GetRootSessionHistory(); if (!rootSH) { updateSHistory = false; @@ -10617,6 +10642,23 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI, NS_ENSURE_TRUE(mOSHE || aReplace, NS_ERROR_FAILURE); nsCOMPtr oldOSHE = mOSHE; + // If this push/replaceState changed the document's current URI and the new + // URI differs from the old URI in more than the hash, or if the old + // SHEntry's URI was modified in this way by a push/replaceState call + // set URIWasModified to true for the current SHEntry (bug 669671). + bool sameExceptHashes = true; + aNewURI->EqualsExceptRef(aCurrentURI, &sameExceptHashes); + bool uriWasModified; + if (sameExceptHashes) { + if (StaticPrefs::fission_sessionHistoryInParent()) { + uriWasModified = mActiveEntry && mActiveEntry->GetURIWasModified(); + } else { + uriWasModified = oldOSHE && oldOSHE->GetURIWasModified(); + } + } else { + uriWasModified = true; + } + mLoadType = LOAD_PUSHSTATE; nsCOMPtr newSHEntry; @@ -10630,49 +10672,63 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI, shistory->RemovePendingHistoryNavigations(); } - // Save the current scroll position (bug 590573). Step 2.3. nsPoint scrollPos = GetCurScrollPos(); - mOSHE->SetScrollPosition(scrollPos.x, scrollPos.y); bool scrollRestorationIsManual; if (StaticPrefs::fission_sessionHistoryInParent()) { scrollRestorationIsManual = mActiveEntry->GetScrollRestorationIsManual(); } else { + // Save the current scroll position (bug 590573). Step 2.3. + mOSHE->SetScrollPosition(scrollPos.x, scrollPos.y); + scrollRestorationIsManual = mOSHE->GetScrollRestorationIsManual(); } nsCOMPtr csp = aDocument->GetCsp(); - // Since we're not changing which page we have loaded, pass - // true for aCloneChildren. - nsresult rv = AddToSessionHistory( - aNewURI, nullptr, - aDocument->NodePrincipal(), // triggeringPrincipal - nullptr, nullptr, csp, true, getter_AddRefs(newSHEntry)); - NS_ENSURE_SUCCESS(rv, rv); - - NS_ENSURE_TRUE(newSHEntry, NS_ERROR_FAILURE); - - // Session history entries created by pushState inherit scroll restoration - // mode from the current entry. - newSHEntry->SetScrollRestorationIsManual(scrollRestorationIsManual); - - // Link the new SHEntry to the old SHEntry's BFCache entry, since the - // two entries correspond to the same document. - NS_ENSURE_SUCCESS(newSHEntry->AdoptBFCacheEntry(oldOSHE), NS_ERROR_FAILURE); - - // Set the new SHEntry's title (bug 655273). - nsString title; if (StaticPrefs::fission_sessionHistoryInParent()) { - title = mActiveEntry->GetTitle(); + nsString title(mActiveEntry->GetTitle()); + UpdateActiveEntry(false, + /* aPreviousScrollPos = */ Some(scrollPos), aNewURI, + /* aOriginalURI = */ nullptr, + /* aTriggeringPrincipal = */ aDocument->NodePrincipal(), + csp, title, Some(scrollRestorationIsManual), aData, + uriWasModified); } else { - mOSHE->GetTitle(title); - } - newSHEntry->SetTitle(title); + // Since we're not changing which page we have loaded, pass + // true for aCloneChildren. + nsresult rv = AddToSessionHistory( + aNewURI, nullptr, + aDocument->NodePrincipal(), // triggeringPrincipal + nullptr, nullptr, csp, true, getter_AddRefs(newSHEntry)); + NS_ENSURE_SUCCESS(rv, rv); - // AddToSessionHistory may not modify mOSHE. In case it doesn't, - // we'll just set mOSHE here. - mOSHE = newSHEntry; + NS_ENSURE_TRUE(newSHEntry, NS_ERROR_FAILURE); + + // Session history entries created by pushState inherit scroll restoration + // mode from the current entry. + newSHEntry->SetScrollRestorationIsManual(scrollRestorationIsManual); + + nsString title; + mOSHE->GetTitle(title); + + // Set the new SHEntry's title (bug 655273). + newSHEntry->SetTitle(title); + + // Link the new SHEntry to the old SHEntry's BFCache entry, since the + // two entries correspond to the same document. + NS_ENSURE_SUCCESS(newSHEntry->AdoptBFCacheEntry(oldOSHE), + NS_ERROR_FAILURE); + + // AddToSessionHistory may not modify mOSHE. In case it doesn't, + // we'll just set mOSHE here. + mOSHE = newSHEntry; + } + } else if (StaticPrefs::fission_sessionHistoryInParent()) { + UpdateActiveEntry( + true, /* aPreviousScrollPos = */ Nothing(), aNewURI, aNewURI, + aDocument->NodePrincipal(), aDocument->GetCsp(), EmptyString(), + /* aScrollRestorationIsManual = */ Nothing(), aData, uriWasModified); } else { // Step 3. newSHEntry = mOSHE; @@ -10688,6 +10744,7 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI, NS_ENSURE_SUCCESS(rv, rv); mOSHE = newSHEntry; } + newSHEntry->SetURI(aNewURI); newSHEntry->SetOriginalURI(aNewURI); // Setting the resultPrincipalURI to nullptr is fine here: it will cause @@ -10697,31 +10754,26 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI, newSHEntry->SetLoadReplace(false); } - // Step 2.4 and 3: Modify new/original session history entry and clear its - // POST data, if there is any. - newSHEntry->SetStateData(aData); - newSHEntry->SetPostData(nullptr); + if (!StaticPrefs::fission_sessionHistoryInParent()) { + // Step 2.4 and 3: Modify new/original session history entry and clear its + // POST data, if there is any. + newSHEntry->SetStateData(aData); + newSHEntry->SetPostData(nullptr); - // If this push/replaceState changed the document's current URI and the new - // URI differs from the old URI in more than the hash, or if the old - // SHEntry's URI was modified in this way by a push/replaceState call - // set URIWasModified to true for the current SHEntry (bug 669671). - bool sameExceptHashes = true; - aNewURI->EqualsExceptRef(aCurrentURI, &sameExceptHashes); - bool oldURIWasModified = oldOSHE && oldOSHE->GetURIWasModified(); - newSHEntry->SetURIWasModified(!sameExceptHashes || oldURIWasModified); + newSHEntry->SetURIWasModified(uriWasModified); - // Step E as described at the top of AddState: If aReplace is false, - // indicating that we're doing a pushState rather than a replaceState, notify - // bfcache that we've added a page to the history so it can evict content - // viewers if appropriate. Otherwise call ReplaceEntry so that we notify - // nsIHistoryListeners that an entry was replaced. We may not have a root - // session history if this call is coming from a document.open() in a docshell - // subtree that disables session history. - RefPtr rootSH = GetRootSessionHistory(); - if (rootSH) { - rootSH->LegacySHistory()->EvictContentViewersOrReplaceEntry(newSHEntry, - aReplace); + // Step E as described at the top of AddState: If aReplace is false, + // indicating that we're doing a pushState rather than a replaceState, + // notify bfcache that we've added a page to the history so it can evict + // content viewers if appropriate. Otherwise call ReplaceEntry so that we + // notify nsIHistoryListeners that an entry was replaced. We may not have a + // root session history if this call is coming from a document.open() in a + // docshell subtree that disables session history. + RefPtr rootSH = GetRootSessionHistory(); + if (rootSH) { + rootSH->LegacySHistory()->EvictContentViewersOrReplaceEntry(newSHEntry, + aReplace); + } } // Step 4: If the document's URI changed, update document's URI and update @@ -10831,6 +10883,7 @@ void nsDocShell::SetCacheKeyOnHistoryEntry(nsISHEntry* aSHEntry, } } +/* static */ bool nsDocShell::ShouldAddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel) { // I believe none of the about: urls should go in the history. But then // that could just be me... If the intent is only deny about:blank then we @@ -11086,6 +11139,58 @@ nsresult nsDocShell::AddToSessionHistory( return rv; } +void nsDocShell::UpdateActiveEntry( + bool aReplace, const Maybe& aPreviousScrollPos, nsIURI* aURI, + nsIURI* aOriginalURI, nsIPrincipal* aTriggeringPrincipal, + nsIContentSecurityPolicy* aCsp, const nsAString& aTitle, + const Maybe& aScrollRestorationIsManual, + nsIStructuredCloneContainer* aData, bool aURIWasModified) { + MOZ_ASSERT(StaticPrefs::fission_sessionHistoryInParent()); + MOZ_ASSERT(aURI, "uri is null"); + MOZ_ASSERT(mLoadType == LOAD_PUSHSTATE, + "This code only deals with pushState"); + MOZ_ASSERT_IF(aPreviousScrollPos.isSome(), !aReplace); + + if (!aReplace || !mActiveEntry) { + if (mActiveEntry) { + // Link this entry to the previous active entry. + mActiveEntry = + MakeUnique(*mActiveEntry, aURI, HistoryID()); + } else { + mActiveEntry = MakeUnique( + aURI, HistoryID(), aTriggeringPrincipal, aCsp, mContentTypeHint); + } + mActiveEntry->SetTitle(aTitle); + mActiveEntry->SetStateData(static_cast(aData)); + mActiveEntry->SetURIWasModified(aURIWasModified); + if (aScrollRestorationIsManual.isSome()) { + mActiveEntry->SetScrollRestorationIsManual( + aScrollRestorationIsManual.value()); + } + if (mBrowsingContext->IsTop()) { + mBrowsingContext->SetActiveSessionHistoryEntryForTop( + aPreviousScrollPos, mActiveEntry.get(), mLoadType); + // FIXME Do we need to update mPreviousEntryIndex and mLoadedEntryIndex? + } else { + // FIXME We should probably just compute mChildOffset in the parent + // instead of passing it over IPC here. + mBrowsingContext->SetActiveSessionHistoryEntryForFrame( + aPreviousScrollPos, mActiveEntry.get(), mChildOffset); + } + } else { + mActiveEntry->SetResultPrincipalURI(nullptr); + mActiveEntry->SetLoadReplace(false); + mActiveEntry->SetStateData(static_cast(aData)); + mActiveEntry->SetPostData(nullptr); + mActiveEntry->SetURIWasModified(aURIWasModified); + if (aScrollRestorationIsManual.isSome()) { + mActiveEntry->SetScrollRestorationIsManual( + aScrollRestorationIsManual.value()); + } + mBrowsingContext->ReplaceActiveSessionHistoryEntry(mActiveEntry.get()); + } +} + nsresult nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType) { NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE); diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 5956b9c926d2..3d03af425dbf 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -502,6 +502,10 @@ class nsDocShell final : public nsDocLoader, void SetLoadingSessionHistoryInfo( const mozilla::dom::LoadingSessionHistoryInfo& aLoadingInfo); + static bool ShouldAddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel); + + bool IsOSHE(nsISHEntry* aEntry) const { return mOSHE == aEntry; } + private: // member functions friend class nsDSURIContentListener; friend class FramingChecker; @@ -594,8 +598,6 @@ class nsDocShell final : public nsDocLoader, // Session History // - bool ShouldAddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel); - // Either aChannel or aOwner must be null. If aChannel is // present, the owner should be gotten from it. // If aCloneChildren is true, then our current session history's @@ -614,6 +616,13 @@ class nsDocShell final : public nsDocLoader, nsIContentSecurityPolicy* aCsp, bool aCloneChildren, nsISHEntry** aNewEntry); + void UpdateActiveEntry( + bool aReplace, const mozilla::Maybe& aPreviousScrollPos, + nsIURI* aURI, nsIURI* aOriginalURI, nsIPrincipal* aTriggeringPrincipal, + nsIContentSecurityPolicy* aCsp, const nsAString& aTitle, + const mozilla::Maybe& aScrollRestorationIsManual, + nsIStructuredCloneContainer* aData, bool aURIWasModified); + nsresult AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset, bool aCloneChildren); diff --git a/docshell/base/nsDocShellLoadState.cpp b/docshell/base/nsDocShellLoadState.cpp index 31a1fa543abd..9523a457b16f 100644 --- a/docshell/base/nsDocShellLoadState.cpp +++ b/docshell/base/nsDocShellLoadState.cpp @@ -528,11 +528,14 @@ nsDocShellLoadState::GetLoadingSessionHistoryInfo() const { } void nsDocShellLoadState::SetLoadIsFromSessionHistory( - int32_t aRequestedIndex, int32_t aSessionHistoryLength) { + int32_t aRequestedIndex, int32_t aSessionHistoryLength, + bool aLoadingFromActiveEntry) { if (mLoadingSessionHistoryInfo) { mLoadingSessionHistoryInfo->mLoadIsFromSessionHistory = true; mLoadingSessionHistoryInfo->mRequestedIndex = aRequestedIndex; mLoadingSessionHistoryInfo->mSessionHistoryLength = aSessionHistoryLength; + mLoadingSessionHistoryInfo->mLoadingCurrentActiveEntry = + aLoadingFromActiveEntry; } } diff --git a/docshell/base/nsDocShellLoadState.h b/docshell/base/nsDocShellLoadState.h index 942d2c4ab7af..1052a607ea82 100644 --- a/docshell/base/nsDocShellLoadState.h +++ b/docshell/base/nsDocShellLoadState.h @@ -281,7 +281,8 @@ class nsDocShellLoadState final { mozilla::dom::DocShellLoadStateInit Serialize(); void SetLoadIsFromSessionHistory(int32_t aRequestedIndex, - int32_t aSessionHistoryLength); + int32_t aSessionHistoryLength, + bool aLoadingFromActiveEntry); void ClearLoadIsFromSessionHistory(); protected: diff --git a/docshell/shistory/SessionHistoryEntry.cpp b/docshell/shistory/SessionHistoryEntry.cpp index b335503f8ad7..0c9fe11e80a2 100644 --- a/docshell/shistory/SessionHistoryEntry.cpp +++ b/docshell/shistory/SessionHistoryEntry.cpp @@ -41,6 +41,61 @@ SessionHistoryInfo::SessionHistoryInfo(nsDocShellLoadState* aLoadState, } } +SessionHistoryInfo::SessionHistoryInfo( + const SessionHistoryInfo& aSharedStateFrom, nsIURI* aURI, + const nsID& aDocShellID) + : mURI(aURI), mSharedState(aSharedStateFrom.mSharedState) { + MaybeUpdateTitleFromURI(); +} + +SessionHistoryInfo::SessionHistoryInfo(nsIURI* aURI, const nsID& aDocShellID, + nsIPrincipal* aTriggeringPrincipal, + nsIContentSecurityPolicy* aCsp, + const nsACString& aContentType) + : mURI(aURI), + mSharedState(SharedState::Create(aTriggeringPrincipal, nullptr, nullptr, + aCsp, aContentType)) { + MaybeUpdateTitleFromURI(); +} + +void SessionHistoryInfo::Reset(nsIURI* aURI, const nsID& aDocShellID, + bool aDynamicCreation, + nsIPrincipal* aTriggeringPrincipal, + nsIPrincipal* aPrincipalToInherit, + nsIPrincipal* aPartitionedPrincipalToInherit, + nsIContentSecurityPolicy* aCsp, + const nsACString& aContentType) { + mURI = aURI; + mOriginalURI = nullptr; + mResultPrincipalURI = nullptr; + mReferrerInfo = nullptr; + // Default title is the URL. + nsAutoCString spec; + if (NS_SUCCEEDED(mURI->GetSpec(spec))) { + CopyUTF8toUTF16(spec, mTitle); + } + mPostData = nullptr; + mLoadType = 0; + mScrollPositionX = 0; + mScrollPositionY = 0; + mStateData = nullptr; + mSrcdocData.Truncate(); + mBaseURI = nullptr; + mLoadReplace = false; + mURIWasModified = false; + mIsSrcdocEntry = false; + mScrollRestorationIsManual = false; + mPersist = false; + + mSharedState.Get()->mTriggeringPrincipal = aTriggeringPrincipal; + mSharedState.Get()->mPrincipalToInherit = aPrincipalToInherit; + mSharedState.Get()->mPartitionedPrincipalToInherit = + aPartitionedPrincipalToInherit; + mSharedState.Get()->mCsp = aCsp; + mSharedState.Get()->mContentType = aContentType; + mSharedState.Get()->mLayoutHistoryState = nullptr; +} + void SessionHistoryInfo::MaybeUpdateTitleFromURI() { if (mTitle.IsEmpty() && mURI) { // Default title is the URL. @@ -51,6 +106,10 @@ void SessionHistoryInfo::MaybeUpdateTitleFromURI() { } } +uint64_t SessionHistoryInfo::SharedId() const { + return mSharedState.Get()->mId; +} + nsILayoutHistoryState* SessionHistoryInfo::GetLayoutHistoryState() { return mSharedState.Get()->mLayoutHistoryState; } @@ -166,6 +225,9 @@ SessionHistoryEntry::SessionHistoryEntry(nsDocShellLoadState* aLoadState, nsIChannel* aChannel) : mInfo(new SessionHistoryInfo(aLoadState, aChannel)), mID(++gEntryID) {} +SessionHistoryEntry::SessionHistoryEntry(SessionHistoryInfo* aInfo) + : mInfo(MakeUnique(*aInfo)), mID(++gEntryID) {} + SessionHistoryEntry::~SessionHistoryEntry() { if (sLoadIdToEntry) { sLoadIdToEntry->RemoveIf( @@ -761,8 +823,13 @@ SessionHistoryEntry::AbandonBFCacheEntry() { NS_IMETHODIMP SessionHistoryEntry::SharesDocumentWith(nsISHEntry* aEntry, bool* aSharesDocumentWith) { - MOZ_CRASH("Might need to implement this"); - return NS_ERROR_NOT_IMPLEMENTED; + SessionHistoryEntry* entry = static_cast(aEntry); + + MOZ_ASSERT_IF(entry->SharedInfo() != SharedInfo(), + entry->SharedInfo()->GetID() != SharedInfo()->GetID()); + + *aSharesDocumentWith = entry->SharedInfo() == SharedInfo(); + return NS_OK; } NS_IMETHODIMP @@ -1024,55 +1091,127 @@ SHEntrySharedParentState* SessionHistoryEntry::SharedInfo() const { return static_cast(mInfo->mSharedState.Get()); } +void SessionHistoryEntry::SetInfo(SessionHistoryInfo* aInfo) { + // FIXME Assert that we're not changing shared state! + mInfo = MakeUnique(*aInfo); +} + } // namespace dom namespace ipc { -void IPDLParamTraits::Write( +void IPDLParamTraits::Write( IPC::Message* aMsg, IProtocol* aActor, - const dom::LoadingSessionHistoryInfo& aParam) { + const dom::SessionHistoryInfo& aParam) { Maybe stateData; - if (aParam.mInfo.mStateData) { + if (aParam.mStateData) { stateData.emplace(); - JSStructuredCloneData& data = aParam.mInfo.mStateData->Data(); + JSStructuredCloneData& data = aParam.mStateData->Data(); auto iter = data.Start(); bool success; stateData->data().data = data.Borrow(iter, data.Size(), &success); if (NS_WARN_IF(!success)) { return; } - MOZ_ASSERT(aParam.mInfo.mStateData->PortIdentifiers().IsEmpty() && - aParam.mInfo.mStateData->BlobImpls().IsEmpty() && - aParam.mInfo.mStateData->InputStreams().IsEmpty()); + MOZ_ASSERT(aParam.mStateData->PortIdentifiers().IsEmpty() && + aParam.mStateData->BlobImpls().IsEmpty() && + aParam.mStateData->InputStreams().IsEmpty()); } - const dom::SessionHistoryInfo& info = aParam.mInfo; - WriteIPDLParam(aMsg, aActor, info.mURI); - WriteIPDLParam(aMsg, aActor, info.mOriginalURI); - WriteIPDLParam(aMsg, aActor, info.mResultPrincipalURI); - WriteIPDLParam(aMsg, aActor, info.mReferrerInfo); - WriteIPDLParam(aMsg, aActor, info.mTitle); - WriteIPDLParam(aMsg, aActor, info.mPostData); - WriteIPDLParam(aMsg, aActor, info.mLoadType); - WriteIPDLParam(aMsg, aActor, info.mScrollPositionX); - WriteIPDLParam(aMsg, aActor, info.mScrollPositionY); + WriteIPDLParam(aMsg, aActor, aParam.mURI); + WriteIPDLParam(aMsg, aActor, aParam.mOriginalURI); + WriteIPDLParam(aMsg, aActor, aParam.mResultPrincipalURI); + WriteIPDLParam(aMsg, aActor, aParam.mReferrerInfo); + WriteIPDLParam(aMsg, aActor, aParam.mTitle); + WriteIPDLParam(aMsg, aActor, aParam.mPostData); + WriteIPDLParam(aMsg, aActor, aParam.mLoadType); + WriteIPDLParam(aMsg, aActor, aParam.mScrollPositionX); + WriteIPDLParam(aMsg, aActor, aParam.mScrollPositionY); WriteIPDLParam(aMsg, aActor, stateData); - WriteIPDLParam(aMsg, aActor, info.mSrcdocData); - WriteIPDLParam(aMsg, aActor, info.mBaseURI); - WriteIPDLParam(aMsg, aActor, info.mLoadReplace); - WriteIPDLParam(aMsg, aActor, info.mURIWasModified); - WriteIPDLParam(aMsg, aActor, info.mIsSrcdocEntry); - WriteIPDLParam(aMsg, aActor, info.mScrollRestorationIsManual); - WriteIPDLParam(aMsg, aActor, info.mPersist); - WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mId); - WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mTriggeringPrincipal); - WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mPrincipalToInherit); + WriteIPDLParam(aMsg, aActor, aParam.mSrcdocData); + WriteIPDLParam(aMsg, aActor, aParam.mBaseURI); + WriteIPDLParam(aMsg, aActor, aParam.mLoadReplace); + WriteIPDLParam(aMsg, aActor, aParam.mURIWasModified); + WriteIPDLParam(aMsg, aActor, aParam.mIsSrcdocEntry); + WriteIPDLParam(aMsg, aActor, aParam.mScrollRestorationIsManual); + WriteIPDLParam(aMsg, aActor, aParam.mPersist); + WriteIPDLParam(aMsg, aActor, aParam.mSharedState.Get()->mId); + WriteIPDLParam(aMsg, aActor, aParam.mSharedState.Get()->mTriggeringPrincipal); + WriteIPDLParam(aMsg, aActor, aParam.mSharedState.Get()->mPrincipalToInherit); WriteIPDLParam(aMsg, aActor, - info.mSharedState.Get()->mPartitionedPrincipalToInherit); - WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mCsp); - WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mContentType); - WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mLayoutHistoryState); - WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mCacheKey); + aParam.mSharedState.Get()->mPartitionedPrincipalToInherit); + WriteIPDLParam(aMsg, aActor, aParam.mSharedState.Get()->mCsp); + WriteIPDLParam(aMsg, aActor, aParam.mSharedState.Get()->mContentType); + WriteIPDLParam(aMsg, aActor, aParam.mSharedState.Get()->mLayoutHistoryState); + WriteIPDLParam(aMsg, aActor, aParam.mSharedState.Get()->mCacheKey); +} + +bool IPDLParamTraits::Read( + const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor, + dom::SessionHistoryInfo* aResult) { + Maybe stateData; + uint64_t sharedId; + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mURI) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mOriginalURI) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mResultPrincipalURI) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mReferrerInfo) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mTitle) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mPostData) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadType) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mScrollPositionX) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mScrollPositionY) || + !ReadIPDLParam(aMsg, aIter, aActor, &stateData) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSrcdocData) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mBaseURI) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadReplace) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mURIWasModified) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mIsSrcdocEntry) || + !ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mScrollRestorationIsManual) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mPersist) || + !ReadIPDLParam(aMsg, aIter, aActor, &sharedId)) { + aActor->FatalError("Error reading fields for SessionHistoryInfo"); + return false; + } + + // FIXME If we're in the parent we need to look up the sharedstate + // by id and reuse it, and only create a new one when there is no + // existing sharedstate. + aResult->mSharedState.Get()->mId = sharedId; + if (!ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mSharedState.Get()->mTriggeringPrincipal) || + !ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mSharedState.Get()->mPrincipalToInherit) || + !ReadIPDLParam( + aMsg, aIter, aActor, + &aResult->mSharedState.Get()->mPartitionedPrincipalToInherit) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSharedState.Get()->mCsp) || + !ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mSharedState.Get()->mContentType) || + !ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mSharedState.Get()->mLayoutHistoryState) || + !ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mSharedState.Get()->mCacheKey)) { + aActor->FatalError("Error reading fields for SessionHistoryInfo"); + return false; + } + + if (stateData.isSome()) { + aResult->mStateData = new nsStructuredCloneContainer(); + if (aActor->GetSide() == ChildSide) { + UnpackClonedMessageDataForChild(stateData.ref(), *aResult->mStateData); + } else { + UnpackClonedMessageDataForParent(stateData.ref(), *aResult->mStateData); + } + } + MOZ_ASSERT_IF(stateData.isNothing(), !aResult->mStateData); + return true; +} + +void IPDLParamTraits::Write( + IPC::Message* aMsg, IProtocol* aActor, + const dom::LoadingSessionHistoryInfo& aParam) { + WriteIPDLParam(aMsg, aActor, aParam.mInfo); WriteIPDLParam(aMsg, aActor, aParam.mLoadId); WriteIPDLParam(aMsg, aActor, aParam.mLoadIsFromSessionHistory); WriteIPDLParam(aMsg, aActor, aParam.mRequestedIndex); @@ -1082,65 +1221,8 @@ void IPDLParamTraits::Write( bool IPDLParamTraits::Read( const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor, dom::LoadingSessionHistoryInfo* aResult) { - Maybe stateData; - - dom::SessionHistoryInfo& info = aResult->mInfo; - uint64_t sharedId; - if (!ReadIPDLParam(aMsg, aIter, aActor, &info.mURI) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mOriginalURI) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mResultPrincipalURI) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mReferrerInfo) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mTitle) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mPostData) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mLoadType) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mScrollPositionX) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mScrollPositionY) || - !ReadIPDLParam(aMsg, aIter, aActor, &stateData) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mSrcdocData) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mBaseURI) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mLoadReplace) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mURIWasModified) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mIsSrcdocEntry) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mScrollRestorationIsManual) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mPersist) || - !ReadIPDLParam(aMsg, aIter, aActor, &sharedId)) { - aActor->FatalError("Error reading fields for SessionHistoryInfo"); - return false; - } - - // FIXME If we're in the parent we should probably look up the sharedstate - // by id and reuse it, and only create a new one when there is no - // existing sharedstate. - info.mSharedState.Get()->mId = sharedId; - if (!ReadIPDLParam(aMsg, aIter, aActor, - &info.mSharedState.Get()->mTriggeringPrincipal) || - !ReadIPDLParam(aMsg, aIter, aActor, - &info.mSharedState.Get()->mPrincipalToInherit) || - !ReadIPDLParam( - aMsg, aIter, aActor, - &info.mSharedState.Get()->mPartitionedPrincipalToInherit) || - !ReadIPDLParam(aMsg, aIter, aActor, &info.mSharedState.Get()->mCsp) || - !ReadIPDLParam(aMsg, aIter, aActor, - &info.mSharedState.Get()->mContentType) || - !ReadIPDLParam(aMsg, aIter, aActor, - &info.mSharedState.Get()->mLayoutHistoryState) || - !ReadIPDLParam(aMsg, aIter, aActor, - &info.mSharedState.Get()->mCacheKey)) { - aActor->FatalError("Error reading fields for SessionHistoryInfo"); - return false; - } - - if (stateData.isSome()) { - info.mStateData = new nsStructuredCloneContainer(); - if (aActor->GetSide() == ChildSide) { - UnpackClonedMessageDataForChild(stateData.ref(), *info.mStateData); - } else { - UnpackClonedMessageDataForParent(stateData.ref(), *info.mStateData); - } - } - MOZ_ASSERT_IF(stateData.isNothing(), !info.mStateData); - - if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadId) || + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mInfo) || + !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadId) || !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadIsFromSessionHistory) || !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRequestedIndex) || diff --git a/docshell/shistory/SessionHistoryEntry.h b/docshell/shistory/SessionHistoryEntry.h index bdc074c4b5e8..440d9549929e 100644 --- a/docshell/shistory/SessionHistoryEntry.h +++ b/docshell/shistory/SessionHistoryEntry.h @@ -35,12 +35,35 @@ class SessionHistoryInfo { SessionHistoryInfo() = default; SessionHistoryInfo(const SessionHistoryInfo& aInfo) = default; SessionHistoryInfo(nsDocShellLoadState* aLoadState, nsIChannel* aChannel); + SessionHistoryInfo(const SessionHistoryInfo& aSharedStateFrom, nsIURI* aURI, + const nsID& aDocShellID); + SessionHistoryInfo(nsIURI* aURI, const nsID& aDocShellID, + nsIPrincipal* aTriggeringPrincipal, + nsIContentSecurityPolicy* aCsp, + const nsACString& aContentType); + + void Reset(nsIURI* aURI, const nsID& aDocShellID, bool aDynamicCreation, + nsIPrincipal* aTriggeringPrincipal, + nsIPrincipal* aPrincipalToInherit, + nsIPrincipal* aPartitionedPrincipalToInherit, + nsIContentSecurityPolicy* aCsp, const nsACString& aContentType); bool operator==(const SessionHistoryInfo& aInfo) const { return false; // FIXME } + nsIURI* GetURI() const { return mURI; } + void SetURI(nsIURI* aURI) { mURI = aURI; } + + void SetOriginalURI(nsIURI* aOriginalURI) { mOriginalURI = aOriginalURI; } + + void SetResultPrincipalURI(nsIURI* aResultPrincipalURI) { + mResultPrincipalURI = aResultPrincipalURI; + } + nsIInputStream* GetPostData() const { return mPostData; } + void SetPostData(nsIInputStream* aPostData) { mPostData = aPostData; } + void GetScrollPosition(int32_t* aScrollPositionX, int32_t* aScrollPositionY) { *aScrollPositionX = mScrollPositionX; *aScrollPositionY = mScrollPositionY; @@ -55,16 +78,29 @@ class SessionHistoryInfo { mScrollRestorationIsManual = aIsManual; } - nsIURI* GetURI() const { return mURI; } + void SetStateData(nsStructuredCloneContainer* aStateData) { + mStateData = aStateData; + } + void SetLoadReplace(bool aLoadReplace) { mLoadReplace = aLoadReplace; } + + void SetURIWasModified(bool aURIWasModified) { + mURIWasModified = aURIWasModified; + } bool GetURIWasModified() const { return mURIWasModified; } + uint64_t SharedId() const; + nsILayoutHistoryState* GetLayoutHistoryState(); void SetLayoutHistoryState(nsILayoutHistoryState* aState); + bool SharesDocumentWith(const SessionHistoryInfo& aOther) const { + return SharedId() == aOther.SharedId(); + } + private: friend class SessionHistoryEntry; - friend struct mozilla::ipc::IPDLParamTraits; + friend struct mozilla::ipc::IPDLParamTraits; void MaybeUpdateTitleFromURI(); @@ -132,10 +168,13 @@ struct LoadingSessionHistoryInfo { // but session-history-in-parent needs to pass needed information explicitly // to the relevant child process. bool mLoadIsFromSessionHistory = false; - // mRequestedIndex and mSessionHistoryLength are relevant - // only if mLoadIsFromSessionHistory is true. + // mRequestedIndex, mSessionHistoryLength and mLoadingCurrentActiveEntry are + // relevant only if mLoadIsFromSessionHistory is true. int32_t mRequestedIndex = -1; int32_t mSessionHistoryLength = 0; + // If we're loading from the current active entry we want to treat it as not + // a same-document navigation (see nsDocShell::IsSameDocumentNavigation). + bool mLoadingCurrentActiveEntry = false; }; // SessionHistoryEntry is used to store session history data in the parent @@ -152,6 +191,7 @@ class SessionHistoryEntry : public nsISHEntry { public: SessionHistoryEntry(nsDocShellLoadState* aLoadState, nsIChannel* aChannel); SessionHistoryEntry(); + explicit SessionHistoryEntry(SessionHistoryInfo* aInfo); NS_DECL_ISUPPORTS NS_DECL_NSISHENTRY @@ -169,6 +209,8 @@ class SessionHistoryEntry : public nsISHEntry { // then it returns false. bool ReplaceChild(SessionHistoryEntry* aNewChild); + void SetInfo(SessionHistoryInfo* aInfo); + // Get an entry based on LoadingSessionHistoryInfo's mLoadId. Parent process // only. static SessionHistoryEntry* GetByLoadId(uint64_t aLoadId); @@ -194,6 +236,15 @@ NS_DEFINE_STATIC_IID_ACCESSOR(SessionHistoryEntry, NS_SESSIONHISTORYENTRY_IID) namespace ipc { +// Allow sending SessionHistoryInfo objects over IPC. +template <> +struct IPDLParamTraits { + static void Write(IPC::Message* aMsg, IProtocol* aActor, + const dom::SessionHistoryInfo& aParam); + static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, dom::SessionHistoryInfo* aResult); +}; + // Allow sending LoadingSessionHistoryInfo objects over IPC. template <> struct IPDLParamTraits { diff --git a/docshell/shistory/nsSHistory.cpp b/docshell/shistory/nsSHistory.cpp index b526f9769ac3..fe18ff273c12 100644 --- a/docshell/shistory/nsSHistory.cpp +++ b/docshell/shistory/nsSHistory.cpp @@ -1730,7 +1730,21 @@ void nsSHistory::InitiateLoad(nsISHEntry* aFrameEntry, loadState->SetLoadType(aLoadType); loadState->SetSHEntry(aFrameEntry); - loadState->SetLoadIsFromSessionHistory(mRequestedIndex, Length()); + + // If we're loading from the current active entry we want to treat it as not + // a same-document navigation (see nsDocShell::IsSameDocumentNavigation), so + // record that here in the LoadingSessionHistoryEntry. + bool loadingFromActiveEntry; + if (StaticPrefs::fission_sessionHistoryInParent()) { + loadingFromActiveEntry = + aFrameBC->Canonical()->GetActiveSessionHistoryEntry() == aFrameEntry; + } else { + loadingFromActiveEntry = + aFrameBC->GetDocShell() && + nsDocShell::Cast(aFrameBC->GetDocShell())->IsOSHE(aFrameEntry); + } + loadState->SetLoadIsFromSessionHistory(mRequestedIndex, Length(), + loadingFromActiveEntry); nsCOMPtr originalURI = aFrameEntry->GetOriginalURI(); loadState->SetOriginalURI(originalURI); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index bcbe1e7e1215..6e35bbd1fe68 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -6902,13 +6902,13 @@ mozilla::ipc::IPCResult ContentParent::RecvHistoryCommit( } mozilla::ipc::IPCResult ContentParent::RecvHistoryGo( - const MaybeDiscarded& aContext, int32_t aOffset, + const MaybeDiscarded& aContext, int32_t aIndex, HistoryGoResolver&& aResolveRequestedIndex) { if (!aContext.IsDiscarded()) { nsSHistory* shistory = static_cast(aContext.get_canonical()->GetSessionHistory()); nsTArray loadResults; - nsresult rv = shistory->GotoIndex(aOffset, loadResults); + nsresult rv = shistory->GotoIndex(aIndex, loadResults); if (NS_FAILED(rv)) { return IPC_FAIL(this, "GotoIndex failed"); } @@ -6995,6 +6995,37 @@ mozilla::ipc::IPCResult ContentParent::RecvSessionHistoryEntryCacheKey( return IPC_OK(); } +mozilla::ipc::IPCResult ContentParent::RecvSetActiveSessionHistoryEntryForTop( + const MaybeDiscarded& aContext, + const Maybe& aPreviousScrollPos, SessionHistoryInfo&& aInfo, + uint32_t aLoadType, const nsID& aChangeID) { + if (!aContext.IsDiscarded()) { + aContext.get_canonical()->SetActiveSessionHistoryEntryForTop( + aPreviousScrollPos, &aInfo, aLoadType, aChangeID); + } + return IPC_OK(); +} + +mozilla::ipc::IPCResult ContentParent::RecvSetActiveSessionHistoryEntryForFrame( + const MaybeDiscarded& aContext, + const Maybe& aPreviousScrollPos, SessionHistoryInfo&& aInfo, + int32_t aChildOffset, const nsID& aChangeID) { + if (!aContext.IsDiscarded()) { + aContext.get_canonical()->SetActiveSessionHistoryEntryForFrame( + aPreviousScrollPos, &aInfo, aChildOffset, aChangeID); + } + return IPC_OK(); +} + +mozilla::ipc::IPCResult ContentParent::RecvReplaceActiveSessionHistoryEntry( + const MaybeDiscarded& aContext, + SessionHistoryInfo&& aInfo) { + if (!aContext.IsDiscarded()) { + aContext.get_canonical()->ReplaceActiveSessionHistoryEntry(&aInfo); + } + return IPC_OK(); +} + mozilla::ipc::IPCResult ContentParent::RecvCommitWindowContextTransaction( const MaybeDiscarded& aContext, WindowContext::BaseTransaction&& aTransaction, uint64_t aEpoch) { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index a6fb284c7e0c..dad28f8b9952 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -1354,6 +1354,20 @@ class ContentParent final const MaybeDiscarded& aContext, const uint32_t& aCacheKey); + mozilla::ipc::IPCResult RecvSetActiveSessionHistoryEntryForTop( + const MaybeDiscarded& aContext, + const Maybe& aPreviousScrollPos, SessionHistoryInfo&& aInfo, + uint32_t aLoadType, const nsID& aChangeID); + + mozilla::ipc::IPCResult RecvSetActiveSessionHistoryEntryForFrame( + const MaybeDiscarded& aContext, + const Maybe& aPreviousScrollPos, SessionHistoryInfo&& aInfo, + int32_t aChildOffset, const nsID& aChangeID); + + mozilla::ipc::IPCResult RecvReplaceActiveSessionHistoryEntry( + const MaybeDiscarded& aContext, + SessionHistoryInfo&& aInfo); + // Notify the ContentChild to enable the input event prioritization when // initializing. void MaybeEnableRemoteInputEventQueue(); diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 37146ea355fa..037610827a46 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -129,6 +129,8 @@ using JSActorMessageKind from "mozilla/dom/JSActor.h"; using JSActorMessageMeta from "mozilla/dom/PWindowGlobal.h"; using mozilla::PermissionDelegateHandler::DelegatedPermissionList from "mozilla/PermissionDelegateIPCUtils.h"; using refcounted class nsILayoutHistoryState from "nsILayoutHistoryState.h"; +using class mozilla::dom::SessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h"; +using nsPoint from "mozilla/GfxMessageUtils.h"; union ChromeRegistryItem { @@ -1676,6 +1678,16 @@ parent: nsID? aAgentClusterId) returns (BlobURLDataRequestResult aResult); + async SetActiveSessionHistoryEntryForTop(MaybeDiscardedBrowsingContext aContext, + nsPoint? previousScrollPosition, + SessionHistoryInfo info, uint32_t loadType, + nsID changeID); + async SetActiveSessionHistoryEntryForFrame( + MaybeDiscardedBrowsingContext aContext, nsPoint? previousScrollPosition, + SessionHistoryInfo info, int32_t childOffset, nsID changeID); + async ReplaceActiveSessionHistoryEntry( + MaybeDiscardedBrowsingContext aContext, SessionHistoryInfo info); + both: async ScriptError(nsString message, nsString sourceName, nsString sourceLine, uint32_t lineNumber, uint32_t colNumber, uint32_t flags, From 6e49bf5815cade3c62591e0c7adc30d4e8509d35 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Sun, 23 Aug 2020 17:41:06 +0000 Subject: [PATCH 06/56] Bug 1659991 - Generate an id if we create a new session history entry in the child process. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D87742 --- docshell/shistory/SessionHistoryEntry.cpp | 5 ++--- docshell/shistory/nsSHEntryShared.cpp | 11 ++++++++--- docshell/shistory/nsSHEntryShared.h | 9 ++++++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/docshell/shistory/SessionHistoryEntry.cpp b/docshell/shistory/SessionHistoryEntry.cpp index 0c9fe11e80a2..390865721ac8 100644 --- a/docshell/shistory/SessionHistoryEntry.cpp +++ b/docshell/shistory/SessionHistoryEntry.cpp @@ -129,10 +129,9 @@ SessionHistoryInfo::SharedState SessionHistoryInfo::SharedState::Create( aPartitionedPrincipalToInherit, aCsp, aContentType)); } - // FIXME Pass the correct ID!!! return SharedState(MakeUnique( - 0, aTriggeringPrincipal, aPrincipalToInherit, - aPartitionedPrincipalToInherit, aCsp, aContentType)); + aTriggeringPrincipal, aPrincipalToInherit, aPartitionedPrincipalToInherit, + aCsp, aContentType)); } SessionHistoryInfo::SharedState::SharedState() { diff --git a/docshell/shistory/nsSHEntryShared.cpp b/docshell/shistory/nsSHEntryShared.cpp index f51265484086..4969cb3488cb 100644 --- a/docshell/shistory/nsSHEntryShared.cpp +++ b/docshell/shistory/nsSHEntryShared.cpp @@ -7,6 +7,7 @@ #include "nsSHEntryShared.h" #include "nsArray.h" +#include "nsContentUtils.h" #include "nsDocShellEditorData.h" #include "nsIContentViewer.h" #include "nsISHistory.h" @@ -28,13 +29,17 @@ uint64_t gSHEntrySharedID = 0; namespace mozilla { namespace dom { +/* static */ +uint64_t SHEntrySharedState::GenerateId() { + return nsContentUtils::GenerateProcessSpecificId(++gSHEntrySharedID); +} + SHEntrySharedParentState::SHEntrySharedParentState( nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aPartitionedPrincipalToInherit, nsIContentSecurityPolicy* aCsp, const nsACString& aContentType) - : SHEntrySharedState(++gSHEntrySharedID, aTriggeringPrincipal, - aPrincipalToInherit, aPartitionedPrincipalToInherit, - aCsp, aContentType) {} + : SHEntrySharedState(aTriggeringPrincipal, aPrincipalToInherit, + aPartitionedPrincipalToInherit, aCsp, aContentType) {} SHEntrySharedParentState::~SHEntrySharedParentState() {} diff --git a/docshell/shistory/nsSHEntryShared.h b/docshell/shistory/nsSHEntryShared.h index 90c9d80d3d08..e8cf83130c05 100644 --- a/docshell/shistory/nsSHEntryShared.h +++ b/docshell/shistory/nsSHEntryShared.h @@ -48,14 +48,14 @@ class Document; * parent process. */ struct SHEntrySharedState { - SHEntrySharedState() = default; + SHEntrySharedState() : mId(GenerateId()) {} SHEntrySharedState(const SHEntrySharedState& aState) = default; - SHEntrySharedState(uint64_t aId, nsIPrincipal* aTriggeringPrincipal, + SHEntrySharedState(nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aPartitionedPrincipalToInherit, nsIContentSecurityPolicy* aCsp, const nsACString& aContentType) - : mId(aId), + : mId(GenerateId()), mTriggeringPrincipal(aTriggeringPrincipal), mPrincipalToInherit(aPrincipalToInherit), mPartitionedPrincipalToInherit(aPartitionedPrincipalToInherit), @@ -77,6 +77,9 @@ struct SHEntrySharedState { // moved to bfcache. nsCOMPtr mLayoutHistoryState; uint32_t mCacheKey = 0; + + protected: + static uint64_t GenerateId(); }; /** From 73b5ecf2d5614f902f95bc518960a70d2e984176 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Sun, 23 Aug 2020 20:14:03 +0000 Subject: [PATCH 07/56] Bug 1659991 - Reuse an existing shared state in the parent process. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D87743 --- docshell/shistory/SessionHistoryEntry.cpp | 82 ++++++++++++++++++----- docshell/shistory/SessionHistoryEntry.h | 4 ++ docshell/shistory/nsSHEntry.cpp | 2 +- docshell/shistory/nsSHEntryShared.cpp | 46 ++++++++++++- docshell/shistory/nsSHEntryShared.h | 9 ++- 5 files changed, 123 insertions(+), 20 deletions(-) diff --git a/docshell/shistory/SessionHistoryEntry.cpp b/docshell/shistory/SessionHistoryEntry.cpp index 390865721ac8..17ef7de3caea 100644 --- a/docshell/shistory/SessionHistoryEntry.cpp +++ b/docshell/shistory/SessionHistoryEntry.cpp @@ -10,6 +10,7 @@ #include "nsStructuredCloneContainer.h" #include "nsXULAppAPI.h" #include "mozilla/PresState.h" +#include "mozilla/dom/nsCSPContext.h" #include "mozilla/ipc/IPDLParamTraits.h" namespace mozilla { @@ -182,6 +183,15 @@ SHEntrySharedState* SessionHistoryInfo::SharedState::Get() const { return mChild.get(); } + +void SessionHistoryInfo::SharedState::ChangeId(uint64_t aId) { + if (XRE_IsParentProcess()) { + mParent->ChangeId(aId); + } else { + mChild->mId = aId; + } +} + static uint64_t gLoadingSessionHistoryInfoLoadId = 0; nsDataHashtable* @@ -825,7 +835,7 @@ SessionHistoryEntry::SharesDocumentWith(nsISHEntry* aEntry, SessionHistoryEntry* entry = static_cast(aEntry); MOZ_ASSERT_IF(entry->SharedInfo() != SharedInfo(), - entry->SharedInfo()->GetID() != SharedInfo()->GetID()); + entry->SharedInfo()->GetId() != SharedInfo()->GetId()); *aSharesDocumentWith = entry->SharedInfo() == SharedInfo(); return NS_OK; @@ -1173,21 +1183,63 @@ bool IPDLParamTraits::Read( return false; } - // FIXME If we're in the parent we need to look up the sharedstate - // by id and reuse it, and only create a new one when there is no - // existing sharedstate. - aResult->mSharedState.Get()->mId = sharedId; + nsCOMPtr triggeringPrincipal; + nsCOMPtr principalToInherit; + nsCOMPtr partitionedPrincipalToInherit; + nsCOMPtr csp; + nsCString contentType; + if (!ReadIPDLParam(aMsg, aIter, aActor, &triggeringPrincipal) || + !ReadIPDLParam(aMsg, aIter, aActor, &principalToInherit) || + !ReadIPDLParam(aMsg, aIter, aActor, &partitionedPrincipalToInherit) || + !ReadIPDLParam(aMsg, aIter, aActor, &csp) || + !ReadIPDLParam(aMsg, aIter, aActor, &contentType)) { + aActor->FatalError("Error reading fields for SessionHistoryInfo"); + return false; + } + + dom::SHEntrySharedParentState* sharedState = nullptr; + if (XRE_IsParentProcess()) { + sharedState = dom::SHEntrySharedParentState::Lookup(sharedId); + } + + if (sharedState) { + aResult->mSharedState.Set(sharedState); + + MOZ_ASSERT(triggeringPrincipal + ? triggeringPrincipal->Equals( + aResult->mSharedState.Get()->mTriggeringPrincipal) + : !aResult->mSharedState.Get()->mTriggeringPrincipal, + "We don't expect this to change!"); + MOZ_ASSERT(principalToInherit + ? principalToInherit->Equals( + aResult->mSharedState.Get()->mPrincipalToInherit) + : !aResult->mSharedState.Get()->mPrincipalToInherit, + "We don't expect this to change!"); + MOZ_ASSERT( + partitionedPrincipalToInherit + ? partitionedPrincipalToInherit->Equals( + aResult->mSharedState.Get()->mPartitionedPrincipalToInherit) + : !aResult->mSharedState.Get()->mPartitionedPrincipalToInherit, + "We don't expect this to change!"); + MOZ_ASSERT( + csp ? nsCSPContext::Equals(csp, aResult->mSharedState.Get()->mCsp) + : !aResult->mSharedState.Get()->mCsp, + "We don't expect this to change!"); + MOZ_ASSERT(contentType.Equals(aResult->mSharedState.Get()->mContentType), + "We don't expect this to change!"); + } else { + aResult->mSharedState.ChangeId(sharedId); + aResult->mSharedState.Get()->mTriggeringPrincipal = + triggeringPrincipal.forget(); + aResult->mSharedState.Get()->mPrincipalToInherit = + principalToInherit.forget(); + aResult->mSharedState.Get()->mPartitionedPrincipalToInherit = + partitionedPrincipalToInherit.forget(); + aResult->mSharedState.Get()->mCsp = csp.forget(); + aResult->mSharedState.Get()->mContentType = contentType; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, - &aResult->mSharedState.Get()->mTriggeringPrincipal) || - !ReadIPDLParam(aMsg, aIter, aActor, - &aResult->mSharedState.Get()->mPrincipalToInherit) || - !ReadIPDLParam( - aMsg, aIter, aActor, - &aResult->mSharedState.Get()->mPartitionedPrincipalToInherit) || - !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSharedState.Get()->mCsp) || - !ReadIPDLParam(aMsg, aIter, aActor, - &aResult->mSharedState.Get()->mContentType) || - !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSharedState.Get()->mLayoutHistoryState) || !ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSharedState.Get()->mCacheKey)) { diff --git a/docshell/shistory/SessionHistoryEntry.h b/docshell/shistory/SessionHistoryEntry.h index 440d9549929e..6294bac58093 100644 --- a/docshell/shistory/SessionHistoryEntry.h +++ b/docshell/shistory/SessionHistoryEntry.h @@ -132,6 +132,10 @@ class SessionHistoryInfo { SHEntrySharedState* Get() const; + void Set(SHEntrySharedParentState* aState) { mParent = aState; } + + void ChangeId(uint64_t aId); + static SharedState Create(nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aPartitionedPrincipalToInherit, diff --git a/docshell/shistory/nsSHEntry.cpp b/docshell/shistory/nsSHEntry.cpp index 99e12abc1fea..6f6284b983be 100644 --- a/docshell/shistory/nsSHEntry.cpp +++ b/docshell/shistory/nsSHEntry.cpp @@ -1057,6 +1057,6 @@ nsSHEntry::AbandonBFCacheEntry() { NS_IMETHODIMP nsSHEntry::GetBfcacheID(uint64_t* aBFCacheID) { - *aBFCacheID = mShared->GetID(); + *aBFCacheID = mShared->GetId(); return NS_OK; } diff --git a/docshell/shistory/nsSHEntryShared.cpp b/docshell/shistory/nsSHEntryShared.cpp index 4969cb3488cb..2ee39b1d900d 100644 --- a/docshell/shistory/nsSHEntryShared.cpp +++ b/docshell/shistory/nsSHEntryShared.cpp @@ -24,6 +24,8 @@ namespace dom = mozilla::dom; namespace { uint64_t gSHEntrySharedID = 0; +nsDataHashtable* + sIdToSharedState = nullptr; } // namespace namespace mozilla { @@ -34,14 +36,54 @@ uint64_t SHEntrySharedState::GenerateId() { return nsContentUtils::GenerateProcessSpecificId(++gSHEntrySharedID); } +/* static */ +SHEntrySharedParentState* SHEntrySharedParentState::Lookup(uint64_t aId) { + MOZ_ASSERT(aId != 0); + + return sIdToSharedState ? sIdToSharedState->Get(aId) : nullptr; +} + +static void AddSHEntrySharedParentState( + SHEntrySharedParentState* aSharedState) { + MOZ_ASSERT(aSharedState->mId != 0); + + if (!sIdToSharedState) { + sIdToSharedState = + new nsDataHashtable(); + } + sIdToSharedState->Put(aSharedState->mId, aSharedState); +} + +SHEntrySharedParentState::SHEntrySharedParentState() { + AddSHEntrySharedParentState(this); +} + SHEntrySharedParentState::SHEntrySharedParentState( nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aPartitionedPrincipalToInherit, nsIContentSecurityPolicy* aCsp, const nsACString& aContentType) : SHEntrySharedState(aTriggeringPrincipal, aPrincipalToInherit, - aPartitionedPrincipalToInherit, aCsp, aContentType) {} + aPartitionedPrincipalToInherit, aCsp, aContentType) { + AddSHEntrySharedParentState(this); +} -SHEntrySharedParentState::~SHEntrySharedParentState() {} +SHEntrySharedParentState::~SHEntrySharedParentState() { + MOZ_ASSERT(mId != 0); + + sIdToSharedState->Remove(mId); + if (sIdToSharedState->IsEmpty()) { + delete sIdToSharedState; + sIdToSharedState = nullptr; + } +} + +void SHEntrySharedParentState::ChangeId(uint64_t aId) { + MOZ_ASSERT(aId != 0); + + sIdToSharedState->Remove(mId); + mId = aId; + sIdToSharedState->Put(mId, this); +} void SHEntrySharedParentState::CopyFrom(SHEntrySharedParentState* aEntry) { mDocShellID = aEntry->mDocShellID; diff --git a/docshell/shistory/nsSHEntryShared.h b/docshell/shistory/nsSHEntryShared.h index e8cf83130c05..603df12e3f9f 100644 --- a/docshell/shistory/nsSHEntryShared.h +++ b/docshell/shistory/nsSHEntryShared.h @@ -90,17 +90,22 @@ class SHEntrySharedParentState : public SHEntrySharedState { public: friend class SessionHistoryInfo; - uint64_t GetID() const { return mId; } + uint64_t GetId() const { return mId; } + void ChangeId(uint64_t aId); void NotifyListenersContentViewerEvicted(); - SHEntrySharedParentState() = default; + SHEntrySharedParentState(); SHEntrySharedParentState(nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aPartitionedPrincipalToInherit, nsIContentSecurityPolicy* aCsp, const nsACString& aContentType); + // This returns the existing SHEntrySharedParentState that was registered for + // aId, if one exists. + static SHEntrySharedParentState* Lookup(uint64_t aId); + protected: virtual ~SHEntrySharedParentState(); NS_INLINE_DECL_VIRTUAL_REFCOUNTING_WITH_DESTROY(SHEntrySharedParentState, From 30b0eb25b21105d672b36ce2f58acebbd139e7bb Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Sun, 23 Aug 2020 17:41:13 +0000 Subject: [PATCH 08/56] Bug 1659992 - Fix nsDocShell::LoadURI for session history loads to not rely on session history in the child. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D87744 --- docshell/base/nsDocShell.cpp | 15 +++- docshell/base/nsDocShell.h | 3 + docshell/shistory/SessionHistoryEntry.cpp | 89 +++++++++++++---------- docshell/shistory/SessionHistoryEntry.h | 4 + 4 files changed, 70 insertions(+), 41 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 5b72fdfed250..cf5f1c08fed3 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -818,7 +818,13 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) { ("nsDocShell[%p]: loading from session history", this)); #endif - return LoadHistoryEntry(aLoadState->SHEntry(), aLoadState->LoadType()); + if (!StaticPrefs::fission_sessionHistoryInParent()) { + return LoadHistoryEntry(aLoadState->SHEntry(), aLoadState->LoadType()); + } + + // FIXME Null check aLoadState->GetLoadingSessionHistoryInfo()? + return LoadHistoryEntry(*aLoadState->GetLoadingSessionHistoryInfo(), + aLoadState->LoadType()); } // On history navigation via Back/Forward buttons, don't execute @@ -11208,6 +11214,13 @@ nsresult nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType) { return LoadHistoryEntry(loadState, aLoadType, aEntry == mOSHE); } +nsresult nsDocShell::LoadHistoryEntry(const LoadingSessionHistoryInfo& aEntry, + uint32_t aLoadType) { + RefPtr loadState = aEntry.CreateLoadInfo(); + return LoadHistoryEntry(loadState, aLoadType, + aEntry.mLoadingCurrentActiveEntry); +} + nsresult nsDocShell::LoadHistoryEntry(nsDocShellLoadState* aLoadState, uint32_t aLoadType, bool aReloadingActiveEntry) { diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 3d03af425dbf..d3781b54c1c7 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -990,6 +990,9 @@ class nsDocShell final : public nsDocLoader, nsPresContext* GetEldestPresContext(); nsresult CheckLoadingPermissions(); nsresult LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType); + nsresult LoadHistoryEntry( + const mozilla::dom::LoadingSessionHistoryInfo& aEntry, + uint32_t aLoadType); nsresult LoadHistoryEntry(nsDocShellLoadState* aLoadState, uint32_t aLoadType, bool aReloadingActiveEntry); nsresult GetHttpChannel(nsIChannel* aChannel, nsIHttpChannel** aReturn); diff --git a/docshell/shistory/SessionHistoryEntry.cpp b/docshell/shistory/SessionHistoryEntry.cpp index 17ef7de3caea..1a434150d387 100644 --- a/docshell/shistory/SessionHistoryEntry.cpp +++ b/docshell/shistory/SessionHistoryEntry.cpp @@ -119,6 +119,42 @@ void SessionHistoryInfo::SetLayoutHistoryState(nsILayoutHistoryState* aState) { mSharedState.Get()->mLayoutHistoryState = aState; } +void SessionHistoryInfo::FillLoadInfo(nsDocShellLoadState& aLoadState) const { + aLoadState.SetOriginalURI(mOriginalURI); + aLoadState.SetMaybeResultPrincipalURI(Some(mResultPrincipalURI)); + aLoadState.SetLoadReplace(mLoadReplace); + aLoadState.SetPostDataStream(mPostData); + aLoadState.SetReferrerInfo(mReferrerInfo); + + aLoadState.SetTypeHint(mSharedState.Get()->mContentType); + aLoadState.SetTriggeringPrincipal(mSharedState.Get()->mTriggeringPrincipal); + aLoadState.SetPrincipalToInherit(mSharedState.Get()->mPrincipalToInherit); + aLoadState.SetPartitionedPrincipalToInherit( + mSharedState.Get()->mPartitionedPrincipalToInherit); + aLoadState.SetCsp(mSharedState.Get()->mCsp); + + // Do not inherit principal from document (security-critical!); + uint32_t flags = nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_NONE; + + // Passing nullptr as aSourceDocShell gives the same behaviour as before + // aSourceDocShell was introduced. According to spec we should be passing + // the source browsing context that was used when the history entry was + // first created. bug 947716 has been created to address this issue. + nsAutoString srcdoc; + nsCOMPtr baseURI; + if (mIsSrcdocEntry) { + srcdoc = mSrcdocData; + baseURI = mBaseURI; + flags |= nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_IS_SRCDOC; + } else { + srcdoc = VoidString(); + } + aLoadState.SetSrcdocData(srcdoc); + aLoadState.SetBaseURI(baseURI); + aLoadState.SetLoadFlags(flags); + + aLoadState.SetFirstParty(true); +} /* static */ SessionHistoryInfo::SharedState SessionHistoryInfo::SharedState::Create( nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit, @@ -207,6 +243,18 @@ LoadingSessionHistoryInfo::LoadingSessionHistoryInfo( SessionHistoryEntry::sLoadIdToEntry->Put(mLoadId, aEntry); } +already_AddRefed +LoadingSessionHistoryInfo::CreateLoadInfo() const { + RefPtr loadState( + new nsDocShellLoadState(mInfo.GetURI())); + + mInfo.FillLoadInfo(*loadState); + + loadState->SetLoadingSessionHistoryInfo(*this); + + return loadState.forget(); +} + static uint32_t gEntryID; SessionHistoryEntry* SessionHistoryEntry::GetByLoadId(uint64_t aLoadId) { @@ -1040,46 +1088,7 @@ SessionHistoryEntry::ClearEntry() { NS_IMETHODIMP SessionHistoryEntry::CreateLoadInfo(nsDocShellLoadState** aLoadState) { - nsCOMPtr uri = GetURI(); - RefPtr loadState(new nsDocShellLoadState(mInfo->mURI)); - - loadState->SetOriginalURI(mInfo->mOriginalURI); - loadState->SetMaybeResultPrincipalURI(Some(mInfo->mResultPrincipalURI)); - loadState->SetLoadReplace(mInfo->mLoadReplace); - loadState->SetPostDataStream(mInfo->mPostData); - loadState->SetReferrerInfo(mInfo->mReferrerInfo); - - loadState->SetTypeHint(SharedInfo()->mContentType); - loadState->SetTriggeringPrincipal(SharedInfo()->mTriggeringPrincipal); - loadState->SetPrincipalToInherit(SharedInfo()->mPrincipalToInherit); - loadState->SetPartitionedPrincipalToInherit( - SharedInfo()->mPartitionedPrincipalToInherit); - loadState->SetCsp(SharedInfo()->mCsp); - - // Do not inherit principal from document (security-critical!); - uint32_t flags = nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_NONE; - - // Passing nullptr as aSourceDocShell gives the same behaviour as before - // aSourceDocShell was introduced. According to spec we should be passing - // the source browsing context that was used when the history entry was - // first created. bug 947716 has been created to address this issue. - nsAutoString srcdoc; - nsCOMPtr baseURI; - if (mInfo->mIsSrcdocEntry) { - srcdoc = mInfo->mSrcdocData; - baseURI = mInfo->mBaseURI; - flags |= nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_IS_SRCDOC; - } else { - srcdoc = VoidString(); - } - loadState->SetSrcdocData(srcdoc); - loadState->SetBaseURI(baseURI); - loadState->SetLoadFlags(flags); - - loadState->SetFirstParty(true); - loadState->SetSHEntry(this); - - loadState.forget(aLoadState); + NS_WARNING("We shouldn't be calling this!"); return NS_OK; } diff --git a/docshell/shistory/SessionHistoryEntry.h b/docshell/shistory/SessionHistoryEntry.h index 6294bac58093..2d9944d90d52 100644 --- a/docshell/shistory/SessionHistoryEntry.h +++ b/docshell/shistory/SessionHistoryEntry.h @@ -98,6 +98,8 @@ class SessionHistoryInfo { return SharedId() == aOther.SharedId(); } + void FillLoadInfo(nsDocShellLoadState& aLoadState) const; + private: friend class SessionHistoryEntry; friend struct mozilla::ipc::IPDLParamTraits; @@ -162,6 +164,8 @@ struct LoadingSessionHistoryInfo { LoadingSessionHistoryInfo() = default; explicit LoadingSessionHistoryInfo(SessionHistoryEntry* aEntry); + already_AddRefed CreateLoadInfo() const; + SessionHistoryInfo mInfo; uint64_t mLoadId = 0; From c4f4ade87092fdbb1ebdc10181bf28246cba2eb4 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Mon, 24 Aug 2020 09:32:04 +0000 Subject: [PATCH 09/56] Bug 1660620 - Automated test for displaying the bookmarks toolbar upon startup of new profile. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D87953 --- ...ser_default_bookmark_toolbar_visibility.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/browser/components/tests/browser/browser_default_bookmark_toolbar_visibility.js b/browser/components/tests/browser/browser_default_bookmark_toolbar_visibility.js index 1a5ab009358b..6dab7ed1edab 100644 --- a/browser/components/tests/browser/browser_default_bookmark_toolbar_visibility.js +++ b/browser/components/tests/browser/browser_default_bookmark_toolbar_visibility.js @@ -41,3 +41,42 @@ add_task(async function test_default_bookmark_toolbar_visibility() { "The bookmarks toolbar should be collapsed by default" ); }); + +/** + * Ensure that the bookmarks toolbar is visible in a new profile + * if the toolbar has > 3 (NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE) bookmarks. + */ +add_task(async function test_bookmark_toolbar_visible_when_populated() { + const { Bookmarks } = ChromeUtils.import( + "resource://gre/modules/Bookmarks.jsm" + ); + const { PlacesUIUtils } = ChromeUtils.import( + "resource:///modules/PlacesUIUtils.jsm" + ); + + let bookmark = { + type: Bookmarks.TYPE_BOOKMARK, + parentGuid: Bookmarks.toolbarGuid, + }; + let bookmarksInserted = await Promise.all([ + Bookmarks.insert(Object.assign({ url: "https://example.com/1" }, bookmark)), + Bookmarks.insert(Object.assign({ url: "https://example.com/2" }, bookmark)), + Bookmarks.insert(Object.assign({ url: "https://example.com/3" }, bookmark)), + Bookmarks.insert(Object.assign({ url: "https://example.com/4" }, bookmark)), + Bookmarks.insert(Object.assign({ url: "https://example.com/5" }, bookmark)), + Bookmarks.insert(Object.assign({ url: "https://example.com/6" }, bookmark)), + ]); + + PlacesUIUtils.maybeToggleBookmarkToolbarVisibility(); + + const personalToolbar = document.getElementById("PersonalToolbar"); + ok( + !personalToolbar.collapsed, + "The bookmarks toolbar should be visible since it has many bookmarks" + ); + + for (let insertedBookmark of bookmarksInserted) { + await Bookmarks.remove(insertedBookmark.guid); + } + personalToolbar.collapsed = true; +}); From 32685b1f6ea4112021df86f33ca4b177b302dc74 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Mon, 24 Aug 2020 10:32:27 +0000 Subject: [PATCH 10/56] Bug 1659847 - Explicitly set the showBookmarksToolbarAfterMigration pref so tests will continue to run after the feature is disabled. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D87980 --- browser/components/migration/tests/unit/xpcshell.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/browser/components/migration/tests/unit/xpcshell.ini b/browser/components/migration/tests/unit/xpcshell.ini index 942d23a167ce..0e25e6bc94b1 100644 --- a/browser/components/migration/tests/unit/xpcshell.ini +++ b/browser/components/migration/tests/unit/xpcshell.ini @@ -2,6 +2,8 @@ head = head_migration.js firefox-appdir = browser skip-if = toolkit == 'android' +prefs = + browser.migrate.showBookmarksToolbarAfterMigration=true support-files = Library/** AppData/** From 2421d68d387d13f657649815cd22197a5df84894 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Mon, 24 Aug 2020 11:09:56 +0000 Subject: [PATCH 11/56] Bug 1660558 - Handle any exception thrown when trying to load Subprocess due to unsupported platforms. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D87954 --- toolkit/modules/Troubleshoot.jsm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/toolkit/modules/Troubleshoot.jsm b/toolkit/modules/Troubleshoot.jsm index 9cfda8f2176e..765f6c303f61 100644 --- a/toolkit/modules/Troubleshoot.jsm +++ b/toolkit/modules/Troubleshoot.jsm @@ -22,10 +22,6 @@ const { FeatureGate } = ChromeUtils.import( "resource://featuregates/FeatureGate.jsm" ); -let { Subprocess } = ChromeUtils.import( - "resource://gre/modules/Subprocess.jsm" -); - XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser"]); // We use a preferences whitelist to make sure we only show preferences that @@ -441,6 +437,16 @@ var dataProviders = { }, async environmentVariables(done) { + let Subprocess; + try { + // Subprocess is not available in all builds + Subprocess = ChromeUtils.import("resource://gre/modules/Subprocess.jsm") + .Subprocess; + } catch (ex) { + done({}); + return; + } + let environment = Subprocess.getEnvironment(); let filteredEnvironment = {}; // Limit the environment variables to those that we From 5341051fc92dc7fccf1a9c87825289f1484a95fb Mon Sep 17 00:00:00 2001 From: Daisuke Akatsuka Date: Mon, 24 Aug 2020 11:19:47 +0000 Subject: [PATCH 12/56] Bug 1634045: Add a README for the compatibility panel. r=rcaliman,Honza Differential Revision: https://phabricator.services.mozilla.com/D87981 --- .../client/inspector/compatibility/README.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 devtools/client/inspector/compatibility/README.md diff --git a/devtools/client/inspector/compatibility/README.md b/devtools/client/inspector/compatibility/README.md new file mode 100644 index 000000000000..5a04ad4d39bb --- /dev/null +++ b/devtools/client/inspector/compatibility/README.md @@ -0,0 +1,62 @@ +# Compatibility Panel + +## Related files +The compatibility panel consists of the following files: +* Client: + * Main: `devtools/client/inspector/compatibility/` + * Style: `devtools/client/themes/compatibility.css` +* Shared: + * MDN compatibility dataset: `devtools/shared/compatibility/dataset/` + * MDN compatibility library: `devtools/shared/compatibility/MDNCompatibility.js` +* Server: + * Actor: `devtools/server/actors/compatibility.js` + * Front: `devtools/client/fronts/compatibility.js` + * Spec: `devtools/shared/specs/compatibility.js` + +## How to update the MDN compatibility data +The Compatibility panel detects issues by comparing against official [MDN compatibility data](https://github.com/mdn/browser-compat-data). It uses a local snapshot of the dataset. This dataset needs to be manually synchronized periodically to `devtools/shared/compatibility/dataset` (ideally with every Firefox release). + +The subsets from the dataset required by the Compatibility panel are: +* browsers: [https://github.com/mdn/browser-compat-data/tree/master/browsers](https://github.com/mdn/browser-compat-data/tree/master/browsers) +* css.properties: [https://github.com/mdn/browser-compat-data/tree/master/css](https://github.com/mdn/browser-compat-data/tree/master/css). + +The MDN compatibility data is available as a node package ([mdn-browser-compat-data](https://www.npmjs.com/package/mdn-browser-compat-data)). +The following node program is a sample of how to download `browsers.json` and `css-properties.json` using the node package. + +```javascript +'use strict'; + +const compatData = require("mdn-browser-compat-data"); +const fs = require("fs") +const path = require("path") + +function exportData(data, fileName) { + const content = `${ JSON.stringify(data) }` + + fs.writeFile( + path.resolve( + __dirname, + fileName + ), + content, + err => { + if (err) { + console.error(err) + } + } + ) +} + +exportData(compatData.css.properties, "css-properties.json"); +exportData(compatData.browsers, "browsers.json"); + +``` + +Save the JSON files created by the script to `devtools/shared/compatibility/dataset/`. + +Check that all tests still pass. It is possible that changes in the structure or contents of the latest dataset will cause tests to fail. If that is the case, fix the tests. **Do not manually change the contents or structure of the local dataset** because any changes will be overwritten by the next update from the official dataset. + +## Tests +* Client: `devtools/client/inspector/compatibility/test` +* MDN compatibility library: `devtools/shared/compatibility/test` +* Server: `devtools/server/tests/browser/browser_compatibility_cssIssues.js` From 4fdec2e03165d994d2f9f49bc9888e1792c83623 Mon Sep 17 00:00:00 2001 From: Kershaw Chang Date: Mon, 24 Aug 2020 11:24:21 +0000 Subject: [PATCH 13/56] Bug 1658532 - Add `REL_PRELOAD_MISS_RATIO` telemetry measuring ratio of used vs unused preloads per "as" type, r=smaug,chutten Differential Revision: https://phabricator.services.mozilla.com/D86736 --- toolkit/components/telemetry/Histograms.json | 22 ++++++++++++++++ uriloader/preload/PreloadHashKey.h | 1 + uriloader/preload/PreloaderBase.cpp | 27 ++++++++++++++++++++ uriloader/preload/PreloaderBase.h | 5 ++++ 4 files changed, 55 insertions(+) diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 0a9af3d09b20..c4372716dad4 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -15606,5 +15606,27 @@ "misuse", "diskspace" ] + }, + "REL_PRELOAD_MISS_RATIO": { + "record_in_processes": ["content"], + "products": ["firefox"], + "alert_emails": ["necko@mozilla.com", "kershaw@mozilla.com"], + "bug_numbers": [1658532, 1583604], + "expires_in_version": "84", + "kind": "categorical", + "labels": [ + "TYPE_SCRIPT_USED", + "TYPE_SCRIPT_UNUSED", + "TYPE_STYLE_USED", + "TYPE_STYLE_UNUSED", + "TYPE_IMAGE_USED", + "TYPE_IMAGE_UNUSED", + "TYPE_FONT_USED", + "TYPE_FONT_UNUSED", + "TYPE_FETCH_USED", + "TYPE_FETCH_UNUSED" + ], + "releaseChannelCollection": "opt-out", + "description": "Ratio of used and unused resources preloaded with link rel=preload tag or response header, broken down by supported resource type." } } diff --git a/uriloader/preload/PreloadHashKey.h b/uriloader/preload/PreloadHashKey.h index c49a9ab480e6..2ab7af6013cd 100644 --- a/uriloader/preload/PreloadHashKey.h +++ b/uriloader/preload/PreloadHashKey.h @@ -73,6 +73,7 @@ class PreloadHashKey : public nsURIHashKey { bool KeyEquals(KeyTypePointer aOther) const; static PLDHashNumber HashKey(KeyTypePointer aKey); + ResourceType As() const { return mAs; } #ifdef MOZILLA_INTERNAL_API size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { diff --git a/uriloader/preload/PreloaderBase.cpp b/uriloader/preload/PreloaderBase.cpp index 76039a6f4894..0e15d9c4ab71 100644 --- a/uriloader/preload/PreloaderBase.cpp +++ b/uriloader/preload/PreloaderBase.cpp @@ -5,6 +5,7 @@ #include "PreloaderBase.h" #include "mozilla/dom/Document.h" +#include "mozilla/Telemetry.h" #include "nsContentUtils.h" #include "nsIAsyncVerifyRedirectCallback.h" #include "nsIChannel.h" @@ -115,6 +116,8 @@ void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey, NS_NewTimerWithCallback(getter_AddRefs(mUsageTimer), callback, 10000, nsITimer::TYPE_ONE_SHOT); } + + ReportUsageTelemetry(); } void PreloaderBase::NotifyOpen(const PreloadHashKey& aKey, nsIChannel* aChannel, @@ -155,6 +158,7 @@ void PreloaderBase::NotifyUsage(LoadBackground aLoadBackground) { } mIsUsed = true; + ReportUsageTelemetry(); CancelUsageTimer(); } @@ -270,6 +274,27 @@ void PreloaderBase::CancelUsageTimer() { } } +void PreloaderBase::ReportUsageTelemetry() { + if (mUsageTelementryReported) { + return; + } + mUsageTelementryReported = true; + + if (mKey.As() == PreloadHashKey::ResourceType::NONE) { + return; + } + + // The labels are structured as type1-used, type1-unused, type2-used, ... + // The first "as" resource type is NONE with value 0. + auto index = (static_cast(mKey.As()) - 1) * 2; + if (!mIsUsed) { + ++index; + } + + auto label = static_cast(index); + Telemetry::AccumulateCategorical(label); +} + nsresult PreloaderBase::AsyncConsume(nsIStreamListener* aListener) { // We want to return an error so that consumers can't ever use a preload to // consume data unless it's properly implemented. @@ -309,6 +334,8 @@ NS_IMETHODIMP PreloaderBase::UsageTimer::Notify(nsITimer* aTimer) { return NS_OK; } + mPreload->ReportUsageTelemetry(); + // PreloadHashKey overrides GetKey, we need to use the nsURIHashKey one to get // the URI. nsIURI* uri = static_cast(&mPreload->mKey)->GetKey(); diff --git a/uriloader/preload/PreloaderBase.h b/uriloader/preload/PreloaderBase.h index 156579199d40..7c520eb49292 100644 --- a/uriloader/preload/PreloaderBase.h +++ b/uriloader/preload/PreloaderBase.h @@ -142,6 +142,8 @@ class PreloaderBase : public SupportsWeakPtr, public nsISupports { void NotifyNodeEvent(nsINode* aNode); void CancelUsageTimer(); + void ReportUsageTelemetry(); + // A helper class that will update the PreloaderBase.mChannel member when a // redirect happens, so that we can reprioritize or cancel when needed. // Having a separate class instead of implementing this on PreloaderBase @@ -205,6 +207,9 @@ class PreloaderBase : public SupportsWeakPtr, public nsISupports { // True after call to NotifyUsage. bool mIsUsed = false; + // True after we have reported the usage telemetry. Prevent duplicates. + bool mUsageTelementryReported = false; + // Emplaced when the data delivery has finished, in NotifyStop, holds the // result of the load. Maybe mOnStopStatus; From 4652cf039ced529384c2dbd7f934c6299e45f854 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Mon, 24 Aug 2020 12:27:17 +0000 Subject: [PATCH 14/56] Bug 1660625 - adjust web-platform-tests expectations to work on windows 10 hardware. r=bc adjust web-platform-tests expectations to work on windows 10 hardware Differential Revision: https://phabricator.services.mozilla.com/D87962 --- ....gradient.interpolate.colouralpha.html.ini | 4 ++++ .../2d.gradient.interpolate.overlap.html.ini | 4 ++++ .../drawimage_canvas.html.ini | 20 +++++++++++++++++++ .../2d.path.arc.selfintersect.1.html.ini | 4 ++++ .../path-objects/2d.path.rect.zero.3.html.ini | 4 ++++ ...eport-only-from-unsafe-none.https.html.ini | 8 ++++---- ...-only-same-origin-report-to.https.html.ini | 4 ++-- ...popup-same-origin-report-to.https.html.ini | 4 ++-- ...reporting-popup-same-origin.https.html.ini | 4 ++-- ...popup-unsafe-none-report-to.https.html.ini | 4 ++-- 10 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 testing/web-platform/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.colouralpha.html.ini create mode 100644 testing/web-platform/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html.ini create mode 100644 testing/web-platform/meta/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas.html.ini create mode 100644 testing/web-platform/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html.ini create mode 100644 testing/web-platform/meta/html/canvas/element/path-objects/2d.path.rect.zero.3.html.ini diff --git a/testing/web-platform/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.colouralpha.html.ini b/testing/web-platform/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.colouralpha.html.ini new file mode 100644 index 000000000000..48ee36e3da50 --- /dev/null +++ b/testing/web-platform/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.colouralpha.html.ini @@ -0,0 +1,4 @@ +[2d.gradient.interpolate.colouralpha.html] + [Canvas test: 2d.gradient.interpolate.colouralpha] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] diff --git a/testing/web-platform/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html.ini b/testing/web-platform/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html.ini new file mode 100644 index 000000000000..b51a048752cd --- /dev/null +++ b/testing/web-platform/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.overlap.html.ini @@ -0,0 +1,4 @@ +[2d.gradient.interpolate.overlap.html] + [Canvas test: 2d.gradient.interpolate.overlap] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] diff --git a/testing/web-platform/meta/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas.html.ini b/testing/web-platform/meta/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas.html.ini new file mode 100644 index 000000000000..6c7ccc66f3dd --- /dev/null +++ b/testing/web-platform/meta/html/canvas/element/manual/drawing-images-to-the-canvas/drawimage_canvas.html.ini @@ -0,0 +1,20 @@ +[drawimage_canvas.html] + [Test scenario 12: sx = -20, sy = -20, sw = 50, sh = 50, dx = 20, dy = 20, dw = 125, dh = 125 --- Pixel 0,0 should be blue.] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] + + [Test scenario 12: sx = -20, sy = -20, sw = 50, sh = 50, dx = 20, dy = 20, dw = 125, dh = 125 --- Pixel 1,1 should be blue.] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] + + [Test scenario 12: sx = -20, sy = -20, sw = 50, sh = 50, dx = 20, dy = 20, dw = 125, dh = 125 --- Pixel 23,23 should be blue.] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] + + [Test scenario 12: sx = -20, sy = -20, sw = 50, sh = 50, dx = 20, dy = 20, dw = 125, dh = 125 --- Pixel 24,24 should be blue.] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] + + [Test scenario 12: sx = -20, sy = -20, sw = 50, sh = 50, dx = 20, dy = 20, dw = 125, dh = 125 --- Pixel 82,82 should be blue.] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] diff --git a/testing/web-platform/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html.ini b/testing/web-platform/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html.ini new file mode 100644 index 000000000000..3bd37e6cee9c --- /dev/null +++ b/testing/web-platform/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html.ini @@ -0,0 +1,4 @@ +[2d.path.arc.selfintersect.1.html] + [arc() with lineWidth > 2*radius is drawn sensibly] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] diff --git a/testing/web-platform/meta/html/canvas/element/path-objects/2d.path.rect.zero.3.html.ini b/testing/web-platform/meta/html/canvas/element/path-objects/2d.path.rect.zero.3.html.ini new file mode 100644 index 000000000000..be114db79111 --- /dev/null +++ b/testing/web-platform/meta/html/canvas/element/path-objects/2d.path.rect.zero.3.html.ini @@ -0,0 +1,4 @@ +[2d.path.rect.zero.3.html] + [Canvas test: 2d.path.rect.zero.3] + expected: + if (os == "win") and (processor == "x86_64"): ["PASS", "FAIL"] diff --git a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.ini b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.ini index fa029ae9571f..3f65776916f5 100644 --- a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.ini +++ b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-from-unsafe-none.https.html.ini @@ -9,7 +9,7 @@ if not debug and (os == "mac"): TIMEOUT [coop reporting test Report only tests for an opener without any COOP/COOP report only set to CROSS_ORIGIN with , , same-origin; report-to="coop-popup-report-only-endpoint", ] expected: - if not debug and (os == "win") and not fission and (processor == "x86_64") and not webrender: TIMEOUT + if not debug and (os == "win") and not fission and (processor == "x86_64") and not webrender: ["TIMEOUT", "FAIL"] if not debug and (os == "win") and not fission and (processor == "x86_64") and webrender: ["TIMEOUT", "FAIL"] if not debug and (os == "win") and not fission and (processor == "x86"): ["TIMEOUT", "FAIL"] if not debug and (os == "linux") and not webrender: ["FAIL", "TIMEOUT"] @@ -23,9 +23,9 @@ [verify remaining reports] expected: - if not debug and (os == "win") and (processor == "x86_64") and webrender and fission: ["PASS", "NOTRUN"] - if not debug and (os == "win") and (processor == "x86_64") and webrender and not fission: ["NOTRUN", "PASS"] - if not debug and (os == "win") and (processor == "x86_64") and not webrender: NOTRUN + if not debug and (os == "win") and (processor == "x86_64") and webrender and fission: ["PASS", "NOTRUN", "TIMEOUT"] + if not debug and (os == "win") and (processor == "x86_64") and webrender and not fission: ["NOTRUN", "PASS", "TIMEOUT"] + if not debug and (os == "win") and (processor == "x86_64") and not webrender: ["NOTRUN", "TIMEOUT"] if not debug and (os == "linux") and not webrender: ["PASS", "NOTRUN"] if not debug and (os == "linux") and webrender: NOTRUN if not debug and (os == "win") and (processor == "x86"): ["NOTRUN", "PASS", "TIMEOUT"] diff --git a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.ini b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.ini index b4f1103039c1..4fc8b867a431 100644 --- a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.ini +++ b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/report-only-same-origin-report-to.https.html.ini @@ -8,7 +8,7 @@ [coop reporting test reporting same origin with report-to to CROSS_ORIGIN with , , same-origin; report-to="coop-popup-report-only-endpoint", ] expected: if not debug and not webrender and (os == "win") and (processor == "x86"): ["FAIL", "TIMEOUT"] - if not debug and not webrender and (os == "win") and (processor == "x86_64"): ["TIMEOUT", "FAIL"] + if not debug and (os == "win") and (processor == "x86_64"): ["TIMEOUT", "FAIL"] if not debug and not webrender and (os == "linux"): ["FAIL", "TIMEOUT"] if not debug and not webrender and (os == "mac"): TIMEOUT if not debug and webrender: TIMEOUT @@ -16,7 +16,7 @@ [coop reporting test reporting same origin with report-to to SAME_ORIGIN with , , same-origin; report-to="coop-popup-report-only-endpoint", ] expected: - if not debug and not webrender and (os == "win") and (processor == "x86_64"): ["NOTRUN", "TIMEOUT"] + if not debug and (os == "win") and (processor == "x86_64"): ["NOTRUN", "TIMEOUT"] if not debug and not webrender and (os == "win") and (processor == "x86"): ["TIMEOUT", "NOTRUN"] if not debug and not webrender and (os == "linux"): ["PASS", "NOTRUN", "TIMEOUT"] if not debug and not webrender and (os == "mac"): NOTRUN diff --git a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.ini b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.ini index d3a309767304..373c8ed7399c 100644 --- a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.ini +++ b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-report-to.https.html.ini @@ -9,7 +9,7 @@ [coop reporting test reporting same origin with report-to to SAME_ORIGIN with unsafe-none, , , ] expected: if debug and (os == "win") and not webrender and (processor == "x86"): ["TIMEOUT", "FAIL"] - if debug and (os == "win") and not webrender and (processor == "x86_64"): TIMEOUT + if debug and (os == "win") and not webrender and (processor == "x86_64"): ["TIMEOUT", "FAIL"] if debug and (os == "win") and webrender: ["TIMEOUT", "FAIL"] if not debug and (os == "linux") and not webrender: ["TIMEOUT", "NOTRUN", "FAIL"] if debug and (os == "linux"): ["TIMEOUT", "FAIL"] @@ -29,7 +29,7 @@ expected: if (os == "win") and (processor == "x86_64") and webrender and not debug and not fission: NOTRUN if (os == "linux") and webrender and not fission: NOTRUN - if (os == "win") and (processor == "x86_64") and not webrender: NOTRUN + if (os == "win") and (processor == "x86_64") and not webrender: ["NOTRUN", "TIMEOUT"] if os == "mac": NOTRUN [NOTRUN, PASS] diff --git a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.ini b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.ini index 17cac267829c..f4c92aeeb014 100644 --- a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.ini +++ b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin.https.html.ini @@ -7,7 +7,7 @@ if not debug and (processor == "x86"): ["TIMEOUT", "OK"] [coop reporting test reporting same origin to SAME_ORIGIN with unsafe-none; report-to="coop-popup-report-endpoint", , , ] expected: - if not debug and (os == "win") and not webrender and (processor == "x86_64"): TIMEOUT + if not debug and (os == "win") and not webrender and (processor == "x86_64"): ["TIMEOUT", "FAIL"] if not debug and (os == "win") and not webrender and (processor == "x86"): ["TIMEOUT", "FAIL"] if not debug and (os == "linux") and webrender: ["TIMEOUT", "FAIL"] if not debug and (os == "linux") and not webrender: ["FAIL", "TIMEOUT"] @@ -18,7 +18,7 @@ [coop reporting test reporting same origin to CROSS_ORIGIN with unsafe-none; report-to="coop-popup-report-endpoint", , , ] expected: if not debug and not webrender and (os == "win") and (processor == "x86"): ["NOTRUN", "FAIL", "TIMEOUT"] - if not debug and not webrender and (os == "win") and (processor == "x86_64"): NOTRUN + if not debug and not webrender and (os == "win") and (processor == "x86_64"): ["NOTRUN", "TIMEOUT"] if not debug and not webrender and (os == "linux"): ["FAIL", "NOTRUN", "TIMEOUT"] if not debug and not webrender and (os == "mac"): NOTRUN if not debug and webrender: ["NOTRUN", "TIMEOUT"] diff --git a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.ini b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.ini index a5751a264774..ef7616d1294f 100644 --- a/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.ini +++ b/testing/web-platform/meta/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-unsafe-none-report-to.https.html.ini @@ -9,7 +9,7 @@ if not debug and (os == "win") and webrender and fission: ["NOTRUN", "TIMEOUT"] if not debug and (os == "win") and webrender and not fission: ["NOTRUN", "TIMEOUT"] if not debug and (os == "win") and not webrender and (processor == "x86"): TIMEOUT - if not debug and (os == "win") and not webrender and (processor == "x86_64"): NOTRUN + if not debug and (os == "win") and not webrender and (processor == "x86_64"): ["NOTRUN", "TIMEOUT"] if not debug and (os == "linux") and webrender: NOTRUN if not debug and (os == "linux") and not webrender: ["FAIL", "NOTRUN", "TIMEOUT"] if not debug and (os == "mac"): NOTRUN @@ -19,7 +19,7 @@ expected: if not debug and (os == "win") and webrender and not fission: ["TIMEOUT", "FAIL"] if not debug and (os == "win") and webrender and fission: ["TIMEOUT", "FAIL"] - if not debug and (os == "win") and not webrender and (processor == "x86_64"): TIMEOUT + if not debug and (os == "win") and not webrender and (processor == "x86_64"): ["TIMEOUT", "FAIL"] if not debug and (os == "linux") and not webrender: ["FAIL", "TIMEOUT"] if not debug and (os == "linux") and webrender: TIMEOUT if not debug and (os == "mac"): TIMEOUT From b0af2e5f2047314db733ecd35843e363c2f446d0 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Mon, 24 Aug 2020 11:39:18 +0000 Subject: [PATCH 15/56] Bug 1660480 - Add expected read access for ShaderCache in browser_startup_content_mainthreadio.js. r=Gijs Add expected read access for ShaderCache in browser_startup_content_mainthreadio.js Differential Revision: https://phabricator.services.mozilla.com/D87929 --- .../performance/browser_startup_content_mainthreadio.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/browser/base/content/test/performance/browser_startup_content_mainthreadio.js b/browser/base/content/test/performance/browser_startup_content_mainthreadio.js index 0e453a09cfd1..6dca6d5116d9 100644 --- a/browser/base/content/test/performance/browser_startup_content_mainthreadio.js +++ b/browser/base/content/test/performance/browser_startup_content_mainthreadio.js @@ -92,6 +92,12 @@ const processes = { ignoreIfUnused: true, stat: 1, }, + { + path: "*ShaderCache*", // Bug 1660480 - seen on hardware + condition: WIN, + ignoreIfUnused: true, + stat: 3, + }, ], "Privileged Content": [ { From 66ed7f07fca11a8109b98bfb211aa1e395664d8c Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Mon, 24 Aug 2020 11:38:58 +0000 Subject: [PATCH 16/56] Bug 1660582 - Add expected file access to browser_startup_mainthreadio.js while running on windows10 hardware. r=Gijs Add expected file access to browser_startup_mainthreadio.js while running on windows10 hardware Differential Revision: https://phabricator.services.mozilla.com/D87938 --- .../test/performance/browser_startup_mainthreadio.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/browser/base/content/test/performance/browser_startup_mainthreadio.js b/browser/base/content/test/performance/browser_startup_mainthreadio.js index de0821e7c99a..1f00e4aa1fbe 100644 --- a/browser/base/content/test/performance/browser_startup_mainthreadio.js +++ b/browser/base/content/test/performance/browser_startup_mainthreadio.js @@ -449,6 +449,14 @@ const startupPhases = { stat: 1, close: 1, }, + { + // Bug 1660582 - access while running on windows10 hardware. + path: "ProfD:wmfvpxvideo.guard", + condition: WIN, + ignoreIfUnused: true, + stat: 1, + close: 1, + }, ], // Things that are expected to be completely out of the startup path From bbef58adcc1fbea429eb841c80231d2b9099d605 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Mon, 24 Aug 2020 11:39:12 +0000 Subject: [PATCH 17/56] Bug 1660590 - add expectations to browser_startup_syncIPC.js to work on windows10 hardware. r=Gijs add expectations to browser_startup_syncIPC.js to pass on windows10 hardware. Differential Revision: https://phabricator.services.mozilla.com/D87939 --- .../performance/browser_startup_syncIPC.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/browser/base/content/test/performance/browser_startup_syncIPC.js b/browser/base/content/test/performance/browser_startup_syncIPC.js index 1c41ef09024c..b09d7fe04993 100644 --- a/browser/base/content/test/performance/browser_startup_syncIPC.js +++ b/browser/base/content/test/performance/browser_startup_syncIPC.js @@ -191,6 +191,18 @@ const startupPhases = { ignoreIfUnused: true, maxCount: 1, }, + { + name: "PContent::Reply_BeginDriverCrashGuard", + condition: WIN, + ignoreIfUnused: true, // Bug 1660590 - found while running test on windows hardware + maxCount: 1, + }, + { + name: "PContent::Reply_EndDriverCrashGuard", + condition: WIN, + ignoreIfUnused: true, // Bug 1660590 - found while running test on windows hardware + maxCount: 1, + }, ], // Things that are expected to be completely out of the startup path @@ -258,6 +270,12 @@ const startupPhases = { ignoreIfUnused: true, maxCount: 1, }, + { + name: "PCompositorBridge::Msg_MakeSnapshot", + condition: WIN, + ignoreIfUnused: true, + maxCount: 1, + }, { name: "PCompositorBridge::Msg_WillClose", condition: WIN, From b0e7b41949e9151055b6ad8b7fde4bbad2395ddb Mon Sep 17 00:00:00 2001 From: Bryce Seager van Dyk Date: Sun, 23 Aug 2020 09:04:23 +0000 Subject: [PATCH 18/56] Bug 1659941 - Add a method to IntervalSet to check if it intersects with another IntervalSet. r=jya Differential Revision: https://phabricator.services.mozilla.com/D87912 --- dom/media/Intervals.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dom/media/Intervals.h b/dom/media/Intervals.h index 4d96e5c54b39..8eddca8a3469 100644 --- a/dom/media/Intervals.h +++ b/dom/media/Intervals.h @@ -614,6 +614,23 @@ class IntervalSet { return false; } + // Returns if there's any intersection between this and aOther. + bool IntersectsStrict(const SelfType& aOther) const { + const ContainerType& other = aOther.mIntervals; + IndexType i = 0, j = 0; + for (; i < mIntervals.Length() && j < other.Length();) { + if (mIntervals[i].IntersectsStrict(other[j])) { + return true; + } + if (mIntervals[i].mEnd < other[j].mEnd) { + i++; + } else { + j++; + } + } + return false; + } + bool IntersectsWithStrictEnd(const ElemType& aInterval) const { for (const auto& interval : mIntervals) { if (interval.IntersectsWithStrictEnd(aInterval)) { From 7f964ba3547d6d34f7c8c774703b215978dea456 Mon Sep 17 00:00:00 2001 From: Bryce Seager van Dyk Date: Sat, 22 Aug 2020 18:48:09 +0000 Subject: [PATCH 19/56] Bug 1659941 - Avoid an IntervalSet copy when inserting frames in TrackBuffersManager. r=jya Differential Revision: https://phabricator.services.mozilla.com/D87913 --- dom/media/mediasource/TrackBuffersManager.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index be29a73c767c..c202bdd11a7a 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -2080,10 +2080,7 @@ void TrackBuffersManager::InsertFrames(TrackBuffer& aSamples, // the previous step and the next random access point after those removed // frames. - TimeIntervals intersection = trackBuffer.mBufferedRanges; - intersection.Intersection(aIntervals); - - if (!intersection.IsEmpty()) { + if (trackBuffer.mBufferedRanges.IntersectsStrict(aIntervals)) { if (aSamples[0]->mKeyframe && (mType.Type() == MEDIAMIMETYPE("video/webm") || mType.Type() == MEDIAMIMETYPE("audio/webm"))) { From b43ea36da97056677dd0a838ac907302bbbd38f6 Mon Sep 17 00:00:00 2001 From: David Major Date: Sat, 22 Aug 2020 13:56:36 +0000 Subject: [PATCH 20/56] Bug 1660341 - Pin code coverage builds to clang-9 r=froydnj At the upcoming upgrade to clang-11, we'll need to keep code coverage builds on clang-9, so that their file format is understandable our currently LLVM-9-based rustc. As currently written this change is NFC, but for the future it will opt-out ccov builds from the retargeting of the `linux64-clang` alias. The macosx.yml change looks larger than it really is, it's mostly pushing defaults down into the tasks so that coverage builds can override them. Differential Revision: https://phabricator.services.mozilla.com/D87901 --- taskcluster/ci/build/linux.yml | 12 ++++----- taskcluster/ci/build/macosx.yml | 40 +++++++++++++++++++++++++++--- taskcluster/ci/build/windows.yml | 2 +- taskcluster/ci/toolchain/clang.yml | 2 +- taskcluster/ci/toolchain/misc.yml | 5 ++-- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/taskcluster/ci/build/linux.yml b/taskcluster/ci/build/linux.yml index 9856b6e198d4..1c9fad1a303b 100644 --- a/taskcluster/ci/build/linux.yml +++ b/taskcluster/ci/build/linux.yml @@ -845,7 +845,7 @@ linux64-asan-fuzzing-ccov/opt: fetches: toolchain: - linux64-binutils - - linux64-clang + - linux64-clang-9 - linux64-rust - linux64-rust-size - linux64-cbindgen @@ -854,7 +854,7 @@ linux64-asan-fuzzing-ccov/opt: - linux64-nasm - linux64-node - linux64-lucetc - - wasi-sysroot + - wasi-sysroot-9 linux64-fuzzing-ccov/opt: description: "Linux64 Fuzzing Opt w/ Coverage" @@ -889,7 +889,7 @@ linux64-fuzzing-ccov/opt: fetches: toolchain: - linux64-binutils - - linux64-clang + - linux64-clang-9 - linux64-gcc-7 - linux64-cbindgen - linux64-dump-syms @@ -899,7 +899,7 @@ linux64-fuzzing-ccov/opt: - linux64-nasm - linux64-node - linux64-lucetc - - wasi-sysroot + - wasi-sysroot-9 optimization: build-fuzzing: null @@ -1219,7 +1219,7 @@ linux64-ccov/opt: fetches: toolchain: - linux64-binutils - - linux64-clang + - linux64-clang-9 - linux64-rust - linux64-gcc-7 - linux64-cbindgen @@ -1229,7 +1229,7 @@ linux64-ccov/opt: - linux64-node - linux64-grcov - linux64-lucetc - - wasi-sysroot + - wasi-sysroot-9 linux64-add-on-devel/opt: description: "Linux64 add-on-devel" diff --git a/taskcluster/ci/build/macosx.yml b/taskcluster/ci/build/macosx.yml index bf90e679adbe..c13f5a2397b1 100644 --- a/taskcluster/ci/build/macosx.yml +++ b/taskcluster/ci/build/macosx.yml @@ -19,8 +19,6 @@ job-defaults: fetches: toolchain: - linux64-binutils - - linux64-cctools-port - - linux64-clang-macosx-cross - linux64-dump-syms - linux64-hfsplus - linux64-libdmg @@ -31,7 +29,6 @@ job-defaults: - linux64-nasm - linux64-node - linux64-lucetc - - wasi-sysroot macosx64/debug: description: "MacOS X x64 Cross-compile" @@ -56,7 +53,10 @@ macosx64/debug: use-sccache: true fetches: toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross - linux64-sccache + - wasi-sysroot macosx64/opt: description: "MacOS X x64 Cross-compile" @@ -81,7 +81,10 @@ macosx64/opt: use-sccache: true fetches: toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross - linux64-sccache + - wasi-sysroot macosx64-asan-fuzzing/opt: description: "MacOS X x64 Cross-compile Fuzzing ASAN" @@ -103,7 +106,10 @@ macosx64-asan-fuzzing/opt: use-sccache: true fetches: toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross - linux64-sccache + - wasi-sysroot optimization: build-fuzzing: null @@ -129,7 +135,10 @@ macosx64-fuzzing/debug: use-sccache: true fetches: toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross - linux64-sccache + - wasi-sysroot optimization: build-fuzzing: null @@ -162,6 +171,11 @@ macosx64-devedition/opt: stage_platform: macosx64-devedition mozconfig-variant: devedition run-on-projects: ['mozilla-beta'] + fetches: + toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross + - wasi-sysroot macosx64-noopt/debug: description: "MacOS X x64 No-optimize Debug" @@ -184,7 +198,10 @@ macosx64-noopt/debug: use-sccache: true fetches: toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross - linux64-sccache + - wasi-sysroot macosx64-add-on-devel/opt: description: "MacOS X x64 add-on-devel" @@ -206,7 +223,10 @@ macosx64-add-on-devel/opt: use-sccache: true fetches: toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross - linux64-sccache + - wasi-sysroot macosx64-shippable/opt: description: "MacOS X x64 Cross-compile" @@ -233,6 +253,11 @@ macosx64-shippable/opt: - builds/releng_base_firefox.py - builds/releng_base_mac_64_cross_builds.py - taskcluster_nightly.py + fetches: + toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross + - wasi-sysroot macosx64-ccov/opt: description: "MacOS X x64 Cross-compile Code Coverage" @@ -257,7 +282,10 @@ macosx64-ccov/opt: use-sccache: true fetches: toolchain: + - linux64-cctools-port-clang-9 + - linux64-clang-9-macosx-cross - linux64-sccache + - wasi-sysroot-9 macosx64-gcp/debug: description: "MacOS X x64 Cross-compile - built on GCP" @@ -283,7 +311,10 @@ macosx64-gcp/debug: use-sccache: true fetches: toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross - linux64-sccache + - wasi-sysroot optimization: push-interval-25: null @@ -310,4 +341,7 @@ macosx64-gcp/opt: use-sccache: true fetches: toolchain: + - linux64-cctools-port + - linux64-clang-macosx-cross - linux64-sccache + - wasi-sysroot diff --git a/taskcluster/ci/build/windows.yml b/taskcluster/ci/build/windows.yml index eafae1fbcf45..2172f00e56df 100644 --- a/taskcluster/ci/build/windows.yml +++ b/taskcluster/ci/build/windows.yml @@ -872,7 +872,7 @@ win64-ccov/opt: use-sccache: true fetches: toolchain: - - win64-clang-cl + - win64-clang-cl-9 - win64-rust - win64-rust-size - win64-cbindgen diff --git a/taskcluster/ci/toolchain/clang.yml b/taskcluster/ci/toolchain/clang.yml index 07c82b524907..73a3174778b3 100644 --- a/taskcluster/ci/toolchain/clang.yml +++ b/taskcluster/ci/toolchain/clang.yml @@ -70,7 +70,7 @@ linux64-clang-9: toolchain: - linux64-binutils - linux64-gcc-7 - - wasi-sysroot + - wasi-sysroot-9 linux64-clang-9-mingw-x86: description: "MinGW-Clang 9 x86 toolchain build" diff --git a/taskcluster/ci/toolchain/misc.yml b/taskcluster/ci/toolchain/misc.yml index 739d42896a0d..e767c0ae318a 100644 --- a/taskcluster/ci/toolchain/misc.yml +++ b/taskcluster/ci/toolchain/misc.yml @@ -140,8 +140,8 @@ browsertime: toolchain: - linux64-node -wasi-sysroot: - description: "wasi sysroot build process" +wasi-sysroot-9: + description: "wasi sysroot build using clang-9" attributes: local-toolchain: true treeherder: @@ -151,6 +151,7 @@ wasi-sysroot: script: build-wasi-sysroot.sh sparse-profile: null toolchain-artifact: public/build/wasi-sysroot.tar.xz + toolchain-alias: wasi-sysroot fetches: fetch: - clang-9 From 406493d10bca8ef51f107a4b9e12933e249021fe Mon Sep 17 00:00:00 2001 From: Hector Zhao Date: Mon, 24 Aug 2020 14:08:17 +0000 Subject: [PATCH 21/56] Bug 1660725 - Consider `CARGO_HOME` when checking for `rustc` & `cargo` in configure. r=froydnj Differential Revision: https://phabricator.services.mozilla.com/D87993 --- build/moz.configure/toolchain.configure | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index e746f4e28cb2..8c32cff15d07 100755 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -731,7 +731,12 @@ def toolchain_search_path_for(host_or_target): )] # Also add the rustup install directory for cargo/rustc. - rustup_path = os.path.expanduser(os.path.join('~', '.cargo', 'bin')) + cargo_home = environ.get('CARGO_HOME', '') + if cargo_home: + cargo_home = os.path.abspath(cargo_home) + else: + cargo_home = os.path.expanduser(os.path.join('~', '.cargo')) + rustup_path = os.path.join(cargo_home, 'bin') result.append(rustup_path) if developer_options: From 4dba1dc4b6210a3eea79fdf87f3b69253cb2abd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 24 Aug 2020 12:02:01 +0000 Subject: [PATCH 22/56] Bug 1636728 - Make a crashtest properly close its windows. r=smaug This crashtest opens a gazillion popups via window.open() which then it never closes. This becomes a problem because other better-behaved crashtests in the same subdirectory get their popups blocked by the popup blocker and then time out when not removing the reftest-wait class, like this: https://searchfox.org/mozilla-central/source/dom/base/crashtests/1529203-2.html#17 This didn't happen before the first patch of this bug, because we were aborting when creating these windows here, and after my patches we fall back to opening in a new window: https://searchfox.org/mozilla-central/rev/3c98465c9d329625c4e1b22a7b832aabeafc4cc3/dom/ipc/ContentParent.cpp#5027-5030 I could restore the abort if preferred, but I don't think that's great. Differential Revision: https://phabricator.services.mozilla.com/D87965 --- dom/base/crashtests/1419902.html | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dom/base/crashtests/1419902.html b/dom/base/crashtests/1419902.html index 2323c48b0ed6..4694396eeb8c 100644 --- a/dom/base/crashtests/1419902.html +++ b/dom/base/crashtests/1419902.html @@ -1,11 +1,19 @@ From 9e353132580b2cf367d922a6403a53506d7e5fc2 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 24 Aug 2020 10:10:28 -0400 Subject: [PATCH 24/56] Bug 1657017 - Add some more WNP locales that missed the Fx80 RC build. r=mtabara DONTBUILD --- browser/config/whats_new_page.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/browser/config/whats_new_page.yml b/browser/config/whats_new_page.yml index 39b73f024037..ce27ae54a250 100644 --- a/browser/config/whats_new_page.yml +++ b/browser/config/whats_new_page.yml @@ -18,6 +18,7 @@ # This is done by taskgraph. versions: ["<{version.major_number}.0"] locales: + - an - ca - cs - cy @@ -29,6 +30,7 @@ - es-AR - es-CL - fr + - hr - hsb - hu - ia @@ -44,6 +46,7 @@ - pt-BR - pt-PT - ro + - ru - sk - sl - sq From 8bd3018124a022ce633a51a7b97f99e2a9f3ac49 Mon Sep 17 00:00:00 2001 From: Miko Mynttinen Date: Sun, 23 Aug 2020 09:42:21 +0000 Subject: [PATCH 25/56] Bug 1659476 - Set gfx.webrender.enable-client-storage to true r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D87292 --- modules/libpref/init/StaticPrefList.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 7016fdca4648..a4320488df5d 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -4506,7 +4506,7 @@ #ifdef XP_MACOSX - name: gfx.webrender.enable-client-storage type: bool - value: @IS_NIGHTLY_BUILD@ + value: true mirror: once #endif From ec09c21cdd534c198d3a56b7973c7a47de34fb7d Mon Sep 17 00:00:00 2001 From: Bob Owen Date: Mon, 24 Aug 2020 14:29:29 +0000 Subject: [PATCH 26/56] Bug 1660463: Only allow printing of a selection when mDisallowSelectionPrint is false. r=jwatt Differential Revision: https://phabricator.services.mozilla.com/D88028 --- layout/printing/nsPrintJob.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/layout/printing/nsPrintJob.cpp b/layout/printing/nsPrintJob.cpp index 2a04b621cab4..d9919a8601cd 100644 --- a/layout/printing/nsPrintJob.cpp +++ b/layout/printing/nsPrintJob.cpp @@ -733,7 +733,8 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview, // Now determine how to set up the Frame print UI printData->mPrintSettings->SetPrintOptions( - nsIPrintSettings::kEnableSelectionRB, !!printData->mSelectionRoot); + nsIPrintSettings::kEnableSelectionRB, + !mDisallowSelectionPrint && printData->mSelectionRoot); bool printingViaParent = XRE_IsContentProcess() && Preferences::GetBool("print.print_via_parent"); @@ -2534,7 +2535,7 @@ nsresult nsPrintJob::EnablePOsForPrinting() { // This means we are either printing a selected iframe or // we are printing the current selection. MOZ_ASSERT(printRangeType == nsIPrintSettings::kRangeSelection); - NS_ENSURE_STATE(printData->mSelectionRoot); + NS_ENSURE_STATE(!mDisallowSelectionPrint && printData->mSelectionRoot); // If mSelectionRoot is a selected iframe without a selection, then just // enable normally from that point. From dd185c9a8b9a118e803603e6e3cfa4d77fb1ce75 Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Mon, 24 Aug 2020 13:55:12 +0000 Subject: [PATCH 27/56] Bug 1622349 - Re-enable test on webrender fission windows opt. r=jib Differential Revision: https://phabricator.services.mozilla.com/D88014 --- ...ream-MediaElement-srcObject.https.html.ini | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 testing/web-platform/meta/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html.ini diff --git a/testing/web-platform/meta/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html.ini b/testing/web-platform/meta/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html.ini deleted file mode 100644 index 625b987c3b17..000000000000 --- a/testing/web-platform/meta/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html.ini +++ /dev/null @@ -1,27 +0,0 @@ -[MediaStream-MediaElement-srcObject.https.html] - expected: - if webrender and fission and (os == "win") and not debug: ["OK", "TIMEOUT"] - [Tests that an audio element with an assigned MediaStream ends when the MediaStream becomes inaudible through track removal] - expected: - if webrender and fission and (os == "win") and not debug: ["PASS", "NOTRUN"] - - [Tests that the loop attribute has no effect on a media element with an assigned MediaStream] - expected: - if webrender and fission and (os == "win") and not debug: ["PASS", "NOTRUN"] - - [Tests that a media element with an assigned MediaStream ends when the MediaStream becomes inactive through track removal] - expected: - if webrender and fission and (os == "win") and not debug: ["PASS", "NOTRUN"] - - [Tests that an audio element with an assigned MediaStream ends when the MediaStream becomes inaudible through audio tracks ending] - expected: - if webrender and fission and (os == "win") and not debug: ["PASS", "NOTRUN"] - - [Tests that a media element with an assigned MediaStream does not start advancing currentTime until potentially playing] - expected: - if webrender and fission and (os == "win") and not debug: ["PASS", "TIMEOUT"] - - [Tests that a media element with an assigned MediaStream ends when the MediaStream becomes inactive through tracks ending] - expected: - if webrender and fission and (os == "win") and not debug: ["PASS", "NOTRUN"] - From 2635280bd608fe748147fd63a0944b9e86904975 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Mon, 24 Aug 2020 16:49:31 +0200 Subject: [PATCH 28/56] Bug 1642506 - Add back Windows ccov test annotations for moving-between-documents folder --- ...are-createHTMLDocument-fetch-error-external-module.html.ini | 1 + ...re-createHTMLDocument-parse-error-external-classic.html.ini | 2 ++ ...are-createHTMLDocument-parse-error-external-module.html.ini | 2 ++ ...repare-createHTMLDocument-success-external-classic.html.ini | 2 ++ ...prepare-createHTMLDocument-success-external-module.html.ini | 2 ++ .../after-prepare-iframe-parse-error-external-classic.html.ini | 3 +++ .../after-prepare-iframe-parse-error-external-module.html.ini | 3 +++ .../after-prepare-iframe-parse-error-inline-classic.html.ini | 1 + .../after-prepare-iframe-success-external-classic.html.ini | 3 +++ .../after-prepare-iframe-success-external-module.html.ini | 3 +++ .../after-prepare-iframe-success-inline-classic.html.ini | 1 + 11 files changed, 23 insertions(+) diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-module.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-module.html.ini index 679aff28712a..e2d6f188bfb1 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-module.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-fetch-error-external-module.html.ini @@ -4,6 +4,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-classic.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-classic.html.ini index 7d88ca493827..2d2a405e47e7 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-classic.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-classic.html.ini @@ -3,6 +3,7 @@ expected: if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS if not debug and (os == "mac"): PASS FAIL @@ -12,6 +13,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-module.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-module.html.ini index d0db2f40bb80..d8e614e91620 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-module.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-parse-error-external-module.html.ini @@ -4,6 +4,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL @@ -12,6 +13,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-classic.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-classic.html.ini index a8846aa8ae46..80919c6b3a14 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-classic.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-classic.html.ini @@ -4,6 +4,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL @@ -12,6 +13,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-module.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-module.html.ini index 5899bb1b74ee..de7715420cec 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-module.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-createHTMLDocument-success-external-module.html.ini @@ -4,6 +4,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL @@ -12,6 +13,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-classic.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-classic.html.ini index ece50e949ebe..7271d82a2b51 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-classic.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-classic.html.ini @@ -4,6 +4,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL @@ -12,6 +13,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL @@ -19,6 +21,7 @@ expected: if not debug and (os == "linux") and webrender: ["FAIL", "PASS"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] + if (os == "win") and ccov: PASS if not debug and (os == "win"): FAIL if not debug and (os == "mac"): FAIL diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html.ini index 27e3ff4bda05..bd86afcde242 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html.ini @@ -4,6 +4,7 @@ if not debug and (os == "linux") and webrender: ["FAIL", "PASS"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): FAIL + if (os == "win") and ccov: PASS if not debug and (os == "win"): FAIL [window error: Move parse-error external module script to iframe after-prepare] @@ -11,6 +12,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL @@ -19,6 +21,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-inline-classic.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-inline-classic.html.ini index 28ae0247cadc..b7eb817c5292 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-inline-classic.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-inline-classic.html.ini @@ -4,6 +4,7 @@ if not debug and (os == "linux") and webrender: ["PASS", "FAIL"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): PASS + if (os == "win") and ccov: FAIL if not debug and (os == "win"): PASS FAIL diff --git a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-classic.html.ini b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-classic.html.ini index 1db6a31df70d..8ae5d5792974 100644 --- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-classic.html.ini +++ b/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-success-external-classic.html.ini @@ -4,12 +4,14 @@ if not debug and (os == "linux") and webrender: ["FAIL", "PASS"] if not debug and (os == "linux") and not webrender: ["PASS", "FAIL"] if not debug and (os == "mac"): FAIL + if (os == "win") and ccov: PASS if not debug and (os == "win"): FAIL [