CSSNestedDeclarations.cpp (6207B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/CSSNestedDeclarations.h" 8 9 #include "mozilla/DeclarationBlock.h" 10 #include "mozilla/dom/CSSNestedDeclarationsBinding.h" 11 12 namespace mozilla::dom { 13 14 CSSNestedDeclarationsDeclaration::CSSNestedDeclarationsDeclaration( 15 already_AddRefed<StyleLockedDeclarationBlock> aDecls) 16 : mDecls(new DeclarationBlock(std::move(aDecls))) { 17 mDecls->SetOwningRule(Rule()); 18 } 19 20 CSSNestedDeclarationsDeclaration::~CSSNestedDeclarationsDeclaration() { 21 mDecls->SetOwningRule(nullptr); 22 } 23 24 // QueryInterface implementation for CSSNestedDeclarationsDeclaration 25 NS_INTERFACE_MAP_BEGIN(CSSNestedDeclarationsDeclaration) 26 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 27 // We forward the cycle collection interfaces to Rule(), which is 28 // never null (in fact, we're part of that object!) 29 if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) || 30 aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) { 31 return Rule()->QueryInterface(aIID, aInstancePtr); 32 } 33 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) 34 35 NS_IMPL_ADDREF_USING_AGGREGATOR(CSSNestedDeclarationsDeclaration, Rule()) 36 NS_IMPL_RELEASE_USING_AGGREGATOR(CSSNestedDeclarationsDeclaration, Rule()) 37 38 css::Rule* CSSNestedDeclarationsDeclaration::GetParentRule() { return Rule(); } 39 nsINode* CSSNestedDeclarationsDeclaration::GetAssociatedNode() const { 40 return Rule()->GetAssociatedDocumentOrShadowRoot(); 41 } 42 nsISupports* CSSNestedDeclarationsDeclaration::GetParentObject() const { 43 return Rule()->GetParentObject(); 44 } 45 DeclarationBlock* CSSNestedDeclarationsDeclaration::GetOrCreateCSSDeclaration( 46 Operation aOperation, DeclarationBlock** aCreated) { 47 if (aOperation != Operation::Read) { 48 if (StyleSheet* sheet = Rule()->GetStyleSheet()) { 49 sheet->WillDirty(); 50 } 51 } 52 return mDecls; 53 } 54 55 void CSSNestedDeclarationsDeclaration::SetRawAfterClone( 56 RefPtr<StyleLockedDeclarationBlock> aRaw) { 57 auto block = MakeRefPtr<DeclarationBlock>(aRaw.forget()); 58 mDecls->SetOwningRule(nullptr); 59 mDecls = std::move(block); 60 mDecls->SetOwningRule(Rule()); 61 } 62 63 nsresult CSSNestedDeclarationsDeclaration::SetCSSDeclaration( 64 DeclarationBlock* aDecl, MutationClosureData* aClosureData) { 65 CSSNestedDeclarations* rule = Rule(); 66 RefPtr<DeclarationBlock> oldDecls; 67 if (aDecl != mDecls) { 68 oldDecls = std::move(mDecls); 69 oldDecls->SetOwningRule(nullptr); 70 Servo_NestedDeclarationsRule_SetStyle(rule->Raw(), aDecl->Raw()); 71 mDecls = aDecl; 72 mDecls->SetOwningRule(rule); 73 } 74 if (StyleSheet* sheet = rule->GetStyleSheet()) { 75 sheet->RuleChanged(rule, {StyleRuleChangeKind::StyleRuleDeclarations, 76 oldDecls ? oldDecls.get() : aDecl, aDecl}); 77 } 78 return NS_OK; 79 } 80 81 nsDOMCSSDeclaration::ParsingEnvironment 82 CSSNestedDeclarationsDeclaration::GetParsingEnvironment(nsIPrincipal*) const { 83 return GetParsingEnvironmentForRule(Rule(), 84 StyleCssRuleType::NestedDeclarations); 85 } 86 87 CSSNestedDeclarations::CSSNestedDeclarations( 88 already_AddRefed<StyleLockedNestedDeclarationsRule> aRawRule, 89 StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, 90 uint32_t aColumn) 91 : css::Rule(aSheet, aParentRule, aLine, aColumn), 92 mRawRule(aRawRule), 93 mDecls(Servo_NestedDeclarationsRule_GetStyle(mRawRule).Consume()) {} 94 95 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSNestedDeclarations, css::Rule) 96 97 NS_IMPL_CYCLE_COLLECTION_CLASS(CSSNestedDeclarations) 98 99 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSNestedDeclarations, css::Rule) 100 // Keep this in sync with IsCCLeaf. 101 102 // Trace the wrapper for our declaration. This just expands out 103 // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use 104 // directly because the wrapper is on the declaration, not on us. 105 tmp->mDecls.TraceWrapper(aCallbacks, aClosure); 106 NS_IMPL_CYCLE_COLLECTION_TRACE_END 107 108 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSNestedDeclarations) 109 // Keep this in sync with IsCCLeaf. 110 111 // Unlink the wrapper for our declaration. 112 // Note that this has to happen before unlinking css::Rule. 113 tmp->UnlinkDeclarationWrapper(tmp->mDecls); 114 NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::Rule) 115 116 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSNestedDeclarations, 117 css::Rule) 118 // Keep this in sync with IsCCLeaf. 119 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 120 121 const StyleLockedDeclarationBlock* CSSNestedDeclarations::RawStyle() const { 122 return mDecls.mDecls->Raw(); 123 } 124 125 bool CSSNestedDeclarations::IsCCLeaf() const { 126 if (!css::Rule::IsCCLeaf()) { 127 return false; 128 } 129 return !mDecls.PreservingWrapper(); 130 } 131 132 void CSSNestedDeclarations::GetCssText(nsACString& aCssText) const { 133 Servo_NestedDeclarationsRule_GetCssText(mRawRule, &aCssText); 134 } 135 136 #ifdef DEBUG 137 void CSSNestedDeclarations::List(FILE* out, int32_t aIndent) const { 138 nsAutoCString str; 139 for (int32_t i = 0; i < aIndent; i++) { 140 str.AppendLiteral(" "); 141 } 142 Servo_NestedDeclarationsRule_Debug(mRawRule, &str); 143 fprintf_stderr(out, "%s\n", str.get()); 144 } 145 #endif 146 147 StyleCssRuleType CSSNestedDeclarations::Type() const { 148 return StyleCssRuleType::NestedDeclarations; 149 } 150 151 size_t CSSNestedDeclarations::SizeOfIncludingThis( 152 MallocSizeOf aMallocSizeOf) const { 153 size_t n = aMallocSizeOf(this); 154 155 // Measurement of the following members may be added later if DMD finds it 156 // is worthwhile: 157 // - mRawRule 158 // - mDecls 159 160 return n; 161 } 162 163 void CSSNestedDeclarations::SetRawAfterClone( 164 RefPtr<StyleLockedNestedDeclarationsRule> aRaw) { 165 mRawRule = std::move(aRaw); 166 mDecls.SetRawAfterClone( 167 Servo_NestedDeclarationsRule_GetStyle(mRawRule).Consume()); 168 } 169 170 JSObject* CSSNestedDeclarations::WrapObject(JSContext* aCx, 171 JS::Handle<JSObject*> aGivenProto) { 172 return CSSNestedDeclarations_Binding::Wrap(aCx, this, aGivenProto); 173 } 174 175 } // namespace mozilla::dom