aboutsummaryrefslogtreecommitdiffstats
path: root/components/style
diff options
context:
space:
mode:
authorJonathan Kew <jkew@mozilla.com>2022-10-07 23:00:43 +0000
committerMartin Robinson <mrobinson@igalia.com>2023-11-03 08:59:49 +0100
commita4ad5e19b0ec17d7e55e468cd9370fe7996b8bc9 (patch)
tree4bd6b90d0cae03e11b2e57103a5b4ce34ff10baf /components/style
parentab4580e112ef2c4e2afb13296b73d17940b86004 (diff)
downloadservo-a4ad5e19b0ec17d7e55e468cd9370fe7996b8bc9.tar.gz
servo-a4ad5e19b0ec17d7e55e468cd9370fe7996b8bc9.zip
style: Implement CSS parsing for the @font-palette-values rule
Not yet hooked up to any rendering functionality. The intention is for both the @font-palette-values at-rule and the font-palette property to be behind the same pref being introduced here. Differential Revision: https://phabricator.services.mozilla.com/D157953
Diffstat (limited to 'components/style')
-rw-r--r--components/style/error_reporting.rs10
-rw-r--r--components/style/gecko/arc_types.rs15
-rw-r--r--components/style/invalidation/stylesheets.rs4
-rw-r--r--components/style/stylesheets/font_feature_values_rule.rs19
-rw-r--r--components/style/stylesheets/font_palette_values_rule.rs215
-rw-r--r--components/style/stylesheets/mod.rs11
-rw-r--r--components/style/stylesheets/rule_parser.rs29
-rw-r--r--components/style/stylesheets/rules_iterator.rs3
-rw-r--r--components/style/stylesheets/stylesheet.rs1
-rw-r--r--components/style/stylist.rs26
-rw-r--r--components/style/values/mod.rs38
-rw-r--r--components/style/values/specified/mod.rs12
12 files changed, 353 insertions, 30 deletions
diff --git a/components/style/error_reporting.rs b/components/style/error_reporting.rs
index 752f68b5bdc..042838f3394 100644
--- a/components/style/error_reporting.rs
+++ b/components/style/error_reporting.rs
@@ -26,6 +26,8 @@ pub enum ContextualParseError<'a> {
UnsupportedFontFaceDescriptor(&'a str, ParseError<'a>),
/// A font feature values descriptor was not recognized.
UnsupportedFontFeatureValuesDescriptor(&'a str, ParseError<'a>),
+ /// A font palette values descriptor was not recognized.
+ UnsupportedFontPaletteValuesDescriptor(&'a str, ParseError<'a>),
/// A keyframe rule was not valid.
InvalidKeyframeRule(&'a str, ParseError<'a>),
/// A font feature values rule was not valid.
@@ -149,6 +151,14 @@ impl<'a> fmt::Display for ContextualParseError<'a> {
)?;
parse_error_to_str(err, f)
},
+ ContextualParseError::UnsupportedFontPaletteValuesDescriptor(decl, ref err) => {
+ write!(
+ f,
+ "Unsupported @font-palette-values descriptor declaration: '{}', ",
+ decl
+ )?;
+ parse_error_to_str(err, f)
+ },
ContextualParseError::InvalidKeyframeRule(rule, ref err) => {
write!(f, "Invalid keyframe rule: '{}', ", rule)?;
parse_error_to_str(err, f)
diff --git a/components/style/gecko/arc_types.rs b/components/style/gecko/arc_types.rs
index bb1d88d8a55..fc712422536 100644
--- a/components/style/gecko/arc_types.rs
+++ b/components/style/gecko/arc_types.rs
@@ -12,10 +12,10 @@ use crate::gecko::url::CssUrlData;
use crate::gecko_bindings::structs::{
RawServoAnimationValue, RawServoContainerRule, RawServoCounterStyleRule, RawServoCssUrlData,
RawServoDeclarationBlock, RawServoFontFaceRule, RawServoFontFeatureValuesRule,
- RawServoImportRule, RawServoKeyframe, RawServoKeyframesRule, RawServoLayerBlockRule,
- RawServoLayerStatementRule, RawServoMediaList, RawServoMediaRule, RawServoMozDocumentRule,
- RawServoNamespaceRule, RawServoPageRule, RawServoStyleRule, RawServoStyleSheetContents,
- RawServoSupportsRule, ServoCssRules,
+ RawServoFontPaletteValuesRule, RawServoImportRule, RawServoKeyframe, RawServoKeyframesRule,
+ RawServoLayerBlockRule, RawServoLayerStatementRule, RawServoMediaList, RawServoMediaRule,
+ RawServoMozDocumentRule, RawServoNamespaceRule, RawServoPageRule, RawServoStyleRule,
+ RawServoStyleSheetContents, RawServoSupportsRule, ServoCssRules,
};
use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
use crate::media_queries::MediaList;
@@ -25,8 +25,8 @@ use crate::shared_lock::Locked;
use crate::stylesheets::keyframes_rule::Keyframe;
use crate::stylesheets::{
ContainerRule, CounterStyleRule, CssRules, DocumentRule, FontFaceRule, FontFeatureValuesRule,
- ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule, MediaRule, NamespaceRule,
- PageRule, StyleRule, StylesheetContents, SupportsRule,
+ FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
+ MediaRule, NamespaceRule, PageRule, StyleRule, StylesheetContents, SupportsRule,
};
use servo_arc::{Arc, ArcBorrow};
use std::{mem, ptr};
@@ -104,6 +104,9 @@ impl_arc_ffi!(Locked<DocumentRule> => RawServoMozDocumentRule
impl_arc_ffi!(Locked<FontFeatureValuesRule> => RawServoFontFeatureValuesRule
[Servo_FontFeatureValuesRule_AddRef, Servo_FontFeatureValuesRule_Release]);
+impl_arc_ffi!(Locked<FontPaletteValuesRule> => RawServoFontPaletteValuesRule
+ [Servo_FontPaletteValuesRule_AddRef, Servo_FontPaletteValuesRule_Release]);
+
impl_arc_ffi!(Locked<FontFaceRule> => RawServoFontFaceRule
[Servo_FontFaceRule_AddRef, Servo_FontFaceRule_Release]);
diff --git a/components/style/invalidation/stylesheets.rs b/components/style/invalidation/stylesheets.rs
index b367e18daa9..f18fe7942c5 100644
--- a/components/style/invalidation/stylesheets.rs
+++ b/components/style/invalidation/stylesheets.rs
@@ -552,6 +552,7 @@ impl StylesheetInvalidationSet {
Page(..) |
Viewport(..) |
FontFeatureValues(..) |
+ FontPaletteValues(..) |
LayerStatement(..) |
FontFace(..) |
Keyframes(..) |
@@ -632,7 +633,8 @@ impl StylesheetInvalidationSet {
// existing elements.
}
},
- CounterStyle(..) | Page(..) | Viewport(..) | FontFeatureValues(..) => {
+ CounterStyle(..) | Page(..) | Viewport(..) | FontFeatureValues(..) |
+ FontPaletteValues(..) => {
debug!(
" > Found unsupported rule, marking the whole subtree \
invalid."
diff --git a/components/style/stylesheets/font_feature_values_rule.rs b/components/style/stylesheets/font_feature_values_rule.rs
index dc128e77fb0..784628f0dde 100644
--- a/components/style/stylesheets/font_feature_values_rule.rs
+++ b/components/style/stylesheets/font_feature_values_rule.rs
@@ -275,23 +275,6 @@ macro_rules! font_feature_values_blocks {
rule
}
- /// Prints font family names.
- pub fn font_family_to_css<W>(
- &self,
- dest: &mut CssWriter<W>,
- ) -> fmt::Result
- where
- W: Write,
- {
- let mut iter = self.family_names.iter();
- iter.next().unwrap().to_css(dest)?;
- for val in iter {
- dest.write_str(", ")?;
- val.to_css(dest)?;
- }
- Ok(())
- }
-
/// Prints inside of `@font-feature-values` block.
pub fn value_to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
@@ -349,7 +332,7 @@ macro_rules! font_feature_values_blocks {
impl ToCssWithGuard for FontFeatureValuesRule {
fn to_css(&self, _guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
dest.write_str("@font-feature-values ")?;
- self.font_family_to_css(&mut CssWriter::new(dest))?;
+ self.family_names.to_css(&mut CssWriter::new(dest))?;
dest.write_str(" {\n")?;
self.value_to_css(&mut CssWriter::new(dest))?;
dest.write_str("}")
diff --git a/components/style/stylesheets/font_palette_values_rule.rs b/components/style/stylesheets/font_palette_values_rule.rs
new file mode 100644
index 00000000000..95d62443321
--- /dev/null
+++ b/components/style/stylesheets/font_palette_values_rule.rs
@@ -0,0 +1,215 @@
+/* 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/. */
+
+//! The [`@font-palette-values`][font-palette-values] at-rule.
+//!
+//! [font-palette-values]: https://drafts.csswg.org/css-fonts/#font-palette-values
+
+use crate::error_reporting::ContextualParseError;
+use crate::parser::{Parse, ParserContext};
+use crate::shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
+use crate::str::CssStringWriter;
+use crate::values::computed::font::FamilyName;
+use crate::values::specified::Color as SpecifiedColor;
+use crate::values::specified::NonNegativeInteger;
+use crate::values::DashedIdent;
+use cssparser::{AtRuleParser, CowRcStr};
+use cssparser::{DeclarationParser, DeclarationListParser, Parser};
+use cssparser::{QualifiedRuleParser, SourceLocation};
+use std::fmt::{self, Write};
+use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
+use style_traits::{Comma, OneOrMoreSeparated};
+use selectors::parser::SelectorParseErrorKind;
+use crate::stylesheets::font_feature_values_rule::parse_family_name_list;
+
+#[allow(missing_docs)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToShmem)]
+pub struct FontPaletteOverrideColor {
+ index: NonNegativeInteger,
+ color: SpecifiedColor,
+}
+
+impl Parse for FontPaletteOverrideColor {
+ fn parse<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<FontPaletteOverrideColor, ParseError<'i>> {
+ let index = NonNegativeInteger::parse(context, input)?;
+ let location = input.current_source_location();
+ let color = SpecifiedColor::parse(context, input)?;
+ // Only absolute colors are accepted here.
+ if let SpecifiedColor::Numeric { parsed: _, authored: _ } = color {
+ Ok(FontPaletteOverrideColor{ index, color })
+ } else {
+ Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
+ }
+ }
+}
+
+impl ToCss for FontPaletteOverrideColor {
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
+ where
+ W: fmt::Write,
+ {
+ self.index.to_css(dest)?;
+ dest.write_str(" ")?;
+ self.color.to_css(dest)
+ }
+}
+
+impl OneOrMoreSeparated for FontPaletteOverrideColor {
+ type S = Comma;
+}
+
+impl OneOrMoreSeparated for FamilyName {
+ type S = Comma;
+}
+
+#[allow(missing_docs)]
+#[derive(Clone, Debug, MallocSizeOf, Parse, PartialEq, ToCss, ToShmem)]
+pub enum FontPaletteBase {
+ Light,
+ Dark,
+ Index(NonNegativeInteger),
+}
+
+/// The [`@font-palette-values`][font-palette-values] at-rule.
+///
+/// [font-palette-values]: https://drafts.csswg.org/css-fonts/#font-palette-values
+#[derive(Clone, Debug, PartialEq, ToShmem)]
+pub struct FontPaletteValuesRule {
+ /// Palette name.
+ pub name: DashedIdent,
+ /// Font family list for @font-palette-values rule.
+ /// Family names cannot contain generic families. FamilyName
+ /// also accepts only non-generic names.
+ pub family_names: Vec<FamilyName>,
+ /// The base palette.
+ pub base_palette: Option<FontPaletteBase>,
+ /// The list of override colors.
+ pub override_colors: Vec<FontPaletteOverrideColor>,
+ /// The line and column of the rule's source code.
+ pub source_location: SourceLocation,
+}
+
+impl FontPaletteValuesRule {
+ /// Creates an empty FontPaletteValuesRule with given location and name.
+ fn new(name: DashedIdent, location: SourceLocation) -> Self {
+ FontPaletteValuesRule {
+ name,
+ family_names: vec![],
+ base_palette: None,
+ override_colors: vec![],
+ source_location: location,
+ }
+ }
+
+ /// Parses a `FontPaletteValuesRule`.
+ pub fn parse(
+ context: &ParserContext,
+ input: &mut Parser,
+ name: DashedIdent,
+ location: SourceLocation,
+ ) -> Self {
+ let mut rule = FontPaletteValuesRule::new(name, location);
+ {
+ let parser = FontPaletteValuesDeclarationParser {
+ context: context,
+ rule: &mut rule,
+ };
+ let mut iter = DeclarationListParser::new(input, parser);
+ while let Some(declaration) = iter.next() {
+ if let Err((error, slice)) = declaration {
+ let location = error.location;
+ let error = ContextualParseError::UnsupportedFontPaletteValuesDescriptor(slice, error);
+ context.log_css_error(location, error);
+ }
+ }
+ }
+ rule
+ }
+
+ /// Prints inside of `@font-palette-values` block.
+ fn value_to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
+ where
+ W: Write,
+ {
+ if !self.family_names.is_empty() {
+ dest.write_str("font-family: ")?;
+ self.family_names.to_css(dest)?;
+ dest.write_str("; ")?;
+ }
+ if let Some(base) = &self.base_palette {
+ dest.write_str("base-palette: ")?;
+ base.to_css(dest)?;
+ dest.write_str("; ")?;
+ }
+ if !self.override_colors.is_empty() {
+ dest.write_str("override-colors: ")?;
+ self.override_colors.to_css(dest)?;
+ dest.write_str("; ")?;
+ }
+ Ok(())
+ }
+}
+
+impl ToCssWithGuard for FontPaletteValuesRule {
+ fn to_css(&self, _guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
+ dest.write_str("@font-palette-values ")?;
+ self.name.to_css(&mut CssWriter::new(dest))?;
+ dest.write_str(" { ")?;
+ self.value_to_css(&mut CssWriter::new(dest))?;
+ dest.write_str("}")
+ }
+}
+
+/// Parser for declarations in `FontPaletteValuesRule`.
+struct FontPaletteValuesDeclarationParser<'a> {
+ context: &'a ParserContext<'a>,
+ rule: &'a mut FontPaletteValuesRule,
+}
+
+impl<'a, 'i> AtRuleParser<'i> for FontPaletteValuesDeclarationParser<'a> {
+ type Prelude = ();
+ type AtRule = ();
+ type Error = StyleParseErrorKind<'i>;
+}
+
+impl<'a, 'i> QualifiedRuleParser<'i> for FontPaletteValuesDeclarationParser<'a> {
+ type Prelude = ();
+ type QualifiedRule = ();
+ type Error = StyleParseErrorKind<'i>;
+}
+
+fn parse_override_colors<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+) -> Result<Vec<FontPaletteOverrideColor>, ParseError<'i>> {
+ input.parse_comma_separated(|i| FontPaletteOverrideColor::parse(context, i))
+}
+
+impl<'a, 'b, 'i> DeclarationParser<'i> for FontPaletteValuesDeclarationParser<'a> {
+ type Declaration = ();
+ type Error = StyleParseErrorKind<'i>;
+
+ fn parse_value<'t>(
+ &mut self,
+ name: CowRcStr<'i>,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<(), ParseError<'i>> {
+ match_ignore_ascii_case! { &*name,
+ "font-family" => {
+ self.rule.family_names = parse_family_name_list(self.context, input)?
+ },
+ "base-palette" => {
+ self.rule.base_palette = Some(input.parse_entirely(|i| FontPaletteBase::parse(self.context, i))?)
+ },
+ "override-colors" => {
+ self.rule.override_colors = parse_override_colors(self.context, input)?
+ },
+ _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))),
+ }
+ Ok(())
+ }
+}
diff --git a/components/style/stylesheets/mod.rs b/components/style/stylesheets/mod.rs
index 9625ad62cb3..01b0c07d7a9 100644
--- a/components/style/stylesheets/mod.rs
+++ b/components/style/stylesheets/mod.rs
@@ -10,6 +10,7 @@ mod counter_style_rule;
mod document_rule;
mod font_face_rule;
pub mod font_feature_values_rule;
+pub mod font_palette_values_rule;
pub mod import_rule;
pub mod keyframes_rule;
pub mod layer_rule;
@@ -50,6 +51,7 @@ pub use self::counter_style_rule::CounterStyleRule;
pub use self::document_rule::DocumentRule;
pub use self::font_face_rule::FontFaceRule;
pub use self::font_feature_values_rule::FontFeatureValuesRule;
+pub use self::font_palette_values_rule::FontPaletteValuesRule;
pub use self::import_rule::ImportRule;
pub use self::keyframes_rule::KeyframesRule;
pub use self::layer_rule::{LayerBlockRule, LayerStatementRule};
@@ -256,6 +258,7 @@ pub enum CssRule {
Container(Arc<Locked<ContainerRule>>),
FontFace(Arc<Locked<FontFaceRule>>),
FontFeatureValues(Arc<Locked<FontFeatureValuesRule>>),
+ FontPaletteValues(Arc<Locked<FontPaletteValuesRule>>),
CounterStyle(Arc<Locked<CounterStyleRule>>),
Viewport(Arc<Locked<ViewportRule>>),
Keyframes(Arc<Locked<KeyframesRule>>),
@@ -293,6 +296,7 @@ impl CssRule {
CssRule::FontFace(_) => 0,
CssRule::FontFeatureValues(_) => 0,
+ CssRule::FontPaletteValues(_) => 0,
CssRule::CounterStyle(_) => 0,
CssRule::Viewport(_) => 0,
CssRule::Keyframes(_) => 0,
@@ -348,6 +352,7 @@ pub enum CssRuleType {
LayerBlock = 16,
LayerStatement = 17,
Container = 18,
+ FontPaletteValues = 19,
}
#[allow(missing_docs)]
@@ -367,6 +372,7 @@ impl CssRule {
CssRule::Media(_) => CssRuleType::Media,
CssRule::FontFace(_) => CssRuleType::FontFace,
CssRule::FontFeatureValues(_) => CssRuleType::FontFeatureValues,
+ CssRule::FontPaletteValues(_) => CssRuleType::FontPaletteValues,
CssRule::CounterStyle(_) => CssRuleType::CounterStyle,
CssRule::Keyframes(_) => CssRuleType::Keyframes,
CssRule::Namespace(_) => CssRuleType::Namespace,
@@ -474,6 +480,10 @@ impl DeepCloneWithLock for CssRule {
let rule = arc.read_with(guard);
CssRule::FontFeatureValues(Arc::new(lock.wrap(rule.clone())))
},
+ CssRule::FontPaletteValues(ref arc) => {
+ let rule = arc.read_with(guard);
+ CssRule::FontPaletteValues(Arc::new(lock.wrap(rule.clone())))
+ },
CssRule::CounterStyle(ref arc) => {
let rule = arc.read_with(guard);
CssRule::CounterStyle(Arc::new(lock.wrap(rule.clone())))
@@ -531,6 +541,7 @@ impl ToCssWithGuard for CssRule {
CssRule::Style(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::FontFace(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::FontFeatureValues(ref lock) => lock.read_with(guard).to_css(guard, dest),
+ CssRule::FontPaletteValues(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::CounterStyle(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::Viewport(ref lock) => lock.read_with(guard).to_css(guard, dest),
CssRule::Keyframes(ref lock) => lock.read_with(guard).to_css(guard, dest),
diff --git a/components/style/stylesheets/rule_parser.rs b/components/style/stylesheets/rule_parser.rs
index 659b704161e..9fe2d0c87e9 100644
--- a/components/style/stylesheets/rule_parser.rs
+++ b/components/style/stylesheets/rule_parser.rs
@@ -23,11 +23,12 @@ use crate::stylesheets::stylesheet::Namespaces;
use crate::stylesheets::supports_rule::SupportsCondition;
use crate::stylesheets::{
viewport_rule, AllowImportRules, CorsMode, CssRule, CssRuleType, CssRules, DocumentRule,
- FontFeatureValuesRule, KeyframesRule, MediaRule, NamespaceRule, PageRule, PageSelectors,
- RulesMutateError, StyleRule, StylesheetLoader, SupportsRule, ViewportRule,
+ FontFeatureValuesRule, FontPaletteValuesRule, KeyframesRule, MediaRule, NamespaceRule,
+ PageRule, PageSelectors, RulesMutateError, StyleRule, StylesheetLoader, SupportsRule,
+ ViewportRule,
};
use crate::values::computed::font::FamilyName;
-use crate::values::{CssUrl, CustomIdent, KeyframesName};
+use crate::values::{CssUrl, CustomIdent, DashedIdent, KeyframesName};
use crate::{Namespace, Prefix};
use cssparser::{
AtRuleParser, BasicParseError, BasicParseErrorKind, CowRcStr, Parser, ParserState,
@@ -184,6 +185,8 @@ pub enum AtRulePrelude {
FontFace,
/// A @font-feature-values rule prelude, with its FamilyName list.
FontFeatureValues(Vec<FamilyName>),
+ /// A @font-palette-values rule prelude, with its identifier.
+ FontPaletteValues(DashedIdent),
/// A @counter-style rule prelude, with its counter style name.
CounterStyle(CustomIdent),
/// A @media rule prelude, with its media queries.
@@ -500,6 +503,10 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
let family_names = parse_family_name_list(self.context, input)?;
AtRulePrelude::FontFeatureValues(family_names)
},
+ "font-palette-values" if static_prefs::pref!("layout.css.font-palette.enabled") => {
+ let name = DashedIdent::parse(self.context, input)?;
+ AtRulePrelude::FontPaletteValues(name)
+ },
"counter-style" if cfg!(feature = "gecko") => {
let name = parse_counter_style_name_definition(input)?;
AtRulePrelude::CounterStyle(name)
@@ -573,6 +580,22 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
),
))))
},
+ AtRulePrelude::FontPaletteValues(name) => {
+ let context = ParserContext::new_with_rule_type(
+ self.context,
+ CssRuleType::FontPaletteValues,
+ self.namespaces,
+ );
+
+ Ok(CssRule::FontPaletteValues(Arc::new(self.shared_lock.wrap(
+ FontPaletteValuesRule::parse(
+ &context,
+ input,
+ name,
+ start.source_location(),
+ ),
+ ))))
+ },
AtRulePrelude::CounterStyle(name) => {
let context = ParserContext::new_with_rule_type(
self.context,
diff --git a/components/style/stylesheets/rules_iterator.rs b/components/style/stylesheets/rules_iterator.rs
index 5c90e506714..00c095bb8b8 100644
--- a/components/style/stylesheets/rules_iterator.rs
+++ b/components/style/stylesheets/rules_iterator.rs
@@ -70,7 +70,8 @@ where
CssRule::Keyframes(_) |
CssRule::Page(_) |
CssRule::LayerStatement(_) |
- CssRule::FontFeatureValues(_) => None,
+ CssRule::FontFeatureValues(_) |
+ CssRule::FontPaletteValues(_) => None,
CssRule::Import(ref import_rule) => {
let import_rule = import_rule.read_with(guard);
if !C::process_import(guard, device, quirks_mode, import_rule) {
diff --git a/components/style/stylesheets/stylesheet.rs b/components/style/stylesheets/stylesheet.rs
index 51a1a29ac07..a1a678ec436 100644
--- a/components/style/stylesheets/stylesheet.rs
+++ b/components/style/stylesheets/stylesheet.rs
@@ -381,6 +381,7 @@ impl SanitizationKind {
CssRule::Keyframes(..) |
CssRule::Page(..) |
CssRule::FontFeatureValues(..) |
+ CssRule::FontPaletteValues(..) |
CssRule::Viewport(..) |
CssRule::CounterStyle(..) => !is_standard,
}
diff --git a/components/style/stylist.rs b/components/style/stylist.rs
index 487f3ade5de..8dfdc91e58b 100644
--- a/components/style/stylist.rs
+++ b/components/style/stylist.rs
@@ -32,7 +32,9 @@ use crate::stylesheets::keyframes_rule::KeyframesAnimation;
use crate::stylesheets::layer_rule::{LayerName, LayerOrder};
use crate::stylesheets::viewport_rule::{self, MaybeNew, ViewportRule};
#[cfg(feature = "gecko")]
-use crate::stylesheets::{CounterStyleRule, FontFaceRule, FontFeatureValuesRule, PageRule};
+use crate::stylesheets::{
+ CounterStyleRule, FontFaceRule, FontFeatureValuesRule, FontPaletteValuesRule, PageRule,
+};
use crate::stylesheets::{
CssRule, EffectiveRulesIterator, Origin, OriginSet, PageRule, PerOrigin, PerOriginIter,
};
@@ -1679,6 +1681,10 @@ pub struct ExtraStyleData {
#[cfg(feature = "gecko")]
pub font_feature_values: LayerOrderedVec<Arc<Locked<FontFeatureValuesRule>>>,
+ /// A list of effective font-palette-values rules.
+ #[cfg(feature = "gecko")]
+ pub font_palette_values: LayerOrderedVec<Arc<Locked<FontPaletteValuesRule>>>,
+
/// A map of effective counter-style rules.
#[cfg(feature = "gecko")]
pub counter_styles: LayerOrderedMap<Arc<Locked<CounterStyleRule>>>,
@@ -1704,6 +1710,15 @@ impl ExtraStyleData {
self.font_feature_values.push(rule.clone(), layer);
}
+ /// Add the given @font-palette-values rule.
+ fn add_font_palette_values(
+ &mut self,
+ rule: &Arc<Locked<FontPaletteValuesRule>>,
+ layer: LayerId,
+ ) {
+ self.font_palette_values.push(rule.clone(), layer);
+ }
+
/// Add the given @counter-style rule.
fn add_counter_style(
&mut self,
@@ -1745,6 +1760,7 @@ impl ExtraStyleData {
fn sort_by_layer(&mut self, layers: &[CascadeLayer]) {
self.font_faces.sort(layers);
self.font_feature_values.sort(layers);
+ self.font_palette_values.sort(layers);
self.counter_styles.sort(layers);
self.pages.global.sort(layers);
}
@@ -1754,6 +1770,7 @@ impl ExtraStyleData {
{
self.font_faces.clear();
self.font_feature_values.clear();
+ self.font_palette_values.clear();
self.counter_styles.clear();
self.pages.clear();
}
@@ -1790,6 +1807,7 @@ impl MallocSizeOf for ExtraStyleData {
let mut n = 0;
n += self.font_faces.shallow_size_of(ops);
n += self.font_feature_values.shallow_size_of(ops);
+ n += self.font_palette_values.shallow_size_of(ops);
n += self.counter_styles.shallow_size_of(ops);
n += self.pages.shallow_size_of(ops);
n
@@ -2638,6 +2656,11 @@ impl CascadeData {
.add_font_feature_values(rule, containing_rule_state.layer_id);
},
#[cfg(feature = "gecko")]
+ CssRule::FontPaletteValues(ref rule) => {
+ self.extra_data
+ .add_font_palette_values(rule, containing_rule_state.layer_id);
+ },
+ #[cfg(feature = "gecko")]
CssRule::CounterStyle(ref rule) => {
self.extra_data.add_counter_style(
guard,
@@ -2888,6 +2911,7 @@ impl CascadeData {
CssRule::Document(..) |
CssRule::LayerBlock(..) |
CssRule::LayerStatement(..) |
+ CssRule::FontPaletteValues(..) |
CssRule::FontFeatureValues(..) => {
// Not affected by device changes.
continue;
diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs
index 2a0481ab684..c0ddeddd7ee 100644
--- a/components/style/values/mod.rs
+++ b/components/style/values/mod.rs
@@ -492,6 +492,44 @@ impl ToCss for CustomIdent {
}
}
+/// <https://www.w3.org/TR/css-values-4/#dashed-idents>
+/// This is simply an Atom, but will only parse if the identifier starts with "--".
+#[repr(transparent)]
+#[derive(
+ Clone,
+ Debug,
+ Eq,
+ Hash,
+ MallocSizeOf,
+ PartialEq,
+ SpecifiedValueInfo,
+ ToComputedValue,
+ ToResolvedValue,
+ ToShmem,
+)]
+pub struct DashedIdent(pub Atom);
+
+impl Parse for DashedIdent {
+ fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
+ let location = input.current_source_location();
+ let ident = input.expect_ident()?;
+ if ident.starts_with("--") {
+ Ok(Self(Atom::from(ident.as_ref())))
+ } else {
+ Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
+ }
+ }
+}
+
+impl ToCss for DashedIdent {
+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
+ where
+ W: Write,
+ {
+ serialize_atom_identifier(&self.0, dest)
+ }
+}
+
/// The <timeline-name> or <keyframes-name>.
/// The definition of these two names are the same, so we use the same type for them.
///
diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs
index b31bc17300e..e157f59d993 100644
--- a/components/style/values/specified/mod.rs
+++ b/components/style/values/specified/mod.rs
@@ -411,6 +411,18 @@ impl NonNegativeNumber {
}
}
+/// An Integer which is >= 0.
+pub type NonNegativeInteger = NonNegative<Integer>;
+
+impl Parse for NonNegativeInteger {
+ fn parse<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<Self, ParseError<'i>> {
+ Ok(NonNegative(Integer::parse_non_negative(context, input)?))
+ }
+}
+
/// A Number which is >= 1.0.
pub type GreaterThanOrEqualToOneNumber = GreaterThanOrEqualToOne<Number>;