diff --git a/layout/style/ServoPageRule.cpp b/layout/style/ServoPageRule.cpp new file mode 100644 index 000000000000..bc1594d4e0af --- /dev/null +++ b/layout/style/ServoPageRule.cpp @@ -0,0 +1,205 @@ +/* -*- 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/. */ + +/* representation of CSSPageRule for stylo */ + +#include "mozilla/ServoPageRule.h" + +#include "mozilla/DeclarationBlockInlines.h" +#include "mozilla/ServoBindings.h" +#include "mozilla/ServoDeclarationBlock.h" + +using namespace mozilla::dom; + +namespace mozilla { + +// -- ServoPageRuleDeclaration --------------------------------------- + +ServoPageRuleDeclaration::ServoPageRuleDeclaration( + already_AddRefed aDecls) + : mDecls(new ServoDeclarationBlock(Move(aDecls))) +{ +} + +ServoPageRuleDeclaration::~ServoPageRuleDeclaration() +{ +} + +// QueryInterface implementation for ServoPageRuleDeclaration +NS_INTERFACE_MAP_BEGIN(ServoPageRuleDeclaration) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + // We forward the cycle collection interfaces to Rule(), which is + // never null (in fact, we're part of that object!) + if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) || + aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) { + return Rule()->QueryInterface(aIID, aInstancePtr); + } + else +NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration) + +NS_IMPL_ADDREF_USING_AGGREGATOR(ServoPageRuleDeclaration, Rule()) +NS_IMPL_RELEASE_USING_AGGREGATOR(ServoPageRuleDeclaration, Rule()) + +/* nsDOMCSSDeclaration implementation */ + +NS_IMETHODIMP +ServoPageRuleDeclaration::GetParentRule(nsIDOMCSSRule** aParent) +{ + *aParent = do_AddRef(Rule()).take(); + return NS_OK; +} + +nsINode* +ServoPageRuleDeclaration::GetParentObject() +{ + return Rule()->GetDocument(); +} + +DeclarationBlock* +ServoPageRuleDeclaration::GetCSSDeclaration(Operation aOperation) +{ + return mDecls; +} + +nsresult +ServoPageRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl) +{ + MOZ_ASSERT(aDecl, "must be non-null"); + ServoPageRule* rule = Rule(); + + if (aDecl != mDecls) { + mDecls->SetOwningRule(nullptr); + RefPtr decls = aDecl->AsServo(); + Servo_PageRule_SetStyle(rule->Raw(), decls->Raw()); + mDecls = decls.forget(); + mDecls->SetOwningRule(rule); + } + + return NS_OK; +} + +nsIDocument* +ServoPageRuleDeclaration::DocToUpdate() +{ + return nullptr; +} + +void +ServoPageRuleDeclaration::GetCSSParsingEnvironment( + CSSParsingEnvironment& aCSSParseEnv) +{ + MOZ_ASSERT_UNREACHABLE("GetCSSParsingEnvironment " + "shouldn't be calling for a Servo rule"); + GetCSSParsingEnvironmentForRule(Rule(), aCSSParseEnv); +} + +URLExtraData* +ServoPageRuleDeclaration::GetURLData() const +{ + return GetURLDataForRule(Rule()); +} + +// -- ServoPageRule -------------------------------------------------- + +ServoPageRule::ServoPageRule(RefPtr aRawRule) + : CSSPageRule(0, 0) + , mRawRule(Move(aRawRule)) + , mDecls(Servo_PageRule_GetStyle(mRawRule).Consume()) +{ +} + +ServoPageRule::~ServoPageRule() +{ +} + +NS_IMPL_ADDREF_INHERITED(ServoPageRule, CSSPageRule) +NS_IMPL_RELEASE_INHERITED(ServoPageRule, CSSPageRule) + +// QueryInterface implementation for PageRule +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoPageRule) +NS_INTERFACE_MAP_END_INHERITING(CSSPageRule) + +NS_IMPL_CYCLE_COLLECTION_CLASS(ServoPageRule) + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ServoPageRule, CSSPageRule) + // Keep this in sync with IsCCLeaf. + + // Trace the wrapper for our declaration. This just expands out + // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use + // directly because the wrapper is on the declaration, not on us. + tmp->mDecls.TraceWrapper(aCallbacks, aClosure); +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoPageRule, CSSPageRule) + // Keep this in sync with IsCCLeaf. + + // Unlink the wrapper for our declaraton. This just expands out + // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use + // directly because the wrapper is on the declaration, not on us. + tmp->mDecls.ReleaseWrapper(static_cast(p)); +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoPageRule, CSSPageRule) + // Keep this in sync with IsCCLeaf. +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +bool +ServoPageRule::IsCCLeaf() const +{ + if (!Rule::IsCCLeaf()) { + return false; + } + + return !mDecls.PreservingWrapper(); +} + +already_AddRefed +ServoPageRule::Clone() const +{ + // Rule::Clone is only used when CSSStyleSheetInner is cloned in + // preparation of being mutated. However, ServoStyleSheet never clones + // anything, so this method should never be called. + MOZ_ASSERT_UNREACHABLE("Shouldn't be cloning ServoPageRule"); + return nullptr; +} + +size_t +ServoPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const +{ + // TODO Implement this! + return aMallocSizeOf(this); +} + +#ifdef DEBUG +void +ServoPageRule::List(FILE* out, int32_t aIndent) const +{ + nsAutoCString str; + for (int32_t i = 0; i < aIndent; i++) { + str.AppendLiteral(" "); + } + Servo_PageRule_Debug(mRawRule, &str); + fprintf_stderr(out, "%s\n", str.get()); +} +#endif + +/* CSSRule implementation */ + +void +ServoPageRule::GetCssTextImpl(nsAString& aCssText) const +{ + Servo_PageRule_GetCssText(mRawRule, &aCssText); +} + +/* CSSPageRule implementation */ + +nsICSSDeclaration* +ServoPageRule::Style() +{ + return &mDecls; +} + +} // namespace mozilla diff --git a/layout/style/ServoPageRule.h b/layout/style/ServoPageRule.h new file mode 100644 index 000000000000..6961a97f33d6 --- /dev/null +++ b/layout/style/ServoPageRule.h @@ -0,0 +1,102 @@ +/* -*- 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/. */ + +/* representation of CSSPageRule for stylo */ + +#ifndef mozilla_ServoPageRule_h +#define mozilla_ServoPageRule_h + +#include "mozilla/dom/CSSPageRule.h" +#include "mozilla/ServoBindingTypes.h" + +#include "nsDOMCSSDeclaration.h" + +namespace mozilla { + +class ServoDeclarationBlock; +class ServoPageRule; + +class ServoPageRuleDeclaration final : public nsDOMCSSDeclaration +{ +public: + NS_DECL_ISUPPORTS_INHERITED + + NS_IMETHOD GetParentRule(nsIDOMCSSRule** aParent) final; + nsINode* GetParentObject() final; + +protected: + DeclarationBlock* GetCSSDeclaration(Operation aOperation) final; + nsresult SetCSSDeclaration(DeclarationBlock* aDecl) final; + nsIDocument* DocToUpdate() final; + void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) final; + URLExtraData* GetURLData() const final; + +private: + // For accessing the constructor. + friend class ServoPageRule; + + explicit ServoPageRuleDeclaration( + already_AddRefed aDecls); + ~ServoPageRuleDeclaration(); + + inline ServoPageRule* Rule(); + inline const ServoPageRule* Rule() const; + + RefPtr mDecls; +}; + +class ServoPageRule final : public dom::CSSPageRule +{ +public: + explicit ServoPageRule(RefPtr aRawRule); + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED( + ServoPageRule, dom::CSSPageRule + ) + bool IsCCLeaf() const final; + + RawServoPageRule* Raw() const { return mRawRule; } + + // WebIDL interface + void GetCssTextImpl(nsAString& aCssText) const final; + nsICSSDeclaration* Style() final; + + // Methods of mozilla::css::Rule + already_AddRefed Clone() const final; + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) + const final; +#ifdef DEBUG + void List(FILE* out = stdout, int32_t aIndent = 0) const final; +#endif + +private: + virtual ~ServoPageRule(); + + // For computing the offset of mDecls. + friend class ServoPageRuleDeclaration; + + RefPtr mRawRule; + ServoPageRuleDeclaration mDecls; +}; + +ServoPageRule* +ServoPageRuleDeclaration::Rule() +{ + return reinterpret_cast( + reinterpret_cast(this) - offsetof(ServoPageRule, mDecls)); +} + +const ServoPageRule* +ServoPageRuleDeclaration::Rule() const +{ + return reinterpret_cast( + reinterpret_cast(this) - offsetof(ServoPageRule, mDecls)); +} + +} // namespace mozilla + +#endif // mozilla_ServoPageRule_h diff --git a/layout/style/ServoStyleRule.cpp b/layout/style/ServoStyleRule.cpp index 7058b67ab2e2..aae45f0f326e 100644 --- a/layout/style/ServoStyleRule.cpp +++ b/layout/style/ServoStyleRule.cpp @@ -73,9 +73,11 @@ ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl) nsCOMPtr doc = sheet->GetAssociatedDocument(); mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true); if (aDecl != mDecls) { + mDecls->SetOwningRule(nullptr); RefPtr decls = aDecl->AsServo(); Servo_StyleRule_SetStyle(rule->Raw(), decls->Raw()); mDecls = decls.forget(); + mDecls->SetOwningRule(rule); } if (doc) { doc->StyleRuleChanged(sheet, rule); diff --git a/layout/style/ServoStyleRule.h b/layout/style/ServoStyleRule.h index 8b432c849b88..7638f7c7c60e 100644 --- a/layout/style/ServoStyleRule.h +++ b/layout/style/ServoStyleRule.h @@ -58,13 +58,13 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ServoStyleRule, css::Rule) - virtual bool IsCCLeaf() const override MOZ_MUST_OVERRIDE; + virtual bool IsCCLeaf() const final MOZ_MUST_OVERRIDE; NS_DECL_NSIDOMCSSSTYLERULE // WebIDL interface - uint16_t Type() const override; - void GetCssTextImpl(nsAString& aCssText) const override; - virtual nsICSSDeclaration* Style() override; + uint16_t Type() const final; + void GetCssTextImpl(nsAString& aCssText) const final; + virtual nsICSSDeclaration* Style() final; RawServoStyleRule* Raw() const { return mRawRule; } diff --git a/layout/style/moz.build b/layout/style/moz.build index 331f8e561fa9..2bbe04134d93 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -106,6 +106,7 @@ EXPORTS.mozilla += [ 'ServoMediaList.h', 'ServoMediaRule.h', 'ServoNamespaceRule.h', + 'ServoPageRule.h', 'ServoPropPrefList.h', 'ServoSpecifiedValues.h', 'ServoStyleRule.h', @@ -225,6 +226,7 @@ UNIFIED_SOURCES += [ 'ServoMediaList.cpp', 'ServoMediaRule.cpp', 'ServoNamespaceRule.cpp', + 'ServoPageRule.cpp', 'ServoSpecifiedValues.cpp', 'ServoStyleRule.cpp', 'ServoStyleSet.cpp',