CSSImportRule.cpp (4834B)
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/CSSImportRule.h" 8 9 #include "mozilla/ServoBindings.h" 10 #include "mozilla/StyleSheet.h" 11 #include "mozilla/dom/CSSImportRuleBinding.h" 12 #include "mozilla/dom/MediaList.h" 13 14 namespace mozilla { 15 namespace dom { 16 17 CSSImportRule::CSSImportRule(RefPtr<StyleLockedImportRule> aRawRule, 18 StyleSheet* aSheet, css::Rule* aParentRule, 19 uint32_t aLine, uint32_t aColumn) 20 : css::Rule(aSheet, aParentRule, aLine, aColumn), 21 mRawRule(std::move(aRawRule)) { 22 const auto* sheet = Servo_ImportRule_GetSheet(mRawRule.get()); 23 mChildSheet = const_cast<StyleSheet*>(sheet); 24 if (mChildSheet) { 25 mChildSheet->AddReferencingRule(*this); 26 } 27 } 28 29 CSSImportRule::~CSSImportRule() { 30 if (mChildSheet) { 31 mChildSheet->RemoveReferencingRule(*this); 32 } 33 } 34 35 // QueryInterface implementation for CSSImportRule 36 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSImportRule) 37 NS_INTERFACE_MAP_END_INHERITING(css::Rule) 38 39 NS_IMPL_CYCLE_COLLECTION_CLASS(CSSImportRule) 40 41 NS_IMPL_ADDREF_INHERITED(CSSImportRule, css::Rule) 42 NS_IMPL_RELEASE_INHERITED(CSSImportRule, css::Rule) 43 44 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSImportRule, css::Rule) 45 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildSheet"); 46 cb.NoteXPCOMChild(tmp->mChildSheet); 47 MOZ_ASSERT_IF(tmp->mRawRule, 48 Servo_ImportRule_GetSheet(tmp->mRawRule) == tmp->mChildSheet); 49 // Note the child sheet twice, since the Servo rule also holds a strong 50 // reference to it, but only if we're the "primary" rule reference. 51 if (tmp->mChildSheet && tmp->mChildSheet->GetOwnerRule() == tmp) { 52 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRawRule.stylesheet"); 53 cb.NoteXPCOMChild(tmp->mChildSheet); 54 } 55 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 56 57 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSImportRule) 58 if (tmp->mChildSheet) { 59 tmp->mChildSheet->RemoveReferencingRule(*tmp); 60 tmp->mChildSheet = nullptr; 61 } 62 tmp->mRawRule = nullptr; 63 NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::Rule) 64 65 #ifdef DEBUG 66 /* virtual */ 67 void CSSImportRule::List(FILE* out, int32_t aIndent) const { 68 nsAutoCString str; 69 for (int32_t i = 0; i < aIndent; i++) { 70 str.AppendLiteral(" "); 71 } 72 Servo_ImportRule_Debug(mRawRule, &str); 73 fprintf_stderr(out, "%s\n", str.get()); 74 } 75 #endif 76 77 StyleCssRuleType CSSImportRule::Type() const { 78 return StyleCssRuleType::Import; 79 } 80 81 void CSSImportRule::SetRawAfterClone(RefPtr<StyleLockedImportRule> aRaw) { 82 mRawRule = std::move(aRaw); 83 if (mChildSheet) { 84 mChildSheet->RemoveReferencingRule(*this); 85 } 86 mChildSheet = 87 const_cast<StyleSheet*>(Servo_ImportRule_GetSheet(mRawRule.get())); 88 if (mChildSheet) { 89 mChildSheet->AddReferencingRule(*this); 90 } 91 } 92 93 StyleSheet* CSSImportRule::GetStyleSheetForBindings() { 94 if (mChildSheet) { 95 // FIXME(emilio): This is needed to make sure we don't expose shared sheets 96 // to the OM (see wpt /css/cssom/cssimportrule-sheet-identity.html for 97 // example). 98 // 99 // Perhaps instead we could create a clone of the stylesheet and keep it in 100 // mChildSheet, without calling EnsureUniqueInner(), or something like that? 101 if (StyleSheet* parent = GetParentStyleSheet()) { 102 parent->EnsureUniqueInner(); 103 } 104 } 105 return mChildSheet; 106 } 107 108 dom::MediaList* CSSImportRule::GetMedia() { 109 auto* sheet = GetStyleSheetForBindings(); 110 return sheet ? sheet->Media() : nullptr; 111 } 112 113 void CSSImportRule::DropSheetReference() { 114 if (mChildSheet) { 115 mChildSheet->RemoveFromParent(); 116 } 117 Rule::DropSheetReference(); 118 } 119 120 void CSSImportRule::GetHref(nsAString& aHref) const { 121 Servo_ImportRule_GetHref(mRawRule, &aHref); 122 } 123 124 void CSSImportRule::GetLayerName(nsACString& aName) const { 125 Servo_ImportRule_GetLayerName(mRawRule, &aName); 126 } 127 128 void CSSImportRule::GetSupportsText(nsACString& aSupportsText) const { 129 Servo_ImportRule_GetSupportsText(mRawRule, &aSupportsText); 130 } 131 132 /* virtual */ 133 void CSSImportRule::GetCssText(nsACString& aCssText) const { 134 Servo_ImportRule_GetCssText(mRawRule, &aCssText); 135 } 136 137 /* virtual */ 138 size_t CSSImportRule::SizeOfIncludingThis( 139 mozilla::MallocSizeOf aMallocSizeOf) const { 140 // TODO Implement this! 141 return aMallocSizeOf(this); 142 } 143 144 bool CSSImportRule::IsCCLeaf() const { 145 // We're not a leaf. 146 return false; 147 } 148 149 /* virtual */ 150 JSObject* CSSImportRule::WrapObject(JSContext* aCx, 151 JS::Handle<JSObject*> aGivenProto) { 152 return CSSImportRule_Binding::Wrap(aCx, this, aGivenProto); 153 } 154 155 } // namespace dom 156 } // namespace mozilla