GroupRule.cpp (3826B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* 8 * internal interface representing CSS style rules that contain other 9 * rules, such as @media rules 10 */ 11 12 #include "mozilla/css/GroupRule.h" 13 14 #include "mozilla/dom/CSSRuleList.h" 15 #include "nsPrintfCString.h" 16 17 using namespace mozilla::dom; 18 19 namespace mozilla::css { 20 21 GroupRule::GroupRule(StyleSheet* aSheet, Rule* aParentRule, 22 uint32_t aLineNumber, uint32_t aColumnNumber) 23 : Rule(aSheet, aParentRule, aLineNumber, aColumnNumber) {} 24 25 GroupRule::~GroupRule() { 26 MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called"); 27 if (mRuleList) { 28 mRuleList->DropReferences(); 29 } 30 } 31 32 NS_IMPL_ADDREF_INHERITED(GroupRule, Rule) 33 NS_IMPL_RELEASE_INHERITED(GroupRule, Rule) 34 35 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule) 36 NS_INTERFACE_MAP_END_INHERITING(Rule) 37 38 bool GroupRule::IsCCLeaf() const { 39 if (!Rule::IsCCLeaf()) { 40 return false; 41 } 42 return !mRuleList; 43 } 44 45 ServoCSSRuleList* GroupRule::CssRules() { 46 if (!mRuleList) { 47 // Lazily create the rule list since most style rules won't have child 48 // rules. 49 mRuleList = 50 new ServoCSSRuleList(GetOrCreateRawRules(), GetStyleSheet(), this); 51 } 52 return mRuleList; 53 } 54 55 NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule) 56 57 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GroupRule, Rule) 58 if (tmp->mRuleList) { 59 // If tmp has a style sheet (which can happen if it gets unlinked 60 // earlier than its owning style sheet), then we need to null out the 61 // style sheet pointer on descendants now, before we clear mRuleList. 62 tmp->mRuleList->DropReferences(); 63 tmp->mRuleList = nullptr; 64 } 65 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 66 67 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GroupRule, Rule) 68 ImplCycleCollectionTraverse(cb, tmp->mRuleList, "mRuleList"); 69 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 70 71 #ifdef DEBUG 72 void GroupRule::List(FILE* out, int32_t aIndent) const { 73 // TODO list something reasonable? 74 } 75 #endif 76 77 /* virtual */ 78 void GroupRule::DropSheetReference() { 79 if (mRuleList) { 80 mRuleList->DropSheetReference(); 81 } 82 Rule::DropSheetReference(); 83 } 84 85 uint32_t GroupRule::InsertRule(const nsACString& aRule, uint32_t aIndex, 86 ErrorResult& aRv) { 87 if (IsReadOnly()) { 88 return 0; 89 } 90 91 StyleSheet* sheet = GetStyleSheet(); 92 if (NS_WARN_IF(!sheet)) { 93 aRv.Throw(NS_ERROR_FAILURE); 94 return 0; 95 } 96 97 uint32_t count = StyleRuleCount(); 98 if (aIndex > count) { 99 aRv.ThrowIndexSizeError(nsPrintfCString( 100 "Can't insert rule at index %u because rule list length is %u", aIndex, 101 count)); 102 return 0; 103 } 104 105 NS_ASSERTION(count <= INT32_MAX, "Too many style rules!"); 106 107 nsresult rv = sheet->InsertRuleIntoGroup(aRule, this, aIndex); 108 if (NS_FAILED(rv)) { 109 aRv.Throw(rv); 110 return 0; 111 } 112 return aIndex; 113 } 114 115 void GroupRule::DeleteRule(uint32_t aIndex, ErrorResult& aRv) { 116 if (IsReadOnly()) { 117 return; 118 } 119 120 StyleSheet* sheet = GetStyleSheet(); 121 if (NS_WARN_IF(!sheet)) { 122 aRv.Throw(NS_ERROR_FAILURE); 123 return; 124 } 125 126 uint32_t count = StyleRuleCount(); 127 if (aIndex >= count) { 128 aRv.ThrowIndexSizeError(nsPrintfCString( 129 "Index %u is too large for list of length %u", aIndex, count)); 130 return; 131 } 132 133 NS_ASSERTION(count <= INT32_MAX, "Too many style rules!"); 134 135 nsresult rv = sheet->DeleteRuleFromGroup(this, aIndex); 136 if (NS_FAILED(rv)) { 137 aRv.Throw(rv); 138 } 139 } 140 141 size_t GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { 142 // TODO how to implement? 143 return 0; 144 } 145 146 } // namespace mozilla::css