|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 /* rules in a CSS stylesheet other than style rules (e.g., @import rules) */ |
|
7 |
|
8 #include "mozilla/Attributes.h" |
|
9 |
|
10 #include "nsCSSRules.h" |
|
11 #include "nsCSSValue.h" |
|
12 #include "mozilla/MemoryReporting.h" |
|
13 #include "mozilla/css/ImportRule.h" |
|
14 #include "mozilla/css/NameSpaceRule.h" |
|
15 |
|
16 #include "nsString.h" |
|
17 #include "nsIAtom.h" |
|
18 |
|
19 #include "nsCSSProps.h" |
|
20 #include "nsCSSStyleSheet.h" |
|
21 |
|
22 #include "nsCOMPtr.h" |
|
23 #include "nsIDOMCSSStyleSheet.h" |
|
24 #include "nsIMediaList.h" |
|
25 #include "nsICSSRuleList.h" |
|
26 #include "nsIDocument.h" |
|
27 #include "nsPresContext.h" |
|
28 |
|
29 #include "nsContentUtils.h" |
|
30 #include "nsError.h" |
|
31 #include "nsStyleUtil.h" |
|
32 #include "mozilla/css/Declaration.h" |
|
33 #include "nsCSSParser.h" |
|
34 #include "nsPrintfCString.h" |
|
35 #include "nsDOMClassInfoID.h" |
|
36 #include "mozilla/dom/CSSStyleDeclarationBinding.h" |
|
37 #include "StyleRule.h" |
|
38 #include "nsFont.h" |
|
39 #include "nsIURI.h" |
|
40 #include "mozAutoDocUpdate.h" |
|
41 |
|
42 using namespace mozilla; |
|
43 |
|
44 #define IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \ |
|
45 /* virtual */ nsIDOMCSSRule* class_::GetDOMRule() \ |
|
46 { return this; } \ |
|
47 /* virtual */ nsIDOMCSSRule* class_::GetExistingDOMRule() \ |
|
48 { return this; } |
|
49 #define IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) \ |
|
50 /* virtual */ void class_::MapRuleInfoInto(nsRuleData* aRuleData) \ |
|
51 { NS_ABORT_IF_FALSE(false, "should not be called"); } |
|
52 |
|
53 #define IMPL_STYLE_RULE_INHERIT(class_, super_) \ |
|
54 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \ |
|
55 IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) |
|
56 |
|
57 // base class for all rule types in a CSS style sheet |
|
58 |
|
59 namespace mozilla { |
|
60 namespace css { |
|
61 |
|
62 nsCSSStyleSheet* |
|
63 Rule::GetStyleSheet() const |
|
64 { |
|
65 if (!(mSheet & 0x1)) { |
|
66 return reinterpret_cast<nsCSSStyleSheet*>(mSheet); |
|
67 } |
|
68 |
|
69 return nullptr; |
|
70 } |
|
71 |
|
72 nsHTMLCSSStyleSheet* |
|
73 Rule::GetHTMLCSSStyleSheet() const |
|
74 { |
|
75 if (mSheet & 0x1) { |
|
76 return reinterpret_cast<nsHTMLCSSStyleSheet*>(mSheet & ~uintptr_t(0x1)); |
|
77 } |
|
78 |
|
79 return nullptr; |
|
80 } |
|
81 |
|
82 /* virtual */ void |
|
83 Rule::SetStyleSheet(nsCSSStyleSheet* aSheet) |
|
84 { |
|
85 // We don't reference count this up reference. The style sheet |
|
86 // will tell us when it's going away or when we're detached from |
|
87 // it. |
|
88 mSheet = reinterpret_cast<uintptr_t>(aSheet); |
|
89 } |
|
90 |
|
91 void |
|
92 Rule::SetHTMLCSSStyleSheet(nsHTMLCSSStyleSheet* aSheet) |
|
93 { |
|
94 // We don't reference count this up reference. The style sheet |
|
95 // will tell us when it's going away or when we're detached from |
|
96 // it. |
|
97 mSheet = reinterpret_cast<uintptr_t>(aSheet); |
|
98 mSheet |= 0x1; |
|
99 } |
|
100 |
|
101 nsresult |
|
102 Rule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
103 { |
|
104 if (mParentRule) { |
|
105 NS_IF_ADDREF(*aParentRule = mParentRule->GetDOMRule()); |
|
106 } else { |
|
107 *aParentRule = nullptr; |
|
108 } |
|
109 return NS_OK; |
|
110 } |
|
111 |
|
112 nsresult |
|
113 Rule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
114 { |
|
115 NS_ENSURE_ARG_POINTER(aSheet); |
|
116 |
|
117 NS_IF_ADDREF(*aSheet = GetStyleSheet()); |
|
118 return NS_OK; |
|
119 } |
|
120 |
|
121 size_t |
|
122 Rule::SizeOfCOMArrayElementIncludingThis(css::Rule* aElement, |
|
123 MallocSizeOf aMallocSizeOf, |
|
124 void* aData) |
|
125 { |
|
126 return aElement->SizeOfIncludingThis(aMallocSizeOf); |
|
127 } |
|
128 |
|
129 // ------------------------------- |
|
130 // Style Rule List for group rules |
|
131 // |
|
132 |
|
133 class GroupRuleRuleList MOZ_FINAL : public nsICSSRuleList |
|
134 { |
|
135 public: |
|
136 GroupRuleRuleList(GroupRule *aGroupRule); |
|
137 |
|
138 NS_DECL_ISUPPORTS |
|
139 |
|
140 virtual nsIDOMCSSRule* |
|
141 IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE; |
|
142 virtual uint32_t |
|
143 Length() MOZ_OVERRIDE; |
|
144 |
|
145 void DropReference() { mGroupRule = nullptr; } |
|
146 |
|
147 private: |
|
148 ~GroupRuleRuleList(); |
|
149 |
|
150 private: |
|
151 GroupRule* mGroupRule; |
|
152 }; |
|
153 |
|
154 GroupRuleRuleList::GroupRuleRuleList(GroupRule *aGroupRule) |
|
155 { |
|
156 // Not reference counted to avoid circular references. |
|
157 // The rule will tell us when its going away. |
|
158 mGroupRule = aGroupRule; |
|
159 } |
|
160 |
|
161 GroupRuleRuleList::~GroupRuleRuleList() |
|
162 { |
|
163 } |
|
164 |
|
165 // QueryInterface implementation for GroupRuleRuleList |
|
166 NS_INTERFACE_MAP_BEGIN(GroupRuleRuleList) |
|
167 NS_INTERFACE_MAP_ENTRY(nsICSSRuleList) |
|
168 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRuleList) |
|
169 NS_INTERFACE_MAP_ENTRY(nsISupports) |
|
170 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSRuleList) |
|
171 NS_INTERFACE_MAP_END |
|
172 |
|
173 |
|
174 NS_IMPL_ADDREF(GroupRuleRuleList) |
|
175 NS_IMPL_RELEASE(GroupRuleRuleList) |
|
176 |
|
177 uint32_t |
|
178 GroupRuleRuleList::Length() |
|
179 { |
|
180 if (!mGroupRule) { |
|
181 return 0; |
|
182 } |
|
183 |
|
184 return SafeCast<uint32_t>(mGroupRule->StyleRuleCount()); |
|
185 } |
|
186 |
|
187 nsIDOMCSSRule* |
|
188 GroupRuleRuleList::IndexedGetter(uint32_t aIndex, bool& aFound) |
|
189 { |
|
190 aFound = false; |
|
191 |
|
192 if (mGroupRule) { |
|
193 nsRefPtr<Rule> rule = mGroupRule->GetStyleRuleAt(aIndex); |
|
194 if (rule) { |
|
195 aFound = true; |
|
196 return rule->GetDOMRule(); |
|
197 } |
|
198 } |
|
199 |
|
200 return nullptr; |
|
201 } |
|
202 |
|
203 } // namespace css |
|
204 } // namespace mozilla |
|
205 |
|
206 // ------------------------------------------- |
|
207 // CharsetRule |
|
208 // |
|
209 |
|
210 // Must be outside namespace |
|
211 DOMCI_DATA(CSSCharsetRule, css::CharsetRule) |
|
212 |
|
213 namespace mozilla { |
|
214 namespace css { |
|
215 |
|
216 CharsetRule::CharsetRule(const nsAString& aEncoding) |
|
217 : Rule(), |
|
218 mEncoding(aEncoding) |
|
219 { |
|
220 } |
|
221 |
|
222 CharsetRule::CharsetRule(const CharsetRule& aCopy) |
|
223 : Rule(aCopy), |
|
224 mEncoding(aCopy.mEncoding) |
|
225 { |
|
226 } |
|
227 |
|
228 NS_IMPL_ADDREF(CharsetRule) |
|
229 NS_IMPL_RELEASE(CharsetRule) |
|
230 |
|
231 // QueryInterface implementation for CharsetRule |
|
232 NS_INTERFACE_MAP_BEGIN(CharsetRule) |
|
233 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
234 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
235 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule) |
|
236 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
237 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSCharsetRule) |
|
238 NS_INTERFACE_MAP_END |
|
239 |
|
240 IMPL_STYLE_RULE_INHERIT(CharsetRule, Rule) |
|
241 |
|
242 #ifdef DEBUG |
|
243 /* virtual */ void |
|
244 CharsetRule::List(FILE* out, int32_t aIndent) const |
|
245 { |
|
246 // Indent |
|
247 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
248 |
|
249 fputs("@charset \"", out); |
|
250 fputs(NS_LossyConvertUTF16toASCII(mEncoding).get(), out); |
|
251 fputs("\"\n", out); |
|
252 } |
|
253 #endif |
|
254 |
|
255 /* virtual */ int32_t |
|
256 CharsetRule::GetType() const |
|
257 { |
|
258 return Rule::CHARSET_RULE; |
|
259 } |
|
260 |
|
261 /* virtual */ already_AddRefed<Rule> |
|
262 CharsetRule::Clone() const |
|
263 { |
|
264 nsRefPtr<Rule> clone = new CharsetRule(*this); |
|
265 return clone.forget(); |
|
266 } |
|
267 |
|
268 NS_IMETHODIMP |
|
269 CharsetRule::GetEncoding(nsAString& aEncoding) |
|
270 { |
|
271 aEncoding = mEncoding; |
|
272 return NS_OK; |
|
273 } |
|
274 |
|
275 NS_IMETHODIMP |
|
276 CharsetRule::SetEncoding(const nsAString& aEncoding) |
|
277 { |
|
278 mEncoding = aEncoding; |
|
279 return NS_OK; |
|
280 } |
|
281 |
|
282 NS_IMETHODIMP |
|
283 CharsetRule::GetType(uint16_t* aType) |
|
284 { |
|
285 *aType = nsIDOMCSSRule::CHARSET_RULE; |
|
286 return NS_OK; |
|
287 } |
|
288 |
|
289 NS_IMETHODIMP |
|
290 CharsetRule::GetCssText(nsAString& aCssText) |
|
291 { |
|
292 aCssText.AssignLiteral("@charset \""); |
|
293 aCssText.Append(mEncoding); |
|
294 aCssText.AppendLiteral("\";"); |
|
295 return NS_OK; |
|
296 } |
|
297 |
|
298 NS_IMETHODIMP |
|
299 CharsetRule::SetCssText(const nsAString& aCssText) |
|
300 { |
|
301 return NS_ERROR_NOT_IMPLEMENTED; |
|
302 } |
|
303 |
|
304 NS_IMETHODIMP |
|
305 CharsetRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
306 { |
|
307 return Rule::GetParentStyleSheet(aSheet); |
|
308 } |
|
309 |
|
310 NS_IMETHODIMP |
|
311 CharsetRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
312 { |
|
313 return Rule::GetParentRule(aParentRule); |
|
314 } |
|
315 |
|
316 /* virtual */ size_t |
|
317 CharsetRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
318 { |
|
319 return aMallocSizeOf(this); |
|
320 |
|
321 // Measurement of the following members may be added later if DMD finds it is |
|
322 // worthwhile: |
|
323 // - mEncoding |
|
324 } |
|
325 |
|
326 // ------------------------------------------- |
|
327 // ImportRule |
|
328 // |
|
329 |
|
330 ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec) |
|
331 : Rule() |
|
332 , mURLSpec(aURLSpec) |
|
333 , mMedia(aMedia) |
|
334 { |
|
335 // XXXbz This is really silly.... the mMedia here will be replaced |
|
336 // with itself if we manage to load a sheet. Which should really |
|
337 // never fail nowadays, in sane cases. |
|
338 } |
|
339 |
|
340 ImportRule::ImportRule(const ImportRule& aCopy) |
|
341 : Rule(aCopy), |
|
342 mURLSpec(aCopy.mURLSpec) |
|
343 { |
|
344 // Whether or not an @import rule has a null sheet is a permanent |
|
345 // property of that @import rule, since it is null only if the target |
|
346 // sheet failed security checks. |
|
347 if (aCopy.mChildSheet) { |
|
348 nsRefPtr<nsCSSStyleSheet> sheet = |
|
349 aCopy.mChildSheet->Clone(nullptr, this, nullptr, nullptr); |
|
350 SetSheet(sheet); |
|
351 // SetSheet sets mMedia appropriately |
|
352 } |
|
353 } |
|
354 |
|
355 ImportRule::~ImportRule() |
|
356 { |
|
357 if (mChildSheet) { |
|
358 mChildSheet->SetOwnerRule(nullptr); |
|
359 } |
|
360 } |
|
361 |
|
362 NS_IMPL_ADDREF(ImportRule) |
|
363 NS_IMPL_RELEASE(ImportRule) |
|
364 |
|
365 // QueryInterface implementation for ImportRule |
|
366 NS_INTERFACE_MAP_BEGIN(ImportRule) |
|
367 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
368 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
369 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule) |
|
370 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
371 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSImportRule) |
|
372 NS_INTERFACE_MAP_END |
|
373 |
|
374 IMPL_STYLE_RULE_INHERIT(ImportRule, Rule) |
|
375 |
|
376 #ifdef DEBUG |
|
377 /* virtual */ void |
|
378 ImportRule::List(FILE* out, int32_t aIndent) const |
|
379 { |
|
380 // Indent |
|
381 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
382 |
|
383 fputs("@import \"", out); |
|
384 fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out); |
|
385 fputs("\" ", out); |
|
386 |
|
387 nsAutoString mediaText; |
|
388 mMedia->GetText(mediaText); |
|
389 fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out); |
|
390 fputs("\n", out); |
|
391 } |
|
392 #endif |
|
393 |
|
394 /* virtual */ int32_t |
|
395 ImportRule::GetType() const |
|
396 { |
|
397 return Rule::IMPORT_RULE; |
|
398 } |
|
399 |
|
400 /* virtual */ already_AddRefed<Rule> |
|
401 ImportRule::Clone() const |
|
402 { |
|
403 nsRefPtr<Rule> clone = new ImportRule(*this); |
|
404 return clone.forget(); |
|
405 } |
|
406 |
|
407 void |
|
408 ImportRule::SetSheet(nsCSSStyleSheet* aSheet) |
|
409 { |
|
410 NS_PRECONDITION(aSheet, "null arg"); |
|
411 |
|
412 // set the new sheet |
|
413 mChildSheet = aSheet; |
|
414 aSheet->SetOwnerRule(this); |
|
415 |
|
416 // set our medialist to be the same as the sheet's medialist |
|
417 mMedia = mChildSheet->Media(); |
|
418 } |
|
419 |
|
420 NS_IMETHODIMP |
|
421 ImportRule::GetType(uint16_t* aType) |
|
422 { |
|
423 NS_ENSURE_ARG_POINTER(aType); |
|
424 *aType = nsIDOMCSSRule::IMPORT_RULE; |
|
425 return NS_OK; |
|
426 } |
|
427 |
|
428 NS_IMETHODIMP |
|
429 ImportRule::GetCssText(nsAString& aCssText) |
|
430 { |
|
431 aCssText.AssignLiteral("@import url("); |
|
432 nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText); |
|
433 aCssText.Append(NS_LITERAL_STRING(")")); |
|
434 if (mMedia) { |
|
435 nsAutoString mediaText; |
|
436 mMedia->GetText(mediaText); |
|
437 if (!mediaText.IsEmpty()) { |
|
438 aCssText.AppendLiteral(" "); |
|
439 aCssText.Append(mediaText); |
|
440 } |
|
441 } |
|
442 aCssText.AppendLiteral(";"); |
|
443 return NS_OK; |
|
444 } |
|
445 |
|
446 NS_IMETHODIMP |
|
447 ImportRule::SetCssText(const nsAString& aCssText) |
|
448 { |
|
449 return NS_ERROR_NOT_IMPLEMENTED; |
|
450 } |
|
451 |
|
452 NS_IMETHODIMP |
|
453 ImportRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
454 { |
|
455 return Rule::GetParentStyleSheet(aSheet); |
|
456 } |
|
457 |
|
458 NS_IMETHODIMP |
|
459 ImportRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
460 { |
|
461 return Rule::GetParentRule(aParentRule); |
|
462 } |
|
463 |
|
464 NS_IMETHODIMP |
|
465 ImportRule::GetHref(nsAString & aHref) |
|
466 { |
|
467 aHref = mURLSpec; |
|
468 return NS_OK; |
|
469 } |
|
470 |
|
471 NS_IMETHODIMP |
|
472 ImportRule::GetMedia(nsIDOMMediaList * *aMedia) |
|
473 { |
|
474 NS_ENSURE_ARG_POINTER(aMedia); |
|
475 |
|
476 NS_IF_ADDREF(*aMedia = mMedia); |
|
477 return NS_OK; |
|
478 } |
|
479 |
|
480 NS_IMETHODIMP |
|
481 ImportRule::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet) |
|
482 { |
|
483 NS_ENSURE_ARG_POINTER(aStyleSheet); |
|
484 |
|
485 NS_IF_ADDREF(*aStyleSheet = mChildSheet); |
|
486 return NS_OK; |
|
487 } |
|
488 |
|
489 /* virtual */ size_t |
|
490 ImportRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
491 { |
|
492 return aMallocSizeOf(this); |
|
493 |
|
494 // Measurement of the following members may be added later if DMD finds it is |
|
495 // worthwhile: |
|
496 // - mURLSpec |
|
497 // |
|
498 // The following members are not measured: |
|
499 // - mMedia, because it is measured via nsCSSStyleSheet::mMedia |
|
500 // - mChildSheet, because it is measured via nsCSSStyleSheetInner::mSheets |
|
501 } |
|
502 |
|
503 } // namespace css |
|
504 } // namespace mozilla |
|
505 |
|
506 // must be outside the namespace |
|
507 DOMCI_DATA(CSSImportRule, css::ImportRule) |
|
508 |
|
509 namespace mozilla { |
|
510 namespace css { |
|
511 |
|
512 GroupRule::GroupRule() |
|
513 : Rule() |
|
514 { |
|
515 } |
|
516 |
|
517 static bool |
|
518 SetParentRuleReference(Rule* aRule, void* aParentRule) |
|
519 { |
|
520 GroupRule* parentRule = static_cast<GroupRule*>(aParentRule); |
|
521 aRule->SetParentRule(parentRule); |
|
522 return true; |
|
523 } |
|
524 |
|
525 GroupRule::GroupRule(const GroupRule& aCopy) |
|
526 : Rule(aCopy) |
|
527 { |
|
528 const_cast<GroupRule&>(aCopy).mRules.EnumerateForwards(GroupRule::CloneRuleInto, &mRules); |
|
529 mRules.EnumerateForwards(SetParentRuleReference, this); |
|
530 } |
|
531 |
|
532 GroupRule::~GroupRule() |
|
533 { |
|
534 NS_ABORT_IF_FALSE(!mSheet, "SetStyleSheet should have been called"); |
|
535 mRules.EnumerateForwards(SetParentRuleReference, nullptr); |
|
536 if (mRuleCollection) { |
|
537 mRuleCollection->DropReference(); |
|
538 } |
|
539 } |
|
540 |
|
541 NS_IMPL_CYCLE_COLLECTING_ADDREF(GroupRule) |
|
542 NS_IMPL_CYCLE_COLLECTING_RELEASE(GroupRule) |
|
543 |
|
544 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule) |
|
545 NS_INTERFACE_MAP_END |
|
546 |
|
547 IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(GroupRule, Rule) |
|
548 |
|
549 static bool |
|
550 SetStyleSheetReference(Rule* aRule, void* aSheet) |
|
551 { |
|
552 nsCSSStyleSheet* sheet = (nsCSSStyleSheet*)aSheet; |
|
553 aRule->SetStyleSheet(sheet); |
|
554 return true; |
|
555 } |
|
556 |
|
557 NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule) |
|
558 |
|
559 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(GroupRule) |
|
560 tmp->mRules.EnumerateForwards(SetParentRuleReference, nullptr); |
|
561 // If tmp does not have a stylesheet, neither do its descendants. In that |
|
562 // case, don't try to null out their stylesheet, to avoid O(N^2) behavior in |
|
563 // depth of group rule nesting. But if tmp _does_ have a stylesheet (which |
|
564 // can happen if it gets unlinked earlier than its owning stylesheet), then we |
|
565 // need to null out the stylesheet pointer on descendants now, before we clear |
|
566 // tmp->mRules. |
|
567 if (tmp->GetStyleSheet()) { |
|
568 tmp->mRules.EnumerateForwards(SetStyleSheetReference, nullptr); |
|
569 } |
|
570 tmp->mRules.Clear(); |
|
571 if (tmp->mRuleCollection) { |
|
572 tmp->mRuleCollection->DropReference(); |
|
573 tmp->mRuleCollection = nullptr; |
|
574 } |
|
575 NS_IMPL_CYCLE_COLLECTION_UNLINK_END |
|
576 |
|
577 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(GroupRule) |
|
578 const nsCOMArray<Rule>& rules = tmp->mRules; |
|
579 for (int32_t i = 0, count = rules.Count(); i < count; ++i) { |
|
580 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]"); |
|
581 cb.NoteXPCOMChild(rules[i]->GetExistingDOMRule()); |
|
582 } |
|
583 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRuleCollection) |
|
584 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END |
|
585 |
|
586 /* virtual */ void |
|
587 GroupRule::SetStyleSheet(nsCSSStyleSheet* aSheet) |
|
588 { |
|
589 // Don't set the sheet on the kids if it's already the same as the sheet we |
|
590 // already have. This is needed to avoid O(N^2) behavior in group nesting |
|
591 // depth when seting the sheet to null during unlink, if we happen to unlin in |
|
592 // order from most nested rule up to least nested rule. |
|
593 if (aSheet != GetStyleSheet()) { |
|
594 mRules.EnumerateForwards(SetStyleSheetReference, aSheet); |
|
595 Rule::SetStyleSheet(aSheet); |
|
596 } |
|
597 } |
|
598 |
|
599 #ifdef DEBUG |
|
600 /* virtual */ void |
|
601 GroupRule::List(FILE* out, int32_t aIndent) const |
|
602 { |
|
603 fputs(" {\n", out); |
|
604 |
|
605 for (int32_t index = 0, count = mRules.Count(); index < count; ++index) { |
|
606 mRules.ObjectAt(index)->List(out, aIndent + 1); |
|
607 } |
|
608 |
|
609 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
610 fputs("}\n", out); |
|
611 } |
|
612 #endif |
|
613 |
|
614 void |
|
615 GroupRule::AppendStyleRule(Rule* aRule) |
|
616 { |
|
617 mRules.AppendObject(aRule); |
|
618 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
619 aRule->SetStyleSheet(sheet); |
|
620 aRule->SetParentRule(this); |
|
621 if (sheet) { |
|
622 sheet->SetModifiedByChildRule(); |
|
623 } |
|
624 } |
|
625 |
|
626 Rule* |
|
627 GroupRule::GetStyleRuleAt(int32_t aIndex) const |
|
628 { |
|
629 return mRules.SafeObjectAt(aIndex); |
|
630 } |
|
631 |
|
632 bool |
|
633 GroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const |
|
634 { |
|
635 return |
|
636 const_cast<GroupRule*>(this)->mRules.EnumerateForwards(aFunc, aData); |
|
637 } |
|
638 |
|
639 /* |
|
640 * The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt) |
|
641 * should never be called unless you have first called WillDirty() on |
|
642 * the parents stylesheet. After they are called, DidDirty() needs to |
|
643 * be called on the sheet |
|
644 */ |
|
645 nsresult |
|
646 GroupRule::DeleteStyleRuleAt(uint32_t aIndex) |
|
647 { |
|
648 Rule* rule = mRules.SafeObjectAt(aIndex); |
|
649 if (rule) { |
|
650 rule->SetStyleSheet(nullptr); |
|
651 rule->SetParentRule(nullptr); |
|
652 } |
|
653 return mRules.RemoveObjectAt(aIndex) ? NS_OK : NS_ERROR_ILLEGAL_VALUE; |
|
654 } |
|
655 |
|
656 nsresult |
|
657 GroupRule::InsertStyleRuleAt(uint32_t aIndex, Rule* aRule) |
|
658 { |
|
659 aRule->SetStyleSheet(GetStyleSheet()); |
|
660 aRule->SetParentRule(this); |
|
661 if (! mRules.InsertObjectAt(aRule, aIndex)) { |
|
662 return NS_ERROR_FAILURE; |
|
663 } |
|
664 return NS_OK; |
|
665 } |
|
666 |
|
667 nsresult |
|
668 GroupRule::ReplaceStyleRule(Rule* aOld, Rule* aNew) |
|
669 { |
|
670 int32_t index = mRules.IndexOf(aOld); |
|
671 NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED); |
|
672 mRules.ReplaceObjectAt(aNew, index); |
|
673 aNew->SetStyleSheet(GetStyleSheet()); |
|
674 aNew->SetParentRule(this); |
|
675 aOld->SetStyleSheet(nullptr); |
|
676 aOld->SetParentRule(nullptr); |
|
677 return NS_OK; |
|
678 } |
|
679 |
|
680 void |
|
681 GroupRule::AppendRulesToCssText(nsAString& aCssText) |
|
682 { |
|
683 aCssText.AppendLiteral(" {\n"); |
|
684 |
|
685 // get all the rules |
|
686 for (int32_t index = 0, count = mRules.Count(); index < count; ++index) { |
|
687 Rule* rule = mRules.ObjectAt(index); |
|
688 nsIDOMCSSRule* domRule = rule->GetDOMRule(); |
|
689 if (domRule) { |
|
690 nsAutoString cssText; |
|
691 domRule->GetCssText(cssText); |
|
692 aCssText.Append(NS_LITERAL_STRING(" ") + |
|
693 cssText + |
|
694 NS_LITERAL_STRING("\n")); |
|
695 } |
|
696 } |
|
697 |
|
698 aCssText.AppendLiteral("}"); |
|
699 } |
|
700 |
|
701 // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods |
|
702 nsresult |
|
703 GroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) |
|
704 { |
|
705 if (!mRuleCollection) { |
|
706 mRuleCollection = new css::GroupRuleRuleList(this); |
|
707 } |
|
708 |
|
709 NS_ADDREF(*aRuleList = mRuleCollection); |
|
710 return NS_OK; |
|
711 } |
|
712 |
|
713 nsresult |
|
714 GroupRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval) |
|
715 { |
|
716 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
717 NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE); |
|
718 |
|
719 if (aIndex > uint32_t(mRules.Count())) |
|
720 return NS_ERROR_DOM_INDEX_SIZE_ERR; |
|
721 |
|
722 NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX, |
|
723 "Too many style rules!"); |
|
724 |
|
725 return sheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval); |
|
726 } |
|
727 |
|
728 nsresult |
|
729 GroupRule::DeleteRule(uint32_t aIndex) |
|
730 { |
|
731 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
732 NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE); |
|
733 |
|
734 if (aIndex >= uint32_t(mRules.Count())) |
|
735 return NS_ERROR_DOM_INDEX_SIZE_ERR; |
|
736 |
|
737 NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX, |
|
738 "Too many style rules!"); |
|
739 |
|
740 return sheet->DeleteRuleFromGroup(this, aIndex); |
|
741 } |
|
742 |
|
743 /* virtual */ size_t |
|
744 GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const |
|
745 { |
|
746 return mRules.SizeOfExcludingThis(Rule::SizeOfCOMArrayElementIncludingThis, |
|
747 aMallocSizeOf); |
|
748 |
|
749 // Measurement of the following members may be added later if DMD finds it is |
|
750 // worthwhile: |
|
751 // - mRuleCollection |
|
752 } |
|
753 |
|
754 |
|
755 // ------------------------------------------- |
|
756 // nsICSSMediaRule |
|
757 // |
|
758 MediaRule::MediaRule() |
|
759 { |
|
760 } |
|
761 |
|
762 MediaRule::MediaRule(const MediaRule& aCopy) |
|
763 : GroupRule(aCopy) |
|
764 { |
|
765 if (aCopy.mMedia) { |
|
766 mMedia = aCopy.mMedia->Clone(); |
|
767 // XXXldb This doesn't really make sense. |
|
768 mMedia->SetStyleSheet(aCopy.GetStyleSheet()); |
|
769 } |
|
770 } |
|
771 |
|
772 MediaRule::~MediaRule() |
|
773 { |
|
774 if (mMedia) { |
|
775 mMedia->SetStyleSheet(nullptr); |
|
776 } |
|
777 } |
|
778 |
|
779 NS_IMPL_ADDREF_INHERITED(MediaRule, GroupRule) |
|
780 NS_IMPL_RELEASE_INHERITED(MediaRule, GroupRule) |
|
781 |
|
782 // QueryInterface implementation for MediaRule |
|
783 NS_INTERFACE_MAP_BEGIN(MediaRule) |
|
784 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
785 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
786 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule) |
|
787 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule) |
|
788 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule) |
|
789 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
790 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMediaRule) |
|
791 NS_INTERFACE_MAP_END_INHERITING(GroupRule) |
|
792 |
|
793 /* virtual */ void |
|
794 MediaRule::SetStyleSheet(nsCSSStyleSheet* aSheet) |
|
795 { |
|
796 if (mMedia) { |
|
797 // Set to null so it knows it's leaving one sheet and joining another. |
|
798 mMedia->SetStyleSheet(nullptr); |
|
799 mMedia->SetStyleSheet(aSheet); |
|
800 } |
|
801 |
|
802 GroupRule::SetStyleSheet(aSheet); |
|
803 } |
|
804 |
|
805 #ifdef DEBUG |
|
806 /* virtual */ void |
|
807 MediaRule::List(FILE* out, int32_t aIndent) const |
|
808 { |
|
809 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
810 |
|
811 nsAutoString buffer; |
|
812 |
|
813 fputs("@media ", out); |
|
814 |
|
815 if (mMedia) { |
|
816 nsAutoString mediaText; |
|
817 mMedia->GetText(mediaText); |
|
818 fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out); |
|
819 } |
|
820 |
|
821 GroupRule::List(out, aIndent); |
|
822 } |
|
823 #endif |
|
824 |
|
825 /* virtual */ int32_t |
|
826 MediaRule::GetType() const |
|
827 { |
|
828 return Rule::MEDIA_RULE; |
|
829 } |
|
830 |
|
831 /* virtual */ already_AddRefed<Rule> |
|
832 MediaRule::Clone() const |
|
833 { |
|
834 nsRefPtr<Rule> clone = new MediaRule(*this); |
|
835 return clone.forget(); |
|
836 } |
|
837 |
|
838 nsresult |
|
839 MediaRule::SetMedia(nsMediaList* aMedia) |
|
840 { |
|
841 mMedia = aMedia; |
|
842 if (aMedia) |
|
843 mMedia->SetStyleSheet(GetStyleSheet()); |
|
844 return NS_OK; |
|
845 } |
|
846 |
|
847 // nsIDOMCSSRule methods |
|
848 NS_IMETHODIMP |
|
849 MediaRule::GetType(uint16_t* aType) |
|
850 { |
|
851 *aType = nsIDOMCSSRule::MEDIA_RULE; |
|
852 return NS_OK; |
|
853 } |
|
854 |
|
855 NS_IMETHODIMP |
|
856 MediaRule::GetCssText(nsAString& aCssText) |
|
857 { |
|
858 aCssText.AssignLiteral("@media "); |
|
859 AppendConditionText(aCssText); |
|
860 GroupRule::AppendRulesToCssText(aCssText); |
|
861 return NS_OK; |
|
862 } |
|
863 |
|
864 NS_IMETHODIMP |
|
865 MediaRule::SetCssText(const nsAString& aCssText) |
|
866 { |
|
867 return NS_ERROR_NOT_IMPLEMENTED; |
|
868 } |
|
869 |
|
870 NS_IMETHODIMP |
|
871 MediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
872 { |
|
873 return GroupRule::GetParentStyleSheet(aSheet); |
|
874 } |
|
875 |
|
876 NS_IMETHODIMP |
|
877 MediaRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
878 { |
|
879 return GroupRule::GetParentRule(aParentRule); |
|
880 } |
|
881 |
|
882 // nsIDOMCSSGroupingRule methods |
|
883 NS_IMETHODIMP |
|
884 MediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) |
|
885 { |
|
886 return GroupRule::GetCssRules(aRuleList); |
|
887 } |
|
888 |
|
889 NS_IMETHODIMP |
|
890 MediaRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval) |
|
891 { |
|
892 return GroupRule::InsertRule(aRule, aIndex, _retval); |
|
893 } |
|
894 |
|
895 NS_IMETHODIMP |
|
896 MediaRule::DeleteRule(uint32_t aIndex) |
|
897 { |
|
898 return GroupRule::DeleteRule(aIndex); |
|
899 } |
|
900 |
|
901 // nsIDOMCSSConditionRule methods |
|
902 NS_IMETHODIMP |
|
903 MediaRule::GetConditionText(nsAString& aConditionText) |
|
904 { |
|
905 aConditionText.Truncate(0); |
|
906 AppendConditionText(aConditionText); |
|
907 return NS_OK; |
|
908 } |
|
909 |
|
910 NS_IMETHODIMP |
|
911 MediaRule::SetConditionText(const nsAString& aConditionText) |
|
912 { |
|
913 if (!mMedia) { |
|
914 nsRefPtr<nsMediaList> media = new nsMediaList(); |
|
915 media->SetStyleSheet(GetStyleSheet()); |
|
916 nsresult rv = media->SetMediaText(aConditionText); |
|
917 if (NS_SUCCEEDED(rv)) { |
|
918 mMedia = media; |
|
919 } |
|
920 return rv; |
|
921 } |
|
922 |
|
923 return mMedia->SetMediaText(aConditionText); |
|
924 } |
|
925 |
|
926 // nsIDOMCSSMediaRule methods |
|
927 NS_IMETHODIMP |
|
928 MediaRule::GetMedia(nsIDOMMediaList* *aMedia) |
|
929 { |
|
930 NS_ENSURE_ARG_POINTER(aMedia); |
|
931 NS_IF_ADDREF(*aMedia = mMedia); |
|
932 return NS_OK; |
|
933 } |
|
934 |
|
935 // GroupRule interface |
|
936 /* virtual */ bool |
|
937 MediaRule::UseForPresentation(nsPresContext* aPresContext, |
|
938 nsMediaQueryResultCacheKey& aKey) |
|
939 { |
|
940 if (mMedia) { |
|
941 return mMedia->Matches(aPresContext, &aKey); |
|
942 } |
|
943 return true; |
|
944 } |
|
945 |
|
946 /* virtual */ size_t |
|
947 MediaRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
948 { |
|
949 size_t n = aMallocSizeOf(this); |
|
950 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf); |
|
951 |
|
952 // Measurement of the following members may be added later if DMD finds it is |
|
953 // worthwhile: |
|
954 // - mMedia |
|
955 |
|
956 return n; |
|
957 } |
|
958 |
|
959 void |
|
960 MediaRule::AppendConditionText(nsAString& aOutput) |
|
961 { |
|
962 if (mMedia) { |
|
963 nsAutoString mediaText; |
|
964 mMedia->GetText(mediaText); |
|
965 aOutput.Append(mediaText); |
|
966 } |
|
967 } |
|
968 |
|
969 } // namespace css |
|
970 } // namespace mozilla |
|
971 |
|
972 // Must be outside namespace |
|
973 DOMCI_DATA(CSSMediaRule, css::MediaRule) |
|
974 |
|
975 namespace mozilla { |
|
976 namespace css { |
|
977 |
|
978 DocumentRule::DocumentRule() |
|
979 { |
|
980 } |
|
981 |
|
982 DocumentRule::DocumentRule(const DocumentRule& aCopy) |
|
983 : GroupRule(aCopy) |
|
984 , mURLs(new URL(*aCopy.mURLs)) |
|
985 { |
|
986 } |
|
987 |
|
988 DocumentRule::~DocumentRule() |
|
989 { |
|
990 } |
|
991 |
|
992 NS_IMPL_ADDREF_INHERITED(DocumentRule, GroupRule) |
|
993 NS_IMPL_RELEASE_INHERITED(DocumentRule, GroupRule) |
|
994 |
|
995 // QueryInterface implementation for DocumentRule |
|
996 NS_INTERFACE_MAP_BEGIN(DocumentRule) |
|
997 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
998 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
999 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule) |
|
1000 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule) |
|
1001 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule) |
|
1002 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
1003 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMozDocumentRule) |
|
1004 NS_INTERFACE_MAP_END_INHERITING(GroupRule) |
|
1005 |
|
1006 #ifdef DEBUG |
|
1007 /* virtual */ void |
|
1008 DocumentRule::List(FILE* out, int32_t aIndent) const |
|
1009 { |
|
1010 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
1011 |
|
1012 nsAutoCString str; |
|
1013 str.AssignLiteral("@-moz-document "); |
|
1014 for (URL *url = mURLs; url; url = url->next) { |
|
1015 switch (url->func) { |
|
1016 case eURL: |
|
1017 str.AppendLiteral("url(\""); |
|
1018 break; |
|
1019 case eURLPrefix: |
|
1020 str.AppendLiteral("url-prefix(\""); |
|
1021 break; |
|
1022 case eDomain: |
|
1023 str.AppendLiteral("domain(\""); |
|
1024 break; |
|
1025 case eRegExp: |
|
1026 str.AppendLiteral("regexp(\""); |
|
1027 break; |
|
1028 } |
|
1029 nsAutoCString escapedURL(url->url); |
|
1030 escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes |
|
1031 str.Append(escapedURL); |
|
1032 str.AppendLiteral("\"), "); |
|
1033 } |
|
1034 str.Cut(str.Length() - 2, 1); // remove last , |
|
1035 fputs(str.get(), out); |
|
1036 |
|
1037 GroupRule::List(out, aIndent); |
|
1038 } |
|
1039 #endif |
|
1040 |
|
1041 /* virtual */ int32_t |
|
1042 DocumentRule::GetType() const |
|
1043 { |
|
1044 return Rule::DOCUMENT_RULE; |
|
1045 } |
|
1046 |
|
1047 /* virtual */ already_AddRefed<Rule> |
|
1048 DocumentRule::Clone() const |
|
1049 { |
|
1050 nsRefPtr<Rule> clone = new DocumentRule(*this); |
|
1051 return clone.forget(); |
|
1052 } |
|
1053 |
|
1054 // nsIDOMCSSRule methods |
|
1055 NS_IMETHODIMP |
|
1056 DocumentRule::GetType(uint16_t* aType) |
|
1057 { |
|
1058 // XXX What should really happen here? |
|
1059 *aType = nsIDOMCSSRule::UNKNOWN_RULE; |
|
1060 return NS_OK; |
|
1061 } |
|
1062 |
|
1063 NS_IMETHODIMP |
|
1064 DocumentRule::GetCssText(nsAString& aCssText) |
|
1065 { |
|
1066 aCssText.AssignLiteral("@-moz-document "); |
|
1067 AppendConditionText(aCssText); |
|
1068 GroupRule::AppendRulesToCssText(aCssText); |
|
1069 return NS_OK; |
|
1070 } |
|
1071 |
|
1072 NS_IMETHODIMP |
|
1073 DocumentRule::SetCssText(const nsAString& aCssText) |
|
1074 { |
|
1075 return NS_ERROR_NOT_IMPLEMENTED; |
|
1076 } |
|
1077 |
|
1078 NS_IMETHODIMP |
|
1079 DocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
1080 { |
|
1081 return GroupRule::GetParentStyleSheet(aSheet); |
|
1082 } |
|
1083 |
|
1084 NS_IMETHODIMP |
|
1085 DocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
1086 { |
|
1087 return GroupRule::GetParentRule(aParentRule); |
|
1088 } |
|
1089 |
|
1090 // nsIDOMCSSGroupingRule methods |
|
1091 NS_IMETHODIMP |
|
1092 DocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) |
|
1093 { |
|
1094 return GroupRule::GetCssRules(aRuleList); |
|
1095 } |
|
1096 |
|
1097 NS_IMETHODIMP |
|
1098 DocumentRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval) |
|
1099 { |
|
1100 return GroupRule::InsertRule(aRule, aIndex, _retval); |
|
1101 } |
|
1102 |
|
1103 NS_IMETHODIMP |
|
1104 DocumentRule::DeleteRule(uint32_t aIndex) |
|
1105 { |
|
1106 return GroupRule::DeleteRule(aIndex); |
|
1107 } |
|
1108 |
|
1109 // nsIDOMCSSConditionRule methods |
|
1110 NS_IMETHODIMP |
|
1111 DocumentRule::GetConditionText(nsAString& aConditionText) |
|
1112 { |
|
1113 aConditionText.Truncate(0); |
|
1114 AppendConditionText(aConditionText); |
|
1115 return NS_OK; |
|
1116 } |
|
1117 |
|
1118 NS_IMETHODIMP |
|
1119 DocumentRule::SetConditionText(const nsAString& aConditionText) |
|
1120 { |
|
1121 return NS_ERROR_NOT_IMPLEMENTED; |
|
1122 } |
|
1123 |
|
1124 // GroupRule interface |
|
1125 /* virtual */ bool |
|
1126 DocumentRule::UseForPresentation(nsPresContext* aPresContext, |
|
1127 nsMediaQueryResultCacheKey& aKey) |
|
1128 { |
|
1129 nsIDocument *doc = aPresContext->Document(); |
|
1130 nsIURI *docURI = doc->GetDocumentURI(); |
|
1131 nsAutoCString docURISpec; |
|
1132 if (docURI) |
|
1133 docURI->GetSpec(docURISpec); |
|
1134 |
|
1135 for (URL *url = mURLs; url; url = url->next) { |
|
1136 switch (url->func) { |
|
1137 case eURL: { |
|
1138 if (docURISpec == url->url) |
|
1139 return true; |
|
1140 } break; |
|
1141 case eURLPrefix: { |
|
1142 if (StringBeginsWith(docURISpec, url->url)) |
|
1143 return true; |
|
1144 } break; |
|
1145 case eDomain: { |
|
1146 nsAutoCString host; |
|
1147 if (docURI) |
|
1148 docURI->GetHost(host); |
|
1149 int32_t lenDiff = host.Length() - url->url.Length(); |
|
1150 if (lenDiff == 0) { |
|
1151 if (host == url->url) |
|
1152 return true; |
|
1153 } else { |
|
1154 if (StringEndsWith(host, url->url) && |
|
1155 host.CharAt(lenDiff - 1) == '.') |
|
1156 return true; |
|
1157 } |
|
1158 } break; |
|
1159 case eRegExp: { |
|
1160 NS_ConvertUTF8toUTF16 spec(docURISpec); |
|
1161 NS_ConvertUTF8toUTF16 regex(url->url); |
|
1162 if (nsContentUtils::IsPatternMatching(spec, regex, doc)) { |
|
1163 return true; |
|
1164 } |
|
1165 } break; |
|
1166 } |
|
1167 } |
|
1168 |
|
1169 return false; |
|
1170 } |
|
1171 |
|
1172 DocumentRule::URL::~URL() |
|
1173 { |
|
1174 NS_CSS_DELETE_LIST_MEMBER(DocumentRule::URL, this, next); |
|
1175 } |
|
1176 |
|
1177 /* virtual */ size_t |
|
1178 DocumentRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
1179 { |
|
1180 size_t n = aMallocSizeOf(this); |
|
1181 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf); |
|
1182 |
|
1183 // Measurement of the following members may be added later if DMD finds it is |
|
1184 // worthwhile: |
|
1185 // - mURLs |
|
1186 |
|
1187 return n; |
|
1188 } |
|
1189 |
|
1190 void |
|
1191 DocumentRule::AppendConditionText(nsAString& aCssText) |
|
1192 { |
|
1193 for (URL *url = mURLs; url; url = url->next) { |
|
1194 switch (url->func) { |
|
1195 case eURL: |
|
1196 aCssText.AppendLiteral("url("); |
|
1197 break; |
|
1198 case eURLPrefix: |
|
1199 aCssText.AppendLiteral("url-prefix("); |
|
1200 break; |
|
1201 case eDomain: |
|
1202 aCssText.AppendLiteral("domain("); |
|
1203 break; |
|
1204 case eRegExp: |
|
1205 aCssText.AppendLiteral("regexp("); |
|
1206 break; |
|
1207 } |
|
1208 nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url), |
|
1209 aCssText); |
|
1210 aCssText.AppendLiteral("), "); |
|
1211 } |
|
1212 aCssText.Truncate(aCssText.Length() - 2); // remove last ", " |
|
1213 } |
|
1214 |
|
1215 } // namespace css |
|
1216 } // namespace mozilla |
|
1217 |
|
1218 // Must be outside namespace |
|
1219 DOMCI_DATA(CSSMozDocumentRule, css::DocumentRule) |
|
1220 |
|
1221 // ------------------------------------------- |
|
1222 // NameSpaceRule |
|
1223 // |
|
1224 |
|
1225 namespace mozilla { |
|
1226 namespace css { |
|
1227 |
|
1228 NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec) |
|
1229 : Rule(), |
|
1230 mPrefix(aPrefix), |
|
1231 mURLSpec(aURLSpec) |
|
1232 { |
|
1233 } |
|
1234 |
|
1235 NameSpaceRule::NameSpaceRule(const NameSpaceRule& aCopy) |
|
1236 : Rule(aCopy), |
|
1237 mPrefix(aCopy.mPrefix), |
|
1238 mURLSpec(aCopy.mURLSpec) |
|
1239 { |
|
1240 } |
|
1241 |
|
1242 NameSpaceRule::~NameSpaceRule() |
|
1243 { |
|
1244 } |
|
1245 |
|
1246 NS_IMPL_ADDREF(NameSpaceRule) |
|
1247 NS_IMPL_RELEASE(NameSpaceRule) |
|
1248 |
|
1249 // QueryInterface implementation for NameSpaceRule |
|
1250 NS_INTERFACE_MAP_BEGIN(NameSpaceRule) |
|
1251 if (aIID.Equals(NS_GET_IID(css::NameSpaceRule))) { |
|
1252 *aInstancePtr = this; |
|
1253 NS_ADDREF_THIS(); |
|
1254 return NS_OK; |
|
1255 } |
|
1256 else |
|
1257 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
1258 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
1259 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
1260 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSNameSpaceRule) |
|
1261 NS_INTERFACE_MAP_END |
|
1262 |
|
1263 IMPL_STYLE_RULE_INHERIT(NameSpaceRule, Rule) |
|
1264 |
|
1265 #ifdef DEBUG |
|
1266 /* virtual */ void |
|
1267 NameSpaceRule::List(FILE* out, int32_t aIndent) const |
|
1268 { |
|
1269 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
1270 |
|
1271 nsAutoString buffer; |
|
1272 |
|
1273 fputs("@namespace ", out); |
|
1274 |
|
1275 if (mPrefix) { |
|
1276 mPrefix->ToString(buffer); |
|
1277 fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out); |
|
1278 fputs(" ", out); |
|
1279 } |
|
1280 |
|
1281 fputs("url(", out); |
|
1282 fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out); |
|
1283 fputs(")\n", out); |
|
1284 } |
|
1285 #endif |
|
1286 |
|
1287 /* virtual */ int32_t |
|
1288 NameSpaceRule::GetType() const |
|
1289 { |
|
1290 return Rule::NAMESPACE_RULE; |
|
1291 } |
|
1292 |
|
1293 /* virtual */ already_AddRefed<Rule> |
|
1294 NameSpaceRule::Clone() const |
|
1295 { |
|
1296 nsRefPtr<Rule> clone = new NameSpaceRule(*this); |
|
1297 return clone.forget(); |
|
1298 } |
|
1299 |
|
1300 NS_IMETHODIMP |
|
1301 NameSpaceRule::GetType(uint16_t* aType) |
|
1302 { |
|
1303 *aType = nsIDOMCSSRule::NAMESPACE_RULE; |
|
1304 return NS_OK; |
|
1305 } |
|
1306 |
|
1307 NS_IMETHODIMP |
|
1308 NameSpaceRule::GetCssText(nsAString& aCssText) |
|
1309 { |
|
1310 aCssText.AssignLiteral("@namespace "); |
|
1311 if (mPrefix) { |
|
1312 aCssText.Append(nsDependentAtomString(mPrefix) + NS_LITERAL_STRING(" ")); |
|
1313 } |
|
1314 aCssText.AppendLiteral("url("); |
|
1315 nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText); |
|
1316 aCssText.Append(NS_LITERAL_STRING(");")); |
|
1317 return NS_OK; |
|
1318 } |
|
1319 |
|
1320 NS_IMETHODIMP |
|
1321 NameSpaceRule::SetCssText(const nsAString& aCssText) |
|
1322 { |
|
1323 return NS_ERROR_NOT_IMPLEMENTED; |
|
1324 } |
|
1325 |
|
1326 NS_IMETHODIMP |
|
1327 NameSpaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
1328 { |
|
1329 return Rule::GetParentStyleSheet(aSheet); |
|
1330 } |
|
1331 |
|
1332 NS_IMETHODIMP |
|
1333 NameSpaceRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
1334 { |
|
1335 return Rule::GetParentRule(aParentRule); |
|
1336 } |
|
1337 |
|
1338 /* virtual */ size_t |
|
1339 NameSpaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
1340 { |
|
1341 return aMallocSizeOf(this); |
|
1342 |
|
1343 // Measurement of the following members may be added later if DMD finds it is |
|
1344 // worthwhile: |
|
1345 // - mPrefix |
|
1346 // - mURLSpec |
|
1347 } |
|
1348 |
|
1349 |
|
1350 } // namespace css |
|
1351 } // namespace mozilla |
|
1352 |
|
1353 // Must be outside namespace |
|
1354 DOMCI_DATA(CSSNameSpaceRule, css::NameSpaceRule) |
|
1355 |
|
1356 // ------------------------------------------- |
|
1357 // nsCSSFontFaceStyleDecl and related routines |
|
1358 // |
|
1359 |
|
1360 // A src: descriptor is represented as an array value; each entry in |
|
1361 // the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or |
|
1362 // eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear |
|
1363 // only after one of the first two. (css3-fonts only contemplates |
|
1364 // annotating URLs with formats, but we handle the general case.) |
|
1365 static void |
|
1366 AppendSerializedFontSrc(const nsCSSValue& src, nsAString & aResult) |
|
1367 { |
|
1368 NS_PRECONDITION(src.GetUnit() == eCSSUnit_Array, |
|
1369 "improper value unit for src:"); |
|
1370 |
|
1371 const nsCSSValue::Array& sources = *src.GetArrayValue(); |
|
1372 size_t i = 0; |
|
1373 |
|
1374 while (i < sources.Count()) { |
|
1375 nsAutoString formats; |
|
1376 |
|
1377 if (sources[i].GetUnit() == eCSSUnit_URL) { |
|
1378 aResult.AppendLiteral("url("); |
|
1379 nsDependentString url(sources[i].GetOriginalURLValue()); |
|
1380 nsStyleUtil::AppendEscapedCSSString(url, aResult); |
|
1381 aResult.AppendLiteral(")"); |
|
1382 } else if (sources[i].GetUnit() == eCSSUnit_Local_Font) { |
|
1383 aResult.AppendLiteral("local("); |
|
1384 nsDependentString local(sources[i].GetStringBufferValue()); |
|
1385 nsStyleUtil::AppendEscapedCSSString(local, aResult); |
|
1386 aResult.AppendLiteral(")"); |
|
1387 } else { |
|
1388 NS_NOTREACHED("entry in src: descriptor with improper unit"); |
|
1389 i++; |
|
1390 continue; |
|
1391 } |
|
1392 |
|
1393 i++; |
|
1394 formats.Truncate(); |
|
1395 while (i < sources.Count() && |
|
1396 sources[i].GetUnit() == eCSSUnit_Font_Format) { |
|
1397 formats.Append('"'); |
|
1398 formats.Append(sources[i].GetStringBufferValue()); |
|
1399 formats.AppendLiteral("\", "); |
|
1400 i++; |
|
1401 } |
|
1402 if (formats.Length() > 0) { |
|
1403 formats.Truncate(formats.Length() - 2); // remove the last comma |
|
1404 aResult.AppendLiteral(" format("); |
|
1405 aResult.Append(formats); |
|
1406 aResult.Append(')'); |
|
1407 } |
|
1408 aResult.AppendLiteral(", "); |
|
1409 } |
|
1410 aResult.Truncate(aResult.Length() - 2); // remove the last comma-space |
|
1411 } |
|
1412 |
|
1413 // print all characters with at least four hex digits |
|
1414 static void |
|
1415 AppendSerializedUnicodePoint(uint32_t aCode, nsACString &aBuf) |
|
1416 { |
|
1417 aBuf.Append(nsPrintfCString("%04X", aCode)); |
|
1418 } |
|
1419 |
|
1420 // A unicode-range: descriptor is represented as an array of integers, |
|
1421 // to be interpreted as a sequence of pairs: min max min max ... |
|
1422 // It is in source order. (Possibly it should be sorted and overlaps |
|
1423 // consolidated, but right now we don't do that.) |
|
1424 static void |
|
1425 AppendSerializedUnicodeRange(nsCSSValue const & aValue, |
|
1426 nsAString & aResult) |
|
1427 { |
|
1428 NS_PRECONDITION(aValue.GetUnit() == eCSSUnit_Null || |
|
1429 aValue.GetUnit() == eCSSUnit_Array, |
|
1430 "improper value unit for unicode-range:"); |
|
1431 aResult.Truncate(); |
|
1432 if (aValue.GetUnit() != eCSSUnit_Array) |
|
1433 return; |
|
1434 |
|
1435 nsCSSValue::Array const & sources = *aValue.GetArrayValue(); |
|
1436 nsAutoCString buf; |
|
1437 |
|
1438 NS_ABORT_IF_FALSE(sources.Count() % 2 == 0, |
|
1439 "odd number of entries in a unicode-range: array"); |
|
1440 |
|
1441 for (uint32_t i = 0; i < sources.Count(); i += 2) { |
|
1442 uint32_t min = sources[i].GetIntValue(); |
|
1443 uint32_t max = sources[i+1].GetIntValue(); |
|
1444 |
|
1445 // We don't try to replicate the U+XX?? notation. |
|
1446 buf.AppendLiteral("U+"); |
|
1447 AppendSerializedUnicodePoint(min, buf); |
|
1448 |
|
1449 if (min != max) { |
|
1450 buf.Append('-'); |
|
1451 AppendSerializedUnicodePoint(max, buf); |
|
1452 } |
|
1453 buf.AppendLiteral(", "); |
|
1454 } |
|
1455 buf.Truncate(buf.Length() - 2); // remove the last comma-space |
|
1456 CopyASCIItoUTF16(buf, aResult); |
|
1457 } |
|
1458 |
|
1459 // Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields. |
|
1460 nsCSSValue nsCSSFontFaceStyleDecl::* const |
|
1461 nsCSSFontFaceStyleDecl::Fields[] = { |
|
1462 #define CSS_FONT_DESC(name_, method_) &nsCSSFontFaceStyleDecl::m##method_, |
|
1463 #include "nsCSSFontDescList.h" |
|
1464 #undef CSS_FONT_DESC |
|
1465 }; |
|
1466 |
|
1467 // QueryInterface implementation for nsCSSFontFaceStyleDecl |
|
1468 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl) |
|
1469 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
|
1470 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration) |
|
1471 NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration) |
|
1472 NS_INTERFACE_MAP_ENTRY(nsISupports) |
|
1473 // We forward the cycle collection interfaces to ContainingRule(), which is |
|
1474 // never null (in fact, we're part of that object!) |
|
1475 if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) || |
|
1476 aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) { |
|
1477 return ContainingRule()->QueryInterface(aIID, aInstancePtr); |
|
1478 } |
|
1479 else |
|
1480 NS_INTERFACE_MAP_END |
|
1481 |
|
1482 NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule()) |
|
1483 NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule()) |
|
1484 |
|
1485 // helper for string GetPropertyValue and RemovePropertyValue |
|
1486 nsresult |
|
1487 nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID, |
|
1488 nsAString & aResult) const |
|
1489 { |
|
1490 NS_ENSURE_ARG_RANGE(aFontDescID, eCSSFontDesc_UNKNOWN, |
|
1491 eCSSFontDesc_COUNT - 1); |
|
1492 |
|
1493 aResult.Truncate(); |
|
1494 if (aFontDescID == eCSSFontDesc_UNKNOWN) |
|
1495 return NS_OK; |
|
1496 |
|
1497 const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID]; |
|
1498 |
|
1499 if (val.GetUnit() == eCSSUnit_Null) { |
|
1500 // Avoid having to check no-value in the Family and Src cases below. |
|
1501 return NS_OK; |
|
1502 } |
|
1503 |
|
1504 switch (aFontDescID) { |
|
1505 case eCSSFontDesc_Family: { |
|
1506 // we don't use nsCSSValue::AppendToString here because it doesn't |
|
1507 // canonicalize the way we want, and anyway it's overkill when |
|
1508 // we know we have eCSSUnit_String |
|
1509 NS_ASSERTION(val.GetUnit() == eCSSUnit_String, "unexpected unit"); |
|
1510 nsDependentString family(val.GetStringBufferValue()); |
|
1511 nsStyleUtil::AppendEscapedCSSString(family, aResult); |
|
1512 return NS_OK; |
|
1513 } |
|
1514 |
|
1515 case eCSSFontDesc_Style: |
|
1516 val.AppendToString(eCSSProperty_font_style, aResult, |
|
1517 nsCSSValue::eNormalized); |
|
1518 return NS_OK; |
|
1519 |
|
1520 case eCSSFontDesc_Weight: |
|
1521 val.AppendToString(eCSSProperty_font_weight, aResult, |
|
1522 nsCSSValue::eNormalized); |
|
1523 return NS_OK; |
|
1524 |
|
1525 case eCSSFontDesc_Stretch: |
|
1526 val.AppendToString(eCSSProperty_font_stretch, aResult, |
|
1527 nsCSSValue::eNormalized); |
|
1528 return NS_OK; |
|
1529 |
|
1530 case eCSSFontDesc_FontFeatureSettings: |
|
1531 nsStyleUtil::AppendFontFeatureSettings(val, aResult); |
|
1532 return NS_OK; |
|
1533 |
|
1534 case eCSSFontDesc_FontLanguageOverride: |
|
1535 val.AppendToString(eCSSProperty_font_language_override, aResult, |
|
1536 nsCSSValue::eNormalized); |
|
1537 return NS_OK; |
|
1538 |
|
1539 case eCSSFontDesc_Src: |
|
1540 AppendSerializedFontSrc(val, aResult); |
|
1541 return NS_OK; |
|
1542 |
|
1543 case eCSSFontDesc_UnicodeRange: |
|
1544 AppendSerializedUnicodeRange(val, aResult); |
|
1545 return NS_OK; |
|
1546 |
|
1547 case eCSSFontDesc_UNKNOWN: |
|
1548 case eCSSFontDesc_COUNT: |
|
1549 ; |
|
1550 } |
|
1551 NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: " |
|
1552 "out-of-range value got to the switch"); |
|
1553 return NS_ERROR_INVALID_ARG; |
|
1554 } |
|
1555 |
|
1556 |
|
1557 // attribute DOMString cssText; |
|
1558 NS_IMETHODIMP |
|
1559 nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText) |
|
1560 { |
|
1561 nsAutoString descStr; |
|
1562 |
|
1563 aCssText.Truncate(); |
|
1564 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); |
|
1565 id < eCSSFontDesc_COUNT; |
|
1566 id = nsCSSFontDesc(id + 1)) { |
|
1567 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() |
|
1568 != eCSSUnit_Null && |
|
1569 NS_SUCCEEDED(GetPropertyValue(id, descStr))) { |
|
1570 NS_ASSERTION(descStr.Length() > 0, |
|
1571 "GetCssText: non-null unit, empty property value"); |
|
1572 aCssText.AppendLiteral(" "); |
|
1573 aCssText.AppendASCII(nsCSSProps::GetStringValue(id).get()); |
|
1574 aCssText.AppendLiteral(": "); |
|
1575 aCssText.Append(descStr); |
|
1576 aCssText.AppendLiteral(";\n"); |
|
1577 } |
|
1578 } |
|
1579 return NS_OK; |
|
1580 } |
|
1581 |
|
1582 NS_IMETHODIMP |
|
1583 nsCSSFontFaceStyleDecl::SetCssText(const nsAString & aCssText) |
|
1584 { |
|
1585 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978 |
|
1586 } |
|
1587 |
|
1588 // DOMString getPropertyValue (in DOMString propertyName); |
|
1589 NS_IMETHODIMP |
|
1590 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString & propertyName, |
|
1591 nsAString & aResult) |
|
1592 { |
|
1593 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult); |
|
1594 } |
|
1595 |
|
1596 NS_IMETHODIMP |
|
1597 nsCSSFontFaceStyleDecl::GetAuthoredPropertyValue(const nsAString& propertyName, |
|
1598 nsAString& aResult) |
|
1599 { |
|
1600 // We don't return any authored property values different from |
|
1601 // GetPropertyValue, currently. |
|
1602 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult); |
|
1603 } |
|
1604 |
|
1605 // nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName); |
|
1606 already_AddRefed<dom::CSSValue> |
|
1607 nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString & propertyName, |
|
1608 ErrorResult& aRv) |
|
1609 { |
|
1610 // ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong. |
|
1611 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); |
|
1612 return nullptr; |
|
1613 } |
|
1614 |
|
1615 // DOMString removeProperty (in DOMString propertyName) raises (DOMException); |
|
1616 NS_IMETHODIMP |
|
1617 nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName, |
|
1618 nsAString & aResult) |
|
1619 { |
|
1620 nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(propertyName); |
|
1621 NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN && |
|
1622 descID < eCSSFontDesc_COUNT, |
|
1623 "LookupFontDesc returned value out of range"); |
|
1624 |
|
1625 if (descID == eCSSFontDesc_UNKNOWN) { |
|
1626 aResult.Truncate(); |
|
1627 } else { |
|
1628 nsresult rv = GetPropertyValue(descID, aResult); |
|
1629 NS_ENSURE_SUCCESS(rv, rv); |
|
1630 (this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset(); |
|
1631 } |
|
1632 return NS_OK; |
|
1633 } |
|
1634 |
|
1635 // DOMString getPropertyPriority (in DOMString propertyName); |
|
1636 NS_IMETHODIMP |
|
1637 nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString & propertyName, |
|
1638 nsAString & aResult) |
|
1639 { |
|
1640 // font descriptors do not have priorities at present |
|
1641 aResult.Truncate(); |
|
1642 return NS_OK; |
|
1643 } |
|
1644 |
|
1645 // void setProperty (in DOMString propertyName, in DOMString value, |
|
1646 // in DOMString priority) raises (DOMException); |
|
1647 NS_IMETHODIMP |
|
1648 nsCSSFontFaceStyleDecl::SetProperty(const nsAString & propertyName, |
|
1649 const nsAString & value, |
|
1650 const nsAString & priority) |
|
1651 { |
|
1652 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978 |
|
1653 } |
|
1654 |
|
1655 // readonly attribute unsigned long length; |
|
1656 NS_IMETHODIMP |
|
1657 nsCSSFontFaceStyleDecl::GetLength(uint32_t *aLength) |
|
1658 { |
|
1659 uint32_t len = 0; |
|
1660 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); |
|
1661 id < eCSSFontDesc_COUNT; |
|
1662 id = nsCSSFontDesc(id + 1)) |
|
1663 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null) |
|
1664 len++; |
|
1665 |
|
1666 *aLength = len; |
|
1667 return NS_OK; |
|
1668 } |
|
1669 |
|
1670 // DOMString item (in unsigned long index); |
|
1671 NS_IMETHODIMP |
|
1672 nsCSSFontFaceStyleDecl::Item(uint32_t aIndex, nsAString& aReturn) |
|
1673 { |
|
1674 bool found; |
|
1675 IndexedGetter(aIndex, found, aReturn); |
|
1676 if (!found) { |
|
1677 aReturn.Truncate(); |
|
1678 } |
|
1679 return NS_OK; |
|
1680 } |
|
1681 |
|
1682 void |
|
1683 nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString & aResult) |
|
1684 { |
|
1685 int32_t nset = -1; |
|
1686 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); |
|
1687 id < eCSSFontDesc_COUNT; |
|
1688 id = nsCSSFontDesc(id + 1)) { |
|
1689 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() |
|
1690 != eCSSUnit_Null) { |
|
1691 nset++; |
|
1692 if (nset == int32_t(index)) { |
|
1693 aFound = true; |
|
1694 aResult.AssignASCII(nsCSSProps::GetStringValue(id).get()); |
|
1695 return; |
|
1696 } |
|
1697 } |
|
1698 } |
|
1699 aFound = false; |
|
1700 } |
|
1701 |
|
1702 // readonly attribute nsIDOMCSSRule parentRule; |
|
1703 NS_IMETHODIMP |
|
1704 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
1705 { |
|
1706 NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule()); |
|
1707 return NS_OK; |
|
1708 } |
|
1709 |
|
1710 NS_IMETHODIMP |
|
1711 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsCSSProperty aPropID, |
|
1712 nsAString& aValue) |
|
1713 { |
|
1714 return |
|
1715 GetPropertyValue(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aPropID)), |
|
1716 aValue); |
|
1717 } |
|
1718 |
|
1719 NS_IMETHODIMP |
|
1720 nsCSSFontFaceStyleDecl::SetPropertyValue(const nsCSSProperty aPropID, |
|
1721 const nsAString& aValue) |
|
1722 { |
|
1723 return SetProperty(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aPropID)), |
|
1724 aValue, EmptyString()); |
|
1725 } |
|
1726 |
|
1727 nsINode* |
|
1728 nsCSSFontFaceStyleDecl::GetParentObject() |
|
1729 { |
|
1730 return ContainingRule()->GetDocument(); |
|
1731 } |
|
1732 |
|
1733 JSObject* |
|
1734 nsCSSFontFaceStyleDecl::WrapObject(JSContext *cx) |
|
1735 { |
|
1736 return mozilla::dom::CSSStyleDeclarationBinding::Wrap(cx, this); |
|
1737 } |
|
1738 |
|
1739 // ------------------------------------------- |
|
1740 // nsCSSFontFaceRule |
|
1741 // |
|
1742 |
|
1743 /* virtual */ already_AddRefed<css::Rule> |
|
1744 nsCSSFontFaceRule::Clone() const |
|
1745 { |
|
1746 nsRefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this); |
|
1747 return clone.forget(); |
|
1748 } |
|
1749 |
|
1750 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSFontFaceRule) |
|
1751 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSFontFaceRule) |
|
1752 |
|
1753 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSFontFaceRule) |
|
1754 |
|
1755 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsCSSFontFaceRule) |
|
1756 // Trace the wrapper for our declaration. This just expands out |
|
1757 // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use |
|
1758 // directly because the wrapper is on the declaration, not on us. |
|
1759 tmp->mDecl.TraceWrapper(aCallbacks, aClosure); |
|
1760 NS_IMPL_CYCLE_COLLECTION_TRACE_END |
|
1761 |
|
1762 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSFontFaceRule) |
|
1763 // Unlink the wrapper for our declaraton. This just expands out |
|
1764 // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use |
|
1765 // directly because the wrapper is on the declaration, not on us. |
|
1766 tmp->mDecl.ReleaseWrapper(static_cast<nsISupports*>(p)); |
|
1767 NS_IMPL_CYCLE_COLLECTION_UNLINK_END |
|
1768 |
|
1769 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSFontFaceRule) |
|
1770 // Just NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS here: that will call |
|
1771 // into our Trace hook, where we do the right thing with declarations |
|
1772 // already. |
|
1773 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS |
|
1774 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END |
|
1775 |
|
1776 DOMCI_DATA(CSSFontFaceRule, nsCSSFontFaceRule) |
|
1777 |
|
1778 // QueryInterface implementation for nsCSSFontFaceRule |
|
1779 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSFontFaceRule) |
|
1780 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
1781 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule) |
|
1782 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
1783 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
1784 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceRule) |
|
1785 NS_INTERFACE_MAP_END |
|
1786 |
|
1787 IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule, Rule) |
|
1788 |
|
1789 #ifdef DEBUG |
|
1790 void |
|
1791 nsCSSFontFaceRule::List(FILE* out, int32_t aIndent) const |
|
1792 { |
|
1793 nsCString baseInd, descInd; |
|
1794 for (int32_t indent = aIndent; --indent >= 0; ) { |
|
1795 baseInd.AppendLiteral(" "); |
|
1796 descInd.AppendLiteral(" "); |
|
1797 } |
|
1798 descInd.AppendLiteral(" "); |
|
1799 |
|
1800 nsString descStr; |
|
1801 |
|
1802 fprintf(out, "%s@font-face {\n", baseInd.get()); |
|
1803 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); |
|
1804 id < eCSSFontDesc_COUNT; |
|
1805 id = nsCSSFontDesc(id + 1)) |
|
1806 if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() |
|
1807 != eCSSUnit_Null) { |
|
1808 if (NS_FAILED(mDecl.GetPropertyValue(id, descStr))) |
|
1809 descStr.AssignLiteral("#<serialization error>"); |
|
1810 else if (descStr.Length() == 0) |
|
1811 descStr.AssignLiteral("#<serialization missing>"); |
|
1812 fprintf(out, "%s%s: %s\n", |
|
1813 descInd.get(), nsCSSProps::GetStringValue(id).get(), |
|
1814 NS_ConvertUTF16toUTF8(descStr).get()); |
|
1815 } |
|
1816 fprintf(out, "%s}\n", baseInd.get()); |
|
1817 } |
|
1818 #endif |
|
1819 |
|
1820 /* virtual */ int32_t |
|
1821 nsCSSFontFaceRule::GetType() const |
|
1822 { |
|
1823 return Rule::FONT_FACE_RULE; |
|
1824 } |
|
1825 |
|
1826 NS_IMETHODIMP |
|
1827 nsCSSFontFaceRule::GetType(uint16_t* aType) |
|
1828 { |
|
1829 *aType = nsIDOMCSSRule::FONT_FACE_RULE; |
|
1830 return NS_OK; |
|
1831 } |
|
1832 |
|
1833 NS_IMETHODIMP |
|
1834 nsCSSFontFaceRule::GetCssText(nsAString& aCssText) |
|
1835 { |
|
1836 nsAutoString propText; |
|
1837 mDecl.GetCssText(propText); |
|
1838 |
|
1839 aCssText.AssignLiteral("@font-face {\n"); |
|
1840 aCssText.Append(propText); |
|
1841 aCssText.Append('}'); |
|
1842 return NS_OK; |
|
1843 } |
|
1844 |
|
1845 NS_IMETHODIMP |
|
1846 nsCSSFontFaceRule::SetCssText(const nsAString& aCssText) |
|
1847 { |
|
1848 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978 |
|
1849 } |
|
1850 |
|
1851 NS_IMETHODIMP |
|
1852 nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
1853 { |
|
1854 return Rule::GetParentStyleSheet(aSheet); |
|
1855 } |
|
1856 |
|
1857 NS_IMETHODIMP |
|
1858 nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
1859 { |
|
1860 return Rule::GetParentRule(aParentRule); |
|
1861 } |
|
1862 |
|
1863 NS_IMETHODIMP |
|
1864 nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) |
|
1865 { |
|
1866 NS_IF_ADDREF(*aStyle = &mDecl); |
|
1867 return NS_OK; |
|
1868 } |
|
1869 |
|
1870 // Arguably these should forward to nsCSSFontFaceStyleDecl methods. |
|
1871 void |
|
1872 nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue) |
|
1873 { |
|
1874 NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN && |
|
1875 aDescID < eCSSFontDesc_COUNT, |
|
1876 "aDescID out of range in nsCSSFontFaceRule::SetDesc"); |
|
1877 |
|
1878 // FIXME: handle dynamic changes |
|
1879 |
|
1880 mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue; |
|
1881 } |
|
1882 |
|
1883 void |
|
1884 nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue) |
|
1885 { |
|
1886 NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN && |
|
1887 aDescID < eCSSFontDesc_COUNT, |
|
1888 "aDescID out of range in nsCSSFontFaceRule::GetDesc"); |
|
1889 |
|
1890 aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID]; |
|
1891 } |
|
1892 |
|
1893 /* virtual */ size_t |
|
1894 nsCSSFontFaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
1895 { |
|
1896 return aMallocSizeOf(this); |
|
1897 |
|
1898 // Measurement of the following members may be added later if DMD finds it is |
|
1899 // worthwhile: |
|
1900 // - mDecl |
|
1901 } |
|
1902 |
|
1903 |
|
1904 // ----------------------------------- |
|
1905 // nsCSSFontFeatureValuesRule |
|
1906 // |
|
1907 |
|
1908 /* virtual */ already_AddRefed<css::Rule> |
|
1909 nsCSSFontFeatureValuesRule::Clone() const |
|
1910 { |
|
1911 nsRefPtr<css::Rule> clone = new nsCSSFontFeatureValuesRule(*this); |
|
1912 return clone.forget(); |
|
1913 } |
|
1914 |
|
1915 NS_IMPL_ADDREF(nsCSSFontFeatureValuesRule) |
|
1916 NS_IMPL_RELEASE(nsCSSFontFeatureValuesRule) |
|
1917 |
|
1918 DOMCI_DATA(CSSFontFeatureValuesRule, nsCSSFontFeatureValuesRule) |
|
1919 |
|
1920 // QueryInterface implementation for nsCSSFontFeatureValuesRule |
|
1921 NS_INTERFACE_MAP_BEGIN(nsCSSFontFeatureValuesRule) |
|
1922 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
1923 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule) |
|
1924 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
1925 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
1926 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFeatureValuesRule) |
|
1927 NS_INTERFACE_MAP_END |
|
1928 |
|
1929 IMPL_STYLE_RULE_INHERIT(nsCSSFontFeatureValuesRule, Rule) |
|
1930 |
|
1931 static void |
|
1932 FamilyListToString(const nsTArray<nsString>& aFamilyList, nsAString& aOutStr) |
|
1933 { |
|
1934 uint32_t i, n = aFamilyList.Length(); |
|
1935 |
|
1936 for (i = 0; i < n; i++) { |
|
1937 nsStyleUtil::AppendEscapedCSSString(aFamilyList[i], aOutStr); |
|
1938 if (i != n - 1) { |
|
1939 aOutStr.AppendLiteral(", "); |
|
1940 } |
|
1941 } |
|
1942 } |
|
1943 |
|
1944 static void |
|
1945 FeatureValuesToString( |
|
1946 const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues, |
|
1947 nsAString& aOutStr) |
|
1948 { |
|
1949 uint32_t i, n; |
|
1950 |
|
1951 // append values |
|
1952 n = aFeatureValues.Length(); |
|
1953 for (i = 0; i < n; i++) { |
|
1954 const gfxFontFeatureValueSet::FeatureValues& fv = aFeatureValues[i]; |
|
1955 |
|
1956 // @alternate |
|
1957 aOutStr.AppendLiteral(" @"); |
|
1958 nsAutoString functAlt; |
|
1959 nsStyleUtil::GetFunctionalAlternatesName(fv.alternate, functAlt); |
|
1960 aOutStr.Append(functAlt); |
|
1961 aOutStr.AppendLiteral(" {"); |
|
1962 |
|
1963 // for each ident-values tuple |
|
1964 uint32_t j, numValues = fv.valuelist.Length(); |
|
1965 for (j = 0; j < numValues; j++) { |
|
1966 aOutStr.AppendLiteral(" "); |
|
1967 const gfxFontFeatureValueSet::ValueList& vlist = fv.valuelist[j]; |
|
1968 nsStyleUtil::AppendEscapedCSSIdent(vlist.name, aOutStr); |
|
1969 aOutStr.AppendLiteral(":"); |
|
1970 |
|
1971 uint32_t k, numSelectors = vlist.featureSelectors.Length(); |
|
1972 for (k = 0; k < numSelectors; k++) { |
|
1973 aOutStr.AppendLiteral(" "); |
|
1974 aOutStr.AppendInt(vlist.featureSelectors[k]); |
|
1975 } |
|
1976 |
|
1977 aOutStr.AppendLiteral(";"); |
|
1978 } |
|
1979 aOutStr.AppendLiteral(" }\n"); |
|
1980 } |
|
1981 } |
|
1982 |
|
1983 static void |
|
1984 FontFeatureValuesRuleToString( |
|
1985 const nsTArray<nsString>& aFamilyList, |
|
1986 const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues, |
|
1987 nsAString& aOutStr) |
|
1988 { |
|
1989 aOutStr.AssignLiteral("@font-feature-values "); |
|
1990 nsAutoString familyListStr, valueTextStr; |
|
1991 FamilyListToString(aFamilyList, familyListStr); |
|
1992 aOutStr.Append(familyListStr); |
|
1993 aOutStr.AppendLiteral(" {\n"); |
|
1994 FeatureValuesToString(aFeatureValues, valueTextStr); |
|
1995 aOutStr.Append(valueTextStr); |
|
1996 aOutStr.AppendLiteral("}"); |
|
1997 } |
|
1998 |
|
1999 #ifdef DEBUG |
|
2000 void |
|
2001 nsCSSFontFeatureValuesRule::List(FILE* out, int32_t aIndent) const |
|
2002 { |
|
2003 nsAutoString text; |
|
2004 FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, text); |
|
2005 NS_ConvertUTF16toUTF8 utf8(text); |
|
2006 |
|
2007 // replace newlines with newlines plus indent spaces |
|
2008 char* indent = new char[(aIndent + 1) * 2]; |
|
2009 int32_t i; |
|
2010 for (i = 1; i < (aIndent + 1) * 2 - 1; i++) { |
|
2011 indent[i] = 0x20; |
|
2012 } |
|
2013 indent[0] = 0xa; |
|
2014 indent[aIndent * 2 + 1] = 0; |
|
2015 utf8.ReplaceSubstring("\n", indent); |
|
2016 delete [] indent; |
|
2017 |
|
2018 for (i = aIndent; --i >= 0; ) fputs(" ", out); |
|
2019 fprintf(out, "%s\n", utf8.get()); |
|
2020 } |
|
2021 #endif |
|
2022 |
|
2023 /* virtual */ int32_t |
|
2024 nsCSSFontFeatureValuesRule::GetType() const |
|
2025 { |
|
2026 return Rule::FONT_FEATURE_VALUES_RULE; |
|
2027 } |
|
2028 |
|
2029 NS_IMETHODIMP |
|
2030 nsCSSFontFeatureValuesRule::GetType(uint16_t* aType) |
|
2031 { |
|
2032 *aType = nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE; |
|
2033 return NS_OK; |
|
2034 } |
|
2035 |
|
2036 NS_IMETHODIMP |
|
2037 nsCSSFontFeatureValuesRule::GetCssText(nsAString& aCssText) |
|
2038 { |
|
2039 FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, aCssText); |
|
2040 return NS_OK; |
|
2041 } |
|
2042 |
|
2043 NS_IMETHODIMP |
|
2044 nsCSSFontFeatureValuesRule::SetCssText(const nsAString& aCssText) |
|
2045 { |
|
2046 // FIXME: implement??? |
|
2047 return NS_ERROR_NOT_IMPLEMENTED; |
|
2048 } |
|
2049 |
|
2050 NS_IMETHODIMP |
|
2051 nsCSSFontFeatureValuesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
2052 { |
|
2053 return Rule::GetParentStyleSheet(aSheet); |
|
2054 } |
|
2055 |
|
2056 NS_IMETHODIMP |
|
2057 nsCSSFontFeatureValuesRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
2058 { |
|
2059 return Rule::GetParentRule(aParentRule); |
|
2060 } |
|
2061 |
|
2062 NS_IMETHODIMP |
|
2063 nsCSSFontFeatureValuesRule::GetFontFamily(nsAString& aFontFamily) |
|
2064 { |
|
2065 FamilyListToString(mFamilyList, aFontFamily); |
|
2066 return NS_OK; |
|
2067 } |
|
2068 |
|
2069 NS_IMETHODIMP |
|
2070 nsCSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily) |
|
2071 { |
|
2072 return NS_ERROR_NOT_IMPLEMENTED; |
|
2073 } |
|
2074 |
|
2075 NS_IMETHODIMP |
|
2076 nsCSSFontFeatureValuesRule::GetValueText(nsAString& aValueText) |
|
2077 { |
|
2078 FeatureValuesToString(mFeatureValues, aValueText); |
|
2079 return NS_OK; |
|
2080 } |
|
2081 |
|
2082 NS_IMETHODIMP |
|
2083 nsCSSFontFeatureValuesRule::SetValueText(const nsAString& aValueText) |
|
2084 { |
|
2085 return NS_ERROR_NOT_IMPLEMENTED; |
|
2086 } |
|
2087 |
|
2088 struct MakeFamilyArray { |
|
2089 MakeFamilyArray(nsTArray<nsString>& aFamilyArray) |
|
2090 : familyArray(aFamilyArray), hasGeneric(false) |
|
2091 {} |
|
2092 |
|
2093 static bool |
|
2094 AddFamily(const nsString& aFamily, bool aGeneric, void* aData) |
|
2095 { |
|
2096 MakeFamilyArray *familyArr = reinterpret_cast<MakeFamilyArray*> (aData); |
|
2097 if (!aGeneric && !aFamily.IsEmpty()) { |
|
2098 familyArr->familyArray.AppendElement(aFamily); |
|
2099 } |
|
2100 if (aGeneric) { |
|
2101 familyArr->hasGeneric = true; |
|
2102 } |
|
2103 return true; |
|
2104 } |
|
2105 |
|
2106 nsTArray<nsString>& familyArray; |
|
2107 bool hasGeneric; |
|
2108 }; |
|
2109 |
|
2110 void |
|
2111 nsCSSFontFeatureValuesRule::SetFamilyList(const nsAString& aFamilyList, |
|
2112 bool& aContainsGeneric) |
|
2113 { |
|
2114 nsFont font(aFamilyList, 0, 0, 0, 0, 0, 0); |
|
2115 MakeFamilyArray families(mFamilyList); |
|
2116 font.EnumerateFamilies(MakeFamilyArray::AddFamily, (void*) &families); |
|
2117 aContainsGeneric = families.hasGeneric; |
|
2118 } |
|
2119 |
|
2120 void |
|
2121 nsCSSFontFeatureValuesRule::AddValueList(int32_t aVariantAlternate, |
|
2122 nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList) |
|
2123 { |
|
2124 uint32_t i, len = mFeatureValues.Length(); |
|
2125 bool foundAlternate = false; |
|
2126 |
|
2127 // add to an existing list for a given property value |
|
2128 for (i = 0; i < len; i++) { |
|
2129 gfxFontFeatureValueSet::FeatureValues& f = mFeatureValues.ElementAt(i); |
|
2130 |
|
2131 if (f.alternate == uint32_t(aVariantAlternate)) { |
|
2132 f.valuelist.AppendElements(aValueList); |
|
2133 foundAlternate = true; |
|
2134 break; |
|
2135 } |
|
2136 } |
|
2137 |
|
2138 // create a new list for a given property value |
|
2139 if (!foundAlternate) { |
|
2140 gfxFontFeatureValueSet::FeatureValues &f = *mFeatureValues.AppendElement(); |
|
2141 f.alternate = aVariantAlternate; |
|
2142 f.valuelist.AppendElements(aValueList); |
|
2143 } |
|
2144 } |
|
2145 |
|
2146 size_t |
|
2147 nsCSSFontFeatureValuesRule::SizeOfIncludingThis( |
|
2148 MallocSizeOf aMallocSizeOf) const |
|
2149 { |
|
2150 return aMallocSizeOf(this); |
|
2151 } |
|
2152 |
|
2153 // ------------------------------------------- |
|
2154 // nsCSSKeyframeStyleDeclaration |
|
2155 // |
|
2156 |
|
2157 nsCSSKeyframeStyleDeclaration::nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule) |
|
2158 : mRule(aRule) |
|
2159 { |
|
2160 } |
|
2161 |
|
2162 nsCSSKeyframeStyleDeclaration::~nsCSSKeyframeStyleDeclaration() |
|
2163 { |
|
2164 NS_ASSERTION(!mRule, "DropReference not called."); |
|
2165 } |
|
2166 |
|
2167 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeStyleDeclaration) |
|
2168 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeStyleDeclaration) |
|
2169 |
|
2170 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSKeyframeStyleDeclaration) |
|
2171 |
|
2172 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeStyleDeclaration) |
|
2173 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
|
2174 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) |
|
2175 |
|
2176 css::Declaration* |
|
2177 nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(bool aAllocate) |
|
2178 { |
|
2179 if (mRule) { |
|
2180 return mRule->Declaration(); |
|
2181 } else { |
|
2182 return nullptr; |
|
2183 } |
|
2184 } |
|
2185 |
|
2186 void |
|
2187 nsCSSKeyframeStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) |
|
2188 { |
|
2189 GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv); |
|
2190 } |
|
2191 |
|
2192 NS_IMETHODIMP |
|
2193 nsCSSKeyframeStyleDeclaration::GetParentRule(nsIDOMCSSRule **aParent) |
|
2194 { |
|
2195 NS_ENSURE_ARG_POINTER(aParent); |
|
2196 |
|
2197 NS_IF_ADDREF(*aParent = mRule); |
|
2198 return NS_OK; |
|
2199 } |
|
2200 |
|
2201 nsresult |
|
2202 nsCSSKeyframeStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl) |
|
2203 { |
|
2204 NS_ABORT_IF_FALSE(aDecl, "must be non-null"); |
|
2205 mRule->ChangeDeclaration(aDecl); |
|
2206 return NS_OK; |
|
2207 } |
|
2208 |
|
2209 nsIDocument* |
|
2210 nsCSSKeyframeStyleDeclaration::DocToUpdate() |
|
2211 { |
|
2212 return nullptr; |
|
2213 } |
|
2214 |
|
2215 nsINode* |
|
2216 nsCSSKeyframeStyleDeclaration::GetParentObject() |
|
2217 { |
|
2218 return mRule ? mRule->GetDocument() : nullptr; |
|
2219 } |
|
2220 |
|
2221 // ------------------------------------------- |
|
2222 // nsCSSKeyframeRule |
|
2223 // |
|
2224 |
|
2225 nsCSSKeyframeRule::nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy) |
|
2226 // copy everything except our reference count and mDOMDeclaration |
|
2227 : Rule(aCopy) |
|
2228 , mKeys(aCopy.mKeys) |
|
2229 , mDeclaration(new css::Declaration(*aCopy.mDeclaration)) |
|
2230 { |
|
2231 } |
|
2232 |
|
2233 nsCSSKeyframeRule::~nsCSSKeyframeRule() |
|
2234 { |
|
2235 if (mDOMDeclaration) { |
|
2236 mDOMDeclaration->DropReference(); |
|
2237 } |
|
2238 } |
|
2239 |
|
2240 /* virtual */ already_AddRefed<css::Rule> |
|
2241 nsCSSKeyframeRule::Clone() const |
|
2242 { |
|
2243 nsRefPtr<css::Rule> clone = new nsCSSKeyframeRule(*this); |
|
2244 return clone.forget(); |
|
2245 } |
|
2246 |
|
2247 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeRule) |
|
2248 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeRule) |
|
2249 |
|
2250 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSKeyframeRule) |
|
2251 |
|
2252 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSKeyframeRule) |
|
2253 if (tmp->mDOMDeclaration) { |
|
2254 tmp->mDOMDeclaration->DropReference(); |
|
2255 tmp->mDOMDeclaration = nullptr; |
|
2256 } |
|
2257 NS_IMPL_CYCLE_COLLECTION_UNLINK_END |
|
2258 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSKeyframeRule) |
|
2259 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration) |
|
2260 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END |
|
2261 |
|
2262 DOMCI_DATA(MozCSSKeyframeRule, nsCSSKeyframeRule) |
|
2263 |
|
2264 // QueryInterface implementation for nsCSSKeyframeRule |
|
2265 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeRule) |
|
2266 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
2267 NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframeRule) |
|
2268 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
2269 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
2270 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframeRule) |
|
2271 NS_INTERFACE_MAP_END |
|
2272 |
|
2273 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSKeyframeRule, Rule) |
|
2274 |
|
2275 /* virtual */ void |
|
2276 nsCSSKeyframeRule::MapRuleInfoInto(nsRuleData* aRuleData) |
|
2277 { |
|
2278 // We need to implement MapRuleInfoInto because the animation manager |
|
2279 // constructs a rule node pointing to us in order to compute the |
|
2280 // styles it needs to animate. |
|
2281 |
|
2282 // The spec says that !important declarations should just be ignored |
|
2283 NS_ASSERTION(!mDeclaration->HasImportantData(), |
|
2284 "Keyframe rules has !important data"); |
|
2285 |
|
2286 mDeclaration->MapNormalRuleInfoInto(aRuleData); |
|
2287 } |
|
2288 |
|
2289 #ifdef DEBUG |
|
2290 void |
|
2291 nsCSSKeyframeRule::List(FILE* out, int32_t aIndent) const |
|
2292 { |
|
2293 for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); |
|
2294 |
|
2295 nsAutoString tmp; |
|
2296 DoGetKeyText(tmp); |
|
2297 fputs(NS_ConvertUTF16toUTF8(tmp).get(), out); |
|
2298 fputs(" ", out); |
|
2299 mDeclaration->List(out, aIndent); |
|
2300 fputs("\n", out); |
|
2301 } |
|
2302 #endif |
|
2303 |
|
2304 /* virtual */ int32_t |
|
2305 nsCSSKeyframeRule::GetType() const |
|
2306 { |
|
2307 return Rule::KEYFRAME_RULE; |
|
2308 } |
|
2309 |
|
2310 NS_IMETHODIMP |
|
2311 nsCSSKeyframeRule::GetType(uint16_t* aType) |
|
2312 { |
|
2313 *aType = nsIDOMCSSRule::KEYFRAME_RULE; |
|
2314 return NS_OK; |
|
2315 } |
|
2316 |
|
2317 NS_IMETHODIMP |
|
2318 nsCSSKeyframeRule::GetCssText(nsAString& aCssText) |
|
2319 { |
|
2320 DoGetKeyText(aCssText); |
|
2321 aCssText.AppendLiteral(" { "); |
|
2322 nsAutoString tmp; |
|
2323 mDeclaration->ToString(tmp); |
|
2324 aCssText.Append(tmp); |
|
2325 aCssText.AppendLiteral(" }"); |
|
2326 return NS_OK; |
|
2327 } |
|
2328 |
|
2329 NS_IMETHODIMP |
|
2330 nsCSSKeyframeRule::SetCssText(const nsAString& aCssText) |
|
2331 { |
|
2332 // FIXME: implement??? |
|
2333 return NS_ERROR_NOT_IMPLEMENTED; |
|
2334 } |
|
2335 |
|
2336 NS_IMETHODIMP |
|
2337 nsCSSKeyframeRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
2338 { |
|
2339 return Rule::GetParentStyleSheet(aSheet); |
|
2340 } |
|
2341 |
|
2342 NS_IMETHODIMP |
|
2343 nsCSSKeyframeRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
2344 { |
|
2345 return Rule::GetParentRule(aParentRule); |
|
2346 } |
|
2347 |
|
2348 NS_IMETHODIMP |
|
2349 nsCSSKeyframeRule::GetKeyText(nsAString& aKeyText) |
|
2350 { |
|
2351 DoGetKeyText(aKeyText); |
|
2352 return NS_OK; |
|
2353 } |
|
2354 |
|
2355 void |
|
2356 nsCSSKeyframeRule::DoGetKeyText(nsAString& aKeyText) const |
|
2357 { |
|
2358 aKeyText.Truncate(); |
|
2359 uint32_t i = 0, i_end = mKeys.Length(); |
|
2360 NS_ABORT_IF_FALSE(i_end != 0, "must have some keys"); |
|
2361 for (;;) { |
|
2362 aKeyText.AppendFloat(mKeys[i] * 100.0f); |
|
2363 aKeyText.Append(char16_t('%')); |
|
2364 if (++i == i_end) { |
|
2365 break; |
|
2366 } |
|
2367 aKeyText.AppendLiteral(", "); |
|
2368 } |
|
2369 } |
|
2370 |
|
2371 NS_IMETHODIMP |
|
2372 nsCSSKeyframeRule::SetKeyText(const nsAString& aKeyText) |
|
2373 { |
|
2374 nsCSSParser parser; |
|
2375 |
|
2376 InfallibleTArray<float> newSelectors; |
|
2377 // FIXME: pass filename and line number |
|
2378 if (!parser.ParseKeyframeSelectorString(aKeyText, nullptr, 0, newSelectors)) { |
|
2379 // for now, we don't do anything if the parse fails |
|
2380 return NS_OK; |
|
2381 } |
|
2382 |
|
2383 nsIDocument* doc = GetDocument(); |
|
2384 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); |
|
2385 |
|
2386 newSelectors.SwapElements(mKeys); |
|
2387 |
|
2388 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
2389 if (sheet) { |
|
2390 sheet->SetModifiedByChildRule(); |
|
2391 |
|
2392 if (doc) { |
|
2393 doc->StyleRuleChanged(sheet, this, this); |
|
2394 } |
|
2395 } |
|
2396 |
|
2397 return NS_OK; |
|
2398 } |
|
2399 |
|
2400 NS_IMETHODIMP |
|
2401 nsCSSKeyframeRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) |
|
2402 { |
|
2403 if (!mDOMDeclaration) { |
|
2404 mDOMDeclaration = new nsCSSKeyframeStyleDeclaration(this); |
|
2405 } |
|
2406 NS_ADDREF(*aStyle = mDOMDeclaration); |
|
2407 return NS_OK; |
|
2408 } |
|
2409 |
|
2410 void |
|
2411 nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration) |
|
2412 { |
|
2413 // Our caller already did a BeginUpdate/EndUpdate, but with |
|
2414 // UPDATE_CONTENT, and we need UPDATE_STYLE to trigger work in |
|
2415 // PresShell::EndUpdate. |
|
2416 nsIDocument* doc = GetDocument(); |
|
2417 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); |
|
2418 |
|
2419 // Be careful to not assign to an nsAutoPtr if we would be assigning |
|
2420 // the thing it already holds. |
|
2421 if (aDeclaration != mDeclaration) { |
|
2422 mDeclaration = aDeclaration; |
|
2423 } |
|
2424 |
|
2425 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
2426 if (sheet) { |
|
2427 sheet->SetModifiedByChildRule(); |
|
2428 |
|
2429 if (doc) { |
|
2430 doc->StyleRuleChanged(sheet, this, this); |
|
2431 } |
|
2432 } |
|
2433 } |
|
2434 |
|
2435 /* virtual */ size_t |
|
2436 nsCSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
2437 { |
|
2438 return aMallocSizeOf(this); |
|
2439 |
|
2440 // Measurement of the following members may be added later if DMD finds it is |
|
2441 // worthwhile: |
|
2442 // - mKeys |
|
2443 // - mDeclaration |
|
2444 // - mDOMDeclaration |
|
2445 } |
|
2446 |
|
2447 |
|
2448 // ------------------------------------------- |
|
2449 // nsCSSKeyframesRule |
|
2450 // |
|
2451 |
|
2452 nsCSSKeyframesRule::nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy) |
|
2453 // copy everything except our reference count. GroupRule's copy |
|
2454 // constructor also doesn't copy the lazily-constructed |
|
2455 // mRuleCollection. |
|
2456 : GroupRule(aCopy), |
|
2457 mName(aCopy.mName) |
|
2458 { |
|
2459 } |
|
2460 |
|
2461 nsCSSKeyframesRule::~nsCSSKeyframesRule() |
|
2462 { |
|
2463 } |
|
2464 |
|
2465 /* virtual */ already_AddRefed<css::Rule> |
|
2466 nsCSSKeyframesRule::Clone() const |
|
2467 { |
|
2468 nsRefPtr<css::Rule> clone = new nsCSSKeyframesRule(*this); |
|
2469 return clone.forget(); |
|
2470 } |
|
2471 |
|
2472 NS_IMPL_ADDREF_INHERITED(nsCSSKeyframesRule, css::GroupRule) |
|
2473 NS_IMPL_RELEASE_INHERITED(nsCSSKeyframesRule, css::GroupRule) |
|
2474 |
|
2475 DOMCI_DATA(MozCSSKeyframesRule, nsCSSKeyframesRule) |
|
2476 |
|
2477 // QueryInterface implementation for nsCSSKeyframesRule |
|
2478 NS_INTERFACE_MAP_BEGIN(nsCSSKeyframesRule) |
|
2479 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
2480 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
2481 NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframesRule) |
|
2482 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
2483 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframesRule) |
|
2484 NS_INTERFACE_MAP_END_INHERITING(GroupRule) |
|
2485 |
|
2486 #ifdef DEBUG |
|
2487 void |
|
2488 nsCSSKeyframesRule::List(FILE* out, int32_t aIndent) const |
|
2489 { |
|
2490 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
2491 |
|
2492 fprintf(out, "@keyframes %s", NS_ConvertUTF16toUTF8(mName).get()); |
|
2493 GroupRule::List(out, aIndent); |
|
2494 } |
|
2495 #endif |
|
2496 |
|
2497 /* virtual */ int32_t |
|
2498 nsCSSKeyframesRule::GetType() const |
|
2499 { |
|
2500 return Rule::KEYFRAMES_RULE; |
|
2501 } |
|
2502 |
|
2503 NS_IMETHODIMP |
|
2504 nsCSSKeyframesRule::GetType(uint16_t* aType) |
|
2505 { |
|
2506 *aType = nsIDOMCSSRule::KEYFRAMES_RULE; |
|
2507 return NS_OK; |
|
2508 } |
|
2509 |
|
2510 NS_IMETHODIMP |
|
2511 nsCSSKeyframesRule::GetCssText(nsAString& aCssText) |
|
2512 { |
|
2513 aCssText.AssignLiteral("@keyframes "); |
|
2514 aCssText.Append(mName); |
|
2515 aCssText.AppendLiteral(" {\n"); |
|
2516 nsAutoString tmp; |
|
2517 for (uint32_t i = 0, i_end = mRules.Count(); i != i_end; ++i) { |
|
2518 static_cast<nsCSSKeyframeRule*>(mRules[i])->GetCssText(tmp); |
|
2519 aCssText.Append(tmp); |
|
2520 aCssText.AppendLiteral("\n"); |
|
2521 } |
|
2522 aCssText.AppendLiteral("}"); |
|
2523 return NS_OK; |
|
2524 } |
|
2525 |
|
2526 NS_IMETHODIMP |
|
2527 nsCSSKeyframesRule::SetCssText(const nsAString& aCssText) |
|
2528 { |
|
2529 // FIXME: implement??? |
|
2530 return NS_ERROR_NOT_IMPLEMENTED; |
|
2531 } |
|
2532 |
|
2533 NS_IMETHODIMP |
|
2534 nsCSSKeyframesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
2535 { |
|
2536 return GroupRule::GetParentStyleSheet(aSheet); |
|
2537 } |
|
2538 |
|
2539 NS_IMETHODIMP |
|
2540 nsCSSKeyframesRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
2541 { |
|
2542 return GroupRule::GetParentRule(aParentRule); |
|
2543 } |
|
2544 |
|
2545 NS_IMETHODIMP |
|
2546 nsCSSKeyframesRule::GetName(nsAString& aName) |
|
2547 { |
|
2548 aName = mName; |
|
2549 return NS_OK; |
|
2550 } |
|
2551 |
|
2552 NS_IMETHODIMP |
|
2553 nsCSSKeyframesRule::SetName(const nsAString& aName) |
|
2554 { |
|
2555 if (mName == aName) { |
|
2556 return NS_OK; |
|
2557 } |
|
2558 |
|
2559 nsIDocument* doc = GetDocument(); |
|
2560 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); |
|
2561 |
|
2562 mName = aName; |
|
2563 |
|
2564 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
2565 if (sheet) { |
|
2566 sheet->SetModifiedByChildRule(); |
|
2567 |
|
2568 if (doc) { |
|
2569 doc->StyleRuleChanged(sheet, this, this); |
|
2570 } |
|
2571 } |
|
2572 |
|
2573 return NS_OK; |
|
2574 } |
|
2575 |
|
2576 NS_IMETHODIMP |
|
2577 nsCSSKeyframesRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) |
|
2578 { |
|
2579 return GroupRule::GetCssRules(aRuleList); |
|
2580 } |
|
2581 |
|
2582 NS_IMETHODIMP |
|
2583 nsCSSKeyframesRule::AppendRule(const nsAString& aRule) |
|
2584 { |
|
2585 // The spec is confusing, and I think we should just append the rule, |
|
2586 // which also turns out to match WebKit: |
|
2587 // http://lists.w3.org/Archives/Public/www-style/2011Apr/0034.html |
|
2588 nsCSSParser parser; |
|
2589 |
|
2590 // FIXME: pass filename and line number |
|
2591 nsRefPtr<nsCSSKeyframeRule> rule = |
|
2592 parser.ParseKeyframeRule(aRule, nullptr, 0); |
|
2593 if (rule) { |
|
2594 nsIDocument* doc = GetDocument(); |
|
2595 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); |
|
2596 |
|
2597 AppendStyleRule(rule); |
|
2598 |
|
2599 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
2600 if (sheet) { |
|
2601 sheet->SetModifiedByChildRule(); |
|
2602 |
|
2603 if (doc) { |
|
2604 doc->StyleRuleChanged(sheet, this, this); |
|
2605 } |
|
2606 } |
|
2607 } |
|
2608 |
|
2609 return NS_OK; |
|
2610 } |
|
2611 |
|
2612 static const uint32_t RULE_NOT_FOUND = uint32_t(-1); |
|
2613 |
|
2614 uint32_t |
|
2615 nsCSSKeyframesRule::FindRuleIndexForKey(const nsAString& aKey) |
|
2616 { |
|
2617 nsCSSParser parser; |
|
2618 |
|
2619 InfallibleTArray<float> keys; |
|
2620 // FIXME: pass filename and line number |
|
2621 if (parser.ParseKeyframeSelectorString(aKey, nullptr, 0, keys)) { |
|
2622 // The spec isn't clear, but we'll match on the key list, which |
|
2623 // mostly matches what WebKit does, except we'll do last-match |
|
2624 // instead of first-match, and handling parsing differences better. |
|
2625 // http://lists.w3.org/Archives/Public/www-style/2011Apr/0036.html |
|
2626 // http://lists.w3.org/Archives/Public/www-style/2011Apr/0037.html |
|
2627 for (uint32_t i = mRules.Count(); i-- != 0; ) { |
|
2628 if (static_cast<nsCSSKeyframeRule*>(mRules[i])->GetKeys() == keys) { |
|
2629 return i; |
|
2630 } |
|
2631 } |
|
2632 } |
|
2633 |
|
2634 return RULE_NOT_FOUND; |
|
2635 } |
|
2636 |
|
2637 NS_IMETHODIMP |
|
2638 nsCSSKeyframesRule::DeleteRule(const nsAString& aKey) |
|
2639 { |
|
2640 uint32_t index = FindRuleIndexForKey(aKey); |
|
2641 if (index != RULE_NOT_FOUND) { |
|
2642 nsIDocument* doc = GetDocument(); |
|
2643 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); |
|
2644 |
|
2645 mRules.RemoveObjectAt(index); |
|
2646 |
|
2647 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
2648 if (sheet) { |
|
2649 sheet->SetModifiedByChildRule(); |
|
2650 |
|
2651 if (doc) { |
|
2652 doc->StyleRuleChanged(sheet, this, this); |
|
2653 } |
|
2654 } |
|
2655 } |
|
2656 return NS_OK; |
|
2657 } |
|
2658 |
|
2659 NS_IMETHODIMP |
|
2660 nsCSSKeyframesRule::FindRule(const nsAString& aKey, |
|
2661 nsIDOMMozCSSKeyframeRule** aResult) |
|
2662 { |
|
2663 uint32_t index = FindRuleIndexForKey(aKey); |
|
2664 if (index == RULE_NOT_FOUND) { |
|
2665 *aResult = nullptr; |
|
2666 } else { |
|
2667 NS_ADDREF(*aResult = static_cast<nsCSSKeyframeRule*>(mRules[index])); |
|
2668 } |
|
2669 return NS_OK; |
|
2670 } |
|
2671 |
|
2672 // GroupRule interface |
|
2673 /* virtual */ bool |
|
2674 nsCSSKeyframesRule::UseForPresentation(nsPresContext* aPresContext, |
|
2675 nsMediaQueryResultCacheKey& aKey) |
|
2676 { |
|
2677 NS_ABORT_IF_FALSE(false, "should not be called"); |
|
2678 return false; |
|
2679 } |
|
2680 |
|
2681 /* virtual */ size_t |
|
2682 nsCSSKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
2683 { |
|
2684 size_t n = aMallocSizeOf(this); |
|
2685 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf); |
|
2686 |
|
2687 // Measurement of the following members may be added later if DMD finds it is |
|
2688 // worthwhile: |
|
2689 // - mName |
|
2690 |
|
2691 return n; |
|
2692 } |
|
2693 |
|
2694 // ------------------------------------------- |
|
2695 // nsCSSPageStyleDeclaration |
|
2696 // |
|
2697 |
|
2698 nsCSSPageStyleDeclaration::nsCSSPageStyleDeclaration(nsCSSPageRule* aRule) |
|
2699 : mRule(aRule) |
|
2700 { |
|
2701 } |
|
2702 |
|
2703 nsCSSPageStyleDeclaration::~nsCSSPageStyleDeclaration() |
|
2704 { |
|
2705 NS_ASSERTION(!mRule, "DropReference not called."); |
|
2706 } |
|
2707 |
|
2708 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageStyleDeclaration) |
|
2709 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageStyleDeclaration) |
|
2710 |
|
2711 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSPageStyleDeclaration) |
|
2712 |
|
2713 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageStyleDeclaration) |
|
2714 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
|
2715 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) |
|
2716 |
|
2717 css::Declaration* |
|
2718 nsCSSPageStyleDeclaration::GetCSSDeclaration(bool aAllocate) |
|
2719 { |
|
2720 if (mRule) { |
|
2721 return mRule->Declaration(); |
|
2722 } else { |
|
2723 return nullptr; |
|
2724 } |
|
2725 } |
|
2726 |
|
2727 void |
|
2728 nsCSSPageStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) |
|
2729 { |
|
2730 GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv); |
|
2731 } |
|
2732 |
|
2733 NS_IMETHODIMP |
|
2734 nsCSSPageStyleDeclaration::GetParentRule(nsIDOMCSSRule** aParent) |
|
2735 { |
|
2736 NS_ENSURE_ARG_POINTER(aParent); |
|
2737 |
|
2738 NS_IF_ADDREF(*aParent = mRule); |
|
2739 return NS_OK; |
|
2740 } |
|
2741 |
|
2742 nsresult |
|
2743 nsCSSPageStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl) |
|
2744 { |
|
2745 NS_ABORT_IF_FALSE(aDecl, "must be non-null"); |
|
2746 mRule->ChangeDeclaration(aDecl); |
|
2747 return NS_OK; |
|
2748 } |
|
2749 |
|
2750 nsIDocument* |
|
2751 nsCSSPageStyleDeclaration::DocToUpdate() |
|
2752 { |
|
2753 return nullptr; |
|
2754 } |
|
2755 |
|
2756 nsINode* |
|
2757 nsCSSPageStyleDeclaration::GetParentObject() |
|
2758 { |
|
2759 return mRule ? mRule->GetDocument() : nullptr; |
|
2760 } |
|
2761 |
|
2762 // ------------------------------------------- |
|
2763 // nsCSSPageRule |
|
2764 // |
|
2765 |
|
2766 nsCSSPageRule::nsCSSPageRule(const nsCSSPageRule& aCopy) |
|
2767 // copy everything except our reference count and mDOMDeclaration |
|
2768 : Rule(aCopy) |
|
2769 , mDeclaration(new css::Declaration(*aCopy.mDeclaration)) |
|
2770 { |
|
2771 } |
|
2772 |
|
2773 nsCSSPageRule::~nsCSSPageRule() |
|
2774 { |
|
2775 if (mDOMDeclaration) { |
|
2776 mDOMDeclaration->DropReference(); |
|
2777 } |
|
2778 } |
|
2779 |
|
2780 /* virtual */ already_AddRefed<css::Rule> |
|
2781 nsCSSPageRule::Clone() const |
|
2782 { |
|
2783 nsRefPtr<css::Rule> clone = new nsCSSPageRule(*this); |
|
2784 return clone.forget(); |
|
2785 } |
|
2786 |
|
2787 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageRule) |
|
2788 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageRule) |
|
2789 |
|
2790 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSPageRule) |
|
2791 |
|
2792 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSPageRule) |
|
2793 if (tmp->mDOMDeclaration) { |
|
2794 tmp->mDOMDeclaration->DropReference(); |
|
2795 tmp->mDOMDeclaration = nullptr; |
|
2796 } |
|
2797 NS_IMPL_CYCLE_COLLECTION_UNLINK_END |
|
2798 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSPageRule) |
|
2799 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration) |
|
2800 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END |
|
2801 |
|
2802 DOMCI_DATA(CSSPageRule, nsCSSPageRule) |
|
2803 |
|
2804 // QueryInterface implementation for nsCSSPageRule |
|
2805 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageRule) |
|
2806 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
2807 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSPageRule) |
|
2808 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
2809 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
2810 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSPageRule) |
|
2811 NS_INTERFACE_MAP_END |
|
2812 |
|
2813 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSPageRule, Rule) |
|
2814 |
|
2815 #ifdef DEBUG |
|
2816 void |
|
2817 nsCSSPageRule::List(FILE* out, int32_t aIndent) const |
|
2818 { |
|
2819 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
2820 |
|
2821 fputs("@page ", out); |
|
2822 mDeclaration->List(out, aIndent); |
|
2823 fputs("\n", out); |
|
2824 } |
|
2825 #endif |
|
2826 |
|
2827 /* virtual */ int32_t |
|
2828 nsCSSPageRule::GetType() const |
|
2829 { |
|
2830 return Rule::PAGE_RULE; |
|
2831 } |
|
2832 |
|
2833 NS_IMETHODIMP |
|
2834 nsCSSPageRule::GetType(uint16_t* aType) |
|
2835 { |
|
2836 *aType = nsIDOMCSSRule::PAGE_RULE; |
|
2837 return NS_OK; |
|
2838 } |
|
2839 |
|
2840 NS_IMETHODIMP |
|
2841 nsCSSPageRule::GetCssText(nsAString& aCssText) |
|
2842 { |
|
2843 aCssText.AppendLiteral("@page { "); |
|
2844 nsAutoString tmp; |
|
2845 mDeclaration->ToString(tmp); |
|
2846 aCssText.Append(tmp); |
|
2847 aCssText.AppendLiteral(" }"); |
|
2848 return NS_OK; |
|
2849 } |
|
2850 |
|
2851 NS_IMETHODIMP |
|
2852 nsCSSPageRule::SetCssText(const nsAString& aCssText) |
|
2853 { |
|
2854 // FIXME: implement??? |
|
2855 return NS_ERROR_NOT_IMPLEMENTED; |
|
2856 } |
|
2857 |
|
2858 NS_IMETHODIMP |
|
2859 nsCSSPageRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
2860 { |
|
2861 return Rule::GetParentStyleSheet(aSheet); |
|
2862 } |
|
2863 |
|
2864 NS_IMETHODIMP |
|
2865 nsCSSPageRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
2866 { |
|
2867 return Rule::GetParentRule(aParentRule); |
|
2868 } |
|
2869 |
|
2870 css::ImportantRule* |
|
2871 nsCSSPageRule::GetImportantRule() |
|
2872 { |
|
2873 if (!mDeclaration->HasImportantData()) { |
|
2874 return nullptr; |
|
2875 } |
|
2876 if (!mImportantRule) { |
|
2877 mImportantRule = new css::ImportantRule(mDeclaration); |
|
2878 } |
|
2879 return mImportantRule; |
|
2880 } |
|
2881 |
|
2882 /* virtual */ void |
|
2883 nsCSSPageRule::MapRuleInfoInto(nsRuleData* aRuleData) |
|
2884 { |
|
2885 mDeclaration->MapNormalRuleInfoInto(aRuleData); |
|
2886 } |
|
2887 |
|
2888 NS_IMETHODIMP |
|
2889 nsCSSPageRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) |
|
2890 { |
|
2891 if (!mDOMDeclaration) { |
|
2892 mDOMDeclaration = new nsCSSPageStyleDeclaration(this); |
|
2893 } |
|
2894 NS_ADDREF(*aStyle = mDOMDeclaration); |
|
2895 return NS_OK; |
|
2896 } |
|
2897 |
|
2898 void |
|
2899 nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration) |
|
2900 { |
|
2901 mImportantRule = nullptr; |
|
2902 // Be careful to not assign to an nsAutoPtr if we would be assigning |
|
2903 // the thing it already holds. |
|
2904 if (aDeclaration != mDeclaration) { |
|
2905 mDeclaration = aDeclaration; |
|
2906 } |
|
2907 |
|
2908 nsCSSStyleSheet* sheet = GetStyleSheet(); |
|
2909 if (sheet) { |
|
2910 sheet->SetModifiedByChildRule(); |
|
2911 } |
|
2912 } |
|
2913 |
|
2914 /* virtual */ size_t |
|
2915 nsCSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
2916 { |
|
2917 return aMallocSizeOf(this); |
|
2918 } |
|
2919 |
|
2920 namespace mozilla { |
|
2921 |
|
2922 CSSSupportsRule::CSSSupportsRule(bool aConditionMet, |
|
2923 const nsString& aCondition) |
|
2924 : mUseGroup(aConditionMet), |
|
2925 mCondition(aCondition) |
|
2926 { |
|
2927 } |
|
2928 |
|
2929 CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy) |
|
2930 : css::GroupRule(aCopy), |
|
2931 mUseGroup(aCopy.mUseGroup), |
|
2932 mCondition(aCopy.mCondition) |
|
2933 { |
|
2934 } |
|
2935 |
|
2936 #ifdef DEBUG |
|
2937 /* virtual */ void |
|
2938 CSSSupportsRule::List(FILE* out, int32_t aIndent) const |
|
2939 { |
|
2940 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out); |
|
2941 |
|
2942 fputs("@supports ", out); |
|
2943 fputs(NS_ConvertUTF16toUTF8(mCondition).get(), out); |
|
2944 css::GroupRule::List(out, aIndent); |
|
2945 } |
|
2946 #endif |
|
2947 |
|
2948 /* virtual */ int32_t |
|
2949 CSSSupportsRule::GetType() const |
|
2950 { |
|
2951 return Rule::SUPPORTS_RULE; |
|
2952 } |
|
2953 |
|
2954 /* virtual */ already_AddRefed<mozilla::css::Rule> |
|
2955 CSSSupportsRule::Clone() const |
|
2956 { |
|
2957 nsRefPtr<css::Rule> clone = new CSSSupportsRule(*this); |
|
2958 return clone.forget(); |
|
2959 } |
|
2960 |
|
2961 /* virtual */ bool |
|
2962 CSSSupportsRule::UseForPresentation(nsPresContext* aPresContext, |
|
2963 nsMediaQueryResultCacheKey& aKey) |
|
2964 { |
|
2965 return mUseGroup; |
|
2966 } |
|
2967 |
|
2968 NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, css::GroupRule) |
|
2969 NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::GroupRule) |
|
2970 |
|
2971 // QueryInterface implementation for CSSSupportsRule |
|
2972 NS_INTERFACE_MAP_BEGIN(CSSSupportsRule) |
|
2973 NS_INTERFACE_MAP_ENTRY(nsIStyleRule) |
|
2974 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule) |
|
2975 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule) |
|
2976 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule) |
|
2977 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSSupportsRule) |
|
2978 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule) |
|
2979 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSSupportsRule) |
|
2980 NS_INTERFACE_MAP_END_INHERITING(GroupRule) |
|
2981 |
|
2982 // nsIDOMCSSRule methods |
|
2983 NS_IMETHODIMP |
|
2984 CSSSupportsRule::GetType(uint16_t* aType) |
|
2985 { |
|
2986 *aType = nsIDOMCSSRule::SUPPORTS_RULE; |
|
2987 return NS_OK; |
|
2988 } |
|
2989 |
|
2990 NS_IMETHODIMP |
|
2991 CSSSupportsRule::GetCssText(nsAString& aCssText) |
|
2992 { |
|
2993 aCssText.AssignLiteral("@supports "); |
|
2994 aCssText.Append(mCondition); |
|
2995 css::GroupRule::AppendRulesToCssText(aCssText); |
|
2996 return NS_OK; |
|
2997 } |
|
2998 |
|
2999 NS_IMETHODIMP |
|
3000 CSSSupportsRule::SetCssText(const nsAString& aCssText) |
|
3001 { |
|
3002 return NS_ERROR_NOT_IMPLEMENTED; |
|
3003 } |
|
3004 |
|
3005 NS_IMETHODIMP |
|
3006 CSSSupportsRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet) |
|
3007 { |
|
3008 return css::GroupRule::GetParentStyleSheet(aSheet); |
|
3009 } |
|
3010 |
|
3011 NS_IMETHODIMP |
|
3012 CSSSupportsRule::GetParentRule(nsIDOMCSSRule** aParentRule) |
|
3013 { |
|
3014 return css::GroupRule::GetParentRule(aParentRule); |
|
3015 } |
|
3016 |
|
3017 // nsIDOMCSSGroupingRule methods |
|
3018 NS_IMETHODIMP |
|
3019 CSSSupportsRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList) |
|
3020 { |
|
3021 return css::GroupRule::GetCssRules(aRuleList); |
|
3022 } |
|
3023 |
|
3024 NS_IMETHODIMP |
|
3025 CSSSupportsRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval) |
|
3026 { |
|
3027 return css::GroupRule::InsertRule(aRule, aIndex, _retval); |
|
3028 } |
|
3029 |
|
3030 NS_IMETHODIMP |
|
3031 CSSSupportsRule::DeleteRule(uint32_t aIndex) |
|
3032 { |
|
3033 return css::GroupRule::DeleteRule(aIndex); |
|
3034 } |
|
3035 |
|
3036 // nsIDOMCSSConditionRule methods |
|
3037 NS_IMETHODIMP |
|
3038 CSSSupportsRule::GetConditionText(nsAString& aConditionText) |
|
3039 { |
|
3040 aConditionText.Assign(mCondition); |
|
3041 return NS_OK; |
|
3042 } |
|
3043 |
|
3044 NS_IMETHODIMP |
|
3045 CSSSupportsRule::SetConditionText(const nsAString& aConditionText) |
|
3046 { |
|
3047 return NS_ERROR_NOT_IMPLEMENTED; |
|
3048 } |
|
3049 |
|
3050 /* virtual */ size_t |
|
3051 CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
3052 { |
|
3053 size_t n = aMallocSizeOf(this); |
|
3054 n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf); |
|
3055 n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf); |
|
3056 return n; |
|
3057 } |
|
3058 |
|
3059 } // namespace mozilla |
|
3060 |
|
3061 // Must be outside namespace |
|
3062 DOMCI_DATA(CSSSupportsRule, mozilla::CSSSupportsRule) |