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
);
61 Document
* DocToUpdate() final
{ return nullptr; }
63 nsINode
* GetParentObject() final
{
64 return mRule
? mRule
->GetParentObject() : nullptr;
67 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
68 size_t n
= aMallocSizeOf(this);
69 // TODO we may want to add size of mDecls as well
74 virtual ~CSSKeyframeDeclaration() {
75 MOZ_ASSERT(!mRule
, "Backpointer should have been cleared");
78 CSSKeyframeRule
* mRule
;
79 RefPtr
<DeclarationBlock
> mDecls
;
82 NS_IMPL_CYCLE_COLLECTING_ADDREF(CSSKeyframeDeclaration
)
83 NS_IMPL_CYCLE_COLLECTING_RELEASE(CSSKeyframeDeclaration
)
85 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(CSSKeyframeDeclaration
)
87 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeDeclaration
)
88 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
89 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration
)
91 // -------------------------------------------
95 CSSKeyframeRule::CSSKeyframeRule(already_AddRefed
<RawServoKeyframe
> aRaw
,
96 StyleSheet
* aSheet
, css::Rule
* aParentRule
,
97 uint32_t aLine
, uint32_t aColumn
)
98 : css::Rule(aSheet
, aParentRule
, aLine
, aColumn
), mRaw(aRaw
) {}
100 CSSKeyframeRule::~CSSKeyframeRule() {
102 mDeclaration
->DropReference();
106 NS_IMPL_ADDREF_INHERITED(CSSKeyframeRule
, css::Rule
)
107 NS_IMPL_RELEASE_INHERITED(CSSKeyframeRule
, css::Rule
)
109 // QueryInterface implementation for nsCSSKeyframeRule
110 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeRule
)
111 NS_INTERFACE_MAP_END_INHERITING(css::Rule
)
113 NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframeRule
)
115 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSKeyframeRule
, css::Rule
)
116 if (tmp
->mDeclaration
) {
117 tmp
->mDeclaration
->DropReference();
118 tmp
->mDeclaration
= nullptr;
120 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
121 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframeRule
, css::Rule
)
122 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration
)
123 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
125 bool CSSKeyframeRule::IsCCLeaf() const {
126 return Rule::IsCCLeaf() && !mDeclaration
;
131 void CSSKeyframeRule::List(FILE* out
, int32_t aIndent
) const {
133 for (int32_t i
= 0; i
< aIndent
; i
++) {
134 str
.AppendLiteral(" ");
136 Servo_Keyframe_Debug(mRaw
, &str
);
137 fprintf_stderr(out
, "%s\n", str
.get());
141 template <typename Func
>
142 void CSSKeyframeRule::UpdateRule(Func aCallback
) {
149 if (StyleSheet
* sheet
= GetStyleSheet()) {
150 sheet
->RuleChanged(this);
154 void CSSKeyframeRule::GetKeyText(nsAString
& aKeyText
) {
155 Servo_Keyframe_GetKeyText(mRaw
, &aKeyText
);
158 void CSSKeyframeRule::SetKeyText(const nsAString
& aKeyText
) {
159 NS_ConvertUTF16toUTF8
keyText(aKeyText
);
160 UpdateRule([this, &keyText
]() { Servo_Keyframe_SetKeyText(mRaw
, &keyText
); });
163 void CSSKeyframeRule::GetCssText(nsAString
& aCssText
) const {
164 Servo_Keyframe_GetCssText(mRaw
, &aCssText
);
167 nsICSSDeclaration
* CSSKeyframeRule::Style() {
169 mDeclaration
= new CSSKeyframeDeclaration(this);
174 size_t CSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
175 size_t n
= aMallocSizeOf(this);
177 n
+= mDeclaration
->SizeOfIncludingThis(aMallocSizeOf
);
183 JSObject
* CSSKeyframeRule::WrapObject(JSContext
* aCx
,
184 JS::Handle
<JSObject
*> aGivenProto
) {
185 return CSSKeyframeRule_Binding::Wrap(aCx
, this, aGivenProto
);
189 } // namespace mozilla