Bug 1529684 - Part 6: Store a mIsInProcess flag to preserve WindowProxy behaviour, r=farre
Currently when we have an in-process WindowProxy object, we will attempt
to either use the cached mWindowProxy value, or fetch the
nsGlobalWindowOuter object from through the nsDocShell. Unfortunately,
when the BrowsingContext is detached, we will fail to get the
nsGlobalWindowOuter object. This happens to be OK for our test cases, as
the cached mWindowProxy value doesn't have the chance to go away, but
isn't acceptable long-term.
These patches exascerbated that issue by causing the nsDocShell pointer
itself to be cleared when it is destroyed, which caused the Remote
WindowProxy logic to be triggered. To deal with that case, this patch
adds a new mIsInProcess flag to continue to act like the old code-path.
In the future, we will need to also handle ensuring that the
nsGlobalWindowOuter lives for long enough, however that is not being
done in this patch in order to land it sooner rather than later.
Depends on D22763
Differential Revision: https://phabricator.services.mozilla.com/D22764

--- a/docshell/base/BrowsingContext.h+++ b/docshell/base/BrowsingContext.h@@ -160,16 +160,21 @@ class BrowsingContext : public nsWrapper // Create a BrowsingContext object from over IPC. static already_AddRefed<BrowsingContext> CreateFromIPC( BrowsingContext* aParent, BrowsingContext* aOpener, const nsAString& aName, uint64_t aId, ContentParent* aOriginProcess); // Cast this object to a canonical browsing context, and return it. CanonicalBrowsingContext* Canonical();+ // Is the most recent Document in this BrowsingContext loaded within this+ // process? This may be true with a null mDocShell after the Window has been+ // closed.+ bool IsInProcess() const { return mIsInProcess; }+ // Get the DocShell for this BrowsingContext if it is in-process, or // null if it's not. nsIDocShell* GetDocShell() { return mDocShell; } void SetDocShell(nsIDocShell* aDocShell); // Get the outer window object for this BrowsingContext if it is in-process // and still has a docshell, or null otherwise. nsPIDOMWindowOuter* GetDOMWindow() const {@@ -369,26 +374,32 @@ class BrowsingContext : public nsWrapper // Unique id identifying BrowsingContext const uint64_t mBrowsingContextId; RefPtr<BrowsingContextGroup> mGroup; RefPtr<BrowsingContext> mParent; Children mChildren; WeakPtr<BrowsingContext> mOpener; nsCOMPtr<nsIDocShell> mDocShell;+ // This is not a strong reference, but using a JS::Heap for that should be // fine. The JSObject stored in here should be a proxy with a // nsOuterWindowProxy handler, which will update the pointer from its // objectMoved hook and clear it from its finalize hook. JS::Heap<JSObject*> mWindowProxy; LocationProxy mLocation; // This flag is only valid in the top level browsing context, it indicates // whether the corresponding document has been activated by user gesture. bool mIsActivatedByUserGesture;++ // Is the most recent Document in this BrowsingContext loaded within this+ // process? This may be true with a null mDocShell after the Window has been+ // closed.+ bool mIsInProcess : 1; }; /** * Gets a WindowProxy object for a BrowsingContext that lives in a different * process (creating the object if it doesn't already exist). The WindowProxy * object will be in the compartment that aCx is currently in. This should only * be called if aContext doesn't hold a docshell, otherwise the BrowsingContext * lives in this process, and a same-process WindowProxy should be used (see