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 : /* representation of CSSStyleRule for stylo */
8 :
9 : #include "mozilla/ServoStyleRule.h"
10 :
11 : #include "mozilla/DeclarationBlockInlines.h"
12 : #include "mozilla/ServoBindings.h"
13 : #include "mozilla/ServoDeclarationBlock.h"
14 : #include "mozilla/dom/CSSStyleRuleBinding.h"
15 :
16 : #include "mozAutoDocUpdate.h"
17 :
18 : namespace mozilla {
19 :
20 : // -- ServoStyleRuleDeclaration ---------------------------------------
21 :
22 0 : ServoStyleRuleDeclaration::ServoStyleRuleDeclaration(
23 0 : already_AddRefed<RawServoDeclarationBlock> aDecls)
24 0 : : mDecls(new ServoDeclarationBlock(Move(aDecls)))
25 : {
26 0 : }
27 :
28 0 : ServoStyleRuleDeclaration::~ServoStyleRuleDeclaration()
29 : {
30 0 : }
31 :
32 : // QueryInterface implementation for ServoStyleRuleDeclaration
33 0 : NS_INTERFACE_MAP_BEGIN(ServoStyleRuleDeclaration)
34 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
35 : // We forward the cycle collection interfaces to Rule(), which is
36 : // never null (in fact, we're part of that object!)
37 0 : if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
38 0 : aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
39 0 : return Rule()->QueryInterface(aIID, aInstancePtr);
40 : }
41 : else
42 0 : NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
43 :
44 0 : NS_IMPL_ADDREF_USING_AGGREGATOR(ServoStyleRuleDeclaration, Rule())
45 0 : NS_IMPL_RELEASE_USING_AGGREGATOR(ServoStyleRuleDeclaration, Rule())
46 :
47 : /* nsDOMCSSDeclaration implementation */
48 :
49 : NS_IMETHODIMP
50 0 : ServoStyleRuleDeclaration::GetParentRule(nsIDOMCSSRule** aParent)
51 : {
52 0 : *aParent = do_AddRef(Rule()).take();
53 0 : return NS_OK;
54 : }
55 :
56 : nsINode*
57 0 : ServoStyleRuleDeclaration::GetParentObject()
58 : {
59 0 : return Rule()->GetDocument();
60 : }
61 :
62 : DeclarationBlock*
63 0 : ServoStyleRuleDeclaration::GetCSSDeclaration(Operation aOperation)
64 : {
65 0 : return mDecls;
66 : }
67 :
68 : nsresult
69 0 : ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
70 : {
71 0 : ServoStyleRule* rule = Rule();
72 0 : if (RefPtr<ServoStyleSheet> sheet = rule->GetStyleSheet()->AsServo()) {
73 0 : nsCOMPtr<nsIDocument> doc = sheet->GetAssociatedDocument();
74 0 : mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
75 0 : if (aDecl != mDecls) {
76 0 : mDecls->SetOwningRule(nullptr);
77 0 : RefPtr<ServoDeclarationBlock> decls = aDecl->AsServo();
78 0 : Servo_StyleRule_SetStyle(rule->Raw(), decls->Raw());
79 0 : mDecls = decls.forget();
80 0 : mDecls->SetOwningRule(rule);
81 : }
82 0 : if (doc) {
83 0 : doc->StyleRuleChanged(sheet, rule);
84 : }
85 : }
86 0 : return NS_OK;
87 : }
88 :
89 : nsIDocument*
90 0 : ServoStyleRuleDeclaration::DocToUpdate()
91 : {
92 0 : return nullptr;
93 : }
94 :
95 : void
96 0 : ServoStyleRuleDeclaration::GetCSSParsingEnvironment(
97 : CSSParsingEnvironment& aCSSParseEnv)
98 : {
99 0 : MOZ_ASSERT_UNREACHABLE("GetCSSParsingEnvironment "
100 : "shouldn't be calling for a Servo rule");
101 : GetCSSParsingEnvironmentForRule(Rule(), aCSSParseEnv);
102 : }
103 :
104 : nsDOMCSSDeclaration::ServoCSSParsingEnvironment
105 0 : ServoStyleRuleDeclaration::GetServoCSSParsingEnvironment() const
106 : {
107 0 : return GetServoCSSParsingEnvironmentForRule(Rule());
108 : }
109 :
110 : // -- ServoStyleRule --------------------------------------------------
111 :
112 0 : ServoStyleRule::ServoStyleRule(already_AddRefed<RawServoStyleRule> aRawRule,
113 0 : uint32_t aLine, uint32_t aColumn)
114 : : BindingStyleRule(aLine, aColumn)
115 : , mRawRule(aRawRule)
116 0 : , mDecls(Servo_StyleRule_GetStyle(mRawRule).Consume())
117 : {
118 0 : }
119 :
120 : // QueryInterface implementation for ServoStyleRule
121 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoStyleRule)
122 0 : NS_INTERFACE_MAP_ENTRY(nsICSSStyleRuleDOMWrapper)
123 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleRule)
124 0 : NS_INTERFACE_MAP_END_INHERITING(css::Rule)
125 :
126 0 : NS_IMPL_ADDREF_INHERITED(ServoStyleRule, css::Rule)
127 0 : NS_IMPL_RELEASE_INHERITED(ServoStyleRule, css::Rule)
128 :
129 : NS_IMPL_CYCLE_COLLECTION_CLASS(ServoStyleRule)
130 :
131 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ServoStyleRule, css::Rule)
132 : // Keep this in sync with IsCCLeaf.
133 :
134 : // Trace the wrapper for our declaration. This just expands out
135 : // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
136 : // directly because the wrapper is on the declaration, not on us.
137 0 : tmp->mDecls.TraceWrapper(aCallbacks, aClosure);
138 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
139 :
140 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoStyleRule, css::Rule)
141 : // Keep this in sync with IsCCLeaf.
142 :
143 : // Unlink the wrapper for our declaraton. This just expands out
144 : // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
145 : // directly because the wrapper is on the declaration, not on us.
146 0 : tmp->mDecls.ReleaseWrapper(static_cast<nsISupports*>(p));
147 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
148 :
149 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoStyleRule, css::Rule)
150 : // Keep this in sync with IsCCLeaf.
151 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
152 :
153 : bool
154 0 : ServoStyleRule::IsCCLeaf() const
155 : {
156 0 : if (!Rule::IsCCLeaf()) {
157 0 : return false;
158 : }
159 :
160 0 : return !mDecls.PreservingWrapper();
161 : }
162 :
163 : already_AddRefed<css::Rule>
164 0 : ServoStyleRule::Clone() const
165 : {
166 : // Rule::Clone is only used when CSSStyleSheetInner is cloned in
167 : // preparation of being mutated. However, ServoStyleSheet never clones
168 : // anything, so this method should never be called.
169 0 : MOZ_ASSERT_UNREACHABLE("Shouldn't be cloning ServoStyleRule");
170 : return nullptr;
171 : }
172 :
173 : size_t
174 0 : ServoStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
175 : {
176 0 : size_t n = aMallocSizeOf(this);
177 :
178 : // Measurement of the following members may be added later if DMD finds it is
179 : // worthwhile:
180 : // - mRawRule
181 : // - mDecls
182 :
183 0 : return n;
184 : }
185 :
186 : #ifdef DEBUG
187 : void
188 0 : ServoStyleRule::List(FILE* out, int32_t aIndent) const
189 : {
190 0 : nsAutoCString str;
191 0 : for (int32_t i = 0; i < aIndent; i++) {
192 0 : str.AppendLiteral(" ");
193 : }
194 0 : Servo_StyleRule_Debug(mRawRule, &str);
195 0 : fprintf_stderr(out, "%s\n", str.get());
196 0 : }
197 : #endif
198 :
199 : /* nsICSSStyleRuleDOMWrapper implementation */
200 :
201 : NS_IMETHODIMP
202 0 : ServoStyleRule::GetCSSStyleRule(BindingStyleRule **aResult)
203 : {
204 0 : NS_ADDREF(*aResult = this);
205 0 : return NS_OK;
206 : }
207 :
208 : /* CSSRule implementation */
209 :
210 : uint16_t
211 0 : ServoStyleRule::Type() const
212 : {
213 0 : return nsIDOMCSSRule::STYLE_RULE;
214 : }
215 :
216 : void
217 0 : ServoStyleRule::GetCssTextImpl(nsAString& aCssText) const
218 : {
219 0 : Servo_StyleRule_GetCssText(mRawRule, &aCssText);
220 0 : }
221 :
222 : nsICSSDeclaration*
223 0 : ServoStyleRule::Style()
224 : {
225 0 : return &mDecls;
226 : }
227 :
228 : /* CSSStyleRule implementation */
229 :
230 : NS_IMETHODIMP
231 0 : ServoStyleRule::GetSelectorText(nsAString& aSelectorText)
232 : {
233 0 : Servo_StyleRule_GetSelectorText(mRawRule, &aSelectorText);
234 0 : return NS_OK;
235 : }
236 :
237 : NS_IMETHODIMP
238 0 : ServoStyleRule::SetSelectorText(const nsAString& aSelectorText)
239 : {
240 : // XXX We need to implement this... But Gecko doesn't have this either
241 : // so it's probably okay to leave it unimplemented currently?
242 : // See bug 37468 and mozilla::css::StyleRule::SetSelectorText.
243 0 : return NS_OK;
244 : }
245 :
246 : NS_IMETHODIMP
247 0 : ServoStyleRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
248 : {
249 0 : *aStyle = do_AddRef(&mDecls).take();
250 0 : return NS_OK;
251 : }
252 :
253 : uint32_t
254 0 : ServoStyleRule::GetSelectorCount()
255 : {
256 : uint32_t aCount;
257 0 : Servo_StyleRule_GetSelectorCount(mRawRule, &aCount);
258 :
259 0 : return aCount;
260 : }
261 :
262 : nsresult
263 0 : ServoStyleRule::GetSelectorText(uint32_t aSelectorIndex, nsAString& aText)
264 : {
265 0 : Servo_StyleRule_GetSelectorTextAtIndex(mRawRule, aSelectorIndex, &aText);
266 0 : return NS_OK;
267 : }
268 :
269 : nsresult
270 0 : ServoStyleRule::GetSpecificity(uint32_t aSelectorIndex, uint64_t* aSpecificity)
271 : {
272 0 : Servo_StyleRule_GetSpecificityAtIndex(mRawRule, aSelectorIndex, aSpecificity);
273 0 : return NS_OK;
274 : }
275 :
276 : nsresult
277 0 : ServoStyleRule::SelectorMatchesElement(Element* aElement,
278 : uint32_t aSelectorIndex,
279 : const nsAString& aPseudo,
280 : bool* aMatches)
281 : {
282 0 : nsCOMPtr<nsIAtom> pseudoElt = NS_Atomize(aPseudo);
283 : const CSSPseudoElementType pseudoType =
284 0 : nsCSSPseudoElements::GetPseudoType(pseudoElt,
285 0 : CSSEnabledState::eIgnoreEnabledState);
286 0 : *aMatches = Servo_StyleRule_SelectorMatchesElement(mRawRule,
287 : aElement,
288 : aSelectorIndex,
289 0 : pseudoType);
290 0 : return NS_OK;
291 : }
292 :
293 : } // namespace mozilla
|