Bug 1451289 - Part 2: Merge ServoKeyframesRule and CSSKeyframesRule r=emilio

MozReview-Commit-ID: FVwVgQZ0B6Q

--HG--
extra : rebase_source : b10e638097a27e581f9c8b95ae8e21ec7b7ac175
This commit is contained in:
Nazım Can Altınova 2018-06-04 12:09:11 +02:00
Родитель 6cdcd1d100
Коммит 92aa0e63d1
11 изменённых файлов: 589 добавлений и 688 удалений

Просмотреть файл

@ -6,12 +6,201 @@
#include "mozilla/dom/CSSKeyframeRule.h"
#include "mozilla/DeclarationBlock.h"
#include "mozilla/dom/CSSKeyframeRuleBinding.h"
#include "nsICSSDeclaration.h"
#include "nsDOMCSSDeclaration.h"
namespace mozilla {
namespace dom {
// -------------------------------------------
// CSSKeyframeDeclaration
//
class CSSKeyframeDeclaration : public nsDOMCSSDeclaration
{
public:
explicit CSSKeyframeDeclaration(CSSKeyframeRule* aRule)
: mRule(aRule)
{
mDecls = new DeclarationBlock(
Servo_Keyframe_GetStyle(aRule->Raw()).Consume());
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
CSSKeyframeDeclaration, nsICSSDeclaration)
css::Rule* GetParentRule() final { return mRule; }
void DropReference() {
mRule = nullptr;
mDecls->SetOwningRule(nullptr);
}
DeclarationBlock* GetCSSDeclaration(Operation aOperation) final
{
return mDecls;
}
nsresult SetCSSDeclaration(DeclarationBlock* aDecls) final
{
if (!mRule) {
return NS_OK;
}
mRule->UpdateRule([this, aDecls]() {
if (mDecls != aDecls) {
mDecls->SetOwningRule(nullptr);
mDecls = aDecls;
mDecls->SetOwningRule(mRule);
Servo_Keyframe_SetStyle(mRule->Raw(), mDecls->Raw());
}
});
return NS_OK;
}
ParsingEnvironment GetParsingEnvironment(
nsIPrincipal* aSubjectPrincipal) const final
{
return GetParsingEnvironmentForRule(mRule);
}
nsIDocument* DocToUpdate() final { return nullptr; }
nsINode* GetParentObject() final
{
return mRule ? mRule->GetParentObject() : nullptr;
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
// TODO we may want to add size of mDecls as well
return n;
}
private:
virtual ~CSSKeyframeDeclaration() {
MOZ_ASSERT(!mRule, "Backpointer should have been cleared");
}
CSSKeyframeRule* mRule;
RefPtr<DeclarationBlock> mDecls;
};
NS_IMPL_CYCLE_COLLECTING_ADDREF(CSSKeyframeDeclaration)
NS_IMPL_CYCLE_COLLECTING_RELEASE(CSSKeyframeDeclaration)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(CSSKeyframeDeclaration)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeDeclaration)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
// -------------------------------------------
// CSSKeyframeRule
//
CSSKeyframeRule::CSSKeyframeRule(already_AddRefed<RawServoKeyframe> aRaw,
uint32_t aLine, uint32_t aColumn)
: css::Rule(aLine, aColumn)
, mRaw(aRaw) {}
CSSKeyframeRule::~CSSKeyframeRule()
{
if (mDeclaration) {
mDeclaration->DropReference();
}
}
NS_IMPL_ADDREF_INHERITED(CSSKeyframeRule, css::Rule)
NS_IMPL_RELEASE_INHERITED(CSSKeyframeRule, css::Rule)
// QueryInterface implementation for nsCSSKeyframeRule
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeRule)
NS_INTERFACE_MAP_END_INHERITING(css::Rule)
NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframeRule)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSKeyframeRule,
css::Rule)
if (tmp->mDeclaration) {
tmp->mDeclaration->DropReference();
tmp->mDeclaration = nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframeRule,
css::Rule)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
bool
CSSKeyframeRule::IsCCLeaf() const
{
return Rule::IsCCLeaf() && !mDeclaration;
}
#ifdef DEBUG
/* virtual */ void
CSSKeyframeRule::List(FILE* out, int32_t aIndent) const
{
nsAutoCString str;
for (int32_t i = 0; i < aIndent; i++) {
str.AppendLiteral(" ");
}
Servo_Keyframe_Debug(mRaw, &str);
fprintf_stderr(out, "%s\n", str.get());
}
#endif
template<typename Func>
void
CSSKeyframeRule::UpdateRule(Func aCallback)
{
aCallback();
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
}
}
void
CSSKeyframeRule::GetKeyText(nsAString& aKeyText)
{
Servo_Keyframe_GetKeyText(mRaw, &aKeyText);
}
void
CSSKeyframeRule::SetKeyText(const nsAString& aKeyText)
{
NS_ConvertUTF16toUTF8 keyText(aKeyText);
UpdateRule([this, &keyText]() {
Servo_Keyframe_SetKeyText(mRaw, &keyText);
});
}
void
CSSKeyframeRule::GetCssText(nsAString& aCssText) const
{
Servo_Keyframe_GetCssText(mRaw, &aCssText);
}
nsICSSDeclaration*
CSSKeyframeRule::Style()
{
if (!mDeclaration) {
mDeclaration = new CSSKeyframeDeclaration(this);
}
return mDeclaration;
}
size_t
CSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
if (mDeclaration) {
n += mDeclaration->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
/* virtual */ JSObject*
CSSKeyframeRule::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)

Просмотреть файл

@ -8,30 +8,55 @@
#define mozilla_dom_CSSKeyframeRule_h
#include "mozilla/css/Rule.h"
#include "mozilla/ServoBindingTypes.h"
class nsICSSDeclaration;
class DeclarationBlock;
namespace mozilla {
namespace dom {
class CSSKeyframeRule : public css::Rule
{
protected:
using css::Rule::Rule;
virtual ~CSSKeyframeRule() {}
class CSSKeyframeDeclaration;
class CSSKeyframeRule final : public css::Rule
{
public:
bool IsCCLeaf() const override { return Rule::IsCCLeaf(); }
CSSKeyframeRule(already_AddRefed<RawServoKeyframe> aRaw,
uint32_t aLine, uint32_t aColumn);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSKeyframeRule,
css::Rule)
bool IsCCLeaf() const final;
#ifdef DEBUG
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
#endif
RawServoKeyframe* Raw() const { return mRaw; }
// WebIDL interface
uint16_t Type() const final { return CSSRuleBinding::KEYFRAME_RULE; }
virtual void GetKeyText(nsAString& aKey) = 0;
virtual void SetKeyText(const nsAString& aKey) = 0;
virtual nsICSSDeclaration* Style() = 0;
void GetCssText(nsAString& aCssText) const final;
void GetKeyText(nsAString& aKey);
void SetKeyText(const nsAString& aKey);
nsICSSDeclaration* Style();
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override = 0;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
private:
virtual ~CSSKeyframeRule();
friend class CSSKeyframeDeclaration;
template<typename Func>
void UpdateRule(Func aCallback);
RefPtr<RawServoKeyframe> mRaw;
// lazily created when needed
RefPtr<CSSKeyframeDeclaration> mDeclaration;
};
} // namespace dom

Просмотреть файл

@ -7,10 +7,334 @@
#include "mozilla/dom/CSSKeyframesRule.h"
#include "mozilla/dom/CSSKeyframesRuleBinding.h"
#include "mozilla/dom/CSSRuleList.h"
#include "mozilla/ServoBindings.h"
#include <limits>
namespace mozilla {
namespace dom {
// -------------------------------------------
// CSSKeyframeList
//
class CSSKeyframeList : public dom::CSSRuleList
{
public:
explicit CSSKeyframeList(already_AddRefed<RawServoKeyframesRule> aRawRule)
: mRawRule(aRawRule)
{
mRules.SetCount(Servo_KeyframesRule_GetCount(mRawRule));
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSKeyframeList, dom::CSSRuleList)
void SetParentRule(CSSKeyframesRule* aParentRule)
{
mParentRule = aParentRule;
for (css::Rule* rule : mRules) {
if (rule) {
rule->SetParentRule(aParentRule);
}
}
}
void SetStyleSheet(StyleSheet* aSheet)
{
mStyleSheet = aSheet;
for (css::Rule* rule : mRules) {
if (rule) {
rule->SetStyleSheet(aSheet);
}
}
}
StyleSheet* GetParentObject() final { return mStyleSheet; }
CSSKeyframeRule* GetRule(uint32_t aIndex) {
if (!mRules[aIndex]) {
uint32_t line = 0, column = 0;
RefPtr<RawServoKeyframe> rule =
Servo_KeyframesRule_GetKeyframeAt(mRawRule, aIndex,
&line, &column).Consume();
CSSKeyframeRule* ruleObj =
new CSSKeyframeRule(rule.forget(), line, column);
mRules.ReplaceObjectAt(ruleObj, aIndex);
ruleObj->SetStyleSheet(mStyleSheet);
ruleObj->SetParentRule(mParentRule);
}
return static_cast<CSSKeyframeRule*>(mRules[aIndex]);
}
CSSKeyframeRule* IndexedGetter(uint32_t aIndex, bool& aFound) final
{
if (aIndex >= mRules.Length()) {
aFound = false;
return nullptr;
}
aFound = true;
return GetRule(aIndex);
}
void AppendRule() {
mRules.AppendObject(nullptr);
}
void RemoveRule(uint32_t aIndex) {
mRules.RemoveObjectAt(aIndex);
}
uint32_t Length() final { return mRules.Length(); }
void DropReference()
{
mStyleSheet = nullptr;
mParentRule = nullptr;
for (css::Rule* rule : mRules) {
if (rule) {
rule->SetStyleSheet(nullptr);
rule->SetParentRule(nullptr);
}
}
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
for (const css::Rule* rule : mRules) {
n += rule ? rule->SizeOfIncludingThis(aMallocSizeOf) : 0;
}
return n;
}
private:
virtual ~CSSKeyframeList() {
MOZ_ASSERT(!mParentRule, "Backpointer should have been cleared");
MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
DropAllRules();
}
void DropAllRules()
{
if (mParentRule || mStyleSheet) {
DropReference();
}
mRules.Clear();
mRawRule = nullptr;
}
// may be nullptr when the style sheet drops the reference to us.
StyleSheet* mStyleSheet = nullptr;
CSSKeyframesRule* mParentRule = nullptr;
RefPtr<RawServoKeyframesRule> mRawRule;
nsCOMArray<css::Rule> mRules;
};
// QueryInterface implementation for CSSKeyframeList
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeList)
NS_INTERFACE_MAP_END_INHERITING(dom::CSSRuleList)
NS_IMPL_ADDREF_INHERITED(CSSKeyframeList, dom::CSSRuleList)
NS_IMPL_RELEASE_INHERITED(CSSKeyframeList, dom::CSSRuleList)
NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframeList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSKeyframeList)
tmp->DropAllRules();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(dom::CSSRuleList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframeList,
dom::CSSRuleList)
for (css::Rule* rule : tmp->mRules) {
if (rule) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
cb.NoteXPCOMChild(rule);
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
// -------------------------------------------
// CSSKeyframesRule
//
CSSKeyframesRule::CSSKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
uint32_t aLine, uint32_t aColumn)
: css::Rule(aLine, aColumn)
, mRawRule(std::move(aRawRule))
{
}
CSSKeyframesRule::~CSSKeyframesRule()
{
if (mKeyframeList) {
mKeyframeList->DropReference();
}
}
NS_IMPL_ADDREF_INHERITED(CSSKeyframesRule, css::Rule)
NS_IMPL_RELEASE_INHERITED(CSSKeyframesRule, css::Rule)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframesRule)
NS_INTERFACE_MAP_END_INHERITING(css::Rule)
NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframesRule)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSKeyframesRule,
css::Rule)
if (tmp->mKeyframeList) {
tmp->mKeyframeList->DropReference();
tmp->mKeyframeList = nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframesRule, Rule)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mKeyframeList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
/* virtual */ bool
CSSKeyframesRule::IsCCLeaf() const
{
// If we don't have rule list constructed, we are a leaf.
return Rule::IsCCLeaf() && !mKeyframeList;
}
#ifdef DEBUG
/* virtual */ void
CSSKeyframesRule::List(FILE* out, int32_t aIndent) const
{
nsAutoCString str;
for (int32_t i = 0; i < aIndent; i++) {
str.AppendLiteral(" ");
}
Servo_KeyframesRule_Debug(mRawRule, &str);
fprintf_stderr(out, "%s\n", str.get());
}
#endif
/* virtual */ void
CSSKeyframesRule::SetStyleSheet(StyleSheet* aSheet)
{
if (mKeyframeList) {
mKeyframeList->SetStyleSheet(aSheet);
}
css::Rule::SetStyleSheet(aSheet);
}
static const uint32_t kRuleNotFound = std::numeric_limits<uint32_t>::max();
uint32_t
CSSKeyframesRule::FindRuleIndexForKey(const nsAString& aKey)
{
NS_ConvertUTF16toUTF8 key(aKey);
return Servo_KeyframesRule_FindRule(mRawRule, &key);
}
template<typename Func>
void
CSSKeyframesRule::UpdateRule(Func aCallback)
{
aCallback();
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
}
}
void
CSSKeyframesRule::GetName(nsAString& aName) const
{
nsAtom* name = Servo_KeyframesRule_GetName(mRawRule);
aName = nsDependentAtomString(name);
}
void
CSSKeyframesRule::SetName(const nsAString& aName)
{
RefPtr<nsAtom> name = NS_Atomize(aName);
nsAtom* oldName = Servo_KeyframesRule_GetName(mRawRule);
if (name == oldName) {
return;
}
UpdateRule([this, &name]() {
Servo_KeyframesRule_SetName(mRawRule, name.forget().take());
});
}
void
CSSKeyframesRule::AppendRule(const nsAString& aRule)
{
StyleSheet* sheet = GetStyleSheet();
if (!sheet) {
// We cannot parse the rule if we don't have a stylesheet.
return;
}
NS_ConvertUTF16toUTF8 rule(aRule);
UpdateRule([this, sheet, &rule]() {
bool parsedOk = Servo_KeyframesRule_AppendRule(
mRawRule, sheet->RawContents(), &rule);
if (parsedOk && mKeyframeList) {
mKeyframeList->AppendRule();
}
});
}
void
CSSKeyframesRule::DeleteRule(const nsAString& aKey)
{
auto index = FindRuleIndexForKey(aKey);
if (index == kRuleNotFound) {
return;
}
UpdateRule([this, index]() {
Servo_KeyframesRule_DeleteRule(mRawRule, index);
if (mKeyframeList) {
mKeyframeList->RemoveRule(index);
}
});
}
/* virtual */ void
CSSKeyframesRule::GetCssText(nsAString& aCssText) const
{
Servo_KeyframesRule_GetCssText(mRawRule, &aCssText);
}
/* virtual */ dom::CSSRuleList*
CSSKeyframesRule::CssRules()
{
if (!mKeyframeList) {
mKeyframeList = new CSSKeyframeList(do_AddRef(mRawRule));
mKeyframeList->SetParentRule(this);
if (StyleSheet* sheet = GetStyleSheet()) {
mKeyframeList->SetStyleSheet(sheet);
}
}
return mKeyframeList;
}
/* virtual */ dom::CSSKeyframeRule*
CSSKeyframesRule::FindRule(const nsAString& aKey)
{
auto index = FindRuleIndexForKey(aKey);
if (index != kRuleNotFound) {
// Construct mKeyframeList but ignore the result.
CssRules();
return mKeyframeList->GetRule(index);
}
return nullptr;
}
/* virtual */ size_t
CSSKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
if (mKeyframeList) {
n += mKeyframeList->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
/* virtual */ JSObject*
CSSKeyframesRule::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)

Просмотреть файл

@ -13,29 +13,50 @@
namespace mozilla {
namespace dom {
class CSSKeyframesRule : public css::Rule
{
protected:
using css::Rule::Rule;
virtual ~CSSKeyframesRule() {}
class CSSKeyframeList;
class CSSKeyframesRule final : public css::Rule
{
public:
// Let's not worry for now about sorting out whether we're a leaf or not.
bool IsCCLeaf() const override { return false; }
CSSKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
uint32_t aLine, uint32_t aColumn);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSKeyframesRule,
css::Rule)
bool IsCCLeaf() const final;
#ifdef DEBUG
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
#endif
void SetStyleSheet(StyleSheet* aSheet) final;
// WebIDL interface
uint16_t Type() const final { return CSSRuleBinding::KEYFRAMES_RULE; }
virtual void GetName(nsAString& aName) const = 0;
virtual void SetName(const nsAString& aName) = 0;
virtual CSSRuleList* CssRules() = 0;
virtual void AppendRule(const nsAString& aRule) = 0;
virtual void DeleteRule(const nsAString& aKey) = 0;
virtual CSSKeyframeRule* FindRule(const nsAString& aKey) = 0;
void GetCssText(nsAString& aCssText) const final;
void GetName(nsAString& aName) const;
void SetName(const nsAString& aName);
CSSRuleList* CssRules();
void AppendRule(const nsAString& aRule);
void DeleteRule(const nsAString& aKey);
CSSKeyframeRule* FindRule(const nsAString& aKey);
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override = 0;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
private:
uint32_t FindRuleIndexForKey(const nsAString& aKey);
template<typename Func>
void UpdateRule(Func aCallback);
virtual ~CSSKeyframesRule();
RefPtr<RawServoKeyframesRule> mRawRule;
RefPtr<CSSKeyframeList> mKeyframeList; // lazily constructed
};
} // namespace dom

Просмотреть файл

@ -8,6 +8,7 @@
#include "mozilla/ServoCSSRuleList.h"
#include "mozilla/dom/CSSKeyframesRule.h"
#include "mozilla/dom/CSSNamespaceRule.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/ServoBindings.h"
@ -16,7 +17,6 @@
#include "mozilla/ServoImportRule.h"
#include "mozilla/ServoFontFaceRule.h"
#include "mozilla/ServoFontFeatureValuesRule.h"
#include "mozilla/ServoKeyframesRule.h"
#include "mozilla/ServoMediaRule.h"
#include "mozilla/ServoPageRule.h"
#include "mozilla/ServoStyleRule.h"
@ -105,7 +105,7 @@ ServoCSSRuleList::GetRule(uint32_t aIndex)
break; \
}
CASE_RULE(STYLE, Style)
CASE_RULE(KEYFRAMES, Keyframes)
CASE_RULE_CSS(KEYFRAMES, Keyframes)
CASE_RULE(MEDIA, Media)
CASE_RULE_CSS(NAMESPACE, Namespace)
CASE_RULE(PAGE, Page)

Просмотреть файл

@ -1,198 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ServoKeyframeRule.h"
#include "mozilla/DeclarationBlock.h"
#include "nsDOMCSSDeclaration.h"
#include "mozAutoDocUpdate.h"
namespace mozilla {
// -------------------------------------------
// ServoKeyframeDeclaration
//
class ServoKeyframeDeclaration : public nsDOMCSSDeclaration
{
public:
explicit ServoKeyframeDeclaration(ServoKeyframeRule* aRule)
: mRule(aRule)
{
mDecls = new DeclarationBlock(
Servo_Keyframe_GetStyle(aRule->Raw()).Consume());
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
ServoKeyframeDeclaration, nsICSSDeclaration)
css::Rule* GetParentRule() final { return mRule; }
void DropReference() {
mRule = nullptr;
mDecls->SetOwningRule(nullptr);
}
DeclarationBlock* GetCSSDeclaration(Operation aOperation) final
{
return mDecls;
}
nsresult SetCSSDeclaration(DeclarationBlock* aDecls) final
{
if (!mRule) {
return NS_OK;
}
mRule->UpdateRule([this, aDecls]() {
if (mDecls != aDecls) {
mDecls->SetOwningRule(nullptr);
mDecls = aDecls;
mDecls->SetOwningRule(mRule);
Servo_Keyframe_SetStyle(mRule->Raw(), mDecls->Raw());
}
});
return NS_OK;
}
ParsingEnvironment GetParsingEnvironment(
nsIPrincipal* aSubjectPrincipal) const final
{
return GetParsingEnvironmentForRule(mRule);
}
nsIDocument* DocToUpdate() final { return nullptr; }
nsINode* GetParentObject() final
{
return mRule ? mRule->GetParentObject() : nullptr;
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
// TODO we may want to add size of mDecls as well
return n;
}
private:
virtual ~ServoKeyframeDeclaration() {
MOZ_ASSERT(!mRule, "Backpointer should have been cleared");
}
ServoKeyframeRule* mRule;
RefPtr<DeclarationBlock> mDecls;
};
NS_IMPL_CYCLE_COLLECTING_ADDREF(ServoKeyframeDeclaration)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ServoKeyframeDeclaration)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(ServoKeyframeDeclaration)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoKeyframeDeclaration)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
// -------------------------------------------
// ServoKeyframeRule
//
ServoKeyframeRule::~ServoKeyframeRule()
{
if (mDeclaration) {
mDeclaration->DropReference();
}
}
NS_IMPL_ADDREF_INHERITED(ServoKeyframeRule, dom::CSSKeyframeRule)
NS_IMPL_RELEASE_INHERITED(ServoKeyframeRule, dom::CSSKeyframeRule)
// QueryInterface implementation for nsCSSKeyframeRule
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoKeyframeRule)
NS_INTERFACE_MAP_END_INHERITING(dom::CSSKeyframeRule)
NS_IMPL_CYCLE_COLLECTION_CLASS(ServoKeyframeRule)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoKeyframeRule,
dom::CSSKeyframeRule)
if (tmp->mDeclaration) {
tmp->mDeclaration->DropReference();
tmp->mDeclaration = nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoKeyframeRule,
dom::CSSKeyframeRule)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
bool
ServoKeyframeRule::IsCCLeaf() const
{
return Rule::IsCCLeaf() && !mDeclaration;
}
#ifdef DEBUG
/* virtual */ void
ServoKeyframeRule::List(FILE* out, int32_t aIndent) const
{
nsAutoCString str;
for (int32_t i = 0; i < aIndent; i++) {
str.AppendLiteral(" ");
}
Servo_Keyframe_Debug(mRaw, &str);
fprintf_stderr(out, "%s\n", str.get());
}
#endif
template<typename Func>
void
ServoKeyframeRule::UpdateRule(Func aCallback)
{
aCallback();
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
}
}
void
ServoKeyframeRule::GetKeyText(nsAString& aKeyText)
{
Servo_Keyframe_GetKeyText(mRaw, &aKeyText);
}
void
ServoKeyframeRule::SetKeyText(const nsAString& aKeyText)
{
NS_ConvertUTF16toUTF8 keyText(aKeyText);
UpdateRule([this, &keyText]() {
Servo_Keyframe_SetKeyText(mRaw, &keyText);
});
}
void
ServoKeyframeRule::GetCssText(nsAString& aCssText) const
{
Servo_Keyframe_GetCssText(mRaw, &aCssText);
}
nsICSSDeclaration*
ServoKeyframeRule::Style()
{
if (!mDeclaration) {
mDeclaration = new ServoKeyframeDeclaration(this);
}
return mDeclaration;
}
size_t
ServoKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
if (mDeclaration) {
n += mDeclaration->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
} // namespace mozilla

Просмотреть файл

@ -1,62 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ServoKeyframeRule_h
#define mozilla_ServoKeyframeRule_h
#include "mozilla/dom/CSSKeyframeRule.h"
#include "mozilla/ServoBindingTypes.h"
class nsICSSDeclaration;
namespace mozilla {
class DeclarationBlock;
class ServoKeyframeDeclaration;
class ServoKeyframeRule final : public dom::CSSKeyframeRule
{
public:
ServoKeyframeRule(already_AddRefed<RawServoKeyframe> aRaw,
uint32_t aLine, uint32_t aColumn)
: CSSKeyframeRule(aLine, aColumn)
, mRaw(aRaw) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoKeyframeRule,
dom::CSSKeyframeRule)
bool IsCCLeaf() const final;
#ifdef DEBUG
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
#endif
RawServoKeyframe* Raw() const { return mRaw; }
// WebIDL interface
void GetCssText(nsAString& aCssText) const final;
void GetKeyText(nsAString& aKeyText) final;
void SetKeyText(const nsAString& aKeyText) final;
nsICSSDeclaration* Style() final;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
private:
virtual ~ServoKeyframeRule();
friend class ServoKeyframeDeclaration;
template<typename Func>
void UpdateRule(Func aCallback);
RefPtr<RawServoKeyframe> mRaw;
// lazily created when needed
RefPtr<ServoKeyframeDeclaration> mDeclaration;
};
} // namespace mozilla
#endif // mozilla_ServoKeyframeRule_h

Просмотреть файл

@ -1,338 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ServoKeyframesRule.h"
#include "mozAutoDocUpdate.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoKeyframeRule.h"
#include <limits>
namespace mozilla {
// -------------------------------------------
// ServoKeyframeList
//
class ServoKeyframeList : public dom::CSSRuleList
{
public:
explicit ServoKeyframeList(already_AddRefed<RawServoKeyframesRule> aRawRule)
: mRawRule(aRawRule)
{
mRules.SetCount(Servo_KeyframesRule_GetCount(mRawRule));
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoKeyframeList, dom::CSSRuleList)
void SetParentRule(ServoKeyframesRule* aParentRule)
{
mParentRule = aParentRule;
for (css::Rule* rule : mRules) {
if (rule) {
rule->SetParentRule(aParentRule);
}
}
}
void SetStyleSheet(StyleSheet* aSheet)
{
mStyleSheet = aSheet;
for (css::Rule* rule : mRules) {
if (rule) {
rule->SetStyleSheet(aSheet);
}
}
}
StyleSheet* GetParentObject() final { return mStyleSheet; }
ServoKeyframeRule* GetRule(uint32_t aIndex) {
if (!mRules[aIndex]) {
uint32_t line = 0, column = 0;
RefPtr<RawServoKeyframe> rule =
Servo_KeyframesRule_GetKeyframeAt(mRawRule, aIndex,
&line, &column).Consume();
ServoKeyframeRule* ruleObj =
new ServoKeyframeRule(rule.forget(), line, column);
mRules.ReplaceObjectAt(ruleObj, aIndex);
ruleObj->SetStyleSheet(mStyleSheet);
ruleObj->SetParentRule(mParentRule);
}
return static_cast<ServoKeyframeRule*>(mRules[aIndex]);
}
ServoKeyframeRule* IndexedGetter(uint32_t aIndex, bool& aFound) final
{
if (aIndex >= mRules.Length()) {
aFound = false;
return nullptr;
}
aFound = true;
return GetRule(aIndex);
}
void AppendRule() {
mRules.AppendObject(nullptr);
}
void RemoveRule(uint32_t aIndex) {
mRules.RemoveObjectAt(aIndex);
}
uint32_t Length() final { return mRules.Length(); }
void DropReference()
{
mStyleSheet = nullptr;
mParentRule = nullptr;
for (css::Rule* rule : mRules) {
if (rule) {
rule->SetStyleSheet(nullptr);
rule->SetParentRule(nullptr);
}
}
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
for (const css::Rule* rule : mRules) {
n += rule ? rule->SizeOfIncludingThis(aMallocSizeOf) : 0;
}
return n;
}
private:
virtual ~ServoKeyframeList() {
MOZ_ASSERT(!mParentRule, "Backpointer should have been cleared");
MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
DropAllRules();
}
void DropAllRules()
{
if (mParentRule || mStyleSheet) {
DropReference();
}
mRules.Clear();
mRawRule = nullptr;
}
// may be nullptr when the style sheet drops the reference to us.
StyleSheet* mStyleSheet = nullptr;
ServoKeyframesRule* mParentRule = nullptr;
RefPtr<RawServoKeyframesRule> mRawRule;
nsCOMArray<css::Rule> mRules;
};
// QueryInterface implementation for ServoKeyframeList
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoKeyframeList)
NS_INTERFACE_MAP_END_INHERITING(dom::CSSRuleList)
NS_IMPL_ADDREF_INHERITED(ServoKeyframeList, dom::CSSRuleList)
NS_IMPL_RELEASE_INHERITED(ServoKeyframeList, dom::CSSRuleList)
NS_IMPL_CYCLE_COLLECTION_CLASS(ServoKeyframeList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ServoKeyframeList)
tmp->DropAllRules();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(dom::CSSRuleList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoKeyframeList,
dom::CSSRuleList)
for (css::Rule* rule : tmp->mRules) {
if (rule) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
cb.NoteXPCOMChild(rule);
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
// -------------------------------------------
// ServoKeyframesRule
//
ServoKeyframesRule::ServoKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
uint32_t aLine, uint32_t aColumn)
: dom::CSSKeyframesRule(aLine, aColumn)
, mRawRule(std::move(aRawRule))
{
}
ServoKeyframesRule::~ServoKeyframesRule()
{
if (mKeyframeList) {
mKeyframeList->DropReference();
}
}
NS_IMPL_ADDREF_INHERITED(ServoKeyframesRule, dom::CSSKeyframesRule)
NS_IMPL_RELEASE_INHERITED(ServoKeyframesRule, dom::CSSKeyframesRule)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoKeyframesRule)
NS_INTERFACE_MAP_END_INHERITING(dom::CSSKeyframesRule)
NS_IMPL_CYCLE_COLLECTION_CLASS(ServoKeyframesRule)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoKeyframesRule,
dom::CSSKeyframesRule)
if (tmp->mKeyframeList) {
tmp->mKeyframeList->DropReference();
tmp->mKeyframeList = nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoKeyframesRule, Rule)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mKeyframeList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
/* virtual */ bool
ServoKeyframesRule::IsCCLeaf() const
{
// If we don't have rule list constructed, we are a leaf.
return Rule::IsCCLeaf() && !mKeyframeList;
}
#ifdef DEBUG
/* virtual */ void
ServoKeyframesRule::List(FILE* out, int32_t aIndent) const
{
nsAutoCString str;
for (int32_t i = 0; i < aIndent; i++) {
str.AppendLiteral(" ");
}
Servo_KeyframesRule_Debug(mRawRule, &str);
fprintf_stderr(out, "%s\n", str.get());
}
#endif
/* virtual */ void
ServoKeyframesRule::SetStyleSheet(StyleSheet* aSheet)
{
if (mKeyframeList) {
mKeyframeList->SetStyleSheet(aSheet);
}
dom::CSSKeyframesRule::SetStyleSheet(aSheet);
}
static const uint32_t kRuleNotFound = std::numeric_limits<uint32_t>::max();
uint32_t
ServoKeyframesRule::FindRuleIndexForKey(const nsAString& aKey)
{
NS_ConvertUTF16toUTF8 key(aKey);
return Servo_KeyframesRule_FindRule(mRawRule, &key);
}
template<typename Func>
void
ServoKeyframesRule::UpdateRule(Func aCallback)
{
aCallback();
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
}
}
void
ServoKeyframesRule::GetName(nsAString& aName) const
{
nsAtom* name = Servo_KeyframesRule_GetName(mRawRule);
aName = nsDependentAtomString(name);
}
void
ServoKeyframesRule::SetName(const nsAString& aName)
{
RefPtr<nsAtom> name = NS_Atomize(aName);
nsAtom* oldName = Servo_KeyframesRule_GetName(mRawRule);
if (name == oldName) {
return;
}
UpdateRule([this, &name]() {
Servo_KeyframesRule_SetName(mRawRule, name.forget().take());
});
}
void
ServoKeyframesRule::AppendRule(const nsAString& aRule)
{
StyleSheet* sheet = GetStyleSheet();
if (!sheet) {
// We cannot parse the rule if we don't have a stylesheet.
return;
}
NS_ConvertUTF16toUTF8 rule(aRule);
UpdateRule([this, sheet, &rule]() {
bool parsedOk = Servo_KeyframesRule_AppendRule(
mRawRule, sheet->RawContents(), &rule);
if (parsedOk && mKeyframeList) {
mKeyframeList->AppendRule();
}
});
}
void
ServoKeyframesRule::DeleteRule(const nsAString& aKey)
{
auto index = FindRuleIndexForKey(aKey);
if (index == kRuleNotFound) {
return;
}
UpdateRule([this, index]() {
Servo_KeyframesRule_DeleteRule(mRawRule, index);
if (mKeyframeList) {
mKeyframeList->RemoveRule(index);
}
});
}
/* virtual */ void
ServoKeyframesRule::GetCssText(nsAString& aCssText) const
{
Servo_KeyframesRule_GetCssText(mRawRule, &aCssText);
}
/* virtual */ dom::CSSRuleList*
ServoKeyframesRule::CssRules()
{
if (!mKeyframeList) {
mKeyframeList = new ServoKeyframeList(do_AddRef(mRawRule));
mKeyframeList->SetParentRule(this);
if (StyleSheet* sheet = GetStyleSheet()) {
mKeyframeList->SetStyleSheet(sheet);
}
}
return mKeyframeList;
}
/* virtual */ dom::CSSKeyframeRule*
ServoKeyframesRule::FindRule(const nsAString& aKey)
{
auto index = FindRuleIndexForKey(aKey);
if (index != kRuleNotFound) {
// Construct mKeyframeList but ignore the result.
CssRules();
return mKeyframeList->GetRule(index);
}
return nullptr;
}
/* virtual */ size_t
ServoKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
if (mKeyframeList) {
n += mKeyframeList->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
} // namespace mozilla

Просмотреть файл

@ -1,58 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ServoKeyframesRule_h
#define mozilla_ServoKeyframesRule_h
#include "mozilla/dom/CSSKeyframesRule.h"
#include "mozilla/ServoBindingTypes.h"
namespace mozilla {
class ServoKeyframeList;
class ServoKeyframesRule final : public dom::CSSKeyframesRule
{
public:
ServoKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
uint32_t aLine, uint32_t aColumn);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoKeyframesRule,
dom::CSSKeyframesRule)
bool IsCCLeaf() const final;
#ifdef DEBUG
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
#endif
void SetStyleSheet(StyleSheet* aSheet) final;
// WebIDL interface
void GetCssText(nsAString& aCssText) const final;
void GetName(nsAString& aName) const final;
void SetName(const nsAString& aName) final;
dom::CSSRuleList* CssRules() final;
void AppendRule(const nsAString& aRule) final;
void DeleteRule(const nsAString& aKey) final;
dom::CSSKeyframeRule* FindRule(const nsAString& aKey) final;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
private:
uint32_t FindRuleIndexForKey(const nsAString& aKey);
template<typename Func>
void UpdateRule(Func aCallback);
virtual ~ServoKeyframesRule();
RefPtr<RawServoKeyframesRule> mRawRule;
RefPtr<ServoKeyframeList> mKeyframeList; // lazily constructed
};
} // namespace mozilla
#endif // mozilla_ServoKeyframesRule_h

Просмотреть файл

@ -25,6 +25,8 @@
namespace mozilla {
using namespace dom;
StyleSheet::StyleSheet(css::SheetParsingMode aParsingMode,
CORSMode aCORSMode,
net::ReferrerPolicy aReferrerPolicy,

Просмотреть файл

@ -91,8 +91,6 @@ EXPORTS.mozilla += [
'ServoFontFaceRule.h',
'ServoFontFeatureValuesRule.h',
'ServoImportRule.h',
'ServoKeyframeRule.h',
'ServoKeyframesRule.h',
'ServoMediaRule.h',
'ServoPageRule.h',
'ServoSpecifiedValues.h',
@ -210,8 +208,6 @@ UNIFIED_SOURCES += [
'ServoFontFaceRule.cpp',
'ServoFontFeatureValuesRule.cpp',
'ServoImportRule.cpp',
'ServoKeyframeRule.cpp',
'ServoKeyframesRule.cpp',
'ServoMediaRule.cpp',
'ServoPageRule.cpp',
'ServoSpecifiedValues.cpp',