зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1451289 - Part 2: Merge ServoKeyframesRule and CSSKeyframesRule r=emilio
MozReview-Commit-ID: FVwVgQZ0B6Q --HG-- extra : rebase_source : b10e638097a27e581f9c8b95ae8e21ec7b7ac175
This commit is contained in:
Родитель
6cdcd1d100
Коммит
92aa0e63d1
|
@ -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',
|
||||
|
|
Загрузка…
Ссылка в новой задаче