Bumping manifests a=b2g-bump
[gecko.git] / layout / style / nsCSSRules.cpp
blob92e42fbf3f8d666277522cc605743b5833dbba45
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/. */
6 /* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
8 #include "mozilla/Attributes.h"
10 #include "nsCSSRules.h"
11 #include "nsCSSValue.h"
12 #include "mozilla/CSSStyleSheet.h"
13 #include "mozilla/MemoryReporting.h"
14 #include "mozilla/css/ImportRule.h"
15 #include "mozilla/css/NameSpaceRule.h"
17 #include "nsString.h"
18 #include "nsIAtom.h"
20 #include "nsCSSProps.h"
22 #include "nsCOMPtr.h"
23 #include "nsIDOMCSSStyleSheet.h"
24 #include "nsIMediaList.h"
25 #include "mozilla/dom/CSSRuleList.h"
26 #include "nsIDocument.h"
27 #include "nsPresContext.h"
29 #include "nsContentUtils.h"
30 #include "nsError.h"
31 #include "nsStyleUtil.h"
32 #include "mozilla/css/Declaration.h"
33 #include "nsCSSParser.h"
34 #include "nsDOMClassInfoID.h"
35 #include "mozilla/dom/CSSStyleDeclarationBinding.h"
36 #include "StyleRule.h"
37 #include "nsFont.h"
38 #include "nsIURI.h"
39 #include "mozAutoDocUpdate.h"
41 using namespace mozilla;
43 #define IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \
44 /* virtual */ nsIDOMCSSRule* class_::GetDOMRule() \
45 { return this; } \
46 /* virtual */ nsIDOMCSSRule* class_::GetExistingDOMRule() \
47 { return this; }
48 #define IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) \
49 /* virtual */ void class_::MapRuleInfoInto(nsRuleData* aRuleData) \
50 { NS_ABORT_IF_FALSE(false, "should not be called"); }
52 #define IMPL_STYLE_RULE_INHERIT(class_, super_) \
53 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \
54 IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_)
56 // base class for all rule types in a CSS style sheet
58 namespace mozilla {
59 namespace css {
61 CSSStyleSheet*
62 Rule::GetStyleSheet() const
64 if (!(mSheet & 0x1)) {
65 return reinterpret_cast<CSSStyleSheet*>(mSheet);
68 return nullptr;
71 nsHTMLCSSStyleSheet*
72 Rule::GetHTMLCSSStyleSheet() const
74 if (mSheet & 0x1) {
75 return reinterpret_cast<nsHTMLCSSStyleSheet*>(mSheet & ~uintptr_t(0x1));
78 return nullptr;
81 /* virtual */ void
82 Rule::SetStyleSheet(CSSStyleSheet* aSheet)
84 // We don't reference count this up reference. The style sheet
85 // will tell us when it's going away or when we're detached from
86 // it.
87 mSheet = reinterpret_cast<uintptr_t>(aSheet);
90 void
91 Rule::SetHTMLCSSStyleSheet(nsHTMLCSSStyleSheet* aSheet)
93 // We don't reference count this up reference. The style sheet
94 // will tell us when it's going away or when we're detached from
95 // it.
96 mSheet = reinterpret_cast<uintptr_t>(aSheet);
97 mSheet |= 0x1;
100 nsresult
101 Rule::GetParentRule(nsIDOMCSSRule** aParentRule)
103 if (mParentRule) {
104 NS_IF_ADDREF(*aParentRule = mParentRule->GetDOMRule());
105 } else {
106 *aParentRule = nullptr;
108 return NS_OK;
111 nsresult
112 Rule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
114 NS_ENSURE_ARG_POINTER(aSheet);
116 NS_IF_ADDREF(*aSheet = GetStyleSheet());
117 return NS_OK;
120 css::Rule*
121 Rule::GetCSSRule()
123 return this;
126 size_t
127 Rule::SizeOfCOMArrayElementIncludingThis(css::Rule* aElement,
128 MallocSizeOf aMallocSizeOf,
129 void* aData)
131 return aElement->SizeOfIncludingThis(aMallocSizeOf);
134 // -------------------------------
135 // Style Rule List for group rules
138 class GroupRuleRuleList MOZ_FINAL : public dom::CSSRuleList
140 public:
141 explicit GroupRuleRuleList(GroupRule *aGroupRule);
143 virtual CSSStyleSheet* GetParentObject() MOZ_OVERRIDE;
145 virtual nsIDOMCSSRule*
146 IndexedGetter(uint32_t aIndex, bool& aFound) MOZ_OVERRIDE;
147 virtual uint32_t
148 Length() MOZ_OVERRIDE;
150 void DropReference() { mGroupRule = nullptr; }
152 private:
153 ~GroupRuleRuleList();
155 private:
156 GroupRule* mGroupRule;
159 GroupRuleRuleList::GroupRuleRuleList(GroupRule *aGroupRule)
161 // Not reference counted to avoid circular references.
162 // The rule will tell us when its going away.
163 mGroupRule = aGroupRule;
166 GroupRuleRuleList::~GroupRuleRuleList()
170 CSSStyleSheet*
171 GroupRuleRuleList::GetParentObject()
173 if (!mGroupRule) {
174 return nullptr;
177 return mGroupRule->GetStyleSheet();
180 uint32_t
181 GroupRuleRuleList::Length()
183 if (!mGroupRule) {
184 return 0;
187 return AssertedCast<uint32_t>(mGroupRule->StyleRuleCount());
190 nsIDOMCSSRule*
191 GroupRuleRuleList::IndexedGetter(uint32_t aIndex, bool& aFound)
193 aFound = false;
195 if (mGroupRule) {
196 nsRefPtr<Rule> rule = mGroupRule->GetStyleRuleAt(aIndex);
197 if (rule) {
198 aFound = true;
199 return rule->GetDOMRule();
203 return nullptr;
206 } // namespace css
207 } // namespace mozilla
209 // -------------------------------------------
210 // CharsetRule
213 // Must be outside namespace
214 DOMCI_DATA(CSSCharsetRule, css::CharsetRule)
216 namespace mozilla {
217 namespace css {
219 CharsetRule::CharsetRule(const nsAString& aEncoding,
220 uint32_t aLineNumber, uint32_t aColumnNumber)
221 : Rule(aLineNumber, aColumnNumber),
222 mEncoding(aEncoding)
226 CharsetRule::CharsetRule(const CharsetRule& aCopy)
227 : Rule(aCopy),
228 mEncoding(aCopy.mEncoding)
232 NS_IMPL_ADDREF(CharsetRule)
233 NS_IMPL_RELEASE(CharsetRule)
235 // QueryInterface implementation for CharsetRule
236 NS_INTERFACE_MAP_BEGIN(CharsetRule)
237 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
238 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
239 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCharsetRule)
240 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
241 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSCharsetRule)
242 NS_INTERFACE_MAP_END
244 IMPL_STYLE_RULE_INHERIT(CharsetRule, Rule)
246 #ifdef DEBUG
247 /* virtual */ void
248 CharsetRule::List(FILE* out, int32_t aIndent) const
250 // Indent
251 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
253 fputs("@charset \"", out);
254 fputs(NS_LossyConvertUTF16toASCII(mEncoding).get(), out);
255 fputs("\"\n", out);
257 #endif
259 /* virtual */ int32_t
260 CharsetRule::GetType() const
262 return Rule::CHARSET_RULE;
265 /* virtual */ already_AddRefed<Rule>
266 CharsetRule::Clone() const
268 nsRefPtr<Rule> clone = new CharsetRule(*this);
269 return clone.forget();
272 NS_IMETHODIMP
273 CharsetRule::GetEncoding(nsAString& aEncoding)
275 aEncoding = mEncoding;
276 return NS_OK;
279 NS_IMETHODIMP
280 CharsetRule::SetEncoding(const nsAString& aEncoding)
282 mEncoding = aEncoding;
283 return NS_OK;
286 NS_IMETHODIMP
287 CharsetRule::GetType(uint16_t* aType)
289 *aType = nsIDOMCSSRule::CHARSET_RULE;
290 return NS_OK;
293 NS_IMETHODIMP
294 CharsetRule::GetCssText(nsAString& aCssText)
296 aCssText.AssignLiteral("@charset \"");
297 aCssText.Append(mEncoding);
298 aCssText.AppendLiteral("\";");
299 return NS_OK;
302 NS_IMETHODIMP
303 CharsetRule::SetCssText(const nsAString& aCssText)
305 return NS_ERROR_NOT_IMPLEMENTED;
308 NS_IMETHODIMP
309 CharsetRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
311 return Rule::GetParentStyleSheet(aSheet);
314 NS_IMETHODIMP
315 CharsetRule::GetParentRule(nsIDOMCSSRule** aParentRule)
317 return Rule::GetParentRule(aParentRule);
320 css::Rule*
321 CharsetRule::GetCSSRule()
323 return Rule::GetCSSRule();
326 /* virtual */ size_t
327 CharsetRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
329 return aMallocSizeOf(this);
331 // Measurement of the following members may be added later if DMD finds it is
332 // worthwhile:
333 // - mEncoding
336 // -------------------------------------------
337 // ImportRule
340 ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
341 uint32_t aLineNumber, uint32_t aColumnNumber)
342 : Rule(aLineNumber, aColumnNumber)
343 , mURLSpec(aURLSpec)
344 , mMedia(aMedia)
346 // XXXbz This is really silly.... the mMedia here will be replaced
347 // with itself if we manage to load a sheet. Which should really
348 // never fail nowadays, in sane cases.
351 ImportRule::ImportRule(const ImportRule& aCopy)
352 : Rule(aCopy),
353 mURLSpec(aCopy.mURLSpec)
355 // Whether or not an @import rule has a null sheet is a permanent
356 // property of that @import rule, since it is null only if the target
357 // sheet failed security checks.
358 if (aCopy.mChildSheet) {
359 nsRefPtr<CSSStyleSheet> sheet =
360 aCopy.mChildSheet->Clone(nullptr, this, nullptr, nullptr);
361 SetSheet(sheet);
362 // SetSheet sets mMedia appropriately
366 ImportRule::~ImportRule()
368 if (mChildSheet) {
369 mChildSheet->SetOwnerRule(nullptr);
373 NS_IMPL_ADDREF(ImportRule)
374 NS_IMPL_RELEASE(ImportRule)
376 // QueryInterface implementation for ImportRule
377 NS_INTERFACE_MAP_BEGIN(ImportRule)
378 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
379 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
380 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule)
381 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
382 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSImportRule)
383 NS_INTERFACE_MAP_END
385 IMPL_STYLE_RULE_INHERIT(ImportRule, Rule)
387 #ifdef DEBUG
388 /* virtual */ void
389 ImportRule::List(FILE* out, int32_t aIndent) const
391 // Indent
392 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
394 fputs("@import \"", out);
395 fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out);
396 fputs("\" ", out);
398 nsAutoString mediaText;
399 mMedia->GetText(mediaText);
400 fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out);
401 fputs("\n", out);
403 #endif
405 /* virtual */ int32_t
406 ImportRule::GetType() const
408 return Rule::IMPORT_RULE;
411 /* virtual */ already_AddRefed<Rule>
412 ImportRule::Clone() const
414 nsRefPtr<Rule> clone = new ImportRule(*this);
415 return clone.forget();
418 void
419 ImportRule::SetSheet(CSSStyleSheet* aSheet)
421 NS_PRECONDITION(aSheet, "null arg");
423 // set the new sheet
424 mChildSheet = aSheet;
425 aSheet->SetOwnerRule(this);
427 // set our medialist to be the same as the sheet's medialist
428 mMedia = mChildSheet->Media();
431 NS_IMETHODIMP
432 ImportRule::GetType(uint16_t* aType)
434 NS_ENSURE_ARG_POINTER(aType);
435 *aType = nsIDOMCSSRule::IMPORT_RULE;
436 return NS_OK;
439 NS_IMETHODIMP
440 ImportRule::GetCssText(nsAString& aCssText)
442 aCssText.AssignLiteral("@import url(");
443 nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText);
444 aCssText.Append(')');
445 if (mMedia) {
446 nsAutoString mediaText;
447 mMedia->GetText(mediaText);
448 if (!mediaText.IsEmpty()) {
449 aCssText.Append(' ');
450 aCssText.Append(mediaText);
453 aCssText.Append(';');
454 return NS_OK;
457 NS_IMETHODIMP
458 ImportRule::SetCssText(const nsAString& aCssText)
460 return NS_ERROR_NOT_IMPLEMENTED;
463 NS_IMETHODIMP
464 ImportRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
466 return Rule::GetParentStyleSheet(aSheet);
469 NS_IMETHODIMP
470 ImportRule::GetParentRule(nsIDOMCSSRule** aParentRule)
472 return Rule::GetParentRule(aParentRule);
475 css::Rule*
476 ImportRule::GetCSSRule()
478 return Rule::GetCSSRule();
481 NS_IMETHODIMP
482 ImportRule::GetHref(nsAString & aHref)
484 aHref = mURLSpec;
485 return NS_OK;
488 NS_IMETHODIMP
489 ImportRule::GetMedia(nsIDOMMediaList * *aMedia)
491 NS_ENSURE_ARG_POINTER(aMedia);
493 NS_IF_ADDREF(*aMedia = mMedia);
494 return NS_OK;
497 NS_IMETHODIMP
498 ImportRule::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
500 NS_ENSURE_ARG_POINTER(aStyleSheet);
502 NS_IF_ADDREF(*aStyleSheet = mChildSheet);
503 return NS_OK;
506 /* virtual */ size_t
507 ImportRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
509 return aMallocSizeOf(this);
511 // Measurement of the following members may be added later if DMD finds it is
512 // worthwhile:
513 // - mURLSpec
515 // The following members are not measured:
516 // - mMedia, because it is measured via CSSStyleSheet::mMedia
517 // - mChildSheet, because it is measured via CSSStyleSheetInner::mSheets
520 } // namespace css
521 } // namespace mozilla
523 // must be outside the namespace
524 DOMCI_DATA(CSSImportRule, css::ImportRule)
526 namespace mozilla {
527 namespace css {
529 GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
530 : Rule(aLineNumber, aColumnNumber)
534 static bool
535 SetParentRuleReference(Rule* aRule, void* aParentRule)
537 GroupRule* parentRule = static_cast<GroupRule*>(aParentRule);
538 aRule->SetParentRule(parentRule);
539 return true;
542 GroupRule::GroupRule(const GroupRule& aCopy)
543 : Rule(aCopy)
545 const_cast<GroupRule&>(aCopy).mRules.EnumerateForwards(GroupRule::CloneRuleInto, &mRules);
546 mRules.EnumerateForwards(SetParentRuleReference, this);
549 GroupRule::~GroupRule()
551 NS_ABORT_IF_FALSE(!mSheet, "SetStyleSheet should have been called");
552 mRules.EnumerateForwards(SetParentRuleReference, nullptr);
553 if (mRuleCollection) {
554 mRuleCollection->DropReference();
558 NS_IMPL_CYCLE_COLLECTING_ADDREF(GroupRule)
559 NS_IMPL_CYCLE_COLLECTING_RELEASE(GroupRule)
561 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule)
562 NS_INTERFACE_MAP_END
564 IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(GroupRule, Rule)
566 static bool
567 SetStyleSheetReference(Rule* aRule, void* aSheet)
569 CSSStyleSheet* sheet = (CSSStyleSheet*)aSheet;
570 aRule->SetStyleSheet(sheet);
571 return true;
574 NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule)
576 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(GroupRule)
577 tmp->mRules.EnumerateForwards(SetParentRuleReference, nullptr);
578 // If tmp does not have a stylesheet, neither do its descendants. In that
579 // case, don't try to null out their stylesheet, to avoid O(N^2) behavior in
580 // depth of group rule nesting. But if tmp _does_ have a stylesheet (which
581 // can happen if it gets unlinked earlier than its owning stylesheet), then we
582 // need to null out the stylesheet pointer on descendants now, before we clear
583 // tmp->mRules.
584 if (tmp->GetStyleSheet()) {
585 tmp->mRules.EnumerateForwards(SetStyleSheetReference, nullptr);
587 tmp->mRules.Clear();
588 if (tmp->mRuleCollection) {
589 tmp->mRuleCollection->DropReference();
590 tmp->mRuleCollection = nullptr;
592 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
594 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(GroupRule)
595 const nsCOMArray<Rule>& rules = tmp->mRules;
596 for (int32_t i = 0, count = rules.Count(); i < count; ++i) {
597 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
598 cb.NoteXPCOMChild(rules[i]->GetExistingDOMRule());
600 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRuleCollection)
601 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
603 /* virtual */ void
604 GroupRule::SetStyleSheet(CSSStyleSheet* aSheet)
606 // Don't set the sheet on the kids if it's already the same as the sheet we
607 // already have. This is needed to avoid O(N^2) behavior in group nesting
608 // depth when seting the sheet to null during unlink, if we happen to unlin in
609 // order from most nested rule up to least nested rule.
610 if (aSheet != GetStyleSheet()) {
611 mRules.EnumerateForwards(SetStyleSheetReference, aSheet);
612 Rule::SetStyleSheet(aSheet);
616 #ifdef DEBUG
617 /* virtual */ void
618 GroupRule::List(FILE* out, int32_t aIndent) const
620 fputs(" {\n", out);
622 for (int32_t index = 0, count = mRules.Count(); index < count; ++index) {
623 mRules.ObjectAt(index)->List(out, aIndent + 1);
626 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
627 fputs("}\n", out);
629 #endif
631 void
632 GroupRule::AppendStyleRule(Rule* aRule)
634 mRules.AppendObject(aRule);
635 CSSStyleSheet* sheet = GetStyleSheet();
636 aRule->SetStyleSheet(sheet);
637 aRule->SetParentRule(this);
638 if (sheet) {
639 sheet->SetModifiedByChildRule();
643 Rule*
644 GroupRule::GetStyleRuleAt(int32_t aIndex) const
646 return mRules.SafeObjectAt(aIndex);
649 bool
650 GroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const
652 return
653 const_cast<GroupRule*>(this)->mRules.EnumerateForwards(aFunc, aData);
657 * The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt)
658 * should never be called unless you have first called WillDirty() on
659 * the parents stylesheet. After they are called, DidDirty() needs to
660 * be called on the sheet
662 nsresult
663 GroupRule::DeleteStyleRuleAt(uint32_t aIndex)
665 Rule* rule = mRules.SafeObjectAt(aIndex);
666 if (rule) {
667 rule->SetStyleSheet(nullptr);
668 rule->SetParentRule(nullptr);
670 return mRules.RemoveObjectAt(aIndex) ? NS_OK : NS_ERROR_ILLEGAL_VALUE;
673 nsresult
674 GroupRule::InsertStyleRuleAt(uint32_t aIndex, Rule* aRule)
676 aRule->SetStyleSheet(GetStyleSheet());
677 aRule->SetParentRule(this);
678 if (! mRules.InsertObjectAt(aRule, aIndex)) {
679 return NS_ERROR_FAILURE;
681 return NS_OK;
684 nsresult
685 GroupRule::ReplaceStyleRule(Rule* aOld, Rule* aNew)
687 int32_t index = mRules.IndexOf(aOld);
688 NS_ENSURE_TRUE(index != -1, NS_ERROR_UNEXPECTED);
689 mRules.ReplaceObjectAt(aNew, index);
690 aNew->SetStyleSheet(GetStyleSheet());
691 aNew->SetParentRule(this);
692 aOld->SetStyleSheet(nullptr);
693 aOld->SetParentRule(nullptr);
694 return NS_OK;
697 void
698 GroupRule::AppendRulesToCssText(nsAString& aCssText)
700 aCssText.AppendLiteral(" {\n");
702 // get all the rules
703 for (int32_t index = 0, count = mRules.Count(); index < count; ++index) {
704 Rule* rule = mRules.ObjectAt(index);
705 nsIDOMCSSRule* domRule = rule->GetDOMRule();
706 if (domRule) {
707 nsAutoString cssText;
708 domRule->GetCssText(cssText);
709 aCssText.AppendLiteral(" ");
710 aCssText.Append(cssText);
711 aCssText.Append('\n');
715 aCssText.Append('}');
718 // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
719 nsresult
720 GroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
722 if (!mRuleCollection) {
723 mRuleCollection = new css::GroupRuleRuleList(this);
726 NS_ADDREF(*aRuleList = mRuleCollection);
727 return NS_OK;
730 nsresult
731 GroupRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
733 CSSStyleSheet* sheet = GetStyleSheet();
734 NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
736 if (aIndex > uint32_t(mRules.Count()))
737 return NS_ERROR_DOM_INDEX_SIZE_ERR;
739 NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX,
740 "Too many style rules!");
742 return sheet->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
745 nsresult
746 GroupRule::DeleteRule(uint32_t aIndex)
748 CSSStyleSheet* sheet = GetStyleSheet();
749 NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
751 if (aIndex >= uint32_t(mRules.Count()))
752 return NS_ERROR_DOM_INDEX_SIZE_ERR;
754 NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX,
755 "Too many style rules!");
757 return sheet->DeleteRuleFromGroup(this, aIndex);
760 /* virtual */ size_t
761 GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
763 return mRules.SizeOfExcludingThis(Rule::SizeOfCOMArrayElementIncludingThis,
764 aMallocSizeOf);
766 // Measurement of the following members may be added later if DMD finds it is
767 // worthwhile:
768 // - mRuleCollection
772 // -------------------------------------------
773 // nsICSSMediaRule
775 MediaRule::MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber)
776 : GroupRule(aLineNumber, aColumnNumber)
780 MediaRule::MediaRule(const MediaRule& aCopy)
781 : GroupRule(aCopy)
783 if (aCopy.mMedia) {
784 mMedia = aCopy.mMedia->Clone();
785 // XXXldb This doesn't really make sense.
786 mMedia->SetStyleSheet(aCopy.GetStyleSheet());
790 MediaRule::~MediaRule()
792 if (mMedia) {
793 mMedia->SetStyleSheet(nullptr);
797 NS_IMPL_ADDREF_INHERITED(MediaRule, GroupRule)
798 NS_IMPL_RELEASE_INHERITED(MediaRule, GroupRule)
800 // QueryInterface implementation for MediaRule
801 NS_INTERFACE_MAP_BEGIN(MediaRule)
802 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
803 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
804 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
805 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
806 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
807 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
808 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMediaRule)
809 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
811 /* virtual */ void
812 MediaRule::SetStyleSheet(CSSStyleSheet* aSheet)
814 if (mMedia) {
815 // Set to null so it knows it's leaving one sheet and joining another.
816 mMedia->SetStyleSheet(nullptr);
817 mMedia->SetStyleSheet(aSheet);
820 GroupRule::SetStyleSheet(aSheet);
823 #ifdef DEBUG
824 /* virtual */ void
825 MediaRule::List(FILE* out, int32_t aIndent) const
827 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
829 nsAutoString buffer;
831 fputs("@media ", out);
833 if (mMedia) {
834 nsAutoString mediaText;
835 mMedia->GetText(mediaText);
836 fputs(NS_LossyConvertUTF16toASCII(mediaText).get(), out);
839 GroupRule::List(out, aIndent);
841 #endif
843 /* virtual */ int32_t
844 MediaRule::GetType() const
846 return Rule::MEDIA_RULE;
849 /* virtual */ already_AddRefed<Rule>
850 MediaRule::Clone() const
852 nsRefPtr<Rule> clone = new MediaRule(*this);
853 return clone.forget();
856 nsresult
857 MediaRule::SetMedia(nsMediaList* aMedia)
859 mMedia = aMedia;
860 if (aMedia)
861 mMedia->SetStyleSheet(GetStyleSheet());
862 return NS_OK;
865 // nsIDOMCSSRule methods
866 NS_IMETHODIMP
867 MediaRule::GetType(uint16_t* aType)
869 *aType = nsIDOMCSSRule::MEDIA_RULE;
870 return NS_OK;
873 NS_IMETHODIMP
874 MediaRule::GetCssText(nsAString& aCssText)
876 aCssText.AssignLiteral("@media ");
877 AppendConditionText(aCssText);
878 GroupRule::AppendRulesToCssText(aCssText);
879 return NS_OK;
882 NS_IMETHODIMP
883 MediaRule::SetCssText(const nsAString& aCssText)
885 return NS_ERROR_NOT_IMPLEMENTED;
888 NS_IMETHODIMP
889 MediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
891 return GroupRule::GetParentStyleSheet(aSheet);
894 NS_IMETHODIMP
895 MediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
897 return GroupRule::GetParentRule(aParentRule);
900 css::Rule*
901 MediaRule::GetCSSRule()
903 return Rule::GetCSSRule();
906 // nsIDOMCSSGroupingRule methods
907 NS_IMETHODIMP
908 MediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
910 return GroupRule::GetCssRules(aRuleList);
913 NS_IMETHODIMP
914 MediaRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
916 return GroupRule::InsertRule(aRule, aIndex, _retval);
919 NS_IMETHODIMP
920 MediaRule::DeleteRule(uint32_t aIndex)
922 return GroupRule::DeleteRule(aIndex);
925 // nsIDOMCSSConditionRule methods
926 NS_IMETHODIMP
927 MediaRule::GetConditionText(nsAString& aConditionText)
929 aConditionText.Truncate(0);
930 AppendConditionText(aConditionText);
931 return NS_OK;
934 NS_IMETHODIMP
935 MediaRule::SetConditionText(const nsAString& aConditionText)
937 if (!mMedia) {
938 nsRefPtr<nsMediaList> media = new nsMediaList();
939 media->SetStyleSheet(GetStyleSheet());
940 nsresult rv = media->SetMediaText(aConditionText);
941 if (NS_SUCCEEDED(rv)) {
942 mMedia = media;
944 return rv;
947 return mMedia->SetMediaText(aConditionText);
950 // nsIDOMCSSMediaRule methods
951 NS_IMETHODIMP
952 MediaRule::GetMedia(nsIDOMMediaList* *aMedia)
954 NS_ENSURE_ARG_POINTER(aMedia);
955 NS_IF_ADDREF(*aMedia = mMedia);
956 return NS_OK;
959 // GroupRule interface
960 /* virtual */ bool
961 MediaRule::UseForPresentation(nsPresContext* aPresContext,
962 nsMediaQueryResultCacheKey& aKey)
964 if (mMedia) {
965 return mMedia->Matches(aPresContext, &aKey);
967 return true;
970 /* virtual */ size_t
971 MediaRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
973 size_t n = aMallocSizeOf(this);
974 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
976 // Measurement of the following members may be added later if DMD finds it is
977 // worthwhile:
978 // - mMedia
980 return n;
983 void
984 MediaRule::AppendConditionText(nsAString& aOutput)
986 if (mMedia) {
987 nsAutoString mediaText;
988 mMedia->GetText(mediaText);
989 aOutput.Append(mediaText);
993 } // namespace css
994 } // namespace mozilla
996 // Must be outside namespace
997 DOMCI_DATA(CSSMediaRule, css::MediaRule)
999 namespace mozilla {
1000 namespace css {
1002 DocumentRule::DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber)
1003 : GroupRule(aLineNumber, aColumnNumber)
1007 DocumentRule::DocumentRule(const DocumentRule& aCopy)
1008 : GroupRule(aCopy)
1009 , mURLs(new URL(*aCopy.mURLs))
1013 DocumentRule::~DocumentRule()
1017 NS_IMPL_ADDREF_INHERITED(DocumentRule, GroupRule)
1018 NS_IMPL_RELEASE_INHERITED(DocumentRule, GroupRule)
1020 // QueryInterface implementation for DocumentRule
1021 NS_INTERFACE_MAP_BEGIN(DocumentRule)
1022 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1023 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1024 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
1025 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
1026 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
1027 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
1028 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMozDocumentRule)
1029 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
1031 #ifdef DEBUG
1032 /* virtual */ void
1033 DocumentRule::List(FILE* out, int32_t aIndent) const
1035 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
1037 nsAutoCString str;
1038 str.AssignLiteral("@-moz-document ");
1039 for (URL *url = mURLs; url; url = url->next) {
1040 switch (url->func) {
1041 case eURL:
1042 str.AppendLiteral("url(\"");
1043 break;
1044 case eURLPrefix:
1045 str.AppendLiteral("url-prefix(\"");
1046 break;
1047 case eDomain:
1048 str.AppendLiteral("domain(\"");
1049 break;
1050 case eRegExp:
1051 str.AppendLiteral("regexp(\"");
1052 break;
1054 nsAutoCString escapedURL(url->url);
1055 escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
1056 str.Append(escapedURL);
1057 str.AppendLiteral("\"), ");
1059 str.Cut(str.Length() - 2, 1); // remove last ,
1060 fputs(str.get(), out);
1062 GroupRule::List(out, aIndent);
1064 #endif
1066 /* virtual */ int32_t
1067 DocumentRule::GetType() const
1069 return Rule::DOCUMENT_RULE;
1072 /* virtual */ already_AddRefed<Rule>
1073 DocumentRule::Clone() const
1075 nsRefPtr<Rule> clone = new DocumentRule(*this);
1076 return clone.forget();
1079 // nsIDOMCSSRule methods
1080 NS_IMETHODIMP
1081 DocumentRule::GetType(uint16_t* aType)
1083 // XXX What should really happen here?
1084 *aType = nsIDOMCSSRule::UNKNOWN_RULE;
1085 return NS_OK;
1088 NS_IMETHODIMP
1089 DocumentRule::GetCssText(nsAString& aCssText)
1091 aCssText.AssignLiteral("@-moz-document ");
1092 AppendConditionText(aCssText);
1093 GroupRule::AppendRulesToCssText(aCssText);
1094 return NS_OK;
1097 NS_IMETHODIMP
1098 DocumentRule::SetCssText(const nsAString& aCssText)
1100 return NS_ERROR_NOT_IMPLEMENTED;
1103 NS_IMETHODIMP
1104 DocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1106 return GroupRule::GetParentStyleSheet(aSheet);
1109 NS_IMETHODIMP
1110 DocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1112 return GroupRule::GetParentRule(aParentRule);
1115 css::Rule*
1116 DocumentRule::GetCSSRule()
1118 return Rule::GetCSSRule();
1121 // nsIDOMCSSGroupingRule methods
1122 NS_IMETHODIMP
1123 DocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
1125 return GroupRule::GetCssRules(aRuleList);
1128 NS_IMETHODIMP
1129 DocumentRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
1131 return GroupRule::InsertRule(aRule, aIndex, _retval);
1134 NS_IMETHODIMP
1135 DocumentRule::DeleteRule(uint32_t aIndex)
1137 return GroupRule::DeleteRule(aIndex);
1140 // nsIDOMCSSConditionRule methods
1141 NS_IMETHODIMP
1142 DocumentRule::GetConditionText(nsAString& aConditionText)
1144 aConditionText.Truncate(0);
1145 AppendConditionText(aConditionText);
1146 return NS_OK;
1149 NS_IMETHODIMP
1150 DocumentRule::SetConditionText(const nsAString& aConditionText)
1152 return NS_ERROR_NOT_IMPLEMENTED;
1155 // GroupRule interface
1156 /* virtual */ bool
1157 DocumentRule::UseForPresentation(nsPresContext* aPresContext,
1158 nsMediaQueryResultCacheKey& aKey)
1160 nsIDocument *doc = aPresContext->Document();
1161 nsIURI *docURI = doc->GetDocumentURI();
1162 nsAutoCString docURISpec;
1163 if (docURI)
1164 docURI->GetSpec(docURISpec);
1166 for (URL *url = mURLs; url; url = url->next) {
1167 switch (url->func) {
1168 case eURL: {
1169 if (docURISpec == url->url)
1170 return true;
1171 } break;
1172 case eURLPrefix: {
1173 if (StringBeginsWith(docURISpec, url->url))
1174 return true;
1175 } break;
1176 case eDomain: {
1177 nsAutoCString host;
1178 if (docURI)
1179 docURI->GetHost(host);
1180 int32_t lenDiff = host.Length() - url->url.Length();
1181 if (lenDiff == 0) {
1182 if (host == url->url)
1183 return true;
1184 } else {
1185 if (StringEndsWith(host, url->url) &&
1186 host.CharAt(lenDiff - 1) == '.')
1187 return true;
1189 } break;
1190 case eRegExp: {
1191 NS_ConvertUTF8toUTF16 spec(docURISpec);
1192 NS_ConvertUTF8toUTF16 regex(url->url);
1193 if (nsContentUtils::IsPatternMatching(spec, regex, doc)) {
1194 return true;
1196 } break;
1200 return false;
1203 DocumentRule::URL::~URL()
1205 NS_CSS_DELETE_LIST_MEMBER(DocumentRule::URL, this, next);
1208 /* virtual */ size_t
1209 DocumentRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
1211 size_t n = aMallocSizeOf(this);
1212 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
1214 // Measurement of the following members may be added later if DMD finds it is
1215 // worthwhile:
1216 // - mURLs
1218 return n;
1221 void
1222 DocumentRule::AppendConditionText(nsAString& aCssText)
1224 for (URL *url = mURLs; url; url = url->next) {
1225 switch (url->func) {
1226 case eURL:
1227 aCssText.AppendLiteral("url(");
1228 break;
1229 case eURLPrefix:
1230 aCssText.AppendLiteral("url-prefix(");
1231 break;
1232 case eDomain:
1233 aCssText.AppendLiteral("domain(");
1234 break;
1235 case eRegExp:
1236 aCssText.AppendLiteral("regexp(");
1237 break;
1239 nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url),
1240 aCssText);
1241 aCssText.AppendLiteral("), ");
1243 aCssText.Truncate(aCssText.Length() - 2); // remove last ", "
1246 } // namespace css
1247 } // namespace mozilla
1249 // Must be outside namespace
1250 DOMCI_DATA(CSSMozDocumentRule, css::DocumentRule)
1252 // -------------------------------------------
1253 // NameSpaceRule
1256 namespace mozilla {
1257 namespace css {
1259 NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec,
1260 uint32_t aLineNumber, uint32_t aColumnNumber)
1261 : Rule(aLineNumber, aColumnNumber),
1262 mPrefix(aPrefix),
1263 mURLSpec(aURLSpec)
1267 NameSpaceRule::NameSpaceRule(const NameSpaceRule& aCopy)
1268 : Rule(aCopy),
1269 mPrefix(aCopy.mPrefix),
1270 mURLSpec(aCopy.mURLSpec)
1274 NameSpaceRule::~NameSpaceRule()
1278 NS_IMPL_ADDREF(NameSpaceRule)
1279 NS_IMPL_RELEASE(NameSpaceRule)
1281 // QueryInterface implementation for NameSpaceRule
1282 NS_INTERFACE_MAP_BEGIN(NameSpaceRule)
1283 if (aIID.Equals(NS_GET_IID(css::NameSpaceRule))) {
1284 *aInstancePtr = this;
1285 NS_ADDREF_THIS();
1286 return NS_OK;
1288 else
1289 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1290 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1291 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
1292 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSNameSpaceRule)
1293 NS_INTERFACE_MAP_END
1295 IMPL_STYLE_RULE_INHERIT(NameSpaceRule, Rule)
1297 #ifdef DEBUG
1298 /* virtual */ void
1299 NameSpaceRule::List(FILE* out, int32_t aIndent) const
1301 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
1303 nsAutoString buffer;
1305 fputs("@namespace ", out);
1307 if (mPrefix) {
1308 mPrefix->ToString(buffer);
1309 fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
1310 fputs(" ", out);
1313 fputs("url(", out);
1314 fputs(NS_LossyConvertUTF16toASCII(mURLSpec).get(), out);
1315 fputs(")\n", out);
1317 #endif
1319 /* virtual */ int32_t
1320 NameSpaceRule::GetType() const
1322 return Rule::NAMESPACE_RULE;
1325 /* virtual */ already_AddRefed<Rule>
1326 NameSpaceRule::Clone() const
1328 nsRefPtr<Rule> clone = new NameSpaceRule(*this);
1329 return clone.forget();
1332 NS_IMETHODIMP
1333 NameSpaceRule::GetType(uint16_t* aType)
1335 *aType = nsIDOMCSSRule::NAMESPACE_RULE;
1336 return NS_OK;
1339 NS_IMETHODIMP
1340 NameSpaceRule::GetCssText(nsAString& aCssText)
1342 aCssText.AssignLiteral("@namespace ");
1343 if (mPrefix) {
1344 aCssText.Append(nsDependentAtomString(mPrefix) + NS_LITERAL_STRING(" "));
1346 aCssText.AppendLiteral("url(");
1347 nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText);
1348 aCssText.AppendLiteral(");");
1349 return NS_OK;
1352 NS_IMETHODIMP
1353 NameSpaceRule::SetCssText(const nsAString& aCssText)
1355 return NS_ERROR_NOT_IMPLEMENTED;
1358 NS_IMETHODIMP
1359 NameSpaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1361 return Rule::GetParentStyleSheet(aSheet);
1364 NS_IMETHODIMP
1365 NameSpaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1367 return Rule::GetParentRule(aParentRule);
1370 css::Rule*
1371 NameSpaceRule::GetCSSRule()
1373 return Rule::GetCSSRule();
1376 /* virtual */ size_t
1377 NameSpaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
1379 return aMallocSizeOf(this);
1381 // Measurement of the following members may be added later if DMD finds it is
1382 // worthwhile:
1383 // - mPrefix
1384 // - mURLSpec
1388 } // namespace css
1389 } // namespace mozilla
1391 // Must be outside namespace
1392 DOMCI_DATA(CSSNameSpaceRule, css::NameSpaceRule)
1394 // -------------------------------------------
1395 // nsCSSFontFaceStyleDecl and related routines
1398 // A src: descriptor is represented as an array value; each entry in
1399 // the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or
1400 // eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear
1401 // only after one of the first two. (css3-fonts only contemplates
1402 // annotating URLs with formats, but we handle the general case.)
1403 static void
1404 AppendSerializedFontSrc(const nsCSSValue& src, nsAString & aResult)
1406 NS_PRECONDITION(src.GetUnit() == eCSSUnit_Array,
1407 "improper value unit for src:");
1409 const nsCSSValue::Array& sources = *src.GetArrayValue();
1410 size_t i = 0;
1412 while (i < sources.Count()) {
1413 nsAutoString formats;
1415 if (sources[i].GetUnit() == eCSSUnit_URL) {
1416 aResult.AppendLiteral("url(");
1417 nsDependentString url(sources[i].GetOriginalURLValue());
1418 nsStyleUtil::AppendEscapedCSSString(url, aResult);
1419 aResult.Append(')');
1420 } else if (sources[i].GetUnit() == eCSSUnit_Local_Font) {
1421 aResult.AppendLiteral("local(");
1422 nsDependentString local(sources[i].GetStringBufferValue());
1423 nsStyleUtil::AppendEscapedCSSString(local, aResult);
1424 aResult.Append(')');
1425 } else {
1426 NS_NOTREACHED("entry in src: descriptor with improper unit");
1427 i++;
1428 continue;
1431 i++;
1432 formats.Truncate();
1433 while (i < sources.Count() &&
1434 sources[i].GetUnit() == eCSSUnit_Font_Format) {
1435 formats.Append('"');
1436 formats.Append(sources[i].GetStringBufferValue());
1437 formats.AppendLiteral("\", ");
1438 i++;
1440 if (formats.Length() > 0) {
1441 formats.Truncate(formats.Length() - 2); // remove the last comma
1442 aResult.AppendLiteral(" format(");
1443 aResult.Append(formats);
1444 aResult.Append(')');
1446 aResult.AppendLiteral(", ");
1448 aResult.Truncate(aResult.Length() - 2); // remove the last comma-space
1451 // Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields.
1452 nsCSSValue nsCSSFontFaceStyleDecl::* const
1453 nsCSSFontFaceStyleDecl::Fields[] = {
1454 #define CSS_FONT_DESC(name_, method_) &nsCSSFontFaceStyleDecl::m##method_,
1455 #include "nsCSSFontDescList.h"
1456 #undef CSS_FONT_DESC
1459 // QueryInterface implementation for nsCSSFontFaceStyleDecl
1460 NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl)
1461 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
1462 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
1463 NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
1464 NS_INTERFACE_MAP_ENTRY(nsISupports)
1465 // We forward the cycle collection interfaces to ContainingRule(), which is
1466 // never null (in fact, we're part of that object!)
1467 if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
1468 aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
1469 return ContainingRule()->QueryInterface(aIID, aInstancePtr);
1471 else
1472 NS_INTERFACE_MAP_END
1474 NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
1475 NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
1477 // helper for string GetPropertyValue and RemovePropertyValue
1478 nsresult
1479 nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
1480 nsAString & aResult) const
1482 NS_ENSURE_ARG_RANGE(aFontDescID, eCSSFontDesc_UNKNOWN,
1483 eCSSFontDesc_COUNT - 1);
1485 aResult.Truncate();
1486 if (aFontDescID == eCSSFontDesc_UNKNOWN)
1487 return NS_OK;
1489 const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID];
1491 if (val.GetUnit() == eCSSUnit_Null) {
1492 // Avoid having to check no-value in the Family and Src cases below.
1493 return NS_OK;
1496 switch (aFontDescID) {
1497 case eCSSFontDesc_Family: {
1498 // we don't use nsCSSValue::AppendToString here because it doesn't
1499 // canonicalize the way we want, and anyway it's overkill when
1500 // we know we have eCSSUnit_String
1501 NS_ASSERTION(val.GetUnit() == eCSSUnit_String, "unexpected unit");
1502 nsDependentString family(val.GetStringBufferValue());
1503 nsStyleUtil::AppendEscapedCSSString(family, aResult);
1504 return NS_OK;
1507 case eCSSFontDesc_Style:
1508 val.AppendToString(eCSSProperty_font_style, aResult,
1509 nsCSSValue::eNormalized);
1510 return NS_OK;
1512 case eCSSFontDesc_Weight:
1513 val.AppendToString(eCSSProperty_font_weight, aResult,
1514 nsCSSValue::eNormalized);
1515 return NS_OK;
1517 case eCSSFontDesc_Stretch:
1518 val.AppendToString(eCSSProperty_font_stretch, aResult,
1519 nsCSSValue::eNormalized);
1520 return NS_OK;
1522 case eCSSFontDesc_FontFeatureSettings:
1523 nsStyleUtil::AppendFontFeatureSettings(val, aResult);
1524 return NS_OK;
1526 case eCSSFontDesc_FontLanguageOverride:
1527 val.AppendToString(eCSSProperty_font_language_override, aResult,
1528 nsCSSValue::eNormalized);
1529 return NS_OK;
1531 case eCSSFontDesc_Src:
1532 AppendSerializedFontSrc(val, aResult);
1533 return NS_OK;
1535 case eCSSFontDesc_UnicodeRange:
1536 nsStyleUtil::AppendUnicodeRange(val, aResult);
1537 return NS_OK;
1539 case eCSSFontDesc_UNKNOWN:
1540 case eCSSFontDesc_COUNT:
1543 NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: "
1544 "out-of-range value got to the switch");
1545 return NS_ERROR_INVALID_ARG;
1549 // attribute DOMString cssText;
1550 NS_IMETHODIMP
1551 nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText)
1553 nsAutoString descStr;
1555 aCssText.Truncate();
1556 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1557 id < eCSSFontDesc_COUNT;
1558 id = nsCSSFontDesc(id + 1)) {
1559 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1560 != eCSSUnit_Null &&
1561 NS_SUCCEEDED(GetPropertyValue(id, descStr))) {
1562 NS_ASSERTION(descStr.Length() > 0,
1563 "GetCssText: non-null unit, empty property value");
1564 aCssText.AppendLiteral(" ");
1565 aCssText.AppendASCII(nsCSSProps::GetStringValue(id).get());
1566 aCssText.AppendLiteral(": ");
1567 aCssText.Append(descStr);
1568 aCssText.AppendLiteral(";\n");
1571 return NS_OK;
1574 NS_IMETHODIMP
1575 nsCSSFontFaceStyleDecl::SetCssText(const nsAString & aCssText)
1577 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1580 // DOMString getPropertyValue (in DOMString propertyName);
1581 NS_IMETHODIMP
1582 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString & propertyName,
1583 nsAString & aResult)
1585 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult);
1588 NS_IMETHODIMP
1589 nsCSSFontFaceStyleDecl::GetAuthoredPropertyValue(const nsAString& propertyName,
1590 nsAString& aResult)
1592 // We don't return any authored property values different from
1593 // GetPropertyValue, currently.
1594 return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult);
1597 // nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName);
1598 already_AddRefed<dom::CSSValue>
1599 nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString & propertyName,
1600 ErrorResult& aRv)
1602 // ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong.
1603 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
1604 return nullptr;
1607 // DOMString removeProperty (in DOMString propertyName) raises (DOMException);
1608 NS_IMETHODIMP
1609 nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName,
1610 nsAString & aResult)
1612 nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(propertyName);
1613 NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN &&
1614 descID < eCSSFontDesc_COUNT,
1615 "LookupFontDesc returned value out of range");
1617 if (descID == eCSSFontDesc_UNKNOWN) {
1618 aResult.Truncate();
1619 } else {
1620 nsresult rv = GetPropertyValue(descID, aResult);
1621 NS_ENSURE_SUCCESS(rv, rv);
1622 (this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset();
1624 return NS_OK;
1627 // DOMString getPropertyPriority (in DOMString propertyName);
1628 NS_IMETHODIMP
1629 nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString & propertyName,
1630 nsAString & aResult)
1632 // font descriptors do not have priorities at present
1633 aResult.Truncate();
1634 return NS_OK;
1637 // void setProperty (in DOMString propertyName, in DOMString value,
1638 // in DOMString priority) raises (DOMException);
1639 NS_IMETHODIMP
1640 nsCSSFontFaceStyleDecl::SetProperty(const nsAString & propertyName,
1641 const nsAString & value,
1642 const nsAString & priority)
1644 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1647 // readonly attribute unsigned long length;
1648 NS_IMETHODIMP
1649 nsCSSFontFaceStyleDecl::GetLength(uint32_t *aLength)
1651 uint32_t len = 0;
1652 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1653 id < eCSSFontDesc_COUNT;
1654 id = nsCSSFontDesc(id + 1))
1655 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null)
1656 len++;
1658 *aLength = len;
1659 return NS_OK;
1662 // DOMString item (in unsigned long index);
1663 NS_IMETHODIMP
1664 nsCSSFontFaceStyleDecl::Item(uint32_t aIndex, nsAString& aReturn)
1666 bool found;
1667 IndexedGetter(aIndex, found, aReturn);
1668 if (!found) {
1669 aReturn.Truncate();
1671 return NS_OK;
1674 void
1675 nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString & aResult)
1677 int32_t nset = -1;
1678 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1679 id < eCSSFontDesc_COUNT;
1680 id = nsCSSFontDesc(id + 1)) {
1681 if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1682 != eCSSUnit_Null) {
1683 nset++;
1684 if (nset == int32_t(index)) {
1685 aFound = true;
1686 aResult.AssignASCII(nsCSSProps::GetStringValue(id).get());
1687 return;
1691 aFound = false;
1694 // readonly attribute nsIDOMCSSRule parentRule;
1695 NS_IMETHODIMP
1696 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule)
1698 NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule());
1699 return NS_OK;
1702 NS_IMETHODIMP
1703 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsCSSProperty aPropID,
1704 nsAString& aValue)
1706 return
1707 GetPropertyValue(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aPropID)),
1708 aValue);
1711 NS_IMETHODIMP
1712 nsCSSFontFaceStyleDecl::SetPropertyValue(const nsCSSProperty aPropID,
1713 const nsAString& aValue)
1715 return SetProperty(NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aPropID)),
1716 aValue, EmptyString());
1719 nsINode*
1720 nsCSSFontFaceStyleDecl::GetParentObject()
1722 return ContainingRule()->GetDocument();
1725 JSObject*
1726 nsCSSFontFaceStyleDecl::WrapObject(JSContext *cx)
1728 return mozilla::dom::CSSStyleDeclarationBinding::Wrap(cx, this);
1731 // -------------------------------------------
1732 // nsCSSFontFaceRule
1735 /* virtual */ already_AddRefed<css::Rule>
1736 nsCSSFontFaceRule::Clone() const
1738 nsRefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this);
1739 return clone.forget();
1742 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSFontFaceRule)
1743 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSFontFaceRule)
1745 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSFontFaceRule)
1747 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsCSSFontFaceRule)
1748 // Trace the wrapper for our declaration. This just expands out
1749 // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
1750 // directly because the wrapper is on the declaration, not on us.
1751 tmp->mDecl.TraceWrapper(aCallbacks, aClosure);
1752 NS_IMPL_CYCLE_COLLECTION_TRACE_END
1754 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSFontFaceRule)
1755 // Unlink the wrapper for our declaraton. This just expands out
1756 // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
1757 // directly because the wrapper is on the declaration, not on us.
1758 tmp->mDecl.ReleaseWrapper(static_cast<nsISupports*>(p));
1759 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
1761 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSFontFaceRule)
1762 // Just NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS here: that will call
1763 // into our Trace hook, where we do the right thing with declarations
1764 // already.
1765 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
1766 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
1768 DOMCI_DATA(CSSFontFaceRule, nsCSSFontFaceRule)
1770 // QueryInterface implementation for nsCSSFontFaceRule
1771 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSFontFaceRule)
1772 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1773 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule)
1774 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1775 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
1776 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceRule)
1777 NS_INTERFACE_MAP_END
1779 IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule, Rule)
1781 #ifdef DEBUG
1782 void
1783 nsCSSFontFaceRule::List(FILE* out, int32_t aIndent) const
1785 nsCString baseInd, descInd;
1786 for (int32_t indent = aIndent; --indent >= 0; ) {
1787 baseInd.AppendLiteral(" ");
1788 descInd.AppendLiteral(" ");
1790 descInd.AppendLiteral(" ");
1792 nsString descStr;
1794 fprintf(out, "%s@font-face {\n", baseInd.get());
1795 for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
1796 id < eCSSFontDesc_COUNT;
1797 id = nsCSSFontDesc(id + 1))
1798 if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
1799 != eCSSUnit_Null) {
1800 if (NS_FAILED(mDecl.GetPropertyValue(id, descStr)))
1801 descStr.AssignLiteral("#<serialization error>");
1802 else if (descStr.Length() == 0)
1803 descStr.AssignLiteral("#<serialization missing>");
1804 fprintf(out, "%s%s: %s\n",
1805 descInd.get(), nsCSSProps::GetStringValue(id).get(),
1806 NS_ConvertUTF16toUTF8(descStr).get());
1808 fprintf(out, "%s}\n", baseInd.get());
1810 #endif
1812 /* virtual */ int32_t
1813 nsCSSFontFaceRule::GetType() const
1815 return Rule::FONT_FACE_RULE;
1818 NS_IMETHODIMP
1819 nsCSSFontFaceRule::GetType(uint16_t* aType)
1821 *aType = nsIDOMCSSRule::FONT_FACE_RULE;
1822 return NS_OK;
1825 NS_IMETHODIMP
1826 nsCSSFontFaceRule::GetCssText(nsAString& aCssText)
1828 nsAutoString propText;
1829 mDecl.GetCssText(propText);
1831 aCssText.AssignLiteral("@font-face {\n");
1832 aCssText.Append(propText);
1833 aCssText.Append('}');
1834 return NS_OK;
1837 NS_IMETHODIMP
1838 nsCSSFontFaceRule::SetCssText(const nsAString& aCssText)
1840 return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
1843 NS_IMETHODIMP
1844 nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
1846 return Rule::GetParentStyleSheet(aSheet);
1849 NS_IMETHODIMP
1850 nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
1852 return Rule::GetParentRule(aParentRule);
1855 css::Rule*
1856 nsCSSFontFaceRule::GetCSSRule()
1858 return Rule::GetCSSRule();
1861 NS_IMETHODIMP
1862 nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
1864 NS_IF_ADDREF(*aStyle = &mDecl);
1865 return NS_OK;
1868 // Arguably these should forward to nsCSSFontFaceStyleDecl methods.
1869 void
1870 nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue)
1872 NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
1873 aDescID < eCSSFontDesc_COUNT,
1874 "aDescID out of range in nsCSSFontFaceRule::SetDesc");
1876 // FIXME: handle dynamic changes
1878 mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue;
1881 void
1882 nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue)
1884 NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
1885 aDescID < eCSSFontDesc_COUNT,
1886 "aDescID out of range in nsCSSFontFaceRule::GetDesc");
1888 aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID];
1891 /* virtual */ size_t
1892 nsCSSFontFaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
1894 return aMallocSizeOf(this);
1896 // Measurement of the following members may be added later if DMD finds it is
1897 // worthwhile:
1898 // - mDecl
1902 // -----------------------------------
1903 // nsCSSFontFeatureValuesRule
1906 /* virtual */ already_AddRefed<css::Rule>
1907 nsCSSFontFeatureValuesRule::Clone() const
1909 nsRefPtr<css::Rule> clone = new nsCSSFontFeatureValuesRule(*this);
1910 return clone.forget();
1913 NS_IMPL_ADDREF(nsCSSFontFeatureValuesRule)
1914 NS_IMPL_RELEASE(nsCSSFontFeatureValuesRule)
1916 DOMCI_DATA(CSSFontFeatureValuesRule, nsCSSFontFeatureValuesRule)
1918 // QueryInterface implementation for nsCSSFontFeatureValuesRule
1919 NS_INTERFACE_MAP_BEGIN(nsCSSFontFeatureValuesRule)
1920 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
1921 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
1922 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
1923 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
1924 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFeatureValuesRule)
1925 NS_INTERFACE_MAP_END
1927 IMPL_STYLE_RULE_INHERIT(nsCSSFontFeatureValuesRule, Rule)
1929 static void
1930 FeatureValuesToString(
1931 const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues,
1932 nsAString& aOutStr)
1934 uint32_t i, n;
1936 // append values
1937 n = aFeatureValues.Length();
1938 for (i = 0; i < n; i++) {
1939 const gfxFontFeatureValueSet::FeatureValues& fv = aFeatureValues[i];
1941 // @alternate
1942 aOutStr.AppendLiteral(" @");
1943 nsAutoString functAlt;
1944 nsStyleUtil::GetFunctionalAlternatesName(fv.alternate, functAlt);
1945 aOutStr.Append(functAlt);
1946 aOutStr.AppendLiteral(" {");
1948 // for each ident-values tuple
1949 uint32_t j, numValues = fv.valuelist.Length();
1950 for (j = 0; j < numValues; j++) {
1951 aOutStr.Append(' ');
1952 const gfxFontFeatureValueSet::ValueList& vlist = fv.valuelist[j];
1953 nsStyleUtil::AppendEscapedCSSIdent(vlist.name, aOutStr);
1954 aOutStr.Append(':');
1956 uint32_t k, numSelectors = vlist.featureSelectors.Length();
1957 for (k = 0; k < numSelectors; k++) {
1958 aOutStr.Append(' ');
1959 aOutStr.AppendInt(vlist.featureSelectors[k]);
1962 aOutStr.Append(';');
1964 aOutStr.AppendLiteral(" }\n");
1968 static void
1969 FontFeatureValuesRuleToString(
1970 const mozilla::FontFamilyList& aFamilyList,
1971 const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues,
1972 nsAString& aOutStr)
1974 aOutStr.AssignLiteral("@font-feature-values ");
1975 nsAutoString familyListStr, valueTextStr;
1976 nsStyleUtil::AppendEscapedCSSFontFamilyList(aFamilyList, familyListStr);
1977 aOutStr.Append(familyListStr);
1978 aOutStr.AppendLiteral(" {\n");
1979 FeatureValuesToString(aFeatureValues, valueTextStr);
1980 aOutStr.Append(valueTextStr);
1981 aOutStr.Append('}');
1984 #ifdef DEBUG
1985 void
1986 nsCSSFontFeatureValuesRule::List(FILE* out, int32_t aIndent) const
1988 nsAutoString text;
1989 FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, text);
1990 NS_ConvertUTF16toUTF8 utf8(text);
1992 // replace newlines with newlines plus indent spaces
1993 char* indent = new char[(aIndent + 1) * 2];
1994 int32_t i;
1995 for (i = 1; i < (aIndent + 1) * 2 - 1; i++) {
1996 indent[i] = 0x20;
1998 indent[0] = 0xa;
1999 indent[aIndent * 2 + 1] = 0;
2000 utf8.ReplaceSubstring("\n", indent);
2001 delete [] indent;
2003 for (i = aIndent; --i >= 0; ) fputs(" ", out);
2004 fprintf(out, "%s\n", utf8.get());
2006 #endif
2008 /* virtual */ int32_t
2009 nsCSSFontFeatureValuesRule::GetType() const
2011 return Rule::FONT_FEATURE_VALUES_RULE;
2014 NS_IMETHODIMP
2015 nsCSSFontFeatureValuesRule::GetType(uint16_t* aType)
2017 *aType = nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE;
2018 return NS_OK;
2021 NS_IMETHODIMP
2022 nsCSSFontFeatureValuesRule::GetCssText(nsAString& aCssText)
2024 FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, aCssText);
2025 return NS_OK;
2028 NS_IMETHODIMP
2029 nsCSSFontFeatureValuesRule::SetCssText(const nsAString& aCssText)
2031 // FIXME: implement???
2032 return NS_ERROR_NOT_IMPLEMENTED;
2035 NS_IMETHODIMP
2036 nsCSSFontFeatureValuesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
2038 return Rule::GetParentStyleSheet(aSheet);
2041 NS_IMETHODIMP
2042 nsCSSFontFeatureValuesRule::GetParentRule(nsIDOMCSSRule** aParentRule)
2044 return Rule::GetParentRule(aParentRule);
2047 css::Rule*
2048 nsCSSFontFeatureValuesRule::GetCSSRule()
2050 return Rule::GetCSSRule();
2053 NS_IMETHODIMP
2054 nsCSSFontFeatureValuesRule::GetFontFamily(nsAString& aFamilyListStr)
2056 nsStyleUtil::AppendEscapedCSSFontFamilyList(mFamilyList, aFamilyListStr);
2057 return NS_OK;
2060 NS_IMETHODIMP
2061 nsCSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily)
2063 return NS_ERROR_NOT_IMPLEMENTED;
2066 NS_IMETHODIMP
2067 nsCSSFontFeatureValuesRule::GetValueText(nsAString& aValueText)
2069 FeatureValuesToString(mFeatureValues, aValueText);
2070 return NS_OK;
2073 NS_IMETHODIMP
2074 nsCSSFontFeatureValuesRule::SetValueText(const nsAString& aValueText)
2076 return NS_ERROR_NOT_IMPLEMENTED;
2079 struct MakeFamilyArray {
2080 explicit MakeFamilyArray(nsTArray<nsString>& aFamilyArray)
2081 : familyArray(aFamilyArray), hasGeneric(false)
2084 static bool
2085 AddFamily(const nsString& aFamily, bool aGeneric, void* aData)
2087 MakeFamilyArray *familyArr = reinterpret_cast<MakeFamilyArray*> (aData);
2088 if (!aGeneric && !aFamily.IsEmpty()) {
2089 familyArr->familyArray.AppendElement(aFamily);
2091 if (aGeneric) {
2092 familyArr->hasGeneric = true;
2094 return true;
2097 nsTArray<nsString>& familyArray;
2098 bool hasGeneric;
2101 void
2102 nsCSSFontFeatureValuesRule::SetFamilyList(
2103 const mozilla::FontFamilyList& aFamilyList)
2105 mFamilyList = aFamilyList;
2108 void
2109 nsCSSFontFeatureValuesRule::AddValueList(int32_t aVariantAlternate,
2110 nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList)
2112 uint32_t i, len = mFeatureValues.Length();
2113 bool foundAlternate = false;
2115 // add to an existing list for a given property value
2116 for (i = 0; i < len; i++) {
2117 gfxFontFeatureValueSet::FeatureValues& f = mFeatureValues.ElementAt(i);
2119 if (f.alternate == uint32_t(aVariantAlternate)) {
2120 f.valuelist.AppendElements(aValueList);
2121 foundAlternate = true;
2122 break;
2126 // create a new list for a given property value
2127 if (!foundAlternate) {
2128 gfxFontFeatureValueSet::FeatureValues &f = *mFeatureValues.AppendElement();
2129 f.alternate = aVariantAlternate;
2130 f.valuelist.AppendElements(aValueList);
2134 size_t
2135 nsCSSFontFeatureValuesRule::SizeOfIncludingThis(
2136 MallocSizeOf aMallocSizeOf) const
2138 return aMallocSizeOf(this);
2141 // -------------------------------------------
2142 // nsCSSKeyframeStyleDeclaration
2145 nsCSSKeyframeStyleDeclaration::nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule)
2146 : mRule(aRule)
2150 nsCSSKeyframeStyleDeclaration::~nsCSSKeyframeStyleDeclaration()
2152 NS_ASSERTION(!mRule, "DropReference not called.");
2155 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeStyleDeclaration)
2156 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeStyleDeclaration)
2158 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSKeyframeStyleDeclaration)
2160 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeStyleDeclaration)
2161 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
2162 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
2164 css::Declaration*
2165 nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(bool aAllocate)
2167 if (mRule) {
2168 return mRule->Declaration();
2169 } else {
2170 return nullptr;
2174 void
2175 nsCSSKeyframeStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv)
2177 GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv);
2180 NS_IMETHODIMP
2181 nsCSSKeyframeStyleDeclaration::GetParentRule(nsIDOMCSSRule **aParent)
2183 NS_ENSURE_ARG_POINTER(aParent);
2185 NS_IF_ADDREF(*aParent = mRule);
2186 return NS_OK;
2189 nsresult
2190 nsCSSKeyframeStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl)
2192 NS_ABORT_IF_FALSE(aDecl, "must be non-null");
2193 mRule->ChangeDeclaration(aDecl);
2194 return NS_OK;
2197 nsIDocument*
2198 nsCSSKeyframeStyleDeclaration::DocToUpdate()
2200 return nullptr;
2203 nsINode*
2204 nsCSSKeyframeStyleDeclaration::GetParentObject()
2206 return mRule ? mRule->GetDocument() : nullptr;
2209 // -------------------------------------------
2210 // nsCSSKeyframeRule
2213 nsCSSKeyframeRule::nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy)
2214 // copy everything except our reference count and mDOMDeclaration
2215 : Rule(aCopy)
2216 , mKeys(aCopy.mKeys)
2217 , mDeclaration(new css::Declaration(*aCopy.mDeclaration))
2221 nsCSSKeyframeRule::~nsCSSKeyframeRule()
2223 if (mDOMDeclaration) {
2224 mDOMDeclaration->DropReference();
2228 /* virtual */ already_AddRefed<css::Rule>
2229 nsCSSKeyframeRule::Clone() const
2231 nsRefPtr<css::Rule> clone = new nsCSSKeyframeRule(*this);
2232 return clone.forget();
2235 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeRule)
2236 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeRule)
2238 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSKeyframeRule)
2240 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSKeyframeRule)
2241 if (tmp->mDOMDeclaration) {
2242 tmp->mDOMDeclaration->DropReference();
2243 tmp->mDOMDeclaration = nullptr;
2245 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
2246 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSKeyframeRule)
2247 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration)
2248 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
2250 DOMCI_DATA(MozCSSKeyframeRule, nsCSSKeyframeRule)
2252 // QueryInterface implementation for nsCSSKeyframeRule
2253 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeRule)
2254 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
2255 NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframeRule)
2256 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
2257 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
2258 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframeRule)
2259 NS_INTERFACE_MAP_END
2261 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSKeyframeRule, Rule)
2263 /* virtual */ void
2264 nsCSSKeyframeRule::MapRuleInfoInto(nsRuleData* aRuleData)
2266 // We need to implement MapRuleInfoInto because the animation manager
2267 // constructs a rule node pointing to us in order to compute the
2268 // styles it needs to animate.
2270 // The spec says that !important declarations should just be ignored
2271 NS_ASSERTION(!mDeclaration->HasImportantData(),
2272 "Keyframe rules has !important data");
2274 mDeclaration->MapNormalRuleInfoInto(aRuleData);
2277 #ifdef DEBUG
2278 void
2279 nsCSSKeyframeRule::List(FILE* out, int32_t aIndent) const
2281 for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out);
2283 nsAutoString tmp;
2284 DoGetKeyText(tmp);
2285 fputs(NS_ConvertUTF16toUTF8(tmp).get(), out);
2286 fputs(" ", out);
2287 mDeclaration->List(out, aIndent);
2288 fputs("\n", out);
2290 #endif
2292 /* virtual */ int32_t
2293 nsCSSKeyframeRule::GetType() const
2295 return Rule::KEYFRAME_RULE;
2298 NS_IMETHODIMP
2299 nsCSSKeyframeRule::GetType(uint16_t* aType)
2301 *aType = nsIDOMCSSRule::KEYFRAME_RULE;
2302 return NS_OK;
2305 NS_IMETHODIMP
2306 nsCSSKeyframeRule::GetCssText(nsAString& aCssText)
2308 DoGetKeyText(aCssText);
2309 aCssText.AppendLiteral(" { ");
2310 nsAutoString tmp;
2311 mDeclaration->ToString(tmp);
2312 aCssText.Append(tmp);
2313 aCssText.AppendLiteral(" }");
2314 return NS_OK;
2317 NS_IMETHODIMP
2318 nsCSSKeyframeRule::SetCssText(const nsAString& aCssText)
2320 // FIXME: implement???
2321 return NS_ERROR_NOT_IMPLEMENTED;
2324 NS_IMETHODIMP
2325 nsCSSKeyframeRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
2327 return Rule::GetParentStyleSheet(aSheet);
2330 NS_IMETHODIMP
2331 nsCSSKeyframeRule::GetParentRule(nsIDOMCSSRule** aParentRule)
2333 return Rule::GetParentRule(aParentRule);
2336 css::Rule*
2337 nsCSSKeyframeRule::GetCSSRule()
2339 return Rule::GetCSSRule();
2342 NS_IMETHODIMP
2343 nsCSSKeyframeRule::GetKeyText(nsAString& aKeyText)
2345 DoGetKeyText(aKeyText);
2346 return NS_OK;
2349 void
2350 nsCSSKeyframeRule::DoGetKeyText(nsAString& aKeyText) const
2352 aKeyText.Truncate();
2353 uint32_t i = 0, i_end = mKeys.Length();
2354 NS_ABORT_IF_FALSE(i_end != 0, "must have some keys");
2355 for (;;) {
2356 aKeyText.AppendFloat(mKeys[i] * 100.0f);
2357 aKeyText.Append(char16_t('%'));
2358 if (++i == i_end) {
2359 break;
2361 aKeyText.AppendLiteral(", ");
2365 NS_IMETHODIMP
2366 nsCSSKeyframeRule::SetKeyText(const nsAString& aKeyText)
2368 nsCSSParser parser;
2370 InfallibleTArray<float> newSelectors;
2371 // FIXME: pass filename and line number
2372 if (!parser.ParseKeyframeSelectorString(aKeyText, nullptr, 0, newSelectors)) {
2373 // for now, we don't do anything if the parse fails
2374 return NS_OK;
2377 nsIDocument* doc = GetDocument();
2378 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
2380 newSelectors.SwapElements(mKeys);
2382 CSSStyleSheet* sheet = GetStyleSheet();
2383 if (sheet) {
2384 sheet->SetModifiedByChildRule();
2386 if (doc) {
2387 doc->StyleRuleChanged(sheet, this, this);
2391 return NS_OK;
2394 NS_IMETHODIMP
2395 nsCSSKeyframeRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
2397 if (!mDOMDeclaration) {
2398 mDOMDeclaration = new nsCSSKeyframeStyleDeclaration(this);
2400 NS_ADDREF(*aStyle = mDOMDeclaration);
2401 return NS_OK;
2404 void
2405 nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration)
2407 // Our caller already did a BeginUpdate/EndUpdate, but with
2408 // UPDATE_CONTENT, and we need UPDATE_STYLE to trigger work in
2409 // PresShell::EndUpdate.
2410 nsIDocument* doc = GetDocument();
2411 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
2413 // Be careful to not assign to an nsAutoPtr if we would be assigning
2414 // the thing it already holds.
2415 if (aDeclaration != mDeclaration) {
2416 mDeclaration = aDeclaration;
2419 CSSStyleSheet* sheet = GetStyleSheet();
2420 if (sheet) {
2421 sheet->SetModifiedByChildRule();
2423 if (doc) {
2424 doc->StyleRuleChanged(sheet, this, this);
2429 /* virtual */ size_t
2430 nsCSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
2432 return aMallocSizeOf(this);
2434 // Measurement of the following members may be added later if DMD finds it is
2435 // worthwhile:
2436 // - mKeys
2437 // - mDeclaration
2438 // - mDOMDeclaration
2442 // -------------------------------------------
2443 // nsCSSKeyframesRule
2446 nsCSSKeyframesRule::nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy)
2447 // copy everything except our reference count. GroupRule's copy
2448 // constructor also doesn't copy the lazily-constructed
2449 // mRuleCollection.
2450 : GroupRule(aCopy),
2451 mName(aCopy.mName)
2455 nsCSSKeyframesRule::~nsCSSKeyframesRule()
2459 /* virtual */ already_AddRefed<css::Rule>
2460 nsCSSKeyframesRule::Clone() const
2462 nsRefPtr<css::Rule> clone = new nsCSSKeyframesRule(*this);
2463 return clone.forget();
2466 NS_IMPL_ADDREF_INHERITED(nsCSSKeyframesRule, css::GroupRule)
2467 NS_IMPL_RELEASE_INHERITED(nsCSSKeyframesRule, css::GroupRule)
2469 DOMCI_DATA(MozCSSKeyframesRule, nsCSSKeyframesRule)
2471 // QueryInterface implementation for nsCSSKeyframesRule
2472 NS_INTERFACE_MAP_BEGIN(nsCSSKeyframesRule)
2473 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
2474 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
2475 NS_INTERFACE_MAP_ENTRY(nsIDOMMozCSSKeyframesRule)
2476 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
2477 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCSSKeyframesRule)
2478 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
2480 #ifdef DEBUG
2481 void
2482 nsCSSKeyframesRule::List(FILE* out, int32_t aIndent) const
2484 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
2486 fprintf(out, "@keyframes %s", NS_ConvertUTF16toUTF8(mName).get());
2487 GroupRule::List(out, aIndent);
2489 #endif
2491 /* virtual */ int32_t
2492 nsCSSKeyframesRule::GetType() const
2494 return Rule::KEYFRAMES_RULE;
2497 NS_IMETHODIMP
2498 nsCSSKeyframesRule::GetType(uint16_t* aType)
2500 *aType = nsIDOMCSSRule::KEYFRAMES_RULE;
2501 return NS_OK;
2504 NS_IMETHODIMP
2505 nsCSSKeyframesRule::GetCssText(nsAString& aCssText)
2507 aCssText.AssignLiteral("@keyframes ");
2508 aCssText.Append(mName);
2509 aCssText.AppendLiteral(" {\n");
2510 nsAutoString tmp;
2511 for (uint32_t i = 0, i_end = mRules.Count(); i != i_end; ++i) {
2512 static_cast<nsCSSKeyframeRule*>(mRules[i])->GetCssText(tmp);
2513 aCssText.Append(tmp);
2514 aCssText.Append('\n');
2516 aCssText.Append('}');
2517 return NS_OK;
2520 NS_IMETHODIMP
2521 nsCSSKeyframesRule::SetCssText(const nsAString& aCssText)
2523 // FIXME: implement???
2524 return NS_ERROR_NOT_IMPLEMENTED;
2527 NS_IMETHODIMP
2528 nsCSSKeyframesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
2530 return GroupRule::GetParentStyleSheet(aSheet);
2533 NS_IMETHODIMP
2534 nsCSSKeyframesRule::GetParentRule(nsIDOMCSSRule** aParentRule)
2536 return GroupRule::GetParentRule(aParentRule);
2539 css::Rule*
2540 nsCSSKeyframesRule::GetCSSRule()
2542 return GroupRule::GetCSSRule();
2545 NS_IMETHODIMP
2546 nsCSSKeyframesRule::GetName(nsAString& aName)
2548 aName = mName;
2549 return NS_OK;
2552 NS_IMETHODIMP
2553 nsCSSKeyframesRule::SetName(const nsAString& aName)
2555 if (mName == aName) {
2556 return NS_OK;
2559 nsIDocument* doc = GetDocument();
2560 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
2562 mName = aName;
2564 CSSStyleSheet* sheet = GetStyleSheet();
2565 if (sheet) {
2566 sheet->SetModifiedByChildRule();
2568 if (doc) {
2569 doc->StyleRuleChanged(sheet, this, this);
2573 return NS_OK;
2576 NS_IMETHODIMP
2577 nsCSSKeyframesRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
2579 return GroupRule::GetCssRules(aRuleList);
2582 NS_IMETHODIMP
2583 nsCSSKeyframesRule::AppendRule(const nsAString& aRule)
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;
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);
2597 AppendStyleRule(rule);
2599 CSSStyleSheet* sheet = GetStyleSheet();
2600 if (sheet) {
2601 sheet->SetModifiedByChildRule();
2603 if (doc) {
2604 doc->StyleRuleChanged(sheet, this, this);
2609 return NS_OK;
2612 static const uint32_t RULE_NOT_FOUND = uint32_t(-1);
2614 uint32_t
2615 nsCSSKeyframesRule::FindRuleIndexForKey(const nsAString& aKey)
2617 nsCSSParser parser;
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;
2634 return RULE_NOT_FOUND;
2637 NS_IMETHODIMP
2638 nsCSSKeyframesRule::DeleteRule(const nsAString& aKey)
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);
2645 mRules.RemoveObjectAt(index);
2647 CSSStyleSheet* sheet = GetStyleSheet();
2648 if (sheet) {
2649 sheet->SetModifiedByChildRule();
2651 if (doc) {
2652 doc->StyleRuleChanged(sheet, this, this);
2656 return NS_OK;
2659 NS_IMETHODIMP
2660 nsCSSKeyframesRule::FindRule(const nsAString& aKey,
2661 nsIDOMMozCSSKeyframeRule** aResult)
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]));
2669 return NS_OK;
2672 // GroupRule interface
2673 /* virtual */ bool
2674 nsCSSKeyframesRule::UseForPresentation(nsPresContext* aPresContext,
2675 nsMediaQueryResultCacheKey& aKey)
2677 NS_ABORT_IF_FALSE(false, "should not be called");
2678 return false;
2681 /* virtual */ size_t
2682 nsCSSKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
2684 size_t n = aMallocSizeOf(this);
2685 n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
2687 // Measurement of the following members may be added later if DMD finds it is
2688 // worthwhile:
2689 // - mName
2691 return n;
2694 // -------------------------------------------
2695 // nsCSSPageStyleDeclaration
2698 nsCSSPageStyleDeclaration::nsCSSPageStyleDeclaration(nsCSSPageRule* aRule)
2699 : mRule(aRule)
2703 nsCSSPageStyleDeclaration::~nsCSSPageStyleDeclaration()
2705 NS_ASSERTION(!mRule, "DropReference not called.");
2708 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageStyleDeclaration)
2709 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageStyleDeclaration)
2711 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsCSSPageStyleDeclaration)
2713 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageStyleDeclaration)
2714 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
2715 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
2717 css::Declaration*
2718 nsCSSPageStyleDeclaration::GetCSSDeclaration(bool aAllocate)
2720 if (mRule) {
2721 return mRule->Declaration();
2722 } else {
2723 return nullptr;
2727 void
2728 nsCSSPageStyleDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv)
2730 GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv);
2733 NS_IMETHODIMP
2734 nsCSSPageStyleDeclaration::GetParentRule(nsIDOMCSSRule** aParent)
2736 NS_ENSURE_ARG_POINTER(aParent);
2738 NS_IF_ADDREF(*aParent = mRule);
2739 return NS_OK;
2742 nsresult
2743 nsCSSPageStyleDeclaration::SetCSSDeclaration(css::Declaration* aDecl)
2745 NS_ABORT_IF_FALSE(aDecl, "must be non-null");
2746 mRule->ChangeDeclaration(aDecl);
2747 return NS_OK;
2750 nsIDocument*
2751 nsCSSPageStyleDeclaration::DocToUpdate()
2753 return nullptr;
2756 nsINode*
2757 nsCSSPageStyleDeclaration::GetParentObject()
2759 return mRule ? mRule->GetDocument() : nullptr;
2762 // -------------------------------------------
2763 // nsCSSPageRule
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))
2773 nsCSSPageRule::~nsCSSPageRule()
2775 if (mDOMDeclaration) {
2776 mDOMDeclaration->DropReference();
2780 /* virtual */ already_AddRefed<css::Rule>
2781 nsCSSPageRule::Clone() const
2783 nsRefPtr<css::Rule> clone = new nsCSSPageRule(*this);
2784 return clone.forget();
2787 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageRule)
2788 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageRule)
2790 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSPageRule)
2792 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSPageRule)
2793 if (tmp->mDOMDeclaration) {
2794 tmp->mDOMDeclaration->DropReference();
2795 tmp->mDOMDeclaration = nullptr;
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
2802 DOMCI_DATA(CSSPageRule, nsCSSPageRule)
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
2813 IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSPageRule, Rule)
2815 #ifdef DEBUG
2816 void
2817 nsCSSPageRule::List(FILE* out, int32_t aIndent) const
2819 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
2821 fputs("@page ", out);
2822 mDeclaration->List(out, aIndent);
2823 fputs("\n", out);
2825 #endif
2827 /* virtual */ int32_t
2828 nsCSSPageRule::GetType() const
2830 return Rule::PAGE_RULE;
2833 NS_IMETHODIMP
2834 nsCSSPageRule::GetType(uint16_t* aType)
2836 *aType = nsIDOMCSSRule::PAGE_RULE;
2837 return NS_OK;
2840 NS_IMETHODIMP
2841 nsCSSPageRule::GetCssText(nsAString& aCssText)
2843 aCssText.AppendLiteral("@page { ");
2844 nsAutoString tmp;
2845 mDeclaration->ToString(tmp);
2846 aCssText.Append(tmp);
2847 aCssText.AppendLiteral(" }");
2848 return NS_OK;
2851 NS_IMETHODIMP
2852 nsCSSPageRule::SetCssText(const nsAString& aCssText)
2854 // FIXME: implement???
2855 return NS_ERROR_NOT_IMPLEMENTED;
2858 NS_IMETHODIMP
2859 nsCSSPageRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
2861 return Rule::GetParentStyleSheet(aSheet);
2864 NS_IMETHODIMP
2865 nsCSSPageRule::GetParentRule(nsIDOMCSSRule** aParentRule)
2867 return Rule::GetParentRule(aParentRule);
2870 css::Rule*
2871 nsCSSPageRule::GetCSSRule()
2873 return Rule::GetCSSRule();
2876 css::ImportantRule*
2877 nsCSSPageRule::GetImportantRule()
2879 if (!mDeclaration->HasImportantData()) {
2880 return nullptr;
2882 if (!mImportantRule) {
2883 mImportantRule = new css::ImportantRule(mDeclaration);
2885 return mImportantRule;
2888 /* virtual */ void
2889 nsCSSPageRule::MapRuleInfoInto(nsRuleData* aRuleData)
2891 mDeclaration->MapNormalRuleInfoInto(aRuleData);
2894 NS_IMETHODIMP
2895 nsCSSPageRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
2897 if (!mDOMDeclaration) {
2898 mDOMDeclaration = new nsCSSPageStyleDeclaration(this);
2900 NS_ADDREF(*aStyle = mDOMDeclaration);
2901 return NS_OK;
2904 void
2905 nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration)
2907 mImportantRule = nullptr;
2908 // Be careful to not assign to an nsAutoPtr if we would be assigning
2909 // the thing it already holds.
2910 if (aDeclaration != mDeclaration) {
2911 mDeclaration = aDeclaration;
2914 CSSStyleSheet* sheet = GetStyleSheet();
2915 if (sheet) {
2916 sheet->SetModifiedByChildRule();
2920 /* virtual */ size_t
2921 nsCSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
2923 return aMallocSizeOf(this);
2926 namespace mozilla {
2928 CSSSupportsRule::CSSSupportsRule(bool aConditionMet,
2929 const nsString& aCondition,
2930 uint32_t aLineNumber, uint32_t aColumnNumber)
2931 : css::GroupRule(aLineNumber, aColumnNumber)
2932 , mUseGroup(aConditionMet)
2933 , mCondition(aCondition)
2937 CSSSupportsRule::~CSSSupportsRule()
2941 CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy)
2942 : css::GroupRule(aCopy),
2943 mUseGroup(aCopy.mUseGroup),
2944 mCondition(aCopy.mCondition)
2948 #ifdef DEBUG
2949 /* virtual */ void
2950 CSSSupportsRule::List(FILE* out, int32_t aIndent) const
2952 for (int32_t indent = aIndent; --indent >= 0; ) fputs(" ", out);
2954 fputs("@supports ", out);
2955 fputs(NS_ConvertUTF16toUTF8(mCondition).get(), out);
2956 css::GroupRule::List(out, aIndent);
2958 #endif
2960 /* virtual */ int32_t
2961 CSSSupportsRule::GetType() const
2963 return Rule::SUPPORTS_RULE;
2966 /* virtual */ already_AddRefed<mozilla::css::Rule>
2967 CSSSupportsRule::Clone() const
2969 nsRefPtr<css::Rule> clone = new CSSSupportsRule(*this);
2970 return clone.forget();
2973 /* virtual */ bool
2974 CSSSupportsRule::UseForPresentation(nsPresContext* aPresContext,
2975 nsMediaQueryResultCacheKey& aKey)
2977 return mUseGroup;
2980 NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, css::GroupRule)
2981 NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::GroupRule)
2983 // QueryInterface implementation for CSSSupportsRule
2984 NS_INTERFACE_MAP_BEGIN(CSSSupportsRule)
2985 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
2986 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
2987 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
2988 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
2989 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSSupportsRule)
2990 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
2991 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSSupportsRule)
2992 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
2994 // nsIDOMCSSRule methods
2995 NS_IMETHODIMP
2996 CSSSupportsRule::GetType(uint16_t* aType)
2998 *aType = nsIDOMCSSRule::SUPPORTS_RULE;
2999 return NS_OK;
3002 NS_IMETHODIMP
3003 CSSSupportsRule::GetCssText(nsAString& aCssText)
3005 aCssText.AssignLiteral("@supports ");
3006 aCssText.Append(mCondition);
3007 css::GroupRule::AppendRulesToCssText(aCssText);
3008 return NS_OK;
3011 NS_IMETHODIMP
3012 CSSSupportsRule::SetCssText(const nsAString& aCssText)
3014 return NS_ERROR_NOT_IMPLEMENTED;
3017 NS_IMETHODIMP
3018 CSSSupportsRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
3020 return css::GroupRule::GetParentStyleSheet(aSheet);
3023 NS_IMETHODIMP
3024 CSSSupportsRule::GetParentRule(nsIDOMCSSRule** aParentRule)
3026 return css::GroupRule::GetParentRule(aParentRule);
3029 css::Rule*
3030 CSSSupportsRule::GetCSSRule()
3032 return css::GroupRule::GetCSSRule();
3035 // nsIDOMCSSGroupingRule methods
3036 NS_IMETHODIMP
3037 CSSSupportsRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
3039 return css::GroupRule::GetCssRules(aRuleList);
3042 NS_IMETHODIMP
3043 CSSSupportsRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
3045 return css::GroupRule::InsertRule(aRule, aIndex, _retval);
3048 NS_IMETHODIMP
3049 CSSSupportsRule::DeleteRule(uint32_t aIndex)
3051 return css::GroupRule::DeleteRule(aIndex);
3054 // nsIDOMCSSConditionRule methods
3055 NS_IMETHODIMP
3056 CSSSupportsRule::GetConditionText(nsAString& aConditionText)
3058 aConditionText.Assign(mCondition);
3059 return NS_OK;
3062 NS_IMETHODIMP
3063 CSSSupportsRule::SetConditionText(const nsAString& aConditionText)
3065 return NS_ERROR_NOT_IMPLEMENTED;
3068 /* virtual */ size_t
3069 CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
3071 size_t n = aMallocSizeOf(this);
3072 n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
3073 n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
3074 return n;
3077 } // namespace mozilla
3079 // Must be outside namespace
3080 DOMCI_DATA(CSSSupportsRule, mozilla::CSSSupportsRule)
3082 // -------------------------------------------
3083 // nsCSSCounterStyleRule
3086 nsCSSCounterStyleRule::nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy)
3087 : Rule(aCopy)
3088 , mName(aCopy.mName)
3089 , mGeneration(aCopy.mGeneration)
3091 for (size_t i = 0; i < ArrayLength(mValues); ++i) {
3092 mValues[i] = aCopy.mValues[i];
3096 nsCSSCounterStyleRule::~nsCSSCounterStyleRule()
3100 /* virtual */ already_AddRefed<css::Rule>
3101 nsCSSCounterStyleRule::Clone() const
3103 nsRefPtr<css::Rule> clone = new nsCSSCounterStyleRule(*this);
3104 return clone.forget();
3107 nsCSSCounterStyleRule::Getter const
3108 nsCSSCounterStyleRule::kGetters[] = {
3109 #define CSS_COUNTER_DESC(name_, method_) &nsCSSCounterStyleRule::Get##method_,
3110 #include "nsCSSCounterDescList.h"
3111 #undef CSS_COUNTER_DESC
3114 NS_IMPL_ADDREF(nsCSSCounterStyleRule)
3115 NS_IMPL_RELEASE(nsCSSCounterStyleRule)
3117 DOMCI_DATA(CSSCounterStyleRule, nsCSSCounterStyleRule)
3119 // QueryInterface implementation for nsCSSCounterStyleRule
3120 NS_INTERFACE_MAP_BEGIN(nsCSSCounterStyleRule)
3121 NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
3122 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
3123 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCounterStyleRule)
3124 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
3125 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSCounterStyleRule)
3126 NS_INTERFACE_MAP_END
3128 IMPL_STYLE_RULE_INHERIT(nsCSSCounterStyleRule, css::Rule)
3130 #ifdef DEBUG
3131 void
3132 nsCSSCounterStyleRule::List(FILE* out, int32_t aIndent) const
3134 nsCString baseInd, descInd;
3135 for (int32_t indent = aIndent; --indent >= 0; ) {
3136 baseInd.AppendLiteral(" ");
3138 descInd = baseInd;
3139 descInd.AppendLiteral(" ");
3141 fprintf(out, "%s@counter-style %s (rev.%u) {\n",
3142 baseInd.get(), NS_ConvertUTF16toUTF8(mName).get(), mGeneration);
3143 // TODO
3144 fprintf(out, "%s}\n", baseInd.get());
3146 #endif
3148 /* virtual */ int32_t
3149 nsCSSCounterStyleRule::GetType() const
3151 return Rule::COUNTER_STYLE_RULE;
3154 // nsIDOMCSSRule methods
3155 NS_IMETHODIMP
3156 nsCSSCounterStyleRule::GetType(uint16_t* aType)
3158 *aType = nsIDOMCSSRule::COUNTER_STYLE_RULE;
3159 return NS_OK;
3162 NS_IMETHODIMP
3163 nsCSSCounterStyleRule::GetCssText(nsAString& aCssText)
3165 aCssText.AssignLiteral(MOZ_UTF16("@counter-style "));
3166 nsStyleUtil::AppendEscapedCSSIdent(mName, aCssText);
3167 aCssText.AppendLiteral(MOZ_UTF16(" {\n"));
3168 for (nsCSSCounterDesc id = nsCSSCounterDesc(0);
3169 id < eCSSCounterDesc_COUNT;
3170 id = nsCSSCounterDesc(id + 1)) {
3171 if (mValues[id].GetUnit() != eCSSUnit_Null) {
3172 nsAutoString tmp;
3173 (this->*kGetters[id])(tmp);
3174 aCssText.AppendLiteral(MOZ_UTF16(" "));
3175 AppendASCIItoUTF16(nsCSSProps::GetStringValue(id), aCssText);
3176 aCssText.AppendLiteral(MOZ_UTF16(": "));
3177 aCssText.Append(tmp);
3178 aCssText.AppendLiteral(MOZ_UTF16(";\n"));
3181 aCssText.AppendLiteral(MOZ_UTF16("}"));
3182 return NS_OK;
3185 NS_IMETHODIMP
3186 nsCSSCounterStyleRule::SetCssText(const nsAString& aCssText)
3188 // FIXME: implement???
3189 return NS_ERROR_NOT_IMPLEMENTED;
3192 NS_IMETHODIMP
3193 nsCSSCounterStyleRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
3195 return Rule::GetParentStyleSheet(aSheet);
3198 NS_IMETHODIMP
3199 nsCSSCounterStyleRule::GetParentRule(nsIDOMCSSRule** aParentRule)
3201 return Rule::GetParentRule(aParentRule);
3204 css::Rule*
3205 nsCSSCounterStyleRule::GetCSSRule()
3207 return Rule::GetCSSRule();
3210 // nsIDOMCSSCounterStyleRule methods
3211 NS_IMETHODIMP
3212 nsCSSCounterStyleRule::GetName(nsAString& aName)
3214 aName.Truncate();
3215 nsStyleUtil::AppendEscapedCSSIdent(mName, aName);
3216 return NS_OK;
3219 NS_IMETHODIMP
3220 nsCSSCounterStyleRule::SetName(const nsAString& aName)
3222 nsCSSParser parser;
3223 nsAutoString name;
3224 if (parser.ParseCounterStyleName(aName, nullptr, name)) {
3225 nsIDocument* doc = GetDocument();
3226 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
3228 mName = name;
3230 CSSStyleSheet* sheet = GetStyleSheet();
3231 if (sheet) {
3232 sheet->SetModifiedByChildRule();
3233 if (doc) {
3234 doc->StyleRuleChanged(sheet, this, this);
3238 return NS_OK;
3241 int32_t
3242 nsCSSCounterStyleRule::GetSystem() const
3244 const nsCSSValue& system = GetDesc(eCSSCounterDesc_System);
3245 switch (system.GetUnit()) {
3246 case eCSSUnit_Enumerated:
3247 return system.GetIntValue();
3248 case eCSSUnit_Pair:
3249 return system.GetPairValue().mXValue.GetIntValue();
3250 default:
3251 return NS_STYLE_COUNTER_SYSTEM_SYMBOLIC;
3255 const nsCSSValue&
3256 nsCSSCounterStyleRule::GetSystemArgument() const
3258 const nsCSSValue& system = GetDesc(eCSSCounterDesc_System);
3259 NS_ABORT_IF_FALSE(system.GetUnit() == eCSSUnit_Pair,
3260 "Invalid system value");
3261 return system.GetPairValue().mYValue;
3264 void
3265 nsCSSCounterStyleRule::SetDesc(nsCSSCounterDesc aDescID, const nsCSSValue& aValue)
3267 NS_ABORT_IF_FALSE(aDescID >= 0 && aDescID < eCSSCounterDesc_COUNT,
3268 "descriptor ID out of range");
3270 nsIDocument* doc = GetDocument();
3271 MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
3273 mValues[aDescID] = aValue;
3274 mGeneration++;
3276 CSSStyleSheet* sheet = GetStyleSheet();
3277 if (sheet) {
3278 sheet->SetModifiedByChildRule();
3279 if (doc) {
3280 doc->StyleRuleChanged(sheet, this, this);
3285 NS_IMETHODIMP
3286 nsCSSCounterStyleRule::GetSystem(nsAString& aSystem)
3288 const nsCSSValue& value = GetDesc(eCSSCounterDesc_System);
3289 if (value.GetUnit() == eCSSUnit_Null) {
3290 aSystem.Truncate();
3291 return NS_OK;
3294 aSystem = NS_ConvertASCIItoUTF16(nsCSSProps::ValueToKeyword(
3295 GetSystem(), nsCSSProps::kCounterSystemKTable));
3296 if (value.GetUnit() == eCSSUnit_Pair) {
3297 aSystem.Append(' ');
3298 GetSystemArgument().AppendToString(
3299 eCSSProperty_UNKNOWN, aSystem, nsCSSValue::eNormalized);
3301 return NS_OK;
3304 NS_IMETHODIMP
3305 nsCSSCounterStyleRule::GetSymbols(nsAString& aSymbols)
3307 const nsCSSValue& value = GetDesc(eCSSCounterDesc_Symbols);
3309 aSymbols.Truncate();
3310 if (value.GetUnit() == eCSSUnit_List) {
3311 for (const nsCSSValueList* item = value.GetListValue();
3312 item; item = item->mNext) {
3313 item->mValue.AppendToString(eCSSProperty_UNKNOWN,
3314 aSymbols,
3315 nsCSSValue::eNormalized);
3316 if (item->mNext) {
3317 aSymbols.Append(' ');
3321 return NS_OK;
3324 NS_IMETHODIMP
3325 nsCSSCounterStyleRule::GetAdditiveSymbols(nsAString& aSymbols)
3327 const nsCSSValue& value = GetDesc(eCSSCounterDesc_AdditiveSymbols);
3329 aSymbols.Truncate();
3330 if (value.GetUnit() == eCSSUnit_PairList) {
3331 for (const nsCSSValuePairList* item = value.GetPairListValue();
3332 item; item = item->mNext) {
3333 item->mXValue.AppendToString(eCSSProperty_UNKNOWN,
3334 aSymbols, nsCSSValue::eNormalized);
3335 aSymbols.Append(' ');
3336 item->mYValue.AppendToString(eCSSProperty_UNKNOWN,
3337 aSymbols, nsCSSValue::eNormalized);
3338 if (item->mNext) {
3339 aSymbols.AppendLiteral(", ");
3343 return NS_OK;
3346 NS_IMETHODIMP
3347 nsCSSCounterStyleRule::GetRange(nsAString& aRange)
3349 const nsCSSValue& value = GetDesc(eCSSCounterDesc_Range);
3351 switch (value.GetUnit()) {
3352 case eCSSUnit_Auto:
3353 aRange.AssignLiteral(MOZ_UTF16("auto"));
3354 break;
3356 case eCSSUnit_PairList:
3357 aRange.Truncate();
3358 for (const nsCSSValuePairList* item = value.GetPairListValue();
3359 item; item = item->mNext) {
3360 const nsCSSValue& lower = item->mXValue;
3361 const nsCSSValue& upper = item->mYValue;
3362 if (lower.GetUnit() == eCSSUnit_Enumerated) {
3363 NS_ASSERTION(lower.GetIntValue() ==
3364 NS_STYLE_COUNTER_RANGE_INFINITE,
3365 "Unrecognized keyword");
3366 aRange.AppendLiteral("infinite");
3367 } else {
3368 aRange.AppendInt(lower.GetIntValue());
3370 aRange.Append(' ');
3371 if (upper.GetUnit() == eCSSUnit_Enumerated) {
3372 NS_ASSERTION(upper.GetIntValue() ==
3373 NS_STYLE_COUNTER_RANGE_INFINITE,
3374 "Unrecognized keyword");
3375 aRange.AppendLiteral("infinite");
3376 } else {
3377 aRange.AppendInt(upper.GetIntValue());
3379 if (item->mNext) {
3380 aRange.AppendLiteral(", ");
3383 break;
3385 default:
3386 aRange.Truncate();
3388 return NS_OK;
3391 NS_IMETHODIMP
3392 nsCSSCounterStyleRule::GetSpeakAs(nsAString& aSpeakAs)
3394 const nsCSSValue& value = GetDesc(eCSSCounterDesc_SpeakAs);
3396 switch (value.GetUnit()) {
3397 case eCSSUnit_Enumerated:
3398 switch (value.GetIntValue()) {
3399 case NS_STYLE_COUNTER_SPEAKAS_BULLETS:
3400 aSpeakAs.AssignLiteral(MOZ_UTF16("bullets"));
3401 break;
3402 case NS_STYLE_COUNTER_SPEAKAS_NUMBERS:
3403 aSpeakAs.AssignLiteral(MOZ_UTF16("numbers"));
3404 break;
3405 case NS_STYLE_COUNTER_SPEAKAS_WORDS:
3406 aSpeakAs.AssignLiteral(MOZ_UTF16("words"));
3407 break;
3408 case NS_STYLE_COUNTER_SPEAKAS_SPELL_OUT:
3409 aSpeakAs.AssignLiteral(MOZ_UTF16("spell-out"));
3410 break;
3411 default:
3412 NS_NOTREACHED("Unknown speech synthesis");
3414 break;
3416 case eCSSUnit_Auto:
3417 case eCSSUnit_Ident:
3418 aSpeakAs.Truncate();
3419 value.AppendToString(eCSSProperty_UNKNOWN,
3420 aSpeakAs, nsCSSValue::eNormalized);
3421 break;
3423 default:
3424 aSpeakAs.Truncate();
3426 return NS_OK;
3429 nsresult
3430 nsCSSCounterStyleRule::GetDescriptor(nsCSSCounterDesc aDescID,
3431 nsAString& aValue)
3433 NS_ASSERTION(aDescID == eCSSCounterDesc_Negative ||
3434 aDescID == eCSSCounterDesc_Prefix ||
3435 aDescID == eCSSCounterDesc_Suffix ||
3436 aDescID == eCSSCounterDesc_Pad ||
3437 aDescID == eCSSCounterDesc_Fallback,
3438 "Unexpected descriptor");
3439 const nsCSSValue& value = GetDesc(aDescID);
3440 aValue.Truncate();
3441 if (value.GetUnit() != eCSSUnit_Null) {
3442 value.AppendToString(
3443 eCSSProperty_UNKNOWN, aValue, nsCSSValue::eNormalized);
3445 return NS_OK;
3448 #define CSS_COUNTER_DESC_GETTER(name_) \
3449 NS_IMETHODIMP \
3450 nsCSSCounterStyleRule::Get##name_(nsAString& a##name_) \
3452 return GetDescriptor(eCSSCounterDesc_##name_, a##name_);\
3454 CSS_COUNTER_DESC_GETTER(Negative)
3455 CSS_COUNTER_DESC_GETTER(Prefix)
3456 CSS_COUNTER_DESC_GETTER(Suffix)
3457 CSS_COUNTER_DESC_GETTER(Pad)
3458 CSS_COUNTER_DESC_GETTER(Fallback)
3459 #undef CSS_COUNTER_DESC_GETTER
3461 /* static */ bool
3462 nsCSSCounterStyleRule::CheckDescValue(int32_t aSystem,
3463 nsCSSCounterDesc aDescID,
3464 const nsCSSValue& aValue)
3466 switch (aDescID) {
3467 case eCSSCounterDesc_System:
3468 if (aValue.GetUnit() != eCSSUnit_Pair) {
3469 return aValue.GetIntValue() == aSystem;
3470 } else {
3471 return aValue.GetPairValue().mXValue.GetIntValue() == aSystem;
3474 case eCSSCounterDesc_Symbols:
3475 switch (aSystem) {
3476 case NS_STYLE_COUNTER_SYSTEM_NUMERIC:
3477 case NS_STYLE_COUNTER_SYSTEM_ALPHABETIC:
3478 // for these two system, the list must contain at least 2 elements
3479 return aValue.GetListValue()->mNext;
3480 case NS_STYLE_COUNTER_SYSTEM_EXTENDS:
3481 // for extends system, no symbols should be set
3482 return false;
3483 default:
3484 return true;
3487 case eCSSCounterDesc_AdditiveSymbols:
3488 switch (aSystem) {
3489 case NS_STYLE_COUNTER_SYSTEM_EXTENDS:
3490 return false;
3491 default:
3492 return true;
3495 default:
3496 return true;
3500 nsresult
3501 nsCSSCounterStyleRule::SetDescriptor(nsCSSCounterDesc aDescID,
3502 const nsAString& aValue)
3504 nsCSSParser parser;
3505 nsCSSValue value;
3506 CSSStyleSheet* sheet = GetStyleSheet();
3507 nsIURI* baseURL = nullptr;
3508 nsIPrincipal* principal = nullptr;
3509 if (sheet) {
3510 baseURL = sheet->GetBaseURI();
3511 principal = sheet->Principal();
3513 if (parser.ParseCounterDescriptor(aDescID, aValue, nullptr,
3514 baseURL, principal, value)) {
3515 if (CheckDescValue(GetSystem(), aDescID, value)) {
3516 SetDesc(aDescID, value);
3519 return NS_OK;
3522 #define CSS_COUNTER_DESC_SETTER(name_) \
3523 NS_IMETHODIMP \
3524 nsCSSCounterStyleRule::Set##name_(const nsAString& a##name_) \
3526 return SetDescriptor(eCSSCounterDesc_##name_, a##name_); \
3528 CSS_COUNTER_DESC_SETTER(System)
3529 CSS_COUNTER_DESC_SETTER(Symbols)
3530 CSS_COUNTER_DESC_SETTER(AdditiveSymbols)
3531 CSS_COUNTER_DESC_SETTER(Negative)
3532 CSS_COUNTER_DESC_SETTER(Prefix)
3533 CSS_COUNTER_DESC_SETTER(Suffix)
3534 CSS_COUNTER_DESC_SETTER(Range)
3535 CSS_COUNTER_DESC_SETTER(Pad)
3536 CSS_COUNTER_DESC_SETTER(Fallback)
3537 CSS_COUNTER_DESC_SETTER(SpeakAs)
3538 #undef CSS_COUNTER_DESC_SETTER
3540 /* virtual */ size_t
3541 nsCSSCounterStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
3543 return aMallocSizeOf(this);