Bug 1550804 - Add color scheme simulation to the inspector. r=pbro
[gecko.git] / layout / style / CSSKeyframeRule.cpp
blobd8f9232bee25f9202fdc0005a1497fd31b5818be
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 {
14 namespace dom {
16 // -------------------------------------------
17 // CSSKeyframeDeclaration
20 class CSSKeyframeDeclaration : public nsDOMCSSDeclaration {
21 public:
22 explicit CSSKeyframeDeclaration(CSSKeyframeRule* aRule) : mRule(aRule) {
23 mDecls =
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,
29 nsICSSDeclaration)
31 css::Rule* GetParentRule() final { return mRule; }
33 void DropReference() {
34 mRule = nullptr;
35 mDecls->SetOwningRule(nullptr);
38 DeclarationBlock* GetOrCreateCSSDeclaration(
39 Operation aOperation, DeclarationBlock** aCreated) final {
40 return mDecls;
42 nsresult SetCSSDeclaration(DeclarationBlock* aDecls,
43 MutationClosureData* aClosureData) final {
44 if (!mRule) {
45 return NS_OK;
47 mRule->UpdateRule([this, aDecls]() {
48 if (mDecls != aDecls) {
49 mDecls->SetOwningRule(nullptr);
50 mDecls = aDecls;
51 mDecls->SetOwningRule(mRule);
52 Servo_Keyframe_SetStyle(mRule->Raw(), mDecls->Raw());
54 });
55 return NS_OK;
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
70 return n;
73 private:
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 // -------------------------------------------
92 // CSSKeyframeRule
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() {
101 if (mDeclaration) {
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;
129 #ifdef DEBUG
130 /* virtual */
131 void CSSKeyframeRule::List(FILE* out, int32_t aIndent) const {
132 nsAutoCString str;
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());
139 #endif
141 template <typename Func>
142 void CSSKeyframeRule::UpdateRule(Func aCallback) {
143 if (IsReadOnly()) {
144 return;
147 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() {
168 if (!mDeclaration) {
169 mDeclaration = new CSSKeyframeDeclaration(this);
171 return mDeclaration;
174 size_t CSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
175 size_t n = aMallocSizeOf(this);
176 if (mDeclaration) {
177 n += mDeclaration->SizeOfIncludingThis(aMallocSizeOf);
179 return n;
182 /* virtual */
183 JSObject* CSSKeyframeRule::WrapObject(JSContext* aCx,
184 JS::Handle<JSObject*> aGivenProto) {
185 return CSSKeyframeRule_Binding::Wrap(aCx, this, aGivenProto);
188 } // namespace dom
189 } // namespace mozilla