зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
245b18cd39
Коммит
0354cad681
|
@ -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?");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче