зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1540839 - Add ability to preserve browsing contexts between FrameLoaders; r=nika
When changing processes and therefore destroying/rebuilding frameloaders, add ability to keep the browsing context around and add it to the new frameloader. Differential Revision: https://phabricator.services.mozilla.com/D26267
This commit is contained in:
Родитель
434596e533
Коммит
9f9436d028
|
@ -385,7 +385,8 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext)
|
|||
mHasLoadedNonBlankURI(false),
|
||||
mBlankTiming(false),
|
||||
mTitleValidForCurrentURI(false),
|
||||
mIsFrame(false) {
|
||||
mIsFrame(false),
|
||||
mSkipBrowsingContextDetachOnDestroy(false) {
|
||||
mHistoryID.m0 = 0;
|
||||
mHistoryID.m1 = 0;
|
||||
mHistoryID.m2 = 0;
|
||||
|
@ -5036,7 +5037,11 @@ nsDocShell::Destroy() {
|
|||
mSessionHistory = nullptr;
|
||||
}
|
||||
|
||||
mBrowsingContext->Detach();
|
||||
// This will be skipped in cases where we want to preserve the browsing
|
||||
// context between loads.
|
||||
if (!mSkipBrowsingContextDetachOnDestroy) {
|
||||
mBrowsingContext->Detach();
|
||||
}
|
||||
|
||||
SetTreeOwner(nullptr);
|
||||
|
||||
|
|
|
@ -405,6 +405,10 @@ class nsDocShell final : public nsDocLoader,
|
|||
// Clear the document's storage access flag if needed.
|
||||
void MaybeClearStorageAccessFlag();
|
||||
|
||||
void SkipBrowsingContextDetach() {
|
||||
mSkipBrowsingContextDetachOnDestroy = true;
|
||||
}
|
||||
|
||||
private: // member functions
|
||||
friend class nsDSURIContentListener;
|
||||
friend class FramingChecker;
|
||||
|
@ -1205,6 +1209,11 @@ class nsDocShell final : public nsDocLoader,
|
|||
bool mTitleValidForCurrentURI : 1;
|
||||
|
||||
bool mIsFrame : 1;
|
||||
|
||||
// If mSkipBrowsingContextDetachOnDestroy is set to true, then when the
|
||||
// docshell is destroyed, the browsing context will not be detached. This is
|
||||
// for cases where we want to preserve the BC for future use.
|
||||
bool mSkipBrowsingContextDetachOnDestroy : 1;
|
||||
};
|
||||
|
||||
#endif /* nsDocShell_h__ */
|
||||
|
|
|
@ -364,7 +364,7 @@ nsFrameLoader* nsFrameLoader::Create(Element* aOwner, BrowsingContext* aOpener,
|
|||
|
||||
/* static */
|
||||
nsFrameLoader* nsFrameLoader::Create(
|
||||
mozilla::dom::Element* aOwner,
|
||||
mozilla::dom::Element* aOwner, BrowsingContext* aPreservedBrowsingContext,
|
||||
const mozilla::dom::RemotenessOptions& aOptions) {
|
||||
NS_ENSURE_TRUE(aOwner, nullptr);
|
||||
// This version of Create is only called for Remoteness updates, so we can
|
||||
|
@ -381,7 +381,12 @@ nsFrameLoader* nsFrameLoader::Create(
|
|||
if (hasOpener) {
|
||||
opener = aOptions.mOpener.Value().Value().get();
|
||||
}
|
||||
RefPtr<BrowsingContext> context = CreateBrowsingContext(aOwner, opener);
|
||||
RefPtr<BrowsingContext> context;
|
||||
if (aPreservedBrowsingContext) {
|
||||
context = aPreservedBrowsingContext;
|
||||
} else {
|
||||
context = CreateBrowsingContext(aOwner, opener);
|
||||
}
|
||||
NS_ENSURE_TRUE(context, nullptr);
|
||||
return new nsFrameLoader(aOwner, context, aOptions);
|
||||
}
|
||||
|
@ -3490,3 +3495,22 @@ JSObject* nsFrameLoader::WrapObject(JSContext* cx,
|
|||
FrameLoader_Binding::Wrap(cx, this, this, aGivenProto, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void nsFrameLoader::SkipBrowsingContextDetach() {
|
||||
if (IsRemoteFrame()) {
|
||||
// OOP Browser - Go directly over Browser Parent
|
||||
if (mBrowserParent) {
|
||||
Unused << mBrowserParent->SendSkipBrowsingContextDetach();
|
||||
}
|
||||
// OOP IFrame - Through Browser Bridge Parent, set on browser child
|
||||
else if (mBrowserBridgeChild) {
|
||||
Unused << mBrowserBridgeChild->SendSkipBrowsingContextDetach();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// In process
|
||||
RefPtr<nsDocShell> docshell = GetDocShell();
|
||||
MOZ_ASSERT(docshell);
|
||||
docshell->SkipBrowsingContextDetach();
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
|
|||
typedef mozilla::dom::PBrowserParent PBrowserParent;
|
||||
typedef mozilla::dom::Document Document;
|
||||
typedef mozilla::dom::BrowserParent BrowserParent;
|
||||
typedef mozilla::dom::BrowsingContext BrowsingContext;
|
||||
typedef mozilla::layout::RenderFrame RenderFrame;
|
||||
|
||||
public:
|
||||
|
@ -106,6 +107,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
|
|||
// Called by nsFrameLoaderOwner::ChangeRemoteness when switching out
|
||||
// FrameLoaders.
|
||||
static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
|
||||
BrowsingContext* aPreservedBrowsingContext,
|
||||
const mozilla::dom::RemotenessOptions& aOptions);
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_FRAMELOADER_IID)
|
||||
|
@ -385,6 +387,8 @@ class nsFrameLoader final : public nsStubMutationObserver,
|
|||
virtual JSObject* WrapObject(JSContext* cx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void SkipBrowsingContextDetach();
|
||||
|
||||
private:
|
||||
nsFrameLoader(mozilla::dom::Element* aOwner,
|
||||
mozilla::dom::BrowsingContext* aBrowsingContext,
|
||||
|
|
|
@ -32,8 +32,14 @@ nsFrameLoaderOwner::GetBrowsingContext() {
|
|||
|
||||
void nsFrameLoaderOwner::ChangeRemoteness(
|
||||
const mozilla::dom::RemotenessOptions& aOptions, mozilla::ErrorResult& rv) {
|
||||
RefPtr<mozilla::dom::BrowsingContext> bc;
|
||||
// If we already have a Frameloader, destroy it.
|
||||
if (mFrameLoader) {
|
||||
bc = mFrameLoader->GetBrowsingContext();
|
||||
|
||||
// TODO pass in Cross-Origin-Load-Policy rules
|
||||
mFrameLoader->SkipBrowsingContextDetach();
|
||||
|
||||
mFrameLoader->Destroy();
|
||||
mFrameLoader = nullptr;
|
||||
}
|
||||
|
@ -43,7 +49,8 @@ void nsFrameLoaderOwner::ChangeRemoteness(
|
|||
// owner.
|
||||
RefPtr<Element> owner = do_QueryObject(this);
|
||||
MOZ_ASSERT(owner);
|
||||
mFrameLoader = nsFrameLoader::Create(owner, aOptions);
|
||||
mFrameLoader = nsFrameLoader::Create(owner, bc, aOptions);
|
||||
|
||||
if (NS_WARN_IF(!mFrameLoader)) {
|
||||
return;
|
||||
}
|
||||
|
@ -70,9 +77,8 @@ void nsFrameLoaderOwner::ChangeRemoteness(
|
|||
// FrameLoader, fire an event to act like we've recreated ourselves, similar
|
||||
// to what XULFrameElement does after rebinding to the tree.
|
||||
// ChromeOnlyDispatch is turns on to make sure this isn't fired into content.
|
||||
(new mozilla::AsyncEventDispatcher(owner,
|
||||
NS_LITERAL_STRING("XULFrameLoaderCreated"),
|
||||
mozilla::CanBubble::eYes,
|
||||
mozilla::ChromeOnlyDispatch::eYes))
|
||||
(new mozilla::AsyncEventDispatcher(
|
||||
owner, NS_LITERAL_STRING("XULFrameLoaderCreated"),
|
||||
mozilla::CanBubble::eYes, mozilla::ChromeOnlyDispatch::eYes))
|
||||
->RunDOMEventWhenSafe();
|
||||
}
|
||||
|
|
|
@ -182,6 +182,11 @@ IPCResult BrowserBridgeParent::RecvDispatchSynthesizedMouseEvent(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult BrowserBridgeParent::RecvSkipBrowsingContextDetach() {
|
||||
mBrowserParent->SkipBrowsingContextDetach();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult BrowserBridgeParent::RecvActivate() {
|
||||
mBrowserParent->Activate();
|
||||
return IPC_OK();
|
||||
|
|
|
@ -59,6 +59,8 @@ class BrowserBridgeParent : public PBrowserBridgeParent {
|
|||
mozilla::ipc::IPCResult RecvDispatchSynthesizedMouseEvent(
|
||||
const WidgetMouseEvent& aEvent);
|
||||
|
||||
mozilla::ipc::IPCResult RecvSkipBrowsingContextDetach();
|
||||
|
||||
mozilla::ipc::IPCResult RecvActivate();
|
||||
|
||||
mozilla::ipc::IPCResult RecvDeactivate();
|
||||
|
|
|
@ -1052,6 +1052,17 @@ BrowserChild::~BrowserChild() {
|
|||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvSkipBrowsingContextDetach() {
|
||||
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
|
||||
if (!docShell) {
|
||||
return IPC_OK();
|
||||
}
|
||||
RefPtr<nsDocShell> docshell = nsDocShell::Cast(docShell);
|
||||
MOZ_ASSERT(docshell);
|
||||
docshell->SkipBrowsingContextDetach();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserChild::RecvLoadURL(const nsCString& aURI,
|
||||
const ShowInfo& aInfo) {
|
||||
if (!mDidLoadURLInit) {
|
||||
|
|
|
@ -555,6 +555,7 @@ class BrowserChild final : public BrowserChildBase,
|
|||
mozilla::ipc::IPCResult RecvUpdateNativeWindowHandle(
|
||||
const uintptr_t& aNewHandle);
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSkipBrowsingContextDetach() override;
|
||||
/**
|
||||
* Native widget remoting protocol for use with windowed plugins with e10s.
|
||||
*/
|
||||
|
|
|
@ -3744,6 +3744,12 @@ BrowserParent::StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void BrowserParent::SkipBrowsingContextDetach() {
|
||||
RefPtr<nsFrameLoader> fl = GetFrameLoader();
|
||||
MOZ_ASSERT(fl);
|
||||
fl->SkipBrowsingContextDetach();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserParent::RecvLookUpDictionary(
|
||||
const nsString& aText, nsTArray<FontRange>&& aFontRangeArray,
|
||||
const bool& aIsVertical, const LayoutDeviceIntPoint& aPoint) {
|
||||
|
|
|
@ -678,6 +678,8 @@ class BrowserParent final : public PBrowserParent,
|
|||
|
||||
void NavigateByKey(bool aForward, bool aForDocumentNavigation);
|
||||
|
||||
void SkipBrowsingContextDetach();
|
||||
|
||||
protected:
|
||||
bool ReceiveMessage(
|
||||
const nsString& aMessage, bool aSync, ipc::StructuredCloneData* aData,
|
||||
|
|
|
@ -948,6 +948,7 @@ child:
|
|||
*/
|
||||
async GetContentBlockingLog() returns(nsCString log, bool success);
|
||||
|
||||
async SkipBrowsingContextDetach();
|
||||
parent:
|
||||
/** Records a history visit. */
|
||||
async VisitURI(URIParams aURI, URIParams? aLastVisitedURI,
|
||||
|
|
|
@ -74,6 +74,8 @@ parent:
|
|||
async Deactivate();
|
||||
|
||||
async SetIsUnderHiddenEmbedderElement(bool aIsUnderHiddenEmbedderElement);
|
||||
|
||||
async SkipBrowsingContextDetach();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -82,10 +82,6 @@ void WindowGlobalParent::Init(const WindowGlobalInit& aInit) {
|
|||
mBrowsingContext = CanonicalBrowsingContext::Cast(aInit.browsingContext());
|
||||
MOZ_ASSERT(mBrowsingContext);
|
||||
|
||||
// XXX(nika): This won't be the case soon, but for now this is a good
|
||||
// assertion as we can't switch processes. We should relax this eventually.
|
||||
MOZ_ASSERT(mBrowsingContext->IsOwnedByProcess(processId));
|
||||
|
||||
// Attach ourself to the browsing context.
|
||||
mBrowsingContext->RegisterWindowGlobal(this);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче