Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett committed Jan 1, 2025
1 parent 0c9d65a commit 79b544c
Show file tree
Hide file tree
Showing 11 changed files with 362 additions and 138 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ visitor = []
into_owned = [
"static-self",
"static-self/smallvec",
"static-self/indexmap",
"parcel_selectors/into_owned",
]
substitute_variables = ["visitor", "into_owned"]
Expand All @@ -72,7 +73,7 @@ const-str = "0.3.1"
pathdiff = "0.2.1"
ahash = "0.8.7"
paste = "1.0.12"
indexmap = "2.2.6"
indexmap = { version = "2.2.6", features = ["serde"] }
# CLI deps
atty = { version = "0.2", optional = true }
clap = { version = "3.0.6", features = ["derive"], optional = true }
Expand All @@ -81,7 +82,7 @@ rayon = { version = "1.5.1", optional = true }
dashmap = { version = "5.0.0", optional = true }
serde_json = { version = "1.0.78", optional = true }
lightningcss-derive = { version = "=1.0.0-alpha.43", path = "./derive" }
schemars = { version = "0.8.19", features = ["smallvec"], optional = true }
schemars = { version = "0.8.19", features = ["smallvec", "indexmap2"], optional = true }
static-self = { version = "0.1.0", path = "static-self", optional = true }

[target.'cfg(target_os = "macos")'.dependencies]
Expand Down
53 changes: 53 additions & 0 deletions node/ast.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export type Rule<D = Declaration, M = MediaQuery> = | {
type: "font-palette-values";
value: FontPaletteValuesRule;
}
| {
type: "font-feature-values";
value: FontFeatureValuesRule;
}
| {
type: "page";
value: PageRule<D>;
Expand Down Expand Up @@ -7159,6 +7163,17 @@ export type BasePalette =
type: "integer";
value: number;
};
/**
* The name of the `@font-feature-values` sub-rule. font-feature-value-type = <@stylistic> | <@historical-forms> | <@styleset> | <@character-variant> | <@swash> | <@ornaments> | <@annotation>
*/
export type FontFeatureSubruleType =
| "stylistic"
| "historical-forms"
| "styleset"
| "character-variant"
| "swash"
| "ornaments"
| "annotation";
/**
* A [page margin box](https://www.w3.org/TR/css-page-3/#margin-boxes).
*/
Expand Down Expand Up @@ -9328,6 +9343,44 @@ export interface OverrideColors {
*/
index: number;
}
/**
* A [@font-feature-values](https://drafts.csswg.org/css-fonts/#font-feature-values) rule.
*/
export interface FontFeatureValuesRule {
/**
* The location of the rule in the source file.
*/
loc: Location2;
/**
* The name of the font feature values.
*/
name: String[];
/**
* The rules within the `@font-feature-values` rule.
*/
rules: {
[k: string]: FontFeatureSubrule;
};
}
/**
* A sub-rule of `@font-feature-values` https://drafts.csswg.org/css-fonts/#font-feature-values-syntax
*/
export interface FontFeatureSubrule {
/**
* The declarations within the `@font-feature-values` sub-rules.
*/
declarations: {
[k: string]: number[];
};
/**
* The location of the rule in the source file.
*/
loc: Location2;
/**
* The name of the `@font-feature-values` sub-rule.
*/
name: FontFeatureSubruleType;
}
/**
* A [@page](https://www.w3.org/TR/css-page-3/#at-page-rule) rule.
*/
Expand Down
31 changes: 29 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13732,11 +13732,38 @@ mod tests {
r#"
@font-feature-values "Fancy Font Name" {
@styleset { cursive: 1; swoopy: 7 16; }
font-display: swap;
@character-variant { ampersand: 1; capital-q: 2; }
}
"#,
r#"@font-feature-values Fancy Font Name{font-display:swap;@styleset{cursive:1;swoopy:7 16}@character-variant{ampersand:1;capital-q:2}}"#,
r#"@font-feature-values Fancy Font Name{@styleset{cursive:1;swoopy:7 16}@character-variant{ampersand:1;capital-q:2}}"#,
);
minify_test(
r#"
@font-feature-values foo {
@swash { pretty: 0; pretty: 1; cool: 2; }
}
"#,
"@font-feature-values foo{@swash{pretty:1;cool:2}}",
);
minify_test(
r#"
@font-feature-values foo {
@swash { pretty: 1; }
@swash { cool: 2; }
}
"#,
"@font-feature-values foo{@swash{pretty:1;cool:2}}",
);
minify_test(
r#"
@font-feature-values foo {
@swash { pretty: 1; }
}
@font-feature-values foo {
@swash { cool: 2; }
}
"#,
"@font-feature-values foo{@swash{pretty:1;cool:2}}",
);
}

Expand Down
6 changes: 3 additions & 3 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::rules::starting_style::StartingStyleRule;
use crate::rules::view_transition::ViewTransitionRule;
use crate::rules::viewport::ViewportRule;

use crate::properties::font::FontFamily;
use crate::properties::font::FamilyName;
use crate::rules::{
counter_style::CounterStyleRule,
custom_media::CustomMediaRule,
Expand Down Expand Up @@ -175,7 +175,7 @@ pub enum AtRulePrelude<'i, T> {
/// A @font-face rule prelude.
FontFace,
/// A @font-feature-values rule prelude, with its FamilyName list.
FontFeatureValues(Vec<FontFamily<'i>>),
FontFeatureValues(Vec<FamilyName<'i>>),
/// A @font-palette-values rule prelude, with its name.
FontPaletteValues(DashedIdent<'i>),
/// A @counter-style rule prelude, with its counter style name.
Expand Down Expand Up @@ -577,7 +577,7 @@ impl<'a, 'o, 'b, 'i, T: crate::traits::AtRuleParser<'i>> AtRuleParser<'i> for Ne
// Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::FontFeatureValues(family_names)))
// },
"font-feature-values" => {
let names = match Vec::<FontFamily>::parse(input) {
let names = match Vec::<FamilyName>::parse(input) {
Ok(names) => names,
Err(e) => return Err(e)
};
Expand Down
83 changes: 53 additions & 30 deletions src/properties/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,19 +348,46 @@ pub enum FontFamily<'i> {
Generic(GenericFontFamily),
/// A custom family name.
#[cfg_attr(feature = "serde", serde(borrow))]
FamilyName(CowArcStr<'i>),
FamilyName(FamilyName<'i>),
}

impl<'i> Parse<'i> for FontFamily<'i> {
fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>> {
if let Ok(value) = input.try_parse(|i| i.expect_string_cloned()) {
return Ok(FontFamily::FamilyName(value.into()));
}

if let Ok(value) = input.try_parse(GenericFontFamily::parse) {
return Ok(FontFamily::Generic(value));
}

let family = FamilyName::parse(input)?;
Ok(FontFamily::FamilyName(family))
}
}

impl<'i> ToCss for FontFamily<'i> {
fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
where
W: std::fmt::Write,
{
match self {
FontFamily::Generic(val) => val.to_css(dest),
FontFamily::FamilyName(val) => val.to_css(dest),
}
}
}

/// A font [family name](https://drafts.csswg.org/css-fonts/#family-name-syntax).
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "visitor", derive(Visit))]
#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent))]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
pub struct FamilyName<'i>(#[cfg_attr(feature = "serde", serde(borrow))] CowArcStr<'i>);

impl<'i> Parse<'i> for FamilyName<'i> {
fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>> {
if let Ok(value) = input.try_parse(|i| i.expect_string_cloned()) {
return Ok(FamilyName(value.into()));
}

let value: CowArcStr<'i> = input.expect_ident()?.into();
let mut string = None;
while let Ok(ident) = input.try_parse(|i| i.expect_ident_cloned()) {
Expand All @@ -380,40 +407,36 @@ impl<'i> Parse<'i> for FontFamily<'i> {
value
};

Ok(FontFamily::FamilyName(value))
Ok(FamilyName(value))
}
}

impl<'i> ToCss for FontFamily<'i> {
impl<'i> ToCss for FamilyName<'i> {
fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
where
W: std::fmt::Write,
{
match self {
FontFamily::Generic(val) => val.to_css(dest),
FontFamily::FamilyName(val) => {
// Generic family names such as sans-serif must be quoted if parsed as a string.
// CSS wide keywords, as well as "default", must also be quoted.
// https://www.w3.org/TR/css-fonts-4/#family-name-syntax
if !val.is_empty() && !GenericFontFamily::parse_string(val).is_ok() {
let mut id = String::new();
let mut first = true;
for slice in val.split(' ') {
if first {
first = false;
} else {
id.push(' ');
}
serialize_identifier(slice, &mut id)?;
}
if id.len() < val.len() + 2 {
return dest.write_str(&id);
}
// Generic family names such as sans-serif must be quoted if parsed as a string.
// CSS wide keywords, as well as "default", must also be quoted.
// https://www.w3.org/TR/css-fonts-4/#family-name-syntax
let val = &self.0;
if !val.is_empty() && !GenericFontFamily::parse_string(val).is_ok() {
let mut id = String::new();
let mut first = true;
for slice in val.split(' ') {
if first {
first = false;
} else {
id.push(' ');
}
serialize_string(&val, dest)?;
Ok(())
serialize_identifier(slice, &mut id)?;
}
if id.len() < val.len() + 2 {
return dest.write_str(&id);
}
}
serialize_string(&val, dest)?;
Ok(())
}
}

Expand Down Expand Up @@ -994,7 +1017,7 @@ fn compatible_font_family(mut family: Option<Vec<FontFamily>>, is_supported: boo
(position + 1)..(position + 1),
DEFAULT_SYSTEM_FONTS
.iter()
.map(|name| FontFamily::FamilyName(CowArcStr::from(*name))),
.map(|name| FontFamily::FamilyName(FamilyName(CowArcStr::from(*name)))),
);
}
}
Expand Down
Loading

0 comments on commit 79b544c

Please sign in to comment.