Bug 1303196 - Part 1: Add the DocGroup and TabGroup Objects, r=billm

MozReview-Commit-ID: ILXWUlPPeHM
This commit is contained in:
Michael Layzell 2016-10-06 17:23:08 -04:00
parent 7689dc3caa
commit cec7ed92f4
4 changed files with 259 additions and 0 deletions

125
dom/base/DocGroup.cpp Normal file
View File

@ -0,0 +1,125 @@
#include "mozilla/dom/DocGroup.h"
#include "mozilla/Telemetry.h"
#include "nsIURI.h"
#include "nsIEffectiveTLDService.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsIDocShell.h"
namespace mozilla {
namespace dom {
/* static */ void
DocGroup::GetKey(nsIPrincipal* aPrincipal, nsACString& aKey)
{
aKey.Truncate();
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (tldService) {
rv = tldService->GetBaseDomain(uri, 0, aKey);
if (NS_FAILED(rv)) {
aKey.Truncate();
}
}
}
}
void
DocGroup::RemoveDocument(nsIDocument* aDocument)
{
MOZ_ASSERT(mDocuments.Contains(aDocument));
mDocuments.RemoveElement(aDocument);
}
DocGroup::DocGroup(TabGroup* aTabGroup, const nsACString& aKey)
: mKey(aKey), mTabGroup(aTabGroup)
{
// This method does not add itself to mTabGroup->mDocGroups as the caller does it for us.
}
DocGroup::~DocGroup()
{
MOZ_ASSERT(mDocuments.IsEmpty());
mTabGroup->mDocGroups.RemoveEntry(mKey);
}
NS_IMPL_ISUPPORTS(DocGroup, nsISupports)
TabGroup::TabGroup()
{}
TabGroup::~TabGroup()
{
MOZ_ASSERT(mDocGroups.IsEmpty());
MOZ_ASSERT(mWindows.IsEmpty());
}
static StaticRefPtr<TabGroup> sChromeTabGroup;
TabGroup*
TabGroup::GetChromeTabGroup()
{
if (!sChromeTabGroup) {
sChromeTabGroup = new TabGroup();
ClearOnShutdown(&sChromeTabGroup);
}
return sChromeTabGroup;
}
already_AddRefed<DocGroup>
TabGroup::GetDocGroup(const nsACString& aKey)
{
RefPtr<DocGroup> docGroup(mDocGroups.GetEntry(aKey)->mDocGroup);
return docGroup.forget();
}
already_AddRefed<DocGroup>
TabGroup::AddDocument(const nsACString& aKey, nsIDocument* aDocument)
{
HashEntry* entry = mDocGroups.PutEntry(aKey);
RefPtr<DocGroup> docGroup;
if (entry->mDocGroup) {
docGroup = entry->mDocGroup;
} else {
docGroup = new DocGroup(this, aKey);
entry->mDocGroup = docGroup;
}
// Make sure that the hashtable was updated and now contains the correct value
MOZ_ASSERT(RefPtr<DocGroup>(GetDocGroup(aKey)) == docGroup);
docGroup->mDocuments.AppendElement(aDocument);
return docGroup.forget();
}
/* static */ already_AddRefed<TabGroup>
TabGroup::Join(nsPIDOMWindowOuter* aWindow, TabGroup* aTabGroup)
{
RefPtr<TabGroup> tabGroup = aTabGroup;
if (!tabGroup) {
tabGroup = new TabGroup();
}
MOZ_ASSERT(!tabGroup->mWindows.Contains(aWindow));
tabGroup->mWindows.AppendElement(aWindow);
return tabGroup.forget();
}
void
TabGroup::Leave(nsPIDOMWindowOuter* aWindow)
{
MOZ_ASSERT(mWindows.Contains(aWindow));
mWindows.RemoveElement(aWindow);
}
NS_IMPL_ISUPPORTS(TabGroup, nsISupports)
TabGroup::HashEntry::HashEntry(const nsACString* aKey)
: nsCStringHashKey(aKey), mDocGroup(nullptr)
{}
}
}

131
dom/base/DocGroup.h Normal file
View File

@ -0,0 +1,131 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DocGroup_h
#define DocGroup_h
#include "nsISupports.h"
#include "nsISupportsImpl.h"
#include "nsIPrincipal.h"
#include "nsTHashtable.h"
#include "nsString.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
namespace dom {
// Two browsing contexts are considered "related" if they are reachable from one
// another through window.opener, window.parent, or window.frames. This is the
// spec concept of a "unit of related browsing contexts"
//
// Two browsing contexts are considered "similar-origin" if they can be made to
// have the same origin by setting document.domain. This is the spec concept of
// a "unit of similar-origin related browsing contexts"
//
// A TabGroup is a set of browsing contexts which are all "related". Within a
// TabGroup, browsing contexts are broken into "similar-origin" DocGroups. In
// more detail, a DocGroup is actually a collection of documents, and a
// TabGroup is a collection of DocGroups. A TabGroup typically will contain
// (through its DocGroups) the documents from one or more tabs related by
// window.opener. A DocGroup is a member of exactly one TabGroup.
class TabGroup;
class DocGroup final : public nsISupports
{
public:
typedef nsTArray<nsIDocument*>::iterator Iterator;
friend class TabGroup;
NS_DECL_THREADSAFE_ISUPPORTS
static void GetKey(nsIPrincipal* aPrincipal, nsACString& aString);
bool MatchesKey(const nsACString& aKey)
{
return aKey == mKey;
}
TabGroup* GetTabGroup()
{
return mTabGroup;
}
void RemoveDocument(nsIDocument* aWindow);
// Iterators for iterating over every document within the DocGroup
Iterator begin()
{
return mDocuments.begin();
}
Iterator end()
{
return mDocuments.end();
}
private:
DocGroup(TabGroup* aTabGroup, const nsACString& aKey);
~DocGroup();
nsCString mKey;
RefPtr<TabGroup> mTabGroup;
nsTArray<nsIDocument*> mDocuments;
};
class TabGroup final : public nsISupports
{
private:
class HashEntry : public nsCStringHashKey
{
public:
// NOTE: Weak reference. The DocGroup destructor removes itself from its
// owning TabGroup.
DocGroup* mDocGroup;
explicit HashEntry(const nsACString* aKey);
};
typedef nsTHashtable<HashEntry> DocGroupMap;
public:
typedef DocGroupMap::Iterator Iterator;
friend class DocGroup;
NS_DECL_THREADSAFE_ISUPPORTS
static TabGroup*
GetChromeTabGroup();
TabGroup();
// Get the docgroup for the corresponding doc group key.
// Returns null if the given key hasn't been seen yet.
already_AddRefed<DocGroup>
GetDocGroup(const nsACString& aKey);
already_AddRefed<DocGroup>
AddDocument(const nsACString& aKey, nsIDocument* aDocument);
// Join the specified TabGroup, returning a reference to it. If aTabGroup is
// nullptr, create a new tabgroup to join.
static already_AddRefed<TabGroup>
Join(nsPIDOMWindowOuter* aWindow, TabGroup* aTabGroup);
void Leave(nsPIDOMWindowOuter* aWindow);
Iterator Iter()
{
return mDocGroups.Iter();
}
private:
~TabGroup();
DocGroupMap mDocGroups;
nsTArray<nsPIDOMWindowOuter*> mWindows;
};
} // namespace dom
} // namespace mozilla
#endif // defined(DocGroup_h)

View File

@ -8,6 +8,7 @@
#include "nsIVariant.h"
#include "nsIInputStream.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/HTMLFormElement.h"
#include "MultipartBlobImpl.h"

View File

@ -159,6 +159,7 @@ EXPORTS.mozilla.dom += [
'Comment.h',
'CustomElementRegistry.h',
'DirectionalityUtils.h',
'DocGroup.h',
'DocumentFragment.h',
'DocumentType.h',
'DOMCursor.h',
@ -226,6 +227,7 @@ UNIFIED_SOURCES += [
'Crypto.cpp',
'CustomElementRegistry.cpp',
'DirectionalityUtils.cpp',
'DocGroup.cpp',
'DocumentFragment.cpp',
'DocumentType.cpp',
'DOMCursor.cpp',