Commit 4bd759fa authored by Bogdan Tara's avatar Bogdan Tara
Browse files

Backed out 7 changesets (bug 1580565) for browser_entry_point_telemetry.js failures CLOSED TREE

Backed out changeset 12a4f3de76a8 (bug 1580565)
Backed out changeset 81d537df2dc1 (bug 1580565)
Backed out changeset b182e872c9d4 (bug 1580565)
Backed out changeset 0b4595b2c153 (bug 1580565)
Backed out changeset 4363e3a3d799 (bug 1580565)
Backed out changeset cbb14b2c7b33 (bug 1580565)
Backed out changeset 46b251848297 (bug 1580565)
parent f052a12a
This diff is collapsed.
......@@ -11,7 +11,6 @@
#include "mozilla/LinkedList.h"
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Span.h"
#include "mozilla/Tuple.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/BindingDeclarations.h"
......@@ -33,7 +32,6 @@
#include "nsILoadContext.h"
class nsDocShellLoadState;
class nsGlobalWindowInner;
class nsGlobalWindowOuter;
class nsILoadInfo;
class nsIPrincipal;
......@@ -74,15 +72,13 @@ class WindowProxyHolder;
// Fields are, by default, settable by any process and readable by any process.
// Racy sets will be resolved as-if they occurred in the order the parent
// process finds out about them.
//
// The `DidSet` and `CanSet` methods may be overloaded to provide different
// behavior for a specific field.
// * `DidSet` is called to run code in every process whenever the value is
// updated (This currently occurs even if the value didn't change, though
// this may change in the future).
// * `CanSet` is called before attempting to set the value, in both the process
// which calls `Set`, and the parent process, and will kill the misbehaving
// process if it fails.
// This defines the default do-nothing implementations for DidSet()
// and CanSet() for all the fields. They may be overloaded to provide
// different behavior for a specific field.
// DidSet() is used to run code in any process that sees the
// the value updated (note: even if the value itself didn't change).
// CanSet() is used to verify that the setting is allowed, and will
// assert if it fails in Debug builds.
#define MOZ_EACH_BC_FIELD(FIELD) \
FIELD(Name, nsString) \
FIELD(Closed, bool) \
......@@ -149,6 +145,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
public:
enum class Type { Chrome, Content };
using Children = nsTArray<RefPtr<BrowsingContext>>;
static void Init();
static LogModule* GetLog();
static void CleanupContexts(uint64_t aProcessId);
......@@ -166,25 +164,26 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
return GetFromWindow(aProxy);
}
// Create a brand-new toplevel BrowsingContext with no relationships to other
// BrowsingContexts, and which is not embedded within any <browser> or frame
// element.
//
// This BrowsingContext is immediately attached, and cannot have LoadContext
// flags customized unless it is of `Type::Chrome`.
//
// The process which created this BrowsingContext is responsible for detaching
// it.
static already_AddRefed<BrowsingContext> CreateIndependent(Type aType);
// Create a brand-new BrowsingContext object.
static already_AddRefed<BrowsingContext> Create(BrowsingContext* aParent,
BrowsingContext* aOpener,
const nsAString& aName,
Type aType);
// Create a brand-new BrowsingContext object, but does not immediately attach
// it. State such as OriginAttributes and PrivateBrowsingId may be customized
// to configure the BrowsingContext before it is attached.
//
// Same as the above, but does not immediately attach the browsing context.
// `EnsureAttached()` must be called before the BrowsingContext is used for a
// DocShell, BrowserParent, or BrowserBridgeChild.
static already_AddRefed<BrowsingContext> CreateDetached(
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
BrowsingContext* aParent, BrowsingContext* aOpener,
const nsAString& aName, Type aType);
// Same as Create, but for a BrowsingContext which does not belong to a
// visible window, and will always be detached by the process that created it.
// In contrast, any top-level BrowsingContext created in a content process
// using Create() is assumed to belong to a <browser> element in the parent
// process, which will be responsible for detaching it.
static already_AddRefed<BrowsingContext> CreateWindowless(
BrowsingContext* aParent, BrowsingContext* aOpener,
const nsAString& aName, Type aType);
void EnsureAttached();
......@@ -238,6 +237,12 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
return mDocShell ? mDocShell->GetWindow() : nullptr;
}
// Attach the current BrowsingContext to its parent, in both the child and the
// parent process. BrowsingContext objects are created attached by default, so
// this method need only be called when restoring cached BrowsingContext
// objects.
void Attach(bool aFromIPC = false);
// Detach the current BrowsingContext from its parent, in both the
// child and the parent process.
void Detach(bool aFromIPC = false);
......@@ -245,6 +250,13 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
// Prepare this BrowsingContext to leave the current process.
void PrepareForProcessChange();
// Remove all children from the current BrowsingContext and cache
// them to allow them to be attached again.
void CacheChildren(bool aFromIPC = false);
// Restore cached browsing contexts.
void RestoreChildren(Children&& aChildren, bool aFromIPC = false);
// Triggers a load in the process which currently owns this BrowsingContext.
nsresult LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating = false);
......@@ -258,7 +270,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
void DisplayLoadError(const nsAString& aURI);
// Determine if the current BrowsingContext is in the BFCache.
// Determine if the current BrowsingContext was 'cached' by the logic in
// CacheChildren.
bool IsCached();
// Check that this browsing context is targetable for navigations (i.e. that
......@@ -280,13 +293,12 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
bool IsContentSubframe() const { return IsContent() && GetParent(); }
uint64_t Id() const { return mBrowsingContextId; }
BrowsingContext* GetParent() const;
BrowsingContext* GetParent() const {
MOZ_ASSERT_IF(mParent, mParent->mType == mType);
return mParent;
}
BrowsingContext* Top();
// NOTE: Unlike `GetEmbedderWindowGlobal`, `GetParentWindow` does not cross
// toplevel content browser boundaries.
WindowContext* GetParentWindow() const { return mParentWindow; }
already_AddRefed<BrowsingContext> GetOpener() const {
RefPtr<BrowsingContext> opener(Get(GetOpenerId()));
if (!mIsDiscarded && opener && !opener->mIsDiscarded) {
......@@ -327,12 +339,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
uint32_t SandboxFlags() { return GetSandboxFlags(); }
Span<RefPtr<BrowsingContext>> Children() const;
void GetChildren(nsTArray<RefPtr<BrowsingContext>>& aChildren);
void GetChildren(Children& aChildren);
const nsTArray<RefPtr<WindowContext>>& GetWindowContexts() {
return mWindowContexts;
}
void GetWindowContexts(nsTArray<RefPtr<WindowContext>>& aWindows);
void RegisterWindowContext(WindowContext* aWindow);
......@@ -440,17 +448,22 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BrowsingContext)
NS_DECL_NSILOADCONTEXT
const Children& GetChildren() { return mChildren; }
const nsTArray<RefPtr<WindowContext>>& GetWindowContexts() {
return mWindowContexts;
}
// Perform a pre-order walk of this BrowsingContext subtree.
void PreOrderWalk(const std::function<void(BrowsingContext*)>& aCallback) {
aCallback(this);
for (auto& child : Children()) {
for (auto& child : GetChildren()) {
child->PreOrderWalk(aCallback);
}
}
// Perform an post-order walk of this BrowsingContext subtree.
void PostOrderWalk(const std::function<void(BrowsingContext*)>& aCallback) {
for (auto& child : Children()) {
for (auto& child : GetChildren()) {
child->PostOrderWalk(aCallback);
}
......@@ -467,7 +480,7 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
void Focus(CallerType aCallerType, ErrorResult& aError);
void Blur(ErrorResult& aError);
WindowProxyHolder GetFrames(ErrorResult& aError);
int32_t Length() const { return Children().Length(); }
int32_t Length() const { return mChildren.Length(); }
Nullable<WindowProxyHolder> GetTop(ErrorResult& aError);
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aOpener,
ErrorResult& aError) const;
......@@ -508,35 +521,27 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
// deserialized before other BrowsingContext in the BrowsingContextGroup
// have been initialized.
uint64_t mParentId = 0;
already_AddRefed<WindowContext> GetParent();
already_AddRefed<BrowsingContext> GetParent();
already_AddRefed<BrowsingContext> GetOpener();
uint64_t GetOpenerId() const { return mozilla::Get<IDX_OpenerId>(mFields); }
bool mCached = false;
bool mWindowless = false;
bool mUseRemoteTabs = false;
bool mUseRemoteSubframes = false;
OriginAttributes mOriginAttributes;
FieldTuple mFields;
bool operator==(const IPCInitializer& aOther) const {
return mId == aOther.mId && mParentId == aOther.mParentId &&
mWindowless == aOther.mWindowless &&
mUseRemoteTabs == aOther.mUseRemoteTabs &&
mUseRemoteSubframes == aOther.mUseRemoteSubframes &&
mOriginAttributes == aOther.mOriginAttributes &&
mFields == aOther.mFields;
}
};
// Create an IPCInitializer object for this BrowsingContext.
IPCInitializer GetIPCInitializer();
// Create a BrowsingContext object from over IPC.
static void CreateFromIPC(IPCInitializer&& aInitializer,
BrowsingContextGroup* aGroup,
ContentParent* aOriginProcess);
static already_AddRefed<BrowsingContext> CreateFromIPC(
IPCInitializer&& aInitializer, BrowsingContextGroup* aGroup,
ContentParent* aOriginProcess);
// Performs access control to check that 'this' can access 'aTarget'.
bool CanAccess(BrowsingContext* aTarget, bool aConsiderOpener = true);
......@@ -558,13 +563,11 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
protected:
virtual ~BrowsingContext();
BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup,
BrowsingContext(BrowsingContext* aParent, BrowsingContextGroup* aGroup,
uint64_t aBrowsingContextId, Type aType,
FieldTuple&& aFields);
private:
void Attach(bool aFromIPC, ContentParent* aOriginProcess);
// Find the special browsing context if aName is '_self', '_parent',
// '_top', but not '_blank'. The latter is handled in FindWithName
BrowsingContext* FindWithSpecialName(const nsAString& aName,
......@@ -708,7 +711,10 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
const uint64_t mBrowsingContextId;
RefPtr<BrowsingContextGroup> mGroup;
RefPtr<WindowContext> mParentWindow;
RefPtr<BrowsingContext> mParent;
// Note: BrowsingContext_Binding::ClearCachedChildrenValue must be called any
// time this array is mutated to keep the JS-exposed reflection in sync.
Children mChildren;
nsCOMPtr<nsIDocShell> mDocShell;
RefPtr<Element> mEmbedderElement;
......@@ -817,6 +823,7 @@ extern bool GetRemoteOuterWindowProxy(JSContext* aCx, BrowsingContext* aContext,
using BrowsingContextTransaction = BrowsingContext::BaseTransaction;
using BrowsingContextInitializer = BrowsingContext::IPCInitializer;
using BrowsingContextChildren = BrowsingContext::Children;
using MaybeDiscardedBrowsingContext = MaybeDiscarded<BrowsingContext>;
// Specialize the transaction object for every translation unit it's used in.
......
......@@ -16,31 +16,13 @@
namespace mozilla {
namespace dom {
static StaticRefPtr<BrowsingContextGroup> sChromeGroup;
static StaticAutoPtr<
nsDataHashtable<nsUint64HashKey, RefPtr<BrowsingContextGroup>>>
sBrowsingContextGroups;
already_AddRefed<BrowsingContextGroup> BrowsingContextGroup::GetOrCreate(
uint64_t aId) {
if (!sBrowsingContextGroups) {
sBrowsingContextGroups =
new nsDataHashtable<nsUint64HashKey, RefPtr<BrowsingContextGroup>>();
ClearOnShutdown(&sBrowsingContextGroups);
BrowsingContextGroup::BrowsingContextGroup() {
if (XRE_IsContentProcess()) {
ContentChild::GetSingleton()->HoldBrowsingContextGroup(this);
} else {
ContentParent::HoldBrowsingContextGroup(this);
}
auto entry = sBrowsingContextGroups->LookupForAdd(aId);
RefPtr<BrowsingContextGroup> group =
entry.OrInsert([&] { return do_AddRef(new BrowsingContextGroup(aId)); });
return group.forget();
}
already_AddRefed<BrowsingContextGroup> BrowsingContextGroup::Create() {
return GetOrCreate(nsContentUtils::GenerateBrowsingContextId());
}
BrowsingContextGroup::BrowsingContextGroup(uint64_t aId) : mId(aId) {
mTimerEventQueue = ThrottledEventQueue::Create(
GetMainThreadSerialEventTarget(), "BrowsingContextGroup timer queue");
......@@ -54,10 +36,6 @@ bool BrowsingContextGroup::Contains(BrowsingContext* aBrowsingContext) {
void BrowsingContextGroup::Register(BrowsingContext* aBrowsingContext) {
MOZ_DIAGNOSTIC_ASSERT(aBrowsingContext);
MOZ_DIAGNOSTIC_ASSERT(this == sChromeGroup ? aBrowsingContext->IsChrome()
: aBrowsingContext->IsContent(),
"Only chrome BCs may exist in the chrome group, and "
"only content BCs may exist in other groups");
mContexts.PutEntry(aBrowsingContext);
}
......@@ -70,7 +48,11 @@ void BrowsingContextGroup::Unregister(BrowsingContext* aBrowsingContext) {
// all subscribers.
UnsubscribeAllContentParents();
sBrowsingContextGroups->Remove(Id());
if (XRE_IsContentProcess()) {
ContentChild::GetSingleton()->ReleaseBrowsingContextGroup(this);
} else {
ContentParent::ReleaseBrowsingContextGroup(this);
}
// We may have been deleted here as the ContentChild/Parent may
// have held the last references to `this`.
// Do not access any members at this point.
......@@ -87,35 +69,6 @@ void BrowsingContextGroup::Unsubscribe(ContentParent* aOriginProcess) {
MOZ_DIAGNOSTIC_ASSERT(aOriginProcess);
mSubscribers.RemoveEntry(aOriginProcess);
aOriginProcess->OnBrowsingContextGroupUnsubscribe(this);
// If this origin process still embeds any non-discarded BrowsingContexts in
// this BrowsingContextGroup, make sure to discard them, as this process is
// going away.
nsTArray<RefPtr<BrowsingContext>> toDiscard;
for (auto& context : mContexts) {
if (context.GetKey()->Canonical()->IsEmbeddedInProcess(
aOriginProcess->ChildID())) {
toDiscard.AppendElement(context.GetKey());
}
}
for (auto& context : toDiscard) {
context->Detach(/* aFromIPC */ true);
}
}
static void CollectContextInitializers(
Span<RefPtr<BrowsingContext>> aContexts,
nsTArray<SyncedContextInitializer>& aInits) {
// The order that we record these initializers is important, as it will keep
// the order that children are attached to their parent in the newly connected
// content process consistent.
for (auto& context : aContexts) {
aInits.AppendElement(context->GetIPCInitializer());
for (auto& window : context->GetWindowContexts()) {
aInits.AppendElement(window->GetIPCInitializer());
CollectContextInitializers(window->Children(), aInits);
}
}
}
void BrowsingContextGroup::EnsureSubscribed(ContentParent* aProcess) {
......@@ -126,33 +79,79 @@ void BrowsingContextGroup::EnsureSubscribed(ContentParent* aProcess) {
Subscribe(aProcess);
// FIXME: This won't send non-discarded children of discarded BCs, but those
// BCs will be in the process of being destroyed anyway.
// FIXME: Prevent that situation from occuring.
nsTArray<SyncedContextInitializer> inits(mContexts.Count() * 2);
CollectContextInitializers(mToplevels, inits);
bool sendFocused = false;
bool sendActive = false;
BrowsingContext* focused = nullptr;
BrowsingContext* active = nullptr;
nsFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
focused = fm->GetFocusedBrowsingContextInChrome();
active = fm->GetActiveBrowsingContextInChrome();
}
// Send all of our contexts to the target content process.
Unused << aProcess->SendRegisterBrowsingContextGroup(Id(), inits);
// If the focused or active BrowsingContexts belong in this group, tell the
// newly subscribed process.
if (nsFocusManager* fm = nsFocusManager::GetFocusManager()) {
BrowsingContext* focused = fm->GetFocusedBrowsingContextInChrome();
if (focused && focused->Group() != this) {
focused = nullptr;
nsTArray<BrowsingContext::IPCInitializer> inits(mContexts.Count());
nsTArray<WindowContext::IPCInitializer> windowInits(mContexts.Count());
auto addInits = [&](BrowsingContext* aContext) {
inits.AppendElement(aContext->GetIPCInitializer());
if (focused == aContext) {
sendFocused = true;
}
BrowsingContext* active = fm->GetActiveBrowsingContextInChrome();
if (active && active->Group() != this) {
active = nullptr;
if (active == aContext) {
sendActive = true;
}
if (focused || active) {
Unused << aProcess->SendSetupFocusedAndActive(focused, active);
for (auto& window : aContext->GetWindowContexts()) {
windowInits.AppendElement(window->GetIPCInitializer());
}
};
// First, perform a pre-order walk of our BrowsingContext objects from our
// toplevels. This should visit every active BrowsingContext.
for (auto& context : mToplevels) {
MOZ_DIAGNOSTIC_ASSERT(!IsContextCached(context),
"cached contexts must have a parent");
context->PreOrderWalk(addInits);
}
// Ensure that cached BrowsingContext objects are also visited, by visiting
// them after mToplevels.
for (auto iter = mCachedContexts.Iter(); !iter.Done(); iter.Next()) {
iter.Get()->GetKey()->PreOrderWalk(addInits);
}
// We should have visited every browsing context.
MOZ_DIAGNOSTIC_ASSERT(inits.Length() == mContexts.Count(),
"Visited the wrong number of contexts!");
// Send all of our contexts to the target content process.
Unused << aProcess->SendRegisterBrowsingContextGroup(inits, windowInits);
if (sendActive || sendFocused) {
Unused << aProcess->SendSetupFocusedAndActive(
sendFocused ? focused : nullptr, sendActive ? active : nullptr);
}
}
bool BrowsingContextGroup::IsContextCached(BrowsingContext* aContext) const {
MOZ_DIAGNOSTIC_ASSERT(aContext);
return mCachedContexts.Contains(aContext);
}
void BrowsingContextGroup::CacheContext(BrowsingContext* aContext) {
mCachedContexts.PutEntry(aContext);
}
void BrowsingContextGroup::CacheContexts(
const BrowsingContext::Children& aContexts) {
for (BrowsingContext* child : aContexts) {
mCachedContexts.PutEntry(child);
}
}
bool BrowsingContextGroup::EvictCachedContext(BrowsingContext* aContext) {
return mCachedContexts.EnsureRemoved(aContext);
}
BrowsingContextGroup::~BrowsingContextGroup() {
UnsubscribeAllContentParents();
}
......@@ -214,11 +213,13 @@ void BrowsingContextGroup::FlushPostMessageEvents() {
}
}
static StaticRefPtr<BrowsingContextGroup> sChromeGroup;
/* static */
BrowsingContextGroup* BrowsingContextGroup::GetChromeGroup() {
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
if (!sChromeGroup && XRE_IsParentProcess()) {
sChromeGroup = BrowsingContextGroup::Create();
sChromeGroup = new BrowsingContextGroup();
ClearOnShutdown(&sChromeGroup);
}
......@@ -259,32 +260,8 @@ void BrowsingContextGroup::RemoveDocument(const nsACString& aKey,
}
}
already_AddRefed<BrowsingContextGroup> BrowsingContextGroup::Select(
WindowContext* aParent, BrowsingContext* aOpener) {
if (aParent) {
return do_AddRef(aParent->Group());
}
if (aOpener) {
return do_AddRef(aOpener->Group());
}
return Create();
}
void BrowsingContextGroup::GetAllGroups(
nsTArray<RefPtr<BrowsingContextGroup>>& aGroups) {
aGroups.Clear();
if (!sBrowsingContextGroups) {
return;
}
aGroups.SetCapacity(sBrowsingContextGroups->Count());
for (auto& group : *sBrowsingContextGroups) {
aGroups.AppendElement(group.GetData());
}
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BrowsingContextGroup, mContexts,
mToplevels, mSubscribers,
mToplevels, mSubscribers, mCachedContexts,
mTimerEventQueue, mWorkerEventQueue)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(BrowsingContextGroup, AddRef)
......
......@@ -21,7 +21,6 @@ class ThrottledEventQueue;
namespace dom {
class BrowsingContext;
class WindowContext;
class ContentParent;
// A BrowsingContextGroup represents the Unit of Related Browsing Contexts in
......@@ -48,24 +47,46 @@ class BrowsingContextGroup final : public nsWrapperCache {
// Force the given ContentParent to subscribe to our BrowsingContextGroup.
void EnsureSubscribed(ContentParent* aProcess);
// Methods interacting with cached contexts.
bool IsContextCached(BrowsingContext* aContext) const;
void CacheContext(BrowsingContext* aContext);
void CacheContexts(const BrowsingContext::Children& aContexts);
bool EvictCachedContext(BrowsingContext* aContext);
// Get a reference to the list of toplevel contexts in this
// BrowsingContextGroup.
nsTArray<RefPtr<BrowsingContext>>& Toplevels() { return mToplevels; }
void GetToplevels(nsTArray<RefPtr<BrowsingContext>>& aToplevels) {
BrowsingContext::Children& Toplevels() { return mToplevels; }
void GetToplevels(BrowsingContext::Children& aToplevels) {
aToplevels.AppendElements(mToplevels);
}
uint64_t Id() { return mId; }
nsISupports* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// Get or create a BrowsingContextGroup with the given ID.
static already_AddRefed<BrowsingContextGroup> GetOrCreate(uint64_t aId);
static already_AddRefed<BrowsingContextGroup> Create();
BrowsingContextGroup();
static already_AddRefed<BrowsingContextGroup> Select(
WindowContext* aParent, BrowsingContext* aOpener);
BrowsingContext* aParent, BrowsingContext* aOpener) {
if (aParent) {
return do_AddRef(aParent->Group());
}
if (aOpener) {
return do_AddRef(aOpener->Group());
}
return MakeAndAddRef<BrowsingContextGroup>();
}
static already_AddRefed<BrowsingContextGroup> Select(uint64_t aParentId,
uint64_t aOpenerId) {
RefPtr<BrowsingContext> parent = BrowsingContext::Get(aParentId);
MOZ_RELEASE_ASSERT(parent || aParentId == 0);
RefPtr<BrowsingContext> opener = BrowsingContext::Get(aOpenerId);
MOZ_RELEASE_ASSERT(opener || aOpenerId == 0);
return Select(parent, opener);
}
// For each 'ContentParent', except for 'aExcludedParent',
// associated with this group call 'aCallback'.
......@@ -114,25 +135,20 @@ class BrowsingContextGroup final : public nsWrapperCache {
return mWorkerEventQueue;
}
static void GetAllGroups(nsTArray<RefPtr<BrowsingContextGroup>>& aGroups);
private:
friend class CanonicalBrowsingContext;
explicit BrowsingContextGroup(uint64_t aId);
~BrowsingContextGroup();
void UnsubscribeAllContentParents();
uint64_t mId;
// A BrowsingContextGroup contains a series of BrowsingContext objects. They
// are addressed using a hashtable to avoid linear lookup when adding or
// removing elements from the set.
nsTHashtable<nsRefPtrHashKey<BrowsingContext>> mContexts;
// The set of toplevel browsing contexts in the current BrowsingContextGroup.
nsTArray<RefPtr<BrowsingContext>> mToplevels;
BrowsingContext::Children mToplevels;
// DocGroups are thread-safe, and not able to be cycle collected,
// but we still keep strong pointers. When all Documents are removed
......@@ -142,6 +158,9 @@ class BrowsingContextGroup final : public nsWrapperCache {
ContentParents mSubscribers;
// Map of cached contexts that need to stay alive due to bfcache.
nsTHashtable<nsRefPtrHashKey<BrowsingContext>> mCachedContexts;
// A queue to store postMessage events during page load, the queue will be
// flushed once the page is loaded
RefPtr<mozilla::ThrottledEventQueue> mPostMessageEventQueue;
......
......@@ -33,14 +33,14 @@ extern mozilla::LazyLogModule gUserInteractionPRLog;
#define USER_ACTIVATION_LOG(msg, ...) \
MOZ_LOG(gUserInteractionPRLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
CanonicalBrowsingContext::CanonicalBrowsingContext(WindowContext* aParentWindow,
CanonicalBrowsingContext::CanonicalBrowsingContext(BrowsingContext* aParent,