blob: a0e1ee7ece87e77549036322ca9d3b31c7f035a8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
/* 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/. */
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/TabGroup.h"
#include "nsIURI.h"
#include "nsIEffectiveTLDService.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsIDocShell.h"
#include "nsDOMMutationObserver.h"
#include "nsNetCID.h"
namespace mozilla {
namespace dom {
AutoTArray<RefPtr<DocGroup>, 2>* DocGroup::sPendingDocGroups = nullptr;
/* static */ void
DocGroup::GetKey(nsIPrincipal* aPrincipal, nsACString& aKey)
{
aKey.Truncate();
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
// GetBaseDomain works fine if |uri| is null, but it outputs a warning
// which ends up cluttering the logs.
if (NS_SUCCEEDED(rv) && uri) {
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());
if (!NS_IsMainThread()) {
NS_ReleaseOnMainThread(mReactionsStack.forget());
}
mTabGroup->mDocGroups.RemoveEntry(mKey);
}
NS_IMPL_ISUPPORTS(DocGroup, nsISupports)
void
DocGroup::SignalSlotChange(const HTMLSlotElement* aSlot)
{
if (mSignalSlotList.Contains(aSlot)) {
return;
}
mSignalSlotList.AppendElement(const_cast<HTMLSlotElement*>(aSlot));
if (!sPendingDocGroups) {
// Queue a mutation observer compound microtask.
nsDOMMutationObserver::QueueMutationObserverMicroTask();
sPendingDocGroups = new AutoTArray<RefPtr<DocGroup>, 2>;
}
sPendingDocGroups->AppendElement(this);
}
}
}
|