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"
16 // -------------------------------------------
17 // CSSKeyframeDeclaration
20 class CSSKeyframeDeclaration
: public nsDOMCSSDeclaration
{
22 explicit CSSKeyframeDeclaration(CSSKeyframeRule
* aRule
) : mRule(aRule
) {
24 new DeclarationBlock(Servo_Keyframe_GetStyle(aRule
->Raw()).Consume());
27 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
28 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_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
{
42 nsresult
SetCSSDeclaration(DeclarationBlock
* aDecls
,
43 MutationClosureData
* aClosureData
) final
{
47 mRule
->UpdateRule([this, aDecls
]() {
48 if (mDecls
!= aDecls
) {
49 mDecls
->SetOwningRule(nullptr);
51 mDecls
->SetOwningRule(mRule
);
52 Servo_Keyframe_SetStyle(mRule
->Raw(), mDecls
->Raw());
57 ParsingEnvironment
GetParsingEnvironment(
58 nsIPrincipal
* aSubjectPrincipal
) const final
{
59 return GetParsingEnvironmentForRule(mRule
, CSSRule_Binding::KEYFRAME_RULE
);
61 Document
* DocToUpdate() final
{ return nullptr; }
63 nsINode
* GetAssociatedNode() const final
{
64 return mRule
? mRule
->GetAssociatedDocumentOrShadowRoot() : nullptr;
67 nsISupports
* GetParentObject() const final
{
68 return mRule
? mRule
->GetParentObject() : nullptr;
71 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
72 size_t n
= aMallocSizeOf(this);
73 // TODO we may want to add size of mDecls as well
78 virtual ~CSSKeyframeDeclaration() {
79 MOZ_ASSERT(!mRule
, "Backpointer should have been cleared");
82 CSSKeyframeRule
* mRule
;
83 RefPtr
<DeclarationBlock
> mDecls
;
86 NS_IMPL_CYCLE_COLLECTING_ADDREF(CSSKeyframeDeclaration
)
87 NS_IMPL_CYCLE_COLLECTING_RELEASE(CSSKeyframeDeclaration
)
89 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(CSSKeyframeDeclaration
)
91 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeDeclaration
)
92 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
93 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration
)
95 // -------------------------------------------
99 CSSKeyframeRule::CSSKeyframeRule(already_AddRefed
<RawServoKeyframe
> aRaw
,
100 StyleSheet
* aSheet
, css::Rule
* aParentRule
,
101 uint32_t aLine
, uint32_t aColumn
)
102 : css::Rule(aSheet
, aParentRule
, aLine
, aColumn
), mRaw(aRaw
) {}
104 CSSKeyframeRule::~CSSKeyframeRule() {
106 mDeclaration
->DropReference();
110 NS_IMPL_ADDREF_INHERITED(CSSKeyframeRule
, css::Rule
)
111 NS_IMPL_RELEASE_INHERITED(CSSKeyframeRule
, css::Rule
)
113 // QueryInterface implementation for nsCSSKeyframeRule
114 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeRule
)
115 NS_INTERFACE_MAP_END_INHERITING(css::Rule
)
117 NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframeRule
)
119 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSKeyframeRule
, css::Rule
)
120 if (tmp
->mDeclaration
) {
121 tmp
->mDeclaration
->DropReference();
122 tmp
->mDeclaration
= nullptr;
124 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
125 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframeRule
, css::Rule
)
126 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration
)
127 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
129 bool CSSKeyframeRule::IsCCLeaf() const {
130 return Rule::IsCCLeaf() && !mDeclaration
;
135 void CSSKeyframeRule::List(FILE* out
, int32_t aIndent
) const {
137 for (int32_t i
= 0; i
< aIndent
; i
++) {
138 str
.AppendLiteral(" ");
140 Servo_Keyframe_Debug(mRaw
, &str
);
141 fprintf_stderr(out
, "%s\n", str
.get());
145 template <typename Func
>
146 void CSSKeyframeRule::UpdateRule(Func aCallback
) {
153 if (StyleSheet
* sheet
= GetStyleSheet()) {
154 sheet
->RuleChanged(this, StyleRuleChangeKind::Generic
);
158 void CSSKeyframeRule::GetKeyText(nsACString
& aKeyText
) {
159 Servo_Keyframe_GetKeyText(mRaw
, &aKeyText
);
162 void CSSKeyframeRule::SetKeyText(const nsACString
& aKeyText
) {
164 [this, &aKeyText
]() { Servo_Keyframe_SetKeyText(mRaw
, &aKeyText
); });
167 void CSSKeyframeRule::GetCssText(nsACString
& aCssText
) const {
168 Servo_Keyframe_GetCssText(mRaw
, &aCssText
);
171 nsICSSDeclaration
* CSSKeyframeRule::Style() {
173 mDeclaration
= new CSSKeyframeDeclaration(this);
178 size_t CSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
179 size_t n
= aMallocSizeOf(this);
181 n
+= mDeclaration
->SizeOfIncludingThis(aMallocSizeOf
);
187 JSObject
* CSSKeyframeRule::WrapObject(JSContext
* aCx
,
188 JS::Handle
<JSObject
*> aGivenProto
) {
189 return CSSKeyframeRule_Binding::Wrap(aCx
, this, aGivenProto
);
193 } // namespace mozilla