Bug 1791777 - patch 1 - Implement CSS parsing for the @font-palette-values rule. r=emilio

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:
Jonathan Kew 2022-10-07 23:00:43 +00:00
parent 62d3894f90
commit 6cbd59c9a6
19 changed files with 429 additions and 34 deletions

View File

@ -103,6 +103,7 @@ void ServoStyleRuleMap::RuleRemoved(StyleSheet& aStyleSheet,
case StyleCssRuleType::Namespace:
case StyleCssRuleType::CounterStyle:
case StyleCssRuleType::FontFeatureValues:
case StyleCssRuleType::FontPaletteValues:
case StyleCssRuleType::Viewport:
break;
}
@ -147,6 +148,7 @@ void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) {
case StyleCssRuleType::Namespace:
case StyleCssRuleType::CounterStyle:
case StyleCssRuleType::FontFeatureValues:
case StyleCssRuleType::FontPaletteValues:
case StyleCssRuleType::Viewport:
break;
}

View File

@ -40,6 +40,7 @@ SERVO_ARC_TYPE(SupportsRule, RawServoSupportsRule)
SERVO_ARC_TYPE(DocumentRule, RawServoMozDocumentRule)
SERVO_ARC_TYPE(ContainerRule, RawServoContainerRule)
SERVO_ARC_TYPE(FontFeatureValuesRule, RawServoFontFeatureValuesRule)
SERVO_ARC_TYPE(FontPaletteValuesRule, RawServoFontPaletteValuesRule)
SERVO_ARC_TYPE(FontFaceRule, RawServoFontFaceRule)
SERVO_ARC_TYPE(CounterStyleRule, RawServoCounterStyleRule)
SERVO_ARC_TYPE(CssUrlData, RawServoCssUrlData)

View File

@ -64,6 +64,7 @@ GROUP_RULE_FUNCS(Supports)
GROUP_RULE_FUNCS(LayerBlock)
BASIC_RULE_FUNCS(LayerStatement)
BASIC_RULE_FUNCS(FontFeatureValues)
BASIC_RULE_FUNCS(FontPaletteValues)
BASIC_RULE_FUNCS(FontFace)
BASIC_RULE_FUNCS(CounterStyle)
GROUP_RULE_FUNCS(Container)

View File

@ -54,6 +54,7 @@ template struct StyleStrong<RawServoNamespaceRule>;
template struct StyleStrong<RawServoPageRule>;
template struct StyleStrong<RawServoSupportsRule>;
template struct StyleStrong<RawServoFontFeatureValuesRule>;
template struct StyleStrong<RawServoFontPaletteValuesRule>;
template struct StyleStrong<RawServoFontFaceRule>;
template struct StyleStrong<RawServoCounterStyleRule>;
template struct StyleStrong<RawServoContainerRule>;

View File

@ -8038,6 +8038,13 @@
mirror: always
rust: true
# Is support for the @font-palette-values rule and font-palette property enabled?
- name: layout.css.font-palette.enabled
type: RelaxedAtomicBool
value: @IS_NIGHTLY_BUILD@
mirror: always
rust: true
# Is support for variation fonts enabled?
- name: layout.css.font-variations.enabled
type: RelaxedAtomicBool

View File

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

View File

@ -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]);

View File

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

View File

@ -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("}")

View 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(())
}
}

View File

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

View File

@ -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.
@ -485,6 +488,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)
@ -557,6 +564,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,

View File

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

View File

@ -370,6 +370,7 @@ impl SanitizationKind {
CssRule::Keyframes(..) |
CssRule::Page(..) |
CssRule::FontFeatureValues(..) |
CssRule::FontPaletteValues(..) |
CssRule::Viewport(..) |
CssRule::CounterStyle(..) => !is_standard,
}

View File

@ -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, PerOrigin, PerOriginIter,
};
@ -1674,6 +1676,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>>>,
@ -1699,6 +1705,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,
@ -1740,6 +1755,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);
}
@ -1749,6 +1765,7 @@ impl ExtraStyleData {
{
self.font_faces.clear();
self.font_feature_values.clear();
self.font_palette_values.clear();
self.counter_styles.clear();
self.pages.clear();
}
@ -1785,6 +1802,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
@ -2630,6 +2648,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,
@ -2880,6 +2903,7 @@ impl CascadeData {
CssRule::Document(..) |
CssRule::LayerBlock(..) |
CssRule::LayerStatement(..) |
CssRule::FontPaletteValues(..) |
CssRule::FontFeatureValues(..) => {
// Not affected by device changes.
continue;

View File

@ -482,6 +482,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.
///

View File

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

View File

@ -193,6 +193,7 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
ContextualParseError::UnsupportedPropertyDeclaration(s, err, _) |
ContextualParseError::UnsupportedFontFaceDescriptor(s, err) |
ContextualParseError::UnsupportedFontFeatureValuesDescriptor(s, err) |
ContextualParseError::UnsupportedFontPaletteValuesDescriptor(s, err) |
ContextualParseError::InvalidKeyframeRule(s, err) |
ContextualParseError::InvalidFontFeatureValuesRule(s, err) |
ContextualParseError::UnsupportedKeyframePropertyDeclaration(s, err) |
@ -401,6 +402,7 @@ impl<'a> ErrorHelpers<'a> for ContextualParseError<'a> {
ContextualParseError::InvalidCounterStyleExtendsWithSymbols |
ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols |
ContextualParseError::UnsupportedFontFeatureValuesDescriptor(..) |
ContextualParseError::UnsupportedFontPaletteValuesDescriptor(..) |
ContextualParseError::InvalidFontFeatureValuesRule(..) => {
(cstr!("PEUnknownAtRule"), Action::Skip)
},

View File

@ -84,6 +84,7 @@ use style::gecko_bindings::structs::{nsINode as RawGeckoNode, Element as RawGeck
use style::gecko_bindings::structs::{
RawServoAnimationValue, RawServoAuthorStyles, RawServoContainerRule, RawServoCounterStyleRule,
RawServoDeclarationBlock, RawServoFontFaceRule, RawServoFontFeatureValuesRule,
RawServoFontPaletteValuesRule,
RawServoImportRule, RawServoKeyframe, RawServoKeyframesRule, RawServoLayerBlockRule,
RawServoLayerStatementRule, RawServoMediaList, RawServoMediaRule, RawServoMozDocumentRule,
RawServoNamespaceRule, RawServoPageRule, RawServoSharedMemoryBuilder, RawServoStyleSet,
@ -119,9 +120,9 @@ use style::stylesheets::layer_rule::LayerOrder;
use style::stylesheets::supports_rule::parse_condition_or_declaration;
use style::stylesheets::{
AllowImportRules, ContainerRule, CounterStyleRule, CssRule, CssRuleType, CssRules,
CssRulesHelpers, DocumentRule, FontFaceRule, FontFeatureValuesRule, ImportRule, KeyframesRule,
LayerBlockRule, LayerStatementRule, MediaRule, NamespaceRule, Origin, OriginSet, PageRule,
SanitizationData, SanitizationKind, StyleRule, StylesheetContents,
CssRulesHelpers, DocumentRule, FontFaceRule, FontFeatureValuesRule, FontPaletteValuesRule,
ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule, MediaRule, NamespaceRule,
Origin, OriginSet, PageRule, SanitizationData, SanitizationKind, StyleRule, StylesheetContents,
StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData,
};
use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist};
@ -2366,6 +2367,13 @@ impl_basic_rule_funcs! { (FontFeatureValues, FontFeatureValuesRule, RawServoFont
changed: Servo_StyleSet_FontFeatureValuesRuleChanged,
}
impl_basic_rule_funcs! { (FontPaletteValues, FontPaletteValuesRule, RawServoFontPaletteValuesRule),
getter: Servo_CssRules_GetFontPaletteValuesRuleAt,
debug: Servo_FontPaletteValuesRule_Debug,
to_css: Servo_FontPaletteValuesRule_GetCssText,
changed: Servo_StyleSet_FontPaletteValuesRuleChanged,
}
impl_basic_rule_funcs! { (FontFace, FontFaceRule, RawServoFontFaceRule),
getter: Servo_CssRules_GetFontFaceRuleAt,
debug: Servo_FontFaceRule_Debug,
@ -2959,7 +2967,7 @@ pub extern "C" fn Servo_FontFeatureValuesRule_GetFontFamily(
result: &mut nsACString,
) {
read_locked_arc(rule, |rule: &FontFeatureValuesRule| {
rule.font_family_to_css(&mut CssWriter::new(result))
rule.family_names.to_css(&mut CssWriter::new(result))
.unwrap()
})
}
@ -2974,6 +2982,54 @@ pub extern "C" fn Servo_FontFeatureValuesRule_GetValueText(
})
}
#[no_mangle]
pub extern "C" fn Servo_FontPaletteValuesRule_GetName(
rule: &RawServoFontPaletteValuesRule,
result: &mut nsACString,
) {
read_locked_arc(rule, |rule: &FontPaletteValuesRule| {
rule.name.to_css(&mut CssWriter::new(result))
.unwrap()
})
}
#[no_mangle]
pub extern "C" fn Servo_FontPaletteValuesRule_GetFontFamily(
rule: &RawServoFontPaletteValuesRule,
result: &mut nsACString,
) {
read_locked_arc(rule, |rule: &FontPaletteValuesRule| {
if !rule.family_names.is_empty() {
rule.family_names.to_css(&mut CssWriter::new(result))
.unwrap()
}
})
}
#[no_mangle]
pub extern "C" fn Servo_FontPaletteValuesRule_GetBasePalette(
rule: &RawServoFontPaletteValuesRule,
result: &mut nsACString,
) {
read_locked_arc(rule, |rule: &FontPaletteValuesRule| {
rule.base_palette.to_css(&mut CssWriter::new(result))
.unwrap()
})
}
#[no_mangle]
pub extern "C" fn Servo_FontPaletteValuesRule_GetOverrideColors(
rule: &RawServoFontPaletteValuesRule,
result: &mut nsACString,
) {
read_locked_arc(rule, |rule: &FontPaletteValuesRule| {
if !rule.override_colors.is_empty() {
rule.override_colors.to_css(&mut CssWriter::new(result))
.unwrap()
}
})
}
#[no_mangle]
pub extern "C" fn Servo_FontFaceRule_CreateEmpty() -> Strong<RawServoFontFaceRule> {
let global_style_data = &*GLOBAL_STYLE_DATA;
@ -6501,6 +6557,8 @@ pub extern "C" fn Servo_StyleSet_BuildFontFeatureValueSet(
set
}
/// TODO FontPaletteValues?
#[no_mangle]
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(
raw_data: &RawServoStyleSet,