Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "mozilla/ServoStyleRuleMap.h"
8 :
9 : #include "mozilla/css/GroupRule.h"
10 : #include "mozilla/IntegerRange.h"
11 : #include "mozilla/ServoStyleRule.h"
12 : #include "mozilla/ServoStyleSet.h"
13 : #include "mozilla/ServoImportRule.h"
14 :
15 : #include "nsDocument.h"
16 : #include "nsStyleSheetService.h"
17 :
18 : namespace mozilla {
19 :
20 0 : ServoStyleRuleMap::ServoStyleRuleMap(ServoStyleSet* aStyleSet)
21 0 : : mStyleSet(aStyleSet)
22 : {
23 0 : }
24 :
25 0 : ServoStyleRuleMap::~ServoStyleRuleMap()
26 : {
27 0 : }
28 :
29 0 : NS_IMPL_ISUPPORTS(ServoStyleRuleMap, nsIDocumentObserver, nsICSSLoaderObserver)
30 :
31 : void
32 0 : ServoStyleRuleMap::EnsureTable()
33 : {
34 0 : if (!IsEmpty()) {
35 0 : return;
36 : }
37 0 : mStyleSet->EnumerateStyleSheetArrays(
38 0 : [this](const nsTArray<RefPtr<ServoStyleSheet>>& aArray) {
39 0 : for (auto& sheet : aArray) {
40 0 : FillTableFromStyleSheet(sheet);
41 : }
42 0 : });
43 : }
44 :
45 : void
46 0 : ServoStyleRuleMap::StyleSheetAdded(StyleSheet* aStyleSheet,
47 : bool aDocumentSheet)
48 : {
49 0 : if (!IsEmpty()) {
50 0 : FillTableFromStyleSheet(aStyleSheet->AsServo());
51 : }
52 0 : }
53 :
54 : void
55 0 : ServoStyleRuleMap::StyleSheetRemoved(StyleSheet* aStyleSheet,
56 : bool aDocumentSheet)
57 : {
58 : // Invalidate all data inside. This isn't strictly necessary since
59 : // we should always get update from document before new queries come.
60 : // But it is probably still safer if we try to avoid having invalid
61 : // pointers inside. Also if the document keep adding and removing
62 : // stylesheets, this would also prevent us from infinitely growing
63 : // memory usage.
64 0 : mTable.Clear();
65 0 : }
66 :
67 : void
68 0 : ServoStyleRuleMap::StyleSheetApplicableStateChanged(StyleSheet* aStyleSheet)
69 : {
70 : // We don't care if the stylesheet is disabled. Not removing no longer
71 : // applicable stylesheets wouldn't make anything wrong.
72 0 : if (!IsEmpty() && aStyleSheet->IsApplicable()) {
73 0 : FillTableFromStyleSheet(aStyleSheet->AsServo());
74 : }
75 0 : }
76 :
77 : void
78 0 : ServoStyleRuleMap::StyleRuleAdded(StyleSheet* aStyleSheet,
79 : css::Rule* aStyleRule)
80 : {
81 0 : if (!IsEmpty()) {
82 0 : FillTableFromRule(aStyleRule);
83 : }
84 0 : }
85 :
86 : void
87 0 : ServoStyleRuleMap::StyleRuleRemoved(StyleSheet* aStyleSheet,
88 : css::Rule* aStyleRule)
89 : {
90 0 : if (IsEmpty()) {
91 0 : return;
92 : }
93 :
94 0 : switch (aStyleRule->Type()) {
95 : case nsIDOMCSSRule::STYLE_RULE: {
96 0 : auto rule = static_cast<ServoStyleRule*>(aStyleRule);
97 0 : mTable.Remove(rule->Raw());
98 0 : break;
99 : }
100 : case nsIDOMCSSRule::IMPORT_RULE:
101 : case nsIDOMCSSRule::MEDIA_RULE:
102 : case nsIDOMCSSRule::SUPPORTS_RULE:
103 : case nsIDOMCSSRule::DOCUMENT_RULE: {
104 : // See the comment in StyleSheetRemoved.
105 0 : mTable.Clear();
106 0 : break;
107 : }
108 : case nsIDOMCSSRule::FONT_FACE_RULE:
109 : case nsIDOMCSSRule::PAGE_RULE:
110 : case nsIDOMCSSRule::KEYFRAMES_RULE:
111 : case nsIDOMCSSRule::KEYFRAME_RULE:
112 : case nsIDOMCSSRule::NAMESPACE_RULE:
113 : case nsIDOMCSSRule::COUNTER_STYLE_RULE:
114 : case nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE:
115 0 : break;
116 : default:
117 0 : MOZ_ASSERT_UNREACHABLE("Unhandled rule");
118 : }
119 : }
120 :
121 : NS_IMETHODIMP
122 0 : ServoStyleRuleMap::StyleSheetLoaded(StyleSheet* aSheet,
123 : bool aWasAlternate,
124 : nsresult aStatus)
125 : {
126 0 : MOZ_ASSERT(aSheet->IsServo());
127 0 : if (!IsEmpty()) {
128 0 : FillTableFromStyleSheet(aSheet->AsServo());
129 : }
130 0 : return NS_OK;
131 : }
132 :
133 : size_t
134 0 : ServoStyleRuleMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
135 : {
136 0 : size_t n = aMallocSizeOf(this);
137 0 : n += mTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
138 0 : return n;
139 : }
140 :
141 : void
142 0 : ServoStyleRuleMap::FillTableFromRule(css::Rule* aRule)
143 : {
144 0 : switch (aRule->Type()) {
145 : case nsIDOMCSSRule::STYLE_RULE: {
146 0 : auto rule = static_cast<ServoStyleRule*>(aRule);
147 0 : mTable.Put(rule->Raw(), rule);
148 0 : break;
149 : }
150 : case nsIDOMCSSRule::MEDIA_RULE:
151 : case nsIDOMCSSRule::SUPPORTS_RULE:
152 : case nsIDOMCSSRule::DOCUMENT_RULE: {
153 0 : auto rule = static_cast<css::GroupRule*>(aRule);
154 0 : auto ruleList = static_cast<ServoCSSRuleList*>(rule->CssRules());
155 0 : FillTableFromRuleList(ruleList);
156 0 : break;
157 : }
158 : case nsIDOMCSSRule::IMPORT_RULE: {
159 0 : auto rule = static_cast<ServoImportRule*>(aRule);
160 0 : FillTableFromStyleSheet(rule->GetStyleSheet()->AsServo());
161 0 : break;
162 : }
163 : }
164 0 : }
165 :
166 : void
167 0 : ServoStyleRuleMap::FillTableFromRuleList(ServoCSSRuleList* aRuleList)
168 : {
169 0 : for (uint32_t i : IntegerRange(aRuleList->Length())) {
170 0 : FillTableFromRule(aRuleList->GetRule(i));
171 : }
172 0 : }
173 :
174 : void
175 0 : ServoStyleRuleMap::FillTableFromStyleSheet(ServoStyleSheet* aSheet)
176 : {
177 0 : if (aSheet->IsComplete()) {
178 0 : FillTableFromRuleList(aSheet->GetCssRulesInternal());
179 : }
180 0 : }
181 :
182 : } // namespace mozilla
|