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/. */
7 #include "mozilla/dom/CSSKeyframeRule.h"
9 #include "mozilla/DeclarationBlock.h"
10 #include "mozilla/dom/CSSKeyframeRuleBinding.h"
11 #include "nsDOMCSSDeclaration.h"
13 namespace mozilla::dom
{
15 // -------------------------------------------
16 // CSSKeyframeDeclaration
19 class CSSKeyframeDeclaration
: public nsDOMCSSDeclaration
{
21 explicit CSSKeyframeDeclaration(CSSKeyframeRule
* aRule
) : mRule(aRule
) {
23 new DeclarationBlock(Servo_Keyframe_GetStyle(aRule
->Raw()).Consume());
24 mDecls
->SetOwningRule(aRule
);
27 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
28 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS_AMBIGUOUS(CSSKeyframeDeclaration
,
31 css::Rule
* GetParentRule() final
{ return mRule
; }
33 void DropReference() {
35 mDecls
->SetOwningRule(nullptr);
38 DeclarationBlock
* GetOrCreateCSSDeclaration(
39 Operation aOperation
, DeclarationBlock
** aCreated
) final
{
40 if (aOperation
!= Operation::Read
&& mRule
) {
41 if (StyleSheet
* sheet
= mRule
->GetStyleSheet()) {
47 nsresult
SetCSSDeclaration(DeclarationBlock
* aDecls
,
48 MutationClosureData
* aClosureData
) final
{
52 mRule
->UpdateRule([this, aDecls
]() {
53 if (mDecls
!= aDecls
) {
54 mDecls
->SetOwningRule(nullptr);
56 mDecls
->SetOwningRule(mRule
);
57 Servo_Keyframe_SetStyle(mRule
->Raw(), mDecls
->Raw());
62 ParsingEnvironment
GetParsingEnvironment(
63 nsIPrincipal
* aSubjectPrincipal
) const final
{
64 return GetParsingEnvironmentForRule(mRule
, StyleCssRuleType::Keyframe
);
66 Document
* DocToUpdate() final
{ return nullptr; }
68 nsINode
* GetAssociatedNode() const final
{
69 return mRule
? mRule
->GetAssociatedDocumentOrShadowRoot() : nullptr;
72 nsISupports
* GetParentObject() const final
{
73 return mRule
? mRule
->GetParentObject() : nullptr;
76 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
77 size_t n
= aMallocSizeOf(this);
78 // TODO we may want to add size of mDecls as well
82 void SetRawAfterClone(StyleLockedKeyframe
* aKeyframe
) {
83 mDecls
->SetOwningRule(nullptr);
84 mDecls
= new DeclarationBlock(Servo_Keyframe_GetStyle(aKeyframe
).Consume());
85 mDecls
->SetOwningRule(mRule
);
89 virtual ~CSSKeyframeDeclaration() {
90 MOZ_ASSERT(!mRule
, "Backpointer should have been cleared");
93 CSSKeyframeRule
* mRule
;
94 RefPtr
<DeclarationBlock
> mDecls
;
97 NS_IMPL_CYCLE_COLLECTING_ADDREF(CSSKeyframeDeclaration
)
98 NS_IMPL_CYCLE_COLLECTING_RELEASE(CSSKeyframeDeclaration
)
100 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(CSSKeyframeDeclaration
)
102 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeDeclaration
)
103 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
104 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration
)
106 // -------------------------------------------
110 CSSKeyframeRule::CSSKeyframeRule(already_AddRefed
<StyleLockedKeyframe
> aRaw
,
111 StyleSheet
* aSheet
, css::Rule
* aParentRule
,
112 uint32_t aLine
, uint32_t aColumn
)
113 : css::Rule(aSheet
, aParentRule
, aLine
, aColumn
), mRaw(aRaw
) {}
115 CSSKeyframeRule::~CSSKeyframeRule() {
117 mDeclaration
->DropReference();
121 NS_IMPL_ADDREF_INHERITED(CSSKeyframeRule
, css::Rule
)
122 NS_IMPL_RELEASE_INHERITED(CSSKeyframeRule
, css::Rule
)
124 // QueryInterface implementation for nsCSSKeyframeRule
125 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeRule
)
126 NS_INTERFACE_MAP_END_INHERITING(css::Rule
)
128 NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframeRule
)
130 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSKeyframeRule
, css::Rule
)
131 if (tmp
->mDeclaration
) {
132 tmp
->mDeclaration
->DropReference();
133 tmp
->mDeclaration
= nullptr;
135 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
136 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframeRule
, css::Rule
)
137 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration
)
138 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
140 bool CSSKeyframeRule::IsCCLeaf() const {
141 return Rule::IsCCLeaf() && !mDeclaration
;
144 StyleCssRuleType
CSSKeyframeRule::Type() const {
145 return StyleCssRuleType::Keyframe
;
148 void CSSKeyframeRule::SetRawAfterClone(RefPtr
<StyleLockedKeyframe
> aRaw
) {
149 mRaw
= std::move(aRaw
);
152 mDeclaration
->SetRawAfterClone(mRaw
);
158 void CSSKeyframeRule::List(FILE* out
, int32_t aIndent
) const {
160 for (int32_t i
= 0; i
< aIndent
; i
++) {
161 str
.AppendLiteral(" ");
163 Servo_Keyframe_Debug(mRaw
, &str
);
164 fprintf_stderr(out
, "%s\n", str
.get());
168 template <typename Func
>
169 void CSSKeyframeRule::UpdateRule(Func aCallback
) {
174 StyleSheet
* sheet
= GetStyleSheet();
182 sheet
->RuleChanged(this, StyleRuleChangeKind::Generic
);
186 void CSSKeyframeRule::GetKeyText(nsACString
& aKeyText
) {
187 Servo_Keyframe_GetKeyText(mRaw
, &aKeyText
);
190 void CSSKeyframeRule::SetKeyText(const nsACString
& aKeyText
) {
192 [this, &aKeyText
]() { Servo_Keyframe_SetKeyText(mRaw
, &aKeyText
); });
195 void CSSKeyframeRule::GetCssText(nsACString
& aCssText
) const {
196 Servo_Keyframe_GetCssText(mRaw
, &aCssText
);
199 nsICSSDeclaration
* CSSKeyframeRule::Style() {
201 mDeclaration
= new CSSKeyframeDeclaration(this);
206 size_t CSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
207 size_t n
= aMallocSizeOf(this);
209 n
+= mDeclaration
->SizeOfIncludingThis(aMallocSizeOf
);
215 JSObject
* CSSKeyframeRule::WrapObject(JSContext
* aCx
,
216 JS::Handle
<JSObject
*> aGivenProto
) {
217 return CSSKeyframeRule_Binding::Wrap(aCx
, this, aGivenProto
);
220 } // namespace mozilla::dom