зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1852149 Part 3 - Add margin rules to servo r=firefox-style-system-reviewers,emilio
Parsing is disabled by the layout.css.margin-rules.enabled pref. This isn't currently testable beyond a crashtest because the DOM interface for margin rules isn't implemented yet. Differential Revision: https://phabricator.services.mozilla.com/D187736
This commit is contained in:
Родитель
1568c7e499
Коммит
8ad20b2ce6
|
@ -97,6 +97,7 @@ void ServoStyleRuleMap::RuleRemoved(StyleSheet& aStyleSheet,
|
|||
case StyleCssRuleType::Property:
|
||||
case StyleCssRuleType::Keyframes:
|
||||
case StyleCssRuleType::Keyframe:
|
||||
case StyleCssRuleType::Margin:
|
||||
case StyleCssRuleType::Namespace:
|
||||
case StyleCssRuleType::CounterStyle:
|
||||
case StyleCssRuleType::FontFeatureValues:
|
||||
|
@ -141,6 +142,7 @@ void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) {
|
|||
case StyleCssRuleType::Property:
|
||||
case StyleCssRuleType::Keyframes:
|
||||
case StyleCssRuleType::Keyframe:
|
||||
case StyleCssRuleType::Margin:
|
||||
case StyleCssRuleType::Namespace:
|
||||
case StyleCssRuleType::CounterStyle:
|
||||
case StyleCssRuleType::FontFeatureValues:
|
||||
|
|
|
@ -104,6 +104,9 @@ 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;
|
||||
|
@ -276,6 +279,9 @@ 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
|
||||
|
|
|
@ -1010,6 +1010,9 @@ 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
|
||||
|
|
|
@ -623,7 +623,7 @@ impl StylesheetInvalidationSet {
|
|||
// Do nothing, @font-face doesn't affect computed style information on it's own.
|
||||
// We'll restyle when the font face loads, if needed.
|
||||
},
|
||||
Page(..) => {
|
||||
Page(..) | Margin(..) => {
|
||||
// Do nothing, we don't support OM mutations on print documents, and page rules
|
||||
// can't affect anything else.
|
||||
},
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! A [`@margin`][margin] rule.
|
||||
//!
|
||||
//! [margin]: https://drafts.csswg.org/css-page-3/#margin-boxes
|
||||
|
||||
use crate::properties::PropertyDeclarationBlock;
|
||||
use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
|
||||
use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use crate::str::CssStringWriter;
|
||||
use cssparser::SourceLocation;
|
||||
#[cfg(feature = "gecko")]
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||
use servo_arc::Arc;
|
||||
use std::fmt::{self, Write};
|
||||
|
||||
macro_rules! margin_rule_types {
|
||||
($($(#[$($meta:tt)+])* $id:ident => $val:literal,)+) => {
|
||||
/// [`@margin`][margin] rule names.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-page-3/#margin-at-rules
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)]
|
||||
#[repr(u8)]
|
||||
pub enum MarginRuleType {
|
||||
$($(#[$($meta)+])* $id,)+
|
||||
}
|
||||
|
||||
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> {
|
||||
Some(match_ignore_ascii_case! { name,
|
||||
$( $val => MarginRuleType::$id, )+
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
margin_rule_types! {
|
||||
/// [`@top-left-corner`][top-left-corner] margin rule
|
||||
///
|
||||
/// [top-left-corner] https://drafts.csswg.org/css-page-3/#top-left-corner-box-def
|
||||
TopLeftCorner => "top-left-corner",
|
||||
/// [`@top-left`][top-left] margin rule
|
||||
///
|
||||
/// [top-left] https://drafts.csswg.org/css-page-3/#top-left-box-def
|
||||
TopLeft => "top-left",
|
||||
/// [`@top-center`][top-center] margin rule
|
||||
///
|
||||
/// [top-center] https://drafts.csswg.org/css-page-3/#top-center-box-def
|
||||
TopCenter => "top-center",
|
||||
/// [`@top-right`][top-right] margin rule
|
||||
///
|
||||
/// [top-right] https://drafts.csswg.org/css-page-3/#top-right-box-def
|
||||
TopRight => "top-right",
|
||||
/// [`@top-right-corner`][top-right-corner] margin rule
|
||||
///
|
||||
/// [top-right-corner] https://drafts.csswg.org/css-page-3/#top-right-corner-box-def
|
||||
TopRightCorner => "top-right-corner",
|
||||
/// [`@bottom-left-corner`][bottom-left-corner] margin rule
|
||||
///
|
||||
/// [bottom-left-corner] https://drafts.csswg.org/css-page-3/#bottom-left-corner-box-def
|
||||
BottomLeftCorner => "bottom-left-corner",
|
||||
/// [`@bottom-left`][bottom-left] margin rule
|
||||
///
|
||||
/// [bottom-left] https://drafts.csswg.org/css-page-3/#bottom-left-box-def
|
||||
BottomLeft => "bottom-left",
|
||||
/// [`@bottom-center`][bottom-center] margin rule
|
||||
///
|
||||
/// [bottom-center] https://drafts.csswg.org/css-page-3/#bottom-center-box-def
|
||||
BottomCenter => "bottom-center",
|
||||
/// [`@bottom-right`][bottom-right] margin rule
|
||||
///
|
||||
/// [bottom-right] https://drafts.csswg.org/css-page-3/#bottom-right-box-def
|
||||
BottomRight => "bottom-right",
|
||||
/// [`@bottom-right-corner`][bottom-right-corner] margin rule
|
||||
///
|
||||
/// [bottom-right-corner] https://drafts.csswg.org/css-page-3/#bottom-right-corner-box-def
|
||||
BottomRightCorner => "bottom-right-corner",
|
||||
/// [`@left-top`][left-top] margin rule
|
||||
///
|
||||
/// [left-top] https://drafts.csswg.org/css-page-3/#left-top-box-def
|
||||
LeftTop => "left-top",
|
||||
/// [`@left-middle`][left-middle] margin rule
|
||||
///
|
||||
/// [left-middle] https://drafts.csswg.org/css-page-3/#left-middle-box-def
|
||||
LeftMiddle => "left-middle",
|
||||
/// [`@left-bottom`][left-bottom] margin rule
|
||||
///
|
||||
/// [left-bottom] https://drafts.csswg.org/css-page-3/#left-bottom-box-def
|
||||
LeftBottom => "left-bottom",
|
||||
/// [`@right-top`][right-top] margin rule
|
||||
///
|
||||
/// [right-top] https://drafts.csswg.org/css-page-3/#right-top-box-def
|
||||
RightTop => "right-top",
|
||||
/// [`@right-middle`][right-middle] margin rule
|
||||
///
|
||||
/// [right-middle] https://drafts.csswg.org/css-page-3/#right-middle-box-def
|
||||
RightMiddle => "right-middle",
|
||||
/// [`@right-bottom`][right-bottom] margin rule
|
||||
///
|
||||
/// [right-bottom] https://drafts.csswg.org/css-page-3/#right-bottom-box-def
|
||||
RightBottom => "right-bottom",
|
||||
}
|
||||
|
||||
/// A [`@margin`][margin] rule.
|
||||
///
|
||||
/// [margin]: https://drafts.csswg.org/css-page-3/#margin-at-rules
|
||||
#[derive(Clone, Debug, ToShmem)]
|
||||
pub struct MarginRule {
|
||||
/// Type of this margin rule.
|
||||
pub rule_type: MarginRuleType,
|
||||
/// The declaration block this margin rule contains.
|
||||
pub block: Arc<Locked<PropertyDeclarationBlock>>,
|
||||
/// The source position this rule was found at.
|
||||
pub source_location: SourceLocation,
|
||||
}
|
||||
|
||||
impl MarginRule {
|
||||
/// Measure heap usage.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
|
||||
// Measurement of other fields may be added later.
|
||||
self.block.unconditional_shallow_size_of(ops) +
|
||||
self.block.read_with(guard).size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCssWithGuard for MarginRule {
|
||||
/// Serialization of a margin-rule is not specced, this is adapted from how
|
||||
/// page-rules and style-rules are serialized.
|
||||
fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
|
||||
dest.write_str(self.rule_type.to_str())?;
|
||||
dest.write_str(" { ")?;
|
||||
let declaration_block = self.block.read_with(guard);
|
||||
declaration_block.to_css(dest)?;
|
||||
if !declaration_block.declarations().is_empty() {
|
||||
dest.write_char(' ')?;
|
||||
}
|
||||
dest.write_char('}')
|
||||
}
|
||||
}
|
||||
|
||||
impl DeepCloneWithLock for MarginRule {
|
||||
fn deep_clone_with_lock(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
_params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
MarginRule {
|
||||
rule_type: self.rule_type,
|
||||
block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())),
|
||||
source_location: self.source_location.clone(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ mod media_rule;
|
|||
mod namespace_rule;
|
||||
pub mod origin;
|
||||
mod page_rule;
|
||||
mod margin_rule;
|
||||
mod property_rule;
|
||||
mod rule_list;
|
||||
mod rule_parser;
|
||||
|
@ -56,6 +57,7 @@ pub use self::import_rule::ImportRule;
|
|||
pub use self::keyframes_rule::KeyframesRule;
|
||||
pub use self::layer_rule::{LayerBlockRule, LayerStatementRule};
|
||||
pub use self::loader::StylesheetLoader;
|
||||
pub use self::margin_rule::{MarginRule, MarginRuleType};
|
||||
pub use self::media_rule::MediaRule;
|
||||
pub use self::namespace_rule::NamespaceRule;
|
||||
pub use self::origin::{Origin, OriginSet, OriginSetIterator, PerOrigin, PerOriginIter};
|
||||
|
@ -244,11 +246,11 @@ impl Eq for UrlExtraData {}
|
|||
#[derive(Clone, Debug, ToShmem)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum CssRule {
|
||||
Style(Arc<Locked<StyleRule>>),
|
||||
// No Charset here, CSSCharsetRule has been removed from CSSOM
|
||||
// https://drafts.csswg.org/cssom/#changes-from-5-december-2013
|
||||
Namespace(Arc<NamespaceRule>),
|
||||
Import(Arc<Locked<ImportRule>>),
|
||||
Style(Arc<Locked<StyleRule>>),
|
||||
Media(Arc<MediaRule>),
|
||||
Container(Arc<ContainerRule>),
|
||||
FontFace(Arc<Locked<FontFaceRule>>),
|
||||
|
@ -256,6 +258,7 @@ pub enum CssRule {
|
|||
FontPaletteValues(Arc<FontPaletteValuesRule>),
|
||||
CounterStyle(Arc<Locked<CounterStyleRule>>),
|
||||
Keyframes(Arc<Locked<KeyframesRule>>),
|
||||
Margin(Arc<MarginRule>),
|
||||
Supports(Arc<SupportsRule>),
|
||||
Page(Arc<Locked<PageRule>>),
|
||||
Property(Arc<PropertyRule>),
|
||||
|
@ -291,6 +294,9 @@ impl CssRule {
|
|||
CssRule::FontPaletteValues(_) => 0,
|
||||
CssRule::CounterStyle(_) => 0,
|
||||
CssRule::Keyframes(_) => 0,
|
||||
CssRule::Margin(ref arc) => {
|
||||
arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
|
||||
},
|
||||
CssRule::Supports(ref arc) => {
|
||||
arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
|
||||
},
|
||||
|
@ -325,7 +331,7 @@ pub enum CssRuleType {
|
|||
Keyframes = 7,
|
||||
Keyframe = 8,
|
||||
// https://drafts.csswg.org/cssom/#the-cssrule-interface
|
||||
// Margin = 9, // Not implemented yet.
|
||||
Margin = 9,
|
||||
Namespace = 10,
|
||||
// https://drafts.csswg.org/css-counter-styles-3/#extentions-to-cssrule-interface
|
||||
CounterStyle = 11,
|
||||
|
@ -421,6 +427,7 @@ impl CssRule {
|
|||
CssRule::FontPaletteValues(_) => CssRuleType::FontPaletteValues,
|
||||
CssRule::CounterStyle(_) => CssRuleType::CounterStyle,
|
||||
CssRule::Keyframes(_) => CssRuleType::Keyframes,
|
||||
CssRule::Margin(_) => CssRuleType::Margin,
|
||||
CssRule::Namespace(_) => CssRuleType::Namespace,
|
||||
CssRule::Supports(_) => CssRuleType::Supports,
|
||||
CssRule::Page(_) => CssRuleType::Page,
|
||||
|
@ -536,6 +543,9 @@ impl DeepCloneWithLock for CssRule {
|
|||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params)),
|
||||
))
|
||||
},
|
||||
CssRule::Margin(ref arc) => {
|
||||
CssRule::Margin(Arc::new(arc.deep_clone_with_lock(lock, guard, params)))
|
||||
},
|
||||
CssRule::Supports(ref arc) => {
|
||||
CssRule::Supports(Arc::new(arc.deep_clone_with_lock(lock, guard, params)))
|
||||
},
|
||||
|
@ -573,6 +583,7 @@ impl ToCssWithGuard for CssRule {
|
|||
CssRule::FontPaletteValues(ref rule) => rule.to_css(guard, dest),
|
||||
CssRule::CounterStyle(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||
CssRule::Keyframes(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||
CssRule::Margin(ref rule) => rule.to_css(guard, dest),
|
||||
CssRule::Media(ref rule) => rule.to_css(guard, dest),
|
||||
CssRule::Supports(ref rule) => rule.to_css(guard, dest),
|
||||
CssRule::Page(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||
|
|
|
@ -26,8 +26,9 @@ use crate::stylesheets::layer_rule::{LayerBlockRule, LayerName, LayerStatementRu
|
|||
use crate::stylesheets::supports_rule::SupportsCondition;
|
||||
use crate::stylesheets::{
|
||||
AllowImportRules, CorsMode, CssRule, CssRuleType, CssRuleTypes, CssRules, DocumentRule,
|
||||
FontFeatureValuesRule, FontPaletteValuesRule, KeyframesRule, MediaRule, NamespaceRule,
|
||||
PageRule, PageSelectors, RulesMutateError, StyleRule, StylesheetLoader, SupportsRule,
|
||||
FontFeatureValuesRule, FontPaletteValuesRule, KeyframesRule, MarginRule, MarginRuleType,
|
||||
MediaRule, NamespaceRule, PageRule, PageSelectors, RulesMutateError, StyleRule,
|
||||
StylesheetLoader, SupportsRule,
|
||||
};
|
||||
use crate::values::computed::font::FamilyName;
|
||||
use crate::values::{CssUrl, CustomIdent, DashedIdent, KeyframesName};
|
||||
|
@ -224,6 +225,8 @@ pub enum AtRulePrelude {
|
|||
Option<ImportSupportsCondition>,
|
||||
ImportLayer,
|
||||
),
|
||||
/// A @margin rule prelude.
|
||||
Margin(MarginRuleType),
|
||||
/// A @namespace rule prelude.
|
||||
Namespace(Option<Prefix>, Namespace),
|
||||
/// A @layer rule prelude.
|
||||
|
@ -245,6 +248,7 @@ impl AtRulePrelude {
|
|||
Self::Property(..) => "property",
|
||||
Self::Document(..) => "-moz-document",
|
||||
Self::Import(..) => "import",
|
||||
Self::Margin(..) => "margin",
|
||||
Self::Namespace(..) => "namespace",
|
||||
Self::Layer(..) => "layer",
|
||||
}
|
||||
|
@ -482,6 +486,11 @@ impl<'a, 'i> NestedRuleParser<'a, 'i> {
|
|||
self.context.rule_types.contains(CssRuleType::Style)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn in_page_rule(&self) -> bool {
|
||||
self.context.rule_types.contains(CssRuleType::Page)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn in_style_or_page_rule(&self) -> bool {
|
||||
let types = CssRuleTypes::from_bits(CssRuleType::Style.bit() | CssRuleType::Page.bit());
|
||||
|
@ -509,6 +518,7 @@ impl<'a, 'i> NestedRuleParser<'a, 'i> {
|
|||
AtRulePrelude::Page(..) |
|
||||
AtRulePrelude::Property(..) |
|
||||
AtRulePrelude::Import(..) => !self.in_style_or_page_rule(),
|
||||
AtRulePrelude::Margin(..) => self.in_page_rule(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -691,7 +701,14 @@ impl<'a, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'i> {
|
|||
let cond = DocumentCondition::parse(&self.context, input)?;
|
||||
AtRulePrelude::Document(cond)
|
||||
},
|
||||
_ => return Err(input.new_error(BasicParseErrorKind::AtRuleInvalid(name.clone())))
|
||||
_ => {
|
||||
if static_prefs::pref!("layout.css.margin-rules.enabled") {
|
||||
if let Some(margin_rule_type) = MarginRuleType::match_name(&name) {
|
||||
return Ok(AtRulePrelude::Margin(margin_rule_type));
|
||||
}
|
||||
}
|
||||
return Err(input.new_error(BasicParseErrorKind::AtRuleInvalid(name.clone())))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -836,6 +853,16 @@ impl<'a, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'i> {
|
|||
source_location,
|
||||
}))
|
||||
},
|
||||
AtRulePrelude::Margin(rule_type) => {
|
||||
let declarations = self.nest_for_rule(CssRuleType::Margin, |p| {
|
||||
parse_property_declaration_list(&p.context, input, &[])
|
||||
});
|
||||
CssRule::Margin(Arc::new(MarginRule {
|
||||
rule_type,
|
||||
block: Arc::new(self.shared_lock.wrap(declarations)),
|
||||
source_location: start.source_location(),
|
||||
}))
|
||||
}
|
||||
AtRulePrelude::Import(..) | AtRulePrelude::Namespace(..) => {
|
||||
// These rules don't have blocks.
|
||||
return Err(input.new_unexpected_token_error(cssparser::Token::CurlyBracketBlock));
|
||||
|
|
|
@ -66,11 +66,16 @@ where
|
|||
CssRule::FontFace(_) |
|
||||
CssRule::CounterStyle(_) |
|
||||
CssRule::Keyframes(_) |
|
||||
CssRule::Page(_) |
|
||||
CssRule::Margin(_) |
|
||||
CssRule::Property(_) |
|
||||
CssRule::LayerStatement(_) |
|
||||
CssRule::FontFeatureValues(_) |
|
||||
CssRule::FontPaletteValues(_) => None,
|
||||
CssRule::Page(ref page_rule) => {
|
||||
let page_rule = page_rule.read_with(guard);
|
||||
let rules = page_rule.rules.read_with(guard);
|
||||
Some(rules.0.iter())
|
||||
},
|
||||
CssRule::Style(ref style_rule) => {
|
||||
let style_rule = style_rule.read_with(guard);
|
||||
style_rule
|
||||
|
|
|
@ -339,6 +339,7 @@ impl SanitizationKind {
|
|||
|
||||
CssRule::Keyframes(..) |
|
||||
CssRule::Page(..) |
|
||||
CssRule::Margin(..) |
|
||||
CssRule::Property(..) |
|
||||
CssRule::FontFeatureValues(..) |
|
||||
CssRule::FontPaletteValues(..) |
|
||||
|
|
|
@ -3002,6 +3002,7 @@ impl CascadeData {
|
|||
CssRule::Page(ref rule) => {
|
||||
self.extra_data
|
||||
.add_page(guard, rule, containing_rule_state.layer_id)?;
|
||||
handled = false;
|
||||
},
|
||||
_ => {
|
||||
handled = false;
|
||||
|
@ -3243,6 +3244,7 @@ impl CascadeData {
|
|||
CssRule::CounterStyle(..) |
|
||||
CssRule::Supports(..) |
|
||||
CssRule::Keyframes(..) |
|
||||
CssRule::Margin(..) |
|
||||
CssRule::Page(..) |
|
||||
CssRule::Property(..) |
|
||||
CssRule::Document(..) |
|
||||
|
|
Загрузка…
Ссылка в новой задаче