From 83a79194236ac070ccf10fb69755cc37da3bf2ff Mon Sep 17 00:00:00 2001 From: ldm0 Date: Wed, 2 Sep 2026 13:38:47 +0800 Subject: [PATCH] fix(cssom): decode escaped property rule names --- moli-css-parse/src/stylo_stylesheet.rs | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/moli-css-parse/src/stylo_stylesheet.rs b/moli-css-parse/src/stylo_stylesheet.rs index 53ffc760aa..9bae517bc9 100644 --- a/moli-css-parse/src/stylo_stylesheet.rs +++ b/moli-css-parse/src/stylo_stylesheet.rs @@ -273,6 +273,23 @@ pub fn parse_font_feature_values_rule_view_with_stylo( pub fn parse_property_rule_view_with_stylo(css_text: &str) -> Option { style::moli_rule_tree::parse_property_rule_view(css_text) + .map(normalize_css_property_rule_view_name) +} + +fn normalize_css_property_rule_view_name(mut view: CssPropertyRuleView) -> CssPropertyRuleView { + let decoded_name = { + let mut input = ParserInput::new(&view.name); + let mut parser = Parser::new(&mut input); + parser + .expect_ident_cloned() + .ok() + .filter(|name| parser.expect_exhausted().is_ok() && name.starts_with("--")) + .map(|name| name.to_string()) + }; + if let Some(decoded_name) = decoded_name { + view.name = decoded_name; + } + view } pub fn native_stylesheet_css_text_with_stylo(stylesheet: &CssNativeStylesheet) -> String { @@ -339,6 +356,7 @@ pub fn native_stylesheet_property_rule_read_with_stylo( rule_path: &[usize], ) -> Option { style::moli_rule_tree::stylesheet_rule_tree_property_rule_view(stylesheet, rule_path) + .map(normalize_css_property_rule_view_name) } pub fn native_stylesheet_font_feature_values_rule_read_with_stylo( @@ -660,6 +678,22 @@ mod tests { ); } + #[test] + fn property_rule_views_decode_escaped_names_without_changing_css_text() { + let property_rule = r#"@property --tab\9 tab { syntax: "*"; inherits: true; }"#; + let parsed = parse_property_rule_view_with_stylo(property_rule) + .expect("escaped @property name should produce a CSSOM view"); + + assert_eq!(parsed.name, "--tab\ttab"); + assert_eq!(parsed.css_text, property_rule); + + let stylesheet = parse_native_stylesheet(property_rule); + assert_eq!( + native_stylesheet_property_rule_read_with_stylo(&stylesheet, &[0]), + Some(parsed), + ); + } + #[test] fn native_stylesheet_adapter_exposes_stylo_counter_style_rules() { let counter_style_rule =