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