Bug 1345206 - Create ServoPageRule. r=xidorn
Adds `ServoPageRule` for use as the CSSOM representation of @page rules parsed
by Servo.
MozReview-Commit-ID: 7AIErJmoZN
new file mode 100644
--- /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<RawServoDeclarationBlock> 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<ServoDeclarationBlock> 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<RawServoPageRule> 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<nsISupports*>(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<css::Rule>
+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
new file mode 100644
--- /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<RawServoDeclarationBlock> aDecls);
+ ~ServoPageRuleDeclaration();
+
+ inline ServoPageRule* Rule();
+ inline const ServoPageRule* Rule() const;
+
+ RefPtr<ServoDeclarationBlock> mDecls;
+};
+
+class ServoPageRule final : public dom::CSSPageRule
+{
+public:
+ explicit ServoPageRule(RefPtr<RawServoPageRule> 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<css::Rule> 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<RawServoPageRule> mRawRule;
+ ServoPageRuleDeclaration mDecls;
+};
+
+ServoPageRule*
+ServoPageRuleDeclaration::Rule()
+{
+ return reinterpret_cast<ServoPageRule*>(
+ reinterpret_cast<uint8_t*>(this) - offsetof(ServoPageRule, mDecls));
+}
+
+const ServoPageRule*
+ServoPageRuleDeclaration::Rule() const
+{
+ return reinterpret_cast<const ServoPageRule*>(
+ reinterpret_cast<const uint8_t*>(this) - offsetof(ServoPageRule, mDecls));
+}
+
+} // namespace mozilla
+
+#endif // mozilla_ServoPageRule_h
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/ServoStyleRule.cpp
@@ -68,19 +68,21 @@ ServoStyleRuleDeclaration::GetCSSDeclara
nsresult
ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
{
ServoStyleRule* rule = Rule();
if (RefPtr<ServoStyleSheet> sheet = rule->GetStyleSheet()->AsServo()) {
nsCOMPtr<nsIDocument> doc = sheet->GetAssociatedDocument();
mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
if (aDecl != mDecls) {
+ mDecls->SetOwningRule(nullptr);
RefPtr<ServoDeclarationBlock> decls = aDecl->AsServo();
Servo_StyleRule_SetStyle(rule->Raw(), decls->Raw());
mDecls = decls.forget();
+ mDecls->SetOwningRule(rule);
}
if (doc) {
doc->StyleRuleChanged(sheet, rule);
}
}
return NS_OK;
}
--- a/layout/style/ServoStyleRule.h
+++ b/layout/style/ServoStyleRule.h
@@ -53,23 +53,23 @@ class ServoStyleRule final : public Bind
, public nsIDOMCSSStyleRule
{
public:
explicit ServoStyleRule(already_AddRefed<RawServoStyleRule> aRawRule);
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; }
// Methods of mozilla::css::Rule
int32_t GetType() const final { return css::Rule::STYLE_RULE; }
using Rule::GetType;
already_AddRefed<Rule> Clone() const final;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -101,16 +101,17 @@ EXPORTS.mozilla += [
'ServoBindings.h',
'ServoBindingTypes.h',
'ServoCSSRuleList.h',
'ServoDeclarationBlock.h',
'ServoElementSnapshot.h',
'ServoMediaList.h',
'ServoMediaRule.h',
'ServoNamespaceRule.h',
+ 'ServoPageRule.h',
'ServoPropPrefList.h',
'ServoSpecifiedValues.h',
'ServoStyleRule.h',
'ServoStyleSet.h',
'ServoStyleSheet.h',
'ServoTypes.h',
'ServoUtils.h',
'SheetType.h',
@@ -220,16 +221,17 @@ UNIFIED_SOURCES += [
'RuleProcessorCache.cpp',
'ServoBindings.cpp',
'ServoCSSRuleList.cpp',
'ServoDeclarationBlock.cpp',
'ServoElementSnapshot.cpp',
'ServoMediaList.cpp',
'ServoMediaRule.cpp',
'ServoNamespaceRule.cpp',
+ 'ServoPageRule.cpp',
'ServoSpecifiedValues.cpp',
'ServoStyleRule.cpp',
'ServoStyleSet.cpp',
'ServoStyleSheet.cpp',
'StyleAnimationValue.cpp',
'StyleRule.cpp',
'StyleSheet.cpp',
'URLExtraData.cpp',