Bug 1833466 - Implement CSSMarginRule and the corresponding DOM API. r=webidl,firefox-style-system-reviewers,smaug,emilio

Differential Revision: https://phabricator.services.mozilla.com/D206804
This commit is contained in:
Emily McDonough 2024-04-16 19:52:39 +00:00
parent 5d5182acb3
commit d999dfa37e
15 changed files with 385 additions and 24 deletions

View File

@ -0,0 +1,15 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* https://drafts.csswg.org/cssom/#the-cssmarginrule-interface
*/
// https://drafts.csswg.org/cssom/#the-cssmarginrule-interface
[Pref="layout.css.margin-rules.enabled", Exposed=Window]
interface CSSMarginRule : CSSRule {
readonly attribute UTF8String name;
[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
};

View File

@ -491,6 +491,7 @@ WEBIDL_FILES = [
"CSSKeyframesRule.webidl",
"CSSLayerBlockRule.webidl",
"CSSLayerStatementRule.webidl",
"CSSMarginRule.webidl",
"CSSMediaRule.webidl",
"CSSMozDocumentRule.webidl",
"CSSNamespaceRule.webidl",

View File

@ -0,0 +1,183 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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/dom/CSSMarginRule.h"
#include "mozilla/dom/CSSMarginRuleBinding.h"
#include "mozilla/DeclarationBlock.h"
#include "mozilla/ServoBindings.h"
namespace mozilla::dom {
// -- CSSMarginRuleDeclaration ---------------------------------------
CSSMarginRuleDeclaration::CSSMarginRuleDeclaration(
already_AddRefed<StyleLockedDeclarationBlock> aDecls)
: mDecls(new DeclarationBlock(std::move(aDecls))) {
mDecls->SetOwningRule(Rule());
}
CSSMarginRuleDeclaration::~CSSMarginRuleDeclaration() {
mDecls->SetOwningRule(nullptr);
}
// QueryInterface implementation for CSSMarginRuleDeclaration
NS_INTERFACE_MAP_BEGIN(CSSMarginRuleDeclaration)
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);
}
NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
NS_IMPL_ADDREF_USING_AGGREGATOR(CSSMarginRuleDeclaration, Rule())
NS_IMPL_RELEASE_USING_AGGREGATOR(CSSMarginRuleDeclaration, Rule())
/* nsDOMCSSDeclaration implementation */
css::Rule* CSSMarginRuleDeclaration::GetParentRule() { return Rule(); }
nsINode* CSSMarginRuleDeclaration::GetAssociatedNode() const {
return Rule()->GetAssociatedDocumentOrShadowRoot();
}
nsISupports* CSSMarginRuleDeclaration::GetParentObject() const {
return Rule()->GetParentObject();
}
DeclarationBlock* CSSMarginRuleDeclaration::GetOrCreateCSSDeclaration(
Operation aOperation, DeclarationBlock** aCreated) {
if (aOperation != Operation::Read) {
if (StyleSheet* sheet = Rule()->GetStyleSheet()) {
sheet->WillDirty();
}
}
return mDecls;
}
void CSSMarginRuleDeclaration::SetRawAfterClone(
RefPtr<StyleLockedDeclarationBlock> aDeclarationBlock) {
mDecls->SetOwningRule(nullptr);
mDecls = new DeclarationBlock(aDeclarationBlock.forget());
mDecls->SetOwningRule(Rule());
}
nsresult CSSMarginRuleDeclaration::SetCSSDeclaration(
DeclarationBlock* aDecl, MutationClosureData* aClosureData) {
MOZ_ASSERT(aDecl, "must be non-null");
CSSMarginRule* rule = Rule();
if (aDecl != mDecls) {
mDecls->SetOwningRule(nullptr);
RefPtr<DeclarationBlock> decls = aDecl;
// TODO alaskanemily: bug 1890418 for implementing this and margin-rule
// style properties in general.
// Servo_MarginRule_SetStyle(rule->Raw(), decls->Raw());
mDecls = std::move(decls);
mDecls->SetOwningRule(rule);
}
return NS_OK;
}
nsDOMCSSDeclaration::ParsingEnvironment
CSSMarginRuleDeclaration::GetParsingEnvironment(
nsIPrincipal* aSubjectPrincipal) const {
return GetParsingEnvironmentForRule(Rule(), StyleCssRuleType::Margin);
}
// -- CSSMarginRule --------------------------------------------------
CSSMarginRule::CSSMarginRule(RefPtr<StyleMarginRule> aRawRule,
StyleSheet* aSheet, css::Rule* aParentRule,
uint32_t aLine, uint32_t aColumn)
: css::Rule(aSheet, aParentRule, aLine, aColumn),
mRawRule(std::move(aRawRule)),
mDecls(Servo_MarginRule_GetStyle(mRawRule).Consume()) {}
NS_IMPL_ADDREF_INHERITED(CSSMarginRule, css::Rule)
NS_IMPL_RELEASE_INHERITED(CSSMarginRule, css::Rule)
// QueryInterface implementation for MarginRule
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSMarginRule)
NS_INTERFACE_MAP_END_INHERITING(css::Rule)
NS_IMPL_CYCLE_COLLECTION_CLASS(CSSMarginRule)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSMarginRule, css::Rule)
// 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(CSSMarginRule)
// Keep this in sync with IsCCLeaf.
// Unlink the wrapper for our declaration.
//
// Note that this has to happen before unlinking css::Rule.
tmp->UnlinkDeclarationWrapper(tmp->mDecls);
tmp->mDecls.mDecls->SetOwningRule(nullptr);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::Rule)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSMarginRule, css::Rule)
// Keep this in sync with IsCCLeaf.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
bool CSSMarginRule::IsCCLeaf() const {
if (!Rule::IsCCLeaf()) {
return false;
}
return !mDecls.PreservingWrapper();
}
void CSSMarginRule::SetRawAfterClone(RefPtr<StyleMarginRule> aRaw) {
mRawRule = std::move(aRaw);
mDecls.SetRawAfterClone(Servo_MarginRule_GetStyle(mRawRule.get()).Consume());
}
// WebIDL interfaces
StyleCssRuleType CSSMarginRule::Type() const {
return StyleCssRuleType::Margin;
}
// CSSRule implementation
void CSSMarginRule::GetCssText(nsACString& aCssText) const {
Servo_MarginRule_GetCssText(mRawRule, &aCssText);
}
void CSSMarginRule::GetName(nsACString& aRuleName) const {
Servo_MarginRule_GetName(mRawRule, &aRuleName);
}
size_t CSSMarginRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
// TODO Implement this!
return aMallocSizeOf(this);
}
#ifdef DEBUG
void CSSMarginRule::List(FILE* out, int32_t aIndent) const {
nsAutoCString str;
for (int32_t i = 0; i < aIndent; i++) {
str.AppendLiteral(" ");
}
Servo_MarginRule_Debug(mRawRule, &str);
fprintf_stderr(out, "%s\n", str.get());
}
#endif
JSObject* CSSMarginRule::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return CSSMarginRule_Binding::Wrap(aCx, this, aGivenProto);
}
} // namespace mozilla::dom

View File

@ -0,0 +1,107 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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_dom_CSSMarginRule_h
#define mozilla_dom_CSSMarginRule_h
#include "mozilla/css/Rule.h"
#include "mozilla/ServoBindingTypes.h"
#include "nsDOMCSSDeclaration.h"
#include "nsICSSDeclaration.h"
namespace mozilla {
class DeclarationBlock;
namespace dom {
class CSSMarginRule;
class CSSMarginRuleDeclaration final : public nsDOMCSSDeclaration {
public:
NS_DECL_ISUPPORTS_INHERITED
css::Rule* GetParentRule() final;
nsINode* GetAssociatedNode() const final;
nsISupports* GetParentObject() const final;
protected:
DeclarationBlock* GetOrCreateCSSDeclaration(
Operation aOperation, DeclarationBlock** aCreated) final;
nsresult SetCSSDeclaration(DeclarationBlock* aDecl,
MutationClosureData* aClosureData) final;
Document* DocToUpdate() final { return nullptr; }
nsDOMCSSDeclaration::ParsingEnvironment GetParsingEnvironment(
nsIPrincipal* aSubjectPrincipal) const final;
private:
// For accessing the constructor.
friend class CSSMarginRule;
explicit CSSMarginRuleDeclaration(
already_AddRefed<StyleLockedDeclarationBlock> aDecls);
void SetRawAfterClone(RefPtr<StyleLockedDeclarationBlock>);
~CSSMarginRuleDeclaration();
inline CSSMarginRule* Rule();
inline const CSSMarginRule* Rule() const;
RefPtr<DeclarationBlock> mDecls;
};
class CSSMarginRule final : public css::Rule {
public:
CSSMarginRule(RefPtr<StyleMarginRule> aRawRule, StyleSheet* aSheet,
css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSMarginRule,
css::Rule)
bool IsCCLeaf() const final;
StyleMarginRule* Raw() const { return mRawRule; }
void SetRawAfterClone(RefPtr<StyleMarginRule>);
// WebIDL interfaces
StyleCssRuleType Type() const final;
void GetCssText(nsACString& aCssText) const final;
nsICSSDeclaration* Style() { return &mDecls; }
void GetName(nsACString& aRuleName) const;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
#ifdef DEBUG
void List(FILE* out = stdout, int32_t aIndent = 0) const final;
#endif
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
private:
~CSSMarginRule() = default;
// For computing the offset of mDecls.
friend class CSSMarginRuleDeclaration;
RefPtr<StyleMarginRule> mRawRule;
CSSMarginRuleDeclaration mDecls;
};
CSSMarginRule* CSSMarginRuleDeclaration::Rule() {
return reinterpret_cast<CSSMarginRule*>(reinterpret_cast<uint8_t*>(this) -
offsetof(CSSMarginRule, mDecls));
}
const CSSMarginRule* CSSMarginRuleDeclaration::Rule() const {
return reinterpret_cast<const CSSMarginRule*>(
reinterpret_cast<const uint8_t*>(this) - offsetof(CSSMarginRule, mDecls));
}
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_CSSMarginRule_h

View File

@ -95,9 +95,10 @@ Rule* Rule::GetParentRule() const { return mParentRule; }
#ifdef DEBUG
void Rule::AssertParentRuleType() {
// Would be nice to check that this->Type() is KEYFRAME_RULE when
// mParentRule->Tye() is KEYFRAMES_RULE, but we can't call
// Would be nice to check that this->Type() is StyleCssRuleType::Keyframe
// when mParentRule->Tye() is StyleCssRuleType::Keyframes, but we can't call
// this->Type() here since it's virtual.
// Same for StyleCssRuleType::Margin and StyleCssRuleType::Page.
if (mParentRule) {
auto type = mParentRule->Type();
MOZ_ASSERT(type == StyleCssRuleType::Media ||
@ -108,7 +109,8 @@ void Rule::AssertParentRuleType() {
type == StyleCssRuleType::LayerBlock ||
type == StyleCssRuleType::Container ||
type == StyleCssRuleType::Scope ||
type == StyleCssRuleType::StartingStyle);
type == StyleCssRuleType::StartingStyle ||
type == StyleCssRuleType::Page);
}
}
#endif

View File

@ -123,6 +123,7 @@ UNLOCKED_RULE_TYPE(Property)
UNLOCKED_RULE_TYPE(LayerBlock)
UNLOCKED_RULE_TYPE(LayerStatement)
UNLOCKED_RULE_TYPE(Namespace)
UNLOCKED_RULE_TYPE(Margin)
UNLOCKED_RULE_TYPE(Container)
UNLOCKED_RULE_TYPE(Media)
UNLOCKED_RULE_TYPE(Supports)

View File

@ -77,6 +77,7 @@ BASIC_RULE_FUNCS_LOCKED(Keyframes)
GROUP_RULE_FUNCS_UNLOCKED(Media)
GROUP_RULE_FUNCS_UNLOCKED(Document)
BASIC_RULE_FUNCS_UNLOCKED(Namespace)
BASIC_RULE_FUNCS_UNLOCKED(Margin)
GROUP_RULE_FUNCS_LOCKED(Page)
BASIC_RULE_FUNCS_UNLOCKED(Property)
GROUP_RULE_FUNCS_UNLOCKED(Supports)

View File

@ -17,6 +17,7 @@
#include "mozilla/dom/CSSLayerStatementRule.h"
#include "mozilla/dom/CSSKeyframesRule.h"
#include "mozilla/dom/CSSContainerRule.h"
#include "mozilla/dom/CSSMarginRule.h"
#include "mozilla/dom/CSSMediaRule.h"
#include "mozilla/dom/CSSMozDocumentRule.h"
#include "mozilla/dom/CSSNamespaceRule.h"
@ -88,6 +89,7 @@ css::Rule* ServoCSSRuleList::GetRule(uint32_t aIndex) {
CASE_RULE_LOCKED(Keyframes, Keyframes)
CASE_RULE_UNLOCKED(Media, Media)
CASE_RULE_UNLOCKED(Namespace, Namespace)
CASE_RULE_UNLOCKED(Margin, Margin)
CASE_RULE_LOCKED(Page, Page)
CASE_RULE_UNLOCKED(Property, Property)
CASE_RULE_UNLOCKED(Supports, Supports)
@ -108,9 +110,6 @@ css::Rule* ServoCSSRuleList::GetRule(uint32_t aIndex) {
case StyleCssRuleType::Keyframe:
MOZ_ASSERT_UNREACHABLE("keyframe rule cannot be here");
return nullptr;
case StyleCssRuleType::Margin:
// Margin rules not implemented yet, see bug 1864737
return nullptr;
}
rule = CastToUint(ruleObj.forget().take());
mRules[aIndex] = rule;
@ -277,6 +276,7 @@ void ServoCSSRuleList::SetRawContents(RefPtr<StyleLockedCssRules> aNewRules,
RULE_CASE_LOCKED(Keyframes, Keyframes)
RULE_CASE_UNLOCKED(Media, Media)
RULE_CASE_UNLOCKED(Namespace, Namespace)
RULE_CASE_UNLOCKED(Margin, Margin)
RULE_CASE_LOCKED(Page, Page)
RULE_CASE_UNLOCKED(Property, Property)
RULE_CASE_UNLOCKED(Supports, Supports)
@ -294,9 +294,6 @@ void ServoCSSRuleList::SetRawContents(RefPtr<StyleLockedCssRules> aNewRules,
case StyleCssRuleType::Keyframe:
MOZ_ASSERT_UNREACHABLE("keyframe rule cannot be here");
break;
case StyleCssRuleType::Margin:
// Margin rules not implemented yet, see bug 1864737
break;
}
#undef RULE_CASE_WITH_PREFIX
#undef RULE_CASE_LOCKED

View File

@ -19,6 +19,7 @@ SERVO_LOCKED_ARC_TYPE(StyleRule)
SERVO_LOCKED_ARC_TYPE(ImportRule)
SERVO_LOCKED_ARC_TYPE(Keyframe)
SERVO_LOCKED_ARC_TYPE(KeyframesRule)
SERVO_LOCKED_ARC_TYPE(MarginList)
SERVO_LOCKED_ARC_TYPE(MediaList)
SERVO_LOCKED_ARC_TYPE(PageRule)
SERVO_LOCKED_ARC_TYPE(FontFaceRule)

View File

@ -45,6 +45,7 @@ template struct StyleStrong<StyleLockedKeyframesRule>;
template struct StyleStrong<StyleMediaRule>;
template struct StyleStrong<StyleDocumentRule>;
template struct StyleStrong<StyleNamespaceRule>;
template struct StyleStrong<StyleMarginRule>;
template struct StyleStrong<StyleLockedPageRule>;
template struct StyleStrong<StylePropertyRule>;
template struct StyleStrong<StyleSupportsRule>;

View File

@ -34,6 +34,7 @@
#include "mozilla/dom/CSSContainerRule.h"
#include "mozilla/dom/CSSLayerBlockRule.h"
#include "mozilla/dom/CSSLayerStatementRule.h"
#include "mozilla/dom/CSSMarginRule.h"
#include "mozilla/dom/CSSMediaRule.h"
#include "mozilla/dom/CSSMozDocumentRule.h"
#include "mozilla/dom/CSSKeyframesRule.h"
@ -994,6 +995,7 @@ void ServoStyleSet::RuleChangedInternal(StyleSheet& aSheet, css::Rule& aRule,
CASE_FOR(Import, Import)
CASE_FOR(Media, Media)
CASE_FOR(Keyframes, Keyframes)
CASE_FOR(Margin, Margin)
CASE_FOR(FontFeatureValues, FontFeatureValues)
CASE_FOR(FontPaletteValues, FontPaletteValues)
CASE_FOR(FontFace, FontFace)
@ -1014,9 +1016,6 @@ void ServoStyleSet::RuleChangedInternal(StyleSheet& aSheet, css::Rule& aRule,
// FIXME: We should probably just forward to the parent @keyframes rule? I
// think that'd do the right thing, but meanwhile...
return MarkOriginsDirty(ToOriginFlags(aSheet.GetOrigin()));
case StyleCssRuleType::Margin:
// Margin rules not implemented yet, see bug 1864737
break;
}
#undef CASE_FOR

View File

@ -138,6 +138,7 @@ EXPORTS.mozilla.dom += [
"CSSKeyframesRule.h",
"CSSLayerBlockRule.h",
"CSSLayerStatementRule.h",
"CSSMarginRule.h",
"CSSMediaRule.h",
"CSSMozDocumentRule.h",
"CSSNamespaceRule.h",
@ -191,6 +192,7 @@ UNIFIED_SOURCES += [
"CSSKeyframesRule.cpp",
"CSSLayerBlockRule.cpp",
"CSSLayerStatementRule.cpp",
"CSSMarginRule.cpp",
"CSSMediaRule.cpp",
"CSSMozDocumentRule.cpp",
"CSSNamespaceRule.cpp",

View File

@ -16,8 +16,8 @@ use crate::stylesheets::keyframes_rule::Keyframe;
use crate::stylesheets::{
ContainerRule, CounterStyleRule, CssRules, DocumentRule, FontFaceRule, FontFeatureValuesRule,
FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
MediaRule, NamespaceRule, PageRule, PropertyRule, ScopeRule, StartingStyleRule, StyleRule,
StylesheetContents, SupportsRule,
MarginRule, MediaRule, NamespaceRule, PageRule, PropertyRule, ScopeRule, StartingStyleRule,
StyleRule, StylesheetContents, SupportsRule,
};
use servo_arc::Arc;
@ -101,6 +101,11 @@ impl_simple_arc_ffi!(
Servo_NamespaceRule_AddRef,
Servo_NamespaceRule_Release
);
impl_simple_arc_ffi!(
MarginRule,
Servo_MarginRule_AddRef,
Servo_MarginRule_Release
);
impl_locked_arc_ffi!(
PageRule,
LockedPageRule,

View File

@ -21,19 +21,21 @@ macro_rules! margin_rule_types {
/// [`@margin`][margin] rule names.
///
/// https://drafts.csswg.org/css-page-3/#margin-at-rules
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)]
#[derive(Clone, Copy, Eq, MallocSizeOf, PartialEq, ToShmem)]
#[repr(u8)]
pub enum MarginRuleType {
$($(#[$($meta)+])* $id,)+
}
/// All [`@margin`][margin] rule names, with a preceding '@'.
///
/// This array lets us have just one single memory region used for
/// to_str, name, and the Debug implementation.
const MARGIN_RULE_AT_NAMES:&[&'static str] = &[
$( concat!('@', $val), )+
];
impl MarginRuleType {
#[inline]
fn to_str(&self) -> &'static str {
match *self {
$(MarginRuleType::$id => concat!('@', $val),)+
}
}
/// Matches the rule type for this name. This does not expect a
/// leading '@'.
pub fn match_name(name: &str) -> Option<Self> {
@ -113,6 +115,27 @@ margin_rule_types! {
RightBottom => "right-bottom",
}
impl MarginRuleType {
#[inline]
fn to_str(&self) -> &'static str {
&MARGIN_RULE_AT_NAMES[*self as usize]
}
#[inline]
fn name(&self) -> &'static str {
// Use the at-name array, skipping the first character to get
// the name without the @ sign.
&MARGIN_RULE_AT_NAMES[*self as usize][1..]
}
}
// Implement Debug manually so that it will share the same string memory as
// MarginRuleType::name and MarginRuleType::to_str.
impl fmt::Debug for MarginRuleType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str(self.name())
}
}
/// A [`@margin`][margin] rule.
///
/// [margin]: https://drafts.csswg.org/css-page-3/#margin-at-rules
@ -134,6 +157,11 @@ impl MarginRule {
self.block.unconditional_shallow_size_of(ops) +
self.block.read_with(guard).size_of(ops)
}
/// Gets the name for this margin rule.
#[inline]
pub fn name(&self) -> &'static str {
self.rule_type.name()
}
}
impl ToCssWithGuard for MarginRule {

View File

@ -137,9 +137,10 @@ use style::stylesheets::{
AllowImportRules, ContainerRule, CounterStyleRule, CssRule, CssRuleType, CssRuleTypes,
CssRules, CssRulesHelpers, DocumentRule, FontFaceRule, FontFeatureValuesRule,
FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
MediaRule, NamespaceRule, Origin, OriginSet, PagePseudoClassFlags, PageRule, PropertyRule,
SanitizationData, SanitizationKind, StartingStyleRule, StyleRule, StylesheetContents,
StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData, ScopeRule,
MarginRule, MediaRule, NamespaceRule, Origin, OriginSet, PagePseudoClassFlags, PageRule,
PropertyRule, SanitizationData, SanitizationKind, StartingStyleRule, StyleRule,
StylesheetContents, StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData,
ScopeRule,
};
use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist};
use style::thread_state;
@ -2402,6 +2403,13 @@ impl_group_rule_funcs! { (Media, MediaRule, MediaRule),
changed: Servo_StyleSet_MediaRuleChanged,
}
impl_basic_rule_funcs! { (Margin, MarginRule, MarginRule),
getter: Servo_CssRules_GetMarginRuleAt,
debug: Servo_MarginRule_Debug,
to_css: Servo_MarginRule_GetCssText,
changed: Servo_StyleSet_MarginRuleChanged,
}
impl_basic_rule_funcs! { (Namespace, NamespaceRule, NamespaceRule),
getter: Servo_CssRules_GetNamespaceRuleAt,
debug: Servo_NamespaceRule_Debug,
@ -2938,6 +2946,16 @@ pub extern "C" fn Servo_NamespaceRule_GetURI(rule: &NamespaceRule) -> *mut nsAto
rule.url.0.as_ptr()
}
#[no_mangle]
pub extern "C" fn Servo_MarginRule_GetStyle(rule: &MarginRule) -> Strong<LockedDeclarationBlock> {
rule.block.clone().into()
}
#[no_mangle]
pub extern "C" fn Servo_MarginRule_GetName(rule: &MarginRule, out: &mut nsACString) {
out.assign(rule.name());
}
#[no_mangle]
pub extern "C" fn Servo_PageRule_GetStyle(rule: &LockedPageRule) -> Strong<LockedDeclarationBlock> {
read_locked_arc(rule, |rule: &PageRule| rule.block.clone().into())