mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
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
This commit is contained in:
parent
ab4580e112
commit
a4ad5e19b0
12 changed files with 353 additions and 30 deletions
|
@ -26,6 +26,8 @@ pub enum ContextualParseError<'a> {
|
||||||
UnsupportedFontFaceDescriptor(&'a str, ParseError<'a>),
|
UnsupportedFontFaceDescriptor(&'a str, ParseError<'a>),
|
||||||
/// A font feature values descriptor was not recognized.
|
/// A font feature values descriptor was not recognized.
|
||||||
UnsupportedFontFeatureValuesDescriptor(&'a str, ParseError<'a>),
|
UnsupportedFontFeatureValuesDescriptor(&'a str, ParseError<'a>),
|
||||||
|
/// A font palette values descriptor was not recognized.
|
||||||
|
UnsupportedFontPaletteValuesDescriptor(&'a str, ParseError<'a>),
|
||||||
/// A keyframe rule was not valid.
|
/// A keyframe rule was not valid.
|
||||||
InvalidKeyframeRule(&'a str, ParseError<'a>),
|
InvalidKeyframeRule(&'a str, ParseError<'a>),
|
||||||
/// A font feature values rule was not valid.
|
/// 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)
|
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) => {
|
ContextualParseError::InvalidKeyframeRule(rule, ref err) => {
|
||||||
write!(f, "Invalid keyframe rule: '{}', ", rule)?;
|
write!(f, "Invalid keyframe rule: '{}', ", rule)?;
|
||||||
parse_error_to_str(err, f)
|
parse_error_to_str(err, f)
|
||||||
|
|
|
@ -12,10 +12,10 @@ use crate::gecko::url::CssUrlData;
|
||||||
use crate::gecko_bindings::structs::{
|
use crate::gecko_bindings::structs::{
|
||||||
RawServoAnimationValue, RawServoContainerRule, RawServoCounterStyleRule, RawServoCssUrlData,
|
RawServoAnimationValue, RawServoContainerRule, RawServoCounterStyleRule, RawServoCssUrlData,
|
||||||
RawServoDeclarationBlock, RawServoFontFaceRule, RawServoFontFeatureValuesRule,
|
RawServoDeclarationBlock, RawServoFontFaceRule, RawServoFontFeatureValuesRule,
|
||||||
RawServoImportRule, RawServoKeyframe, RawServoKeyframesRule, RawServoLayerBlockRule,
|
RawServoFontPaletteValuesRule, RawServoImportRule, RawServoKeyframe, RawServoKeyframesRule,
|
||||||
RawServoLayerStatementRule, RawServoMediaList, RawServoMediaRule, RawServoMozDocumentRule,
|
RawServoLayerBlockRule, RawServoLayerStatementRule, RawServoMediaList, RawServoMediaRule,
|
||||||
RawServoNamespaceRule, RawServoPageRule, RawServoStyleRule, RawServoStyleSheetContents,
|
RawServoMozDocumentRule, RawServoNamespaceRule, RawServoPageRule, RawServoStyleRule,
|
||||||
RawServoSupportsRule, ServoCssRules,
|
RawServoStyleSheetContents, RawServoSupportsRule, ServoCssRules,
|
||||||
};
|
};
|
||||||
use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
|
use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
|
||||||
use crate::media_queries::MediaList;
|
use crate::media_queries::MediaList;
|
||||||
|
@ -25,8 +25,8 @@ use crate::shared_lock::Locked;
|
||||||
use crate::stylesheets::keyframes_rule::Keyframe;
|
use crate::stylesheets::keyframes_rule::Keyframe;
|
||||||
use crate::stylesheets::{
|
use crate::stylesheets::{
|
||||||
ContainerRule, CounterStyleRule, CssRules, DocumentRule, FontFaceRule, FontFeatureValuesRule,
|
ContainerRule, CounterStyleRule, CssRules, DocumentRule, FontFaceRule, FontFeatureValuesRule,
|
||||||
ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule, MediaRule, NamespaceRule,
|
FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
|
||||||
PageRule, StyleRule, StylesheetContents, SupportsRule,
|
MediaRule, NamespaceRule, PageRule, StyleRule, StylesheetContents, SupportsRule,
|
||||||
};
|
};
|
||||||
use servo_arc::{Arc, ArcBorrow};
|
use servo_arc::{Arc, ArcBorrow};
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
@ -104,6 +104,9 @@ impl_arc_ffi!(Locked<DocumentRule> => RawServoMozDocumentRule
|
||||||
impl_arc_ffi!(Locked<FontFeatureValuesRule> => RawServoFontFeatureValuesRule
|
impl_arc_ffi!(Locked<FontFeatureValuesRule> => RawServoFontFeatureValuesRule
|
||||||
[Servo_FontFeatureValuesRule_AddRef, Servo_FontFeatureValuesRule_Release]);
|
[Servo_FontFeatureValuesRule_AddRef, Servo_FontFeatureValuesRule_Release]);
|
||||||
|
|
||||||
|
impl_arc_ffi!(Locked<FontPaletteValuesRule> => RawServoFontPaletteValuesRule
|
||||||
|
[Servo_FontPaletteValuesRule_AddRef, Servo_FontPaletteValuesRule_Release]);
|
||||||
|
|
||||||
impl_arc_ffi!(Locked<FontFaceRule> => RawServoFontFaceRule
|
impl_arc_ffi!(Locked<FontFaceRule> => RawServoFontFaceRule
|
||||||
[Servo_FontFaceRule_AddRef, Servo_FontFaceRule_Release]);
|
[Servo_FontFaceRule_AddRef, Servo_FontFaceRule_Release]);
|
||||||
|
|
||||||
|
|
|
@ -552,6 +552,7 @@ impl StylesheetInvalidationSet {
|
||||||
Page(..) |
|
Page(..) |
|
||||||
Viewport(..) |
|
Viewport(..) |
|
||||||
FontFeatureValues(..) |
|
FontFeatureValues(..) |
|
||||||
|
FontPaletteValues(..) |
|
||||||
LayerStatement(..) |
|
LayerStatement(..) |
|
||||||
FontFace(..) |
|
FontFace(..) |
|
||||||
Keyframes(..) |
|
Keyframes(..) |
|
||||||
|
@ -632,7 +633,8 @@ impl StylesheetInvalidationSet {
|
||||||
// existing elements.
|
// existing elements.
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CounterStyle(..) | Page(..) | Viewport(..) | FontFeatureValues(..) => {
|
CounterStyle(..) | Page(..) | Viewport(..) | FontFeatureValues(..) |
|
||||||
|
FontPaletteValues(..) => {
|
||||||
debug!(
|
debug!(
|
||||||
" > Found unsupported rule, marking the whole subtree \
|
" > Found unsupported rule, marking the whole subtree \
|
||||||
invalid."
|
invalid."
|
||||||
|
|
|
@ -275,23 +275,6 @@ macro_rules! font_feature_values_blocks {
|
||||||
rule
|
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.
|
/// Prints inside of `@font-feature-values` block.
|
||||||
pub fn value_to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
pub fn value_to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
where
|
where
|
||||||
|
@ -349,7 +332,7 @@ macro_rules! font_feature_values_blocks {
|
||||||
impl ToCssWithGuard for FontFeatureValuesRule {
|
impl ToCssWithGuard for FontFeatureValuesRule {
|
||||||
fn to_css(&self, _guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
|
fn to_css(&self, _guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
|
||||||
dest.write_str("@font-feature-values ")?;
|
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")?;
|
dest.write_str(" {\n")?;
|
||||||
self.value_to_css(&mut CssWriter::new(dest))?;
|
self.value_to_css(&mut CssWriter::new(dest))?;
|
||||||
dest.write_str("}")
|
dest.write_str("}")
|
||||||
|
|
215
components/style/stylesheets/font_palette_values_rule.rs
Normal file
215
components/style/stylesheets/font_palette_values_rule.rs
Normal file
|
@ -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(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ mod counter_style_rule;
|
||||||
mod document_rule;
|
mod document_rule;
|
||||||
mod font_face_rule;
|
mod font_face_rule;
|
||||||
pub mod font_feature_values_rule;
|
pub mod font_feature_values_rule;
|
||||||
|
pub mod font_palette_values_rule;
|
||||||
pub mod import_rule;
|
pub mod import_rule;
|
||||||
pub mod keyframes_rule;
|
pub mod keyframes_rule;
|
||||||
pub mod layer_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::document_rule::DocumentRule;
|
||||||
pub use self::font_face_rule::FontFaceRule;
|
pub use self::font_face_rule::FontFaceRule;
|
||||||
pub use self::font_feature_values_rule::FontFeatureValuesRule;
|
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::import_rule::ImportRule;
|
||||||
pub use self::keyframes_rule::KeyframesRule;
|
pub use self::keyframes_rule::KeyframesRule;
|
||||||
pub use self::layer_rule::{LayerBlockRule, LayerStatementRule};
|
pub use self::layer_rule::{LayerBlockRule, LayerStatementRule};
|
||||||
|
@ -256,6 +258,7 @@ pub enum CssRule {
|
||||||
Container(Arc<Locked<ContainerRule>>),
|
Container(Arc<Locked<ContainerRule>>),
|
||||||
FontFace(Arc<Locked<FontFaceRule>>),
|
FontFace(Arc<Locked<FontFaceRule>>),
|
||||||
FontFeatureValues(Arc<Locked<FontFeatureValuesRule>>),
|
FontFeatureValues(Arc<Locked<FontFeatureValuesRule>>),
|
||||||
|
FontPaletteValues(Arc<Locked<FontPaletteValuesRule>>),
|
||||||
CounterStyle(Arc<Locked<CounterStyleRule>>),
|
CounterStyle(Arc<Locked<CounterStyleRule>>),
|
||||||
Viewport(Arc<Locked<ViewportRule>>),
|
Viewport(Arc<Locked<ViewportRule>>),
|
||||||
Keyframes(Arc<Locked<KeyframesRule>>),
|
Keyframes(Arc<Locked<KeyframesRule>>),
|
||||||
|
@ -293,6 +296,7 @@ impl CssRule {
|
||||||
|
|
||||||
CssRule::FontFace(_) => 0,
|
CssRule::FontFace(_) => 0,
|
||||||
CssRule::FontFeatureValues(_) => 0,
|
CssRule::FontFeatureValues(_) => 0,
|
||||||
|
CssRule::FontPaletteValues(_) => 0,
|
||||||
CssRule::CounterStyle(_) => 0,
|
CssRule::CounterStyle(_) => 0,
|
||||||
CssRule::Viewport(_) => 0,
|
CssRule::Viewport(_) => 0,
|
||||||
CssRule::Keyframes(_) => 0,
|
CssRule::Keyframes(_) => 0,
|
||||||
|
@ -348,6 +352,7 @@ pub enum CssRuleType {
|
||||||
LayerBlock = 16,
|
LayerBlock = 16,
|
||||||
LayerStatement = 17,
|
LayerStatement = 17,
|
||||||
Container = 18,
|
Container = 18,
|
||||||
|
FontPaletteValues = 19,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
@ -367,6 +372,7 @@ impl CssRule {
|
||||||
CssRule::Media(_) => CssRuleType::Media,
|
CssRule::Media(_) => CssRuleType::Media,
|
||||||
CssRule::FontFace(_) => CssRuleType::FontFace,
|
CssRule::FontFace(_) => CssRuleType::FontFace,
|
||||||
CssRule::FontFeatureValues(_) => CssRuleType::FontFeatureValues,
|
CssRule::FontFeatureValues(_) => CssRuleType::FontFeatureValues,
|
||||||
|
CssRule::FontPaletteValues(_) => CssRuleType::FontPaletteValues,
|
||||||
CssRule::CounterStyle(_) => CssRuleType::CounterStyle,
|
CssRule::CounterStyle(_) => CssRuleType::CounterStyle,
|
||||||
CssRule::Keyframes(_) => CssRuleType::Keyframes,
|
CssRule::Keyframes(_) => CssRuleType::Keyframes,
|
||||||
CssRule::Namespace(_) => CssRuleType::Namespace,
|
CssRule::Namespace(_) => CssRuleType::Namespace,
|
||||||
|
@ -474,6 +480,10 @@ impl DeepCloneWithLock for CssRule {
|
||||||
let rule = arc.read_with(guard);
|
let rule = arc.read_with(guard);
|
||||||
CssRule::FontFeatureValues(Arc::new(lock.wrap(rule.clone())))
|
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) => {
|
CssRule::CounterStyle(ref arc) => {
|
||||||
let rule = arc.read_with(guard);
|
let rule = arc.read_with(guard);
|
||||||
CssRule::CounterStyle(Arc::new(lock.wrap(rule.clone())))
|
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::Style(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||||
CssRule::FontFace(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::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::CounterStyle(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||||
CssRule::Viewport(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),
|
CssRule::Keyframes(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||||
|
|
|
@ -23,11 +23,12 @@ use crate::stylesheets::stylesheet::Namespaces;
|
||||||
use crate::stylesheets::supports_rule::SupportsCondition;
|
use crate::stylesheets::supports_rule::SupportsCondition;
|
||||||
use crate::stylesheets::{
|
use crate::stylesheets::{
|
||||||
viewport_rule, AllowImportRules, CorsMode, CssRule, CssRuleType, CssRules, DocumentRule,
|
viewport_rule, AllowImportRules, CorsMode, CssRule, CssRuleType, CssRules, DocumentRule,
|
||||||
FontFeatureValuesRule, KeyframesRule, MediaRule, NamespaceRule, PageRule, PageSelectors,
|
FontFeatureValuesRule, FontPaletteValuesRule, KeyframesRule, MediaRule, NamespaceRule,
|
||||||
RulesMutateError, StyleRule, StylesheetLoader, SupportsRule, ViewportRule,
|
PageRule, PageSelectors, RulesMutateError, StyleRule, StylesheetLoader, SupportsRule,
|
||||||
|
ViewportRule,
|
||||||
};
|
};
|
||||||
use crate::values::computed::font::FamilyName;
|
use crate::values::computed::font::FamilyName;
|
||||||
use crate::values::{CssUrl, CustomIdent, KeyframesName};
|
use crate::values::{CssUrl, CustomIdent, DashedIdent, KeyframesName};
|
||||||
use crate::{Namespace, Prefix};
|
use crate::{Namespace, Prefix};
|
||||||
use cssparser::{
|
use cssparser::{
|
||||||
AtRuleParser, BasicParseError, BasicParseErrorKind, CowRcStr, Parser, ParserState,
|
AtRuleParser, BasicParseError, BasicParseErrorKind, CowRcStr, Parser, ParserState,
|
||||||
|
@ -184,6 +185,8 @@ pub enum AtRulePrelude {
|
||||||
FontFace,
|
FontFace,
|
||||||
/// A @font-feature-values rule prelude, with its FamilyName list.
|
/// A @font-feature-values rule prelude, with its FamilyName list.
|
||||||
FontFeatureValues(Vec<FamilyName>),
|
FontFeatureValues(Vec<FamilyName>),
|
||||||
|
/// A @font-palette-values rule prelude, with its identifier.
|
||||||
|
FontPaletteValues(DashedIdent),
|
||||||
/// A @counter-style rule prelude, with its counter style name.
|
/// A @counter-style rule prelude, with its counter style name.
|
||||||
CounterStyle(CustomIdent),
|
CounterStyle(CustomIdent),
|
||||||
/// A @media rule prelude, with its media queries.
|
/// 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)?;
|
let family_names = parse_family_name_list(self.context, input)?;
|
||||||
AtRulePrelude::FontFeatureValues(family_names)
|
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") => {
|
"counter-style" if cfg!(feature = "gecko") => {
|
||||||
let name = parse_counter_style_name_definition(input)?;
|
let name = parse_counter_style_name_definition(input)?;
|
||||||
AtRulePrelude::CounterStyle(name)
|
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) => {
|
AtRulePrelude::CounterStyle(name) => {
|
||||||
let context = ParserContext::new_with_rule_type(
|
let context = ParserContext::new_with_rule_type(
|
||||||
self.context,
|
self.context,
|
||||||
|
|
|
@ -70,7 +70,8 @@ where
|
||||||
CssRule::Keyframes(_) |
|
CssRule::Keyframes(_) |
|
||||||
CssRule::Page(_) |
|
CssRule::Page(_) |
|
||||||
CssRule::LayerStatement(_) |
|
CssRule::LayerStatement(_) |
|
||||||
CssRule::FontFeatureValues(_) => None,
|
CssRule::FontFeatureValues(_) |
|
||||||
|
CssRule::FontPaletteValues(_) => None,
|
||||||
CssRule::Import(ref import_rule) => {
|
CssRule::Import(ref import_rule) => {
|
||||||
let import_rule = import_rule.read_with(guard);
|
let import_rule = import_rule.read_with(guard);
|
||||||
if !C::process_import(guard, device, quirks_mode, import_rule) {
|
if !C::process_import(guard, device, quirks_mode, import_rule) {
|
||||||
|
|
|
@ -381,6 +381,7 @@ impl SanitizationKind {
|
||||||
CssRule::Keyframes(..) |
|
CssRule::Keyframes(..) |
|
||||||
CssRule::Page(..) |
|
CssRule::Page(..) |
|
||||||
CssRule::FontFeatureValues(..) |
|
CssRule::FontFeatureValues(..) |
|
||||||
|
CssRule::FontPaletteValues(..) |
|
||||||
CssRule::Viewport(..) |
|
CssRule::Viewport(..) |
|
||||||
CssRule::CounterStyle(..) => !is_standard,
|
CssRule::CounterStyle(..) => !is_standard,
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,9 @@ use crate::stylesheets::keyframes_rule::KeyframesAnimation;
|
||||||
use crate::stylesheets::layer_rule::{LayerName, LayerOrder};
|
use crate::stylesheets::layer_rule::{LayerName, LayerOrder};
|
||||||
use crate::stylesheets::viewport_rule::{self, MaybeNew, ViewportRule};
|
use crate::stylesheets::viewport_rule::{self, MaybeNew, ViewportRule};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::stylesheets::{CounterStyleRule, FontFaceRule, FontFeatureValuesRule, PageRule};
|
use crate::stylesheets::{
|
||||||
|
CounterStyleRule, FontFaceRule, FontFeatureValuesRule, FontPaletteValuesRule, PageRule,
|
||||||
|
};
|
||||||
use crate::stylesheets::{
|
use crate::stylesheets::{
|
||||||
CssRule, EffectiveRulesIterator, Origin, OriginSet, PageRule, PerOrigin, PerOriginIter,
|
CssRule, EffectiveRulesIterator, Origin, OriginSet, PageRule, PerOrigin, PerOriginIter,
|
||||||
};
|
};
|
||||||
|
@ -1679,6 +1681,10 @@ pub struct ExtraStyleData {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub font_feature_values: LayerOrderedVec<Arc<Locked<FontFeatureValuesRule>>>,
|
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.
|
/// A map of effective counter-style rules.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub counter_styles: LayerOrderedMap<Arc<Locked<CounterStyleRule>>>,
|
pub counter_styles: LayerOrderedMap<Arc<Locked<CounterStyleRule>>>,
|
||||||
|
@ -1704,6 +1710,15 @@ impl ExtraStyleData {
|
||||||
self.font_feature_values.push(rule.clone(), layer);
|
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.
|
/// Add the given @counter-style rule.
|
||||||
fn add_counter_style(
|
fn add_counter_style(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1745,6 +1760,7 @@ impl ExtraStyleData {
|
||||||
fn sort_by_layer(&mut self, layers: &[CascadeLayer]) {
|
fn sort_by_layer(&mut self, layers: &[CascadeLayer]) {
|
||||||
self.font_faces.sort(layers);
|
self.font_faces.sort(layers);
|
||||||
self.font_feature_values.sort(layers);
|
self.font_feature_values.sort(layers);
|
||||||
|
self.font_palette_values.sort(layers);
|
||||||
self.counter_styles.sort(layers);
|
self.counter_styles.sort(layers);
|
||||||
self.pages.global.sort(layers);
|
self.pages.global.sort(layers);
|
||||||
}
|
}
|
||||||
|
@ -1754,6 +1770,7 @@ impl ExtraStyleData {
|
||||||
{
|
{
|
||||||
self.font_faces.clear();
|
self.font_faces.clear();
|
||||||
self.font_feature_values.clear();
|
self.font_feature_values.clear();
|
||||||
|
self.font_palette_values.clear();
|
||||||
self.counter_styles.clear();
|
self.counter_styles.clear();
|
||||||
self.pages.clear();
|
self.pages.clear();
|
||||||
}
|
}
|
||||||
|
@ -1790,6 +1807,7 @@ impl MallocSizeOf for ExtraStyleData {
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
n += self.font_faces.shallow_size_of(ops);
|
n += self.font_faces.shallow_size_of(ops);
|
||||||
n += self.font_feature_values.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.counter_styles.shallow_size_of(ops);
|
||||||
n += self.pages.shallow_size_of(ops);
|
n += self.pages.shallow_size_of(ops);
|
||||||
n
|
n
|
||||||
|
@ -2638,6 +2656,11 @@ impl CascadeData {
|
||||||
.add_font_feature_values(rule, containing_rule_state.layer_id);
|
.add_font_feature_values(rule, containing_rule_state.layer_id);
|
||||||
},
|
},
|
||||||
#[cfg(feature = "gecko")]
|
#[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) => {
|
CssRule::CounterStyle(ref rule) => {
|
||||||
self.extra_data.add_counter_style(
|
self.extra_data.add_counter_style(
|
||||||
guard,
|
guard,
|
||||||
|
@ -2888,6 +2911,7 @@ impl CascadeData {
|
||||||
CssRule::Document(..) |
|
CssRule::Document(..) |
|
||||||
CssRule::LayerBlock(..) |
|
CssRule::LayerBlock(..) |
|
||||||
CssRule::LayerStatement(..) |
|
CssRule::LayerStatement(..) |
|
||||||
|
CssRule::FontPaletteValues(..) |
|
||||||
CssRule::FontFeatureValues(..) => {
|
CssRule::FontFeatureValues(..) => {
|
||||||
// Not affected by device changes.
|
// Not affected by device changes.
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -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 <timeline-name> or <keyframes-name>.
|
||||||
/// The definition of these two names are the same, so we use the same type for them.
|
/// The definition of these two names are the same, so we use the same type for them.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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.
|
/// A Number which is >= 1.0.
|
||||||
pub type GreaterThanOrEqualToOneNumber = GreaterThanOrEqualToOne<Number>;
|
pub type GreaterThanOrEqualToOneNumber = GreaterThanOrEqualToOne<Number>;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue