/src/mozilla-central/layout/style/CSSStyleRule.cpp
Line | Count | Source (jump to first uncovered line) |
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/dom/CSSStyleRule.h" |
8 | | |
9 | | #include "mozilla/DeclarationBlock.h" |
10 | | #include "mozilla/ServoBindings.h" |
11 | | #include "mozilla/dom/CSSStyleRuleBinding.h" |
12 | | |
13 | | #include "mozAutoDocUpdate.h" |
14 | | |
15 | | using namespace mozilla::dom; |
16 | | |
17 | | namespace mozilla { |
18 | | namespace dom { |
19 | | |
20 | | // -- CSSStyleRuleDeclaration --------------------------------------- |
21 | | |
22 | | CSSStyleRuleDeclaration::CSSStyleRuleDeclaration( |
23 | | already_AddRefed<RawServoDeclarationBlock> aDecls) |
24 | | : mDecls(new DeclarationBlock(std::move(aDecls))) |
25 | 0 | { |
26 | 0 | } |
27 | | |
28 | | CSSStyleRuleDeclaration::~CSSStyleRuleDeclaration() |
29 | 0 | { |
30 | 0 | mDecls->SetOwningRule(nullptr); |
31 | 0 | } |
32 | | |
33 | | // QueryInterface implementation for CSSStyleRuleDeclaration |
34 | 0 | NS_INTERFACE_MAP_BEGIN(CSSStyleRuleDeclaration) |
35 | 0 | NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
36 | 0 | // We forward the cycle collection interfaces to Rule(), which is |
37 | 0 | // never null (in fact, we're part of that object!) |
38 | 0 | if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) || |
39 | 0 | aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) { |
40 | 0 | return Rule()->QueryInterface(aIID, aInstancePtr); |
41 | 0 | } |
42 | 0 | else |
43 | 0 | NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration) |
44 | | |
45 | | NS_IMPL_ADDREF_USING_AGGREGATOR(CSSStyleRuleDeclaration, Rule()) |
46 | | NS_IMPL_RELEASE_USING_AGGREGATOR(CSSStyleRuleDeclaration, Rule()) |
47 | | |
48 | | /* nsDOMCSSDeclaration implementation */ |
49 | | |
50 | | css::Rule* |
51 | | CSSStyleRuleDeclaration::GetParentRule() |
52 | 0 | { |
53 | 0 | return Rule(); |
54 | 0 | } |
55 | | |
56 | | nsINode* |
57 | | CSSStyleRuleDeclaration::GetParentObject() |
58 | 0 | { |
59 | 0 | return Rule()->GetParentObject(); |
60 | 0 | } |
61 | | |
62 | | DeclarationBlock* |
63 | | CSSStyleRuleDeclaration::GetOrCreateCSSDeclaration(Operation aOperation, |
64 | | DeclarationBlock** aCreated) |
65 | 0 | { |
66 | 0 | return mDecls; |
67 | 0 | } |
68 | | |
69 | | nsresult |
70 | | CSSStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl, |
71 | | MutationClosureData* aClosureData) |
72 | 0 | { |
73 | 0 | CSSStyleRule* rule = Rule(); |
74 | 0 | if (RefPtr<StyleSheet> sheet = rule->GetStyleSheet()) { |
75 | 0 | if (aDecl != mDecls) { |
76 | 0 | mDecls->SetOwningRule(nullptr); |
77 | 0 | RefPtr<DeclarationBlock> decls = aDecl; |
78 | 0 | Servo_StyleRule_SetStyle(rule->Raw(), decls->Raw()); |
79 | 0 | mDecls = decls.forget(); |
80 | 0 | mDecls->SetOwningRule(rule); |
81 | 0 | } |
82 | 0 | sheet->RuleChanged(rule); |
83 | 0 | } |
84 | 0 | return NS_OK; |
85 | 0 | } |
86 | | |
87 | | nsIDocument* |
88 | | CSSStyleRuleDeclaration::DocToUpdate() |
89 | 0 | { |
90 | 0 | return nullptr; |
91 | 0 | } |
92 | | |
93 | | nsDOMCSSDeclaration::ParsingEnvironment |
94 | | CSSStyleRuleDeclaration::GetParsingEnvironment( |
95 | | nsIPrincipal* aSubjectPrincipal) const |
96 | 0 | { |
97 | 0 | return GetParsingEnvironmentForRule(Rule()); |
98 | 0 | } |
99 | | |
100 | | // -- CSSStyleRule -------------------------------------------------- |
101 | | |
102 | | CSSStyleRule::CSSStyleRule(already_AddRefed<RawServoStyleRule> aRawRule, |
103 | | StyleSheet* aSheet, |
104 | | css::Rule* aParentRule, |
105 | | uint32_t aLine, |
106 | | uint32_t aColumn) |
107 | | : BindingStyleRule(aSheet, aParentRule, aLine, aColumn) |
108 | | , mRawRule(aRawRule) |
109 | | , mDecls(Servo_StyleRule_GetStyle(mRawRule).Consume()) |
110 | 0 | { |
111 | 0 | } |
112 | | |
113 | | NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSStyleRule, css::Rule) |
114 | | |
115 | | NS_IMPL_CYCLE_COLLECTION_CLASS(CSSStyleRule) |
116 | | |
117 | 0 | NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSStyleRule, css::Rule) |
118 | 0 | // Keep this in sync with IsCCLeaf. |
119 | 0 |
|
120 | 0 | // Trace the wrapper for our declaration. This just expands out |
121 | 0 | // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use |
122 | 0 | // directly because the wrapper is on the declaration, not on us. |
123 | 0 | tmp->mDecls.TraceWrapper(aCallbacks, aClosure); |
124 | 0 | NS_IMPL_CYCLE_COLLECTION_TRACE_END |
125 | | |
126 | 0 | NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSStyleRule, css::Rule) |
127 | 0 | // Keep this in sync with IsCCLeaf. |
128 | 0 |
|
129 | 0 | // Unlink the wrapper for our declaraton. This just expands out |
130 | 0 | // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use |
131 | 0 | // directly because the wrapper is on the declaration, not on us. |
132 | 0 | tmp->mDecls.ReleaseWrapper(static_cast<nsISupports*>(p)); |
133 | 0 | NS_IMPL_CYCLE_COLLECTION_UNLINK_END |
134 | | |
135 | 0 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSStyleRule, css::Rule) |
136 | 0 | // Keep this in sync with IsCCLeaf. |
137 | 0 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END |
138 | | |
139 | | bool |
140 | | CSSStyleRule::IsCCLeaf() const |
141 | 0 | { |
142 | 0 | if (!Rule::IsCCLeaf()) { |
143 | 0 | return false; |
144 | 0 | } |
145 | 0 | |
146 | 0 | return !mDecls.PreservingWrapper(); |
147 | 0 | } |
148 | | |
149 | | size_t |
150 | | CSSStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
151 | 0 | { |
152 | 0 | size_t n = aMallocSizeOf(this); |
153 | 0 |
|
154 | 0 | // Measurement of the following members may be added later if DMD finds it is |
155 | 0 | // worthwhile: |
156 | 0 | // - mRawRule |
157 | 0 | // - mDecls |
158 | 0 |
|
159 | 0 | return n; |
160 | 0 | } |
161 | | |
162 | | #ifdef DEBUG |
163 | | void |
164 | | CSSStyleRule::List(FILE* out, int32_t aIndent) const |
165 | | { |
166 | | nsAutoCString str; |
167 | | for (int32_t i = 0; i < aIndent; i++) { |
168 | | str.AppendLiteral(" "); |
169 | | } |
170 | | Servo_StyleRule_Debug(mRawRule, &str); |
171 | | fprintf_stderr(out, "%s\n", str.get()); |
172 | | } |
173 | | #endif |
174 | | |
175 | | /* CSSRule implementation */ |
176 | | |
177 | | void |
178 | | CSSStyleRule::GetCssText(nsAString& aCssText) const |
179 | 0 | { |
180 | 0 | Servo_StyleRule_GetCssText(mRawRule, &aCssText); |
181 | 0 | } |
182 | | |
183 | | nsICSSDeclaration* |
184 | | CSSStyleRule::Style() |
185 | 0 | { |
186 | 0 | return &mDecls; |
187 | 0 | } |
188 | | |
189 | | /* CSSStyleRule implementation */ |
190 | | |
191 | | void |
192 | | CSSStyleRule::GetSelectorText(nsAString& aSelectorText) |
193 | 0 | { |
194 | 0 | Servo_StyleRule_GetSelectorText(mRawRule, &aSelectorText); |
195 | 0 | } |
196 | | |
197 | | void |
198 | | CSSStyleRule::SetSelectorText(const nsAString& aSelectorText) |
199 | 0 | { |
200 | 0 | if (RefPtr<StyleSheet> sheet = GetStyleSheet()) { |
201 | 0 | // StyleRule lives inside of the Inner, it is unsafe to call WillDirty |
202 | 0 | // if sheet does not already have a unique Inner. |
203 | 0 | sheet->AssertHasUniqueInner(); |
204 | 0 | sheet->WillDirty(); |
205 | 0 |
|
206 | 0 | const RawServoStyleSheetContents* contents = sheet->RawContents(); |
207 | 0 | if (Servo_StyleRule_SetSelectorText(contents, mRawRule, &aSelectorText)) { |
208 | 0 | sheet->RuleChanged(this); |
209 | 0 | } |
210 | 0 | } |
211 | 0 | } |
212 | | |
213 | | uint32_t |
214 | | CSSStyleRule::GetSelectorCount() |
215 | 0 | { |
216 | 0 | uint32_t aCount; |
217 | 0 | Servo_StyleRule_GetSelectorCount(mRawRule, &aCount); |
218 | 0 | return aCount; |
219 | 0 | } |
220 | | |
221 | | nsresult |
222 | | CSSStyleRule::GetSelectorText(uint32_t aSelectorIndex, nsAString& aText) |
223 | 0 | { |
224 | 0 | Servo_StyleRule_GetSelectorTextAtIndex(mRawRule, aSelectorIndex, &aText); |
225 | 0 | return NS_OK; |
226 | 0 | } |
227 | | |
228 | | nsresult |
229 | | CSSStyleRule::GetSpecificity(uint32_t aSelectorIndex, uint64_t* aSpecificity) |
230 | 0 | { |
231 | 0 | Servo_StyleRule_GetSpecificityAtIndex(mRawRule, aSelectorIndex, aSpecificity); |
232 | 0 | return NS_OK; |
233 | 0 | } |
234 | | |
235 | | nsresult |
236 | | CSSStyleRule::SelectorMatchesElement(Element* aElement, |
237 | | uint32_t aSelectorIndex, |
238 | | const nsAString& aPseudo, |
239 | | bool* aMatches) |
240 | 0 | { |
241 | 0 | CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo; |
242 | 0 | if (!aPseudo.IsEmpty()) { |
243 | 0 | RefPtr<nsAtom> pseudoElt = NS_Atomize(aPseudo); |
244 | 0 | pseudoType = nsCSSPseudoElements::GetPseudoType( |
245 | 0 | pseudoElt, CSSEnabledState::eIgnoreEnabledState); |
246 | 0 |
|
247 | 0 | if (pseudoType == CSSPseudoElementType::NotPseudo) { |
248 | 0 | *aMatches = false; |
249 | 0 | return NS_OK; |
250 | 0 | } |
251 | 0 | } |
252 | 0 | |
253 | 0 | *aMatches = Servo_StyleRule_SelectorMatchesElement(mRawRule, aElement, |
254 | 0 | aSelectorIndex, pseudoType); |
255 | 0 |
|
256 | 0 | return NS_OK; |
257 | 0 | } |
258 | | |
259 | | NotNull<DeclarationBlock*> |
260 | | CSSStyleRule::GetDeclarationBlock() const |
261 | 0 | { |
262 | 0 | return WrapNotNull(mDecls.mDecls); |
263 | 0 | } |
264 | | |
265 | | } // namespace dom |
266 | | } // namespace mozilla |