Bug 1345206 - Create ServoPageRule. r=xidorn

Adds `ServoPageRule` for use as the CSSOM representation of @page rules parsed
by Servo.

MozReview-Commit-ID: 7AIErJmoZN

--HG--
extra : rebase_source : f47448b9053e6a49023799631ca1d36f058272f4
This commit is contained in:
J. Ryan Stinnett 2017-03-31 16:13:12 -05:00
Родитель 0ccdacdf3a
Коммит 7a5e0808ba
5 изменённых файлов: 315 добавлений и 4 удалений

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

@ -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

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

@ -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

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

@ -73,9 +73,11 @@ ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
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);

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

@ -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; }

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

@ -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',