Bug 1577711 - Part 2: Perform frame static clone after parent static clone, r=smaug

This is done by delaying the code within nsFrameLoader::CreateStaticClone until
after the document has been created. The nsFrameLoader is re-discovered using
the subframe BrowsingContext's mEmbedderElement.

Differential Revision: https://phabricator.services.mozilla.com/D44586

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2019-09-05 14:55:19 +00:00
Родитель 245b18cd39
Коммит 0354cad681
3 изменённых файлов: 60 добавлений и 10 удалений

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

@ -155,7 +155,8 @@ typedef ScrollableLayerGuid::ViewID ViewID;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsFrameLoader, mBrowsingContext,
mMessageManager, mChildMessageManager,
mParentSHistory, mRemoteBrowser)
mParentSHistory, mRemoteBrowser,
mStaticCloneOf)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader)
@ -2804,23 +2805,42 @@ void nsFrameLoader::ActivateFrameEvent(const nsAString& aType, bool aCapture,
}
nsresult nsFrameLoader::CreateStaticClone(nsFrameLoader* aDest) {
aDest->MaybeCreateDocShell();
NS_ENSURE_STATE(aDest->GetDocShell());
if (NS_WARN_IF(IsRemoteFrame())) {
return NS_ERROR_NOT_IMPLEMENTED;
}
nsCOMPtr<Document> kungFuDeathGrip = aDest->GetDocShell()->GetDocument();
// Ensure that the embedder element is set correctly.
aDest->mBrowsingContext->SetEmbedderElement(aDest->mOwnerContent);
aDest->mStaticCloneOf = this;
return NS_OK;
}
nsresult nsFrameLoader::FinishStaticClone() {
// After cloning is complete, discard the reference to the original
// nsFrameLoader, as it is no longer needed.
auto exitGuard = MakeScopeExit([&] { mStaticCloneOf = nullptr; });
if (NS_WARN_IF(!mStaticCloneOf || IsDead())) {
return NS_ERROR_UNEXPECTED;
}
MaybeCreateDocShell();
NS_ENSURE_STATE(GetDocShell());
nsCOMPtr<Document> kungFuDeathGrip = GetDocShell()->GetDocument();
Unused << kungFuDeathGrip;
nsCOMPtr<nsIContentViewer> viewer;
aDest->GetDocShell()->GetContentViewer(getter_AddRefs(viewer));
GetDocShell()->GetContentViewer(getter_AddRefs(viewer));
NS_ENSURE_STATE(viewer);
nsIDocShell* origDocShell = GetDocShell(IgnoreErrors());
nsIDocShell* origDocShell = mStaticCloneOf->GetDocShell(IgnoreErrors());
NS_ENSURE_STATE(origDocShell);
nsCOMPtr<Document> doc = origDocShell->GetDocument();
NS_ENSURE_STATE(doc);
nsCOMPtr<Document> clonedDoc = doc->CreateStaticClone(aDest->GetDocShell());
nsCOMPtr<Document> clonedDoc = doc->CreateStaticClone(GetDocShell());
viewer->SetDocument(clonedDoc);
return NS_OK;

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

@ -128,10 +128,21 @@ class nsFrameLoader final : public nsStubMutationObserver,
GetBrowserChildMessageManager() const {
return mChildMessageManager;
}
nsresult CreateStaticClone(nsFrameLoader* aDest);
nsresult UpdatePositionAndSize(nsSubDocumentFrame* aIFrame);
void SendIsUnderHiddenEmbedderElement(bool aIsUnderHiddenEmbedderElement);
// When creating a nsFrameLoader which is a static clone, two methods are
// called at different stages. The `CreateStaticClone` method is first called
// on the source nsFrameLoader, passing in the destination frameLoader as the
// `aDest` argument. This is done during the static clone operation on the
// original document.
//
// After the original document's clone is complete, the `FinishStaticClone`
// method is called on the target nsFrameLoader, which clones the inner
// document of the source nsFrameLoader.
nsresult CreateStaticClone(nsFrameLoader* aDest);
nsresult FinishStaticClone();
// WebIDL methods
nsDocShell* GetDocShell(mozilla::ErrorResult& aRv);
@ -486,6 +497,10 @@ class nsFrameLoader final : public nsStubMutationObserver,
// a reframe, so that we know not to restore the presentation.
RefPtr<Document> mContainerDocWhileDetached;
// When performing a static clone, this holds the other nsFrameLoader which
// this object is a static clone of.
RefPtr<nsFrameLoader> mStaticCloneOf;
// When performing a process switch, this value is used rather than mURIToLoad
// to identify the process-switching load which should be resumed in the
// target process.

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

@ -462,14 +462,29 @@ static void BuildNestedPrintObjects(BrowsingContext* aBrowsingContext,
MOZ_ASSERT(aPO, "Pointer is null!");
for (auto& childBC : aBrowsingContext->GetChildren()) {
// if we no longer have a nsFrameLoader for this BrowsingContext, it's
// probably being torn down.
nsCOMPtr<nsFrameLoaderOwner> flo =
do_QueryInterface(childBC->GetEmbedderElement());
RefPtr<nsFrameLoader> frameLoader = flo ? flo->GetFrameLoader() : nullptr;
if (!frameLoader) {
continue;
}
// Finish performing the static clone for this BrowsingContext.
nsresult rv = frameLoader->FinishStaticClone();
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
auto window = childBC->GetDOMWindow();
if (!window) {
// XXXfission - handle OOP-iframes
continue;
}
auto childPO = MakeUnique<nsPrintObject>();
nsresult rv = childPO->InitAsNestedObject(
childBC->GetDocShell(), window->GetExtantDoc(), aPO.get());
rv = childPO->InitAsNestedObject(childBC->GetDocShell(),
window->GetExtantDoc(), aPO.get());
if (NS_FAILED(rv)) {
MOZ_ASSERT_UNREACHABLE("Init failed?");
}