CSSMarginRule.cpp (6078B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=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/CSSMarginRule.h" 8 9 #include "mozilla/DeclarationBlock.h" 10 #include "mozilla/ServoBindings.h" 11 #include "mozilla/dom/CSSMarginRuleBinding.h" 12 13 namespace mozilla::dom { 14 15 // -- CSSMarginRuleDeclaration --------------------------------------- 16 17 CSSMarginRuleDeclaration::CSSMarginRuleDeclaration( 18 already_AddRefed<StyleLockedDeclarationBlock> aDecls) 19 : mDecls(new DeclarationBlock(std::move(aDecls))) { 20 mDecls->SetOwningRule(Rule()); 21 } 22 23 CSSMarginRuleDeclaration::~CSSMarginRuleDeclaration() { 24 mDecls->SetOwningRule(nullptr); 25 } 26 27 // QueryInterface implementation for CSSMarginRuleDeclaration 28 NS_INTERFACE_MAP_BEGIN(CSSMarginRuleDeclaration) 29 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 30 // We forward the cycle collection interfaces to Rule(), which is 31 // never null (in fact, we're part of that object!) 32 if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) || 33 aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) { 34 return Rule()->QueryInterface(aIID, aInstancePtr); 35 } 36 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) 37 38 NS_IMPL_ADDREF_USING_AGGREGATOR(CSSMarginRuleDeclaration, Rule()) 39 NS_IMPL_RELEASE_USING_AGGREGATOR(CSSMarginRuleDeclaration, Rule()) 40 41 /* nsDOMCSSDeclaration implementation */ 42 css::Rule* CSSMarginRuleDeclaration::GetParentRule() { return Rule(); } 43 44 nsINode* CSSMarginRuleDeclaration::GetAssociatedNode() const { 45 return Rule()->GetAssociatedDocumentOrShadowRoot(); 46 } 47 48 nsISupports* CSSMarginRuleDeclaration::GetParentObject() const { 49 return Rule()->GetParentObject(); 50 } 51 52 DeclarationBlock* CSSMarginRuleDeclaration::GetOrCreateCSSDeclaration( 53 Operation aOperation, DeclarationBlock** aCreated) { 54 if (aOperation != Operation::Read) { 55 if (StyleSheet* sheet = Rule()->GetStyleSheet()) { 56 sheet->WillDirty(); 57 } 58 } 59 return mDecls; 60 } 61 62 void CSSMarginRuleDeclaration::SetRawAfterClone( 63 RefPtr<StyleLockedDeclarationBlock> aDeclarationBlock) { 64 mDecls->SetOwningRule(nullptr); 65 mDecls = new DeclarationBlock(aDeclarationBlock.forget()); 66 mDecls->SetOwningRule(Rule()); 67 } 68 69 nsresult CSSMarginRuleDeclaration::SetCSSDeclaration( 70 DeclarationBlock* aDecl, MutationClosureData* aClosureData) { 71 MOZ_ASSERT(aDecl, "must be non-null"); 72 CSSMarginRule* rule = Rule(); 73 74 if (aDecl != mDecls) { 75 mDecls->SetOwningRule(nullptr); 76 RefPtr<DeclarationBlock> decls = aDecl; 77 // TODO alaskanemily: bug 1890418 for implementing this and margin-rule 78 // style properties in general. 79 // Servo_MarginRule_SetStyle(rule->Raw(), decls->Raw()); 80 mDecls = std::move(decls); 81 mDecls->SetOwningRule(rule); 82 } 83 84 return NS_OK; 85 } 86 87 nsDOMCSSDeclaration::ParsingEnvironment 88 CSSMarginRuleDeclaration::GetParsingEnvironment( 89 nsIPrincipal* aSubjectPrincipal) const { 90 return GetParsingEnvironmentForRule(Rule(), StyleCssRuleType::Margin); 91 } 92 93 // -- CSSMarginRule -------------------------------------------------- 94 95 CSSMarginRule::CSSMarginRule(RefPtr<StyleMarginRule> aRawRule, 96 StyleSheet* aSheet, css::Rule* aParentRule, 97 uint32_t aLine, uint32_t aColumn) 98 : css::Rule(aSheet, aParentRule, aLine, aColumn), 99 mRawRule(std::move(aRawRule)), 100 mDecls(Servo_MarginRule_GetStyle(mRawRule).Consume()) {} 101 102 NS_IMPL_ADDREF_INHERITED(CSSMarginRule, css::Rule) 103 NS_IMPL_RELEASE_INHERITED(CSSMarginRule, css::Rule) 104 105 // QueryInterface implementation for MarginRule 106 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSMarginRule) 107 NS_INTERFACE_MAP_END_INHERITING(css::Rule) 108 109 NS_IMPL_CYCLE_COLLECTION_CLASS(CSSMarginRule) 110 111 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSMarginRule, css::Rule) 112 // Keep this in sync with IsCCLeaf. 113 114 // Trace the wrapper for our declaration. This just expands out 115 // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use 116 // directly because the wrapper is on the declaration, not on us. 117 tmp->mDecls.TraceWrapper(aCallbacks, aClosure); 118 NS_IMPL_CYCLE_COLLECTION_TRACE_END 119 120 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSMarginRule) 121 // Keep this in sync with IsCCLeaf. 122 123 // Unlink the wrapper for our declaration. 124 // 125 // Note that this has to happen before unlinking css::Rule. 126 tmp->UnlinkDeclarationWrapper(tmp->mDecls); 127 tmp->mDecls.mDecls->SetOwningRule(nullptr); 128 NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::Rule) 129 130 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSMarginRule, css::Rule) 131 // Keep this in sync with IsCCLeaf. 132 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 133 134 bool CSSMarginRule::IsCCLeaf() const { 135 if (!Rule::IsCCLeaf()) { 136 return false; 137 } 138 139 return !mDecls.PreservingWrapper(); 140 } 141 142 void CSSMarginRule::SetRawAfterClone(RefPtr<StyleMarginRule> aRaw) { 143 mRawRule = std::move(aRaw); 144 mDecls.SetRawAfterClone(Servo_MarginRule_GetStyle(mRawRule.get()).Consume()); 145 } 146 147 // WebIDL interfaces 148 StyleCssRuleType CSSMarginRule::Type() const { 149 return StyleCssRuleType::Margin; 150 } 151 152 // CSSRule implementation 153 154 void CSSMarginRule::GetCssText(nsACString& aCssText) const { 155 Servo_MarginRule_GetCssText(mRawRule, &aCssText); 156 } 157 158 void CSSMarginRule::GetName(nsACString& aRuleName) const { 159 Servo_MarginRule_GetName(mRawRule, &aRuleName); 160 } 161 162 size_t CSSMarginRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { 163 // TODO Implement this! 164 return aMallocSizeOf(this); 165 } 166 167 #ifdef DEBUG 168 void CSSMarginRule::List(FILE* out, int32_t aIndent) const { 169 nsAutoCString str; 170 for (int32_t i = 0; i < aIndent; i++) { 171 str.AppendLiteral(" "); 172 } 173 Servo_MarginRule_Debug(mRawRule, &str); 174 fprintf_stderr(out, "%s\n", str.get()); 175 } 176 #endif 177 178 JSObject* CSSMarginRule::WrapObject(JSContext* aCx, 179 JS::Handle<JSObject*> aGivenProto) { 180 return CSSMarginRule_Binding::Wrap(aCx, this, aGivenProto); 181 } 182 183 } // namespace mozilla::dom