From 257107014801e892a78ec68c2c0ec0899a083053 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Tue, 20 Dec 2022 15:43:58 +0300 Subject: [PATCH] feat(css/parser): Normalize and improve function name (#6667) --- crates/jsdoc/tests/fixtures/constanttag.debug | 2 +- .../swc_atoms/scripts/add-from-cargo-check.sh | 0 crates/swc_atoms/words.txt | 277 ++++++ crates/swc_css_ast/src/at_rule.rs | 9 + crates/swc_css_ast/src/base.rs | 48 +- crates/swc_css_ast/src/lib.rs | 23 + crates/swc_css_codegen/src/lib.rs | 8 + crates/swc_css_codegen/tests/fixture.rs | 6 - .../src/compiler/color_alpha_parameter.rs | 53 +- .../src/compiler/color_hex_alpha.rs | 6 +- .../swc_css_compat/src/compiler/color_hwb.rs | 14 +- .../color_space_separated_parameters.rs | 13 +- .../src/compiler/legacy_rgb_and_hsl.rs | 10 +- ...custom_property_no_missing_var_function.rs | 4 +- .../output.swc-stderr | 4 +- .../swc_css_minifier/src/compressor/color.rs | 10 +- .../src/compressor/easing_function.rs | 8 +- .../src/compressor/math/mod.rs | 11 +- crates/swc_css_minifier/src/compressor/mod.rs | 4 +- .../src/compressor/transform_function.rs | 139 ++- .../fixture/compress_angle/output.min.css | 2 +- ...index-loader-syntax.modules.transform.json | 8 +- crates/swc_css_parser/src/parser/input.rs | 39 +- .../swc_css_parser/src/parser/syntax/mod.rs | 34 +- crates/swc_css_parser/src/parser/util.rs | 3 +- .../src/parser/values_and_units/mod.rs | 827 ++++++++++-------- .../tests/fixture/at-rule/import/output.json | 8 +- .../fixture/at-rule/keyframe/output.json | 8 +- .../fixture/at-rule/supports/output.json | 4 +- .../fixture/at-rule/supports/span.swc-stderr | 12 +- .../fixture/at-rule/unknown/span.swc-stderr | 2 +- .../tests/fixture/dashed-ident/input.css | 4 + .../tests/fixture/dashed-ident/output.json | 134 ++- .../fixture/dashed-ident/span.swc-stderr | 160 +++- .../fixture/function/unknown/output.json | 66 +- .../fixture/function/unknown/span.swc-stderr | 56 +- .../tests/fixture/value/color/output.json | 6 +- .../media/wrong-stylesheet/span.swc-stderr | 2 +- .../at-rule/page/without-page/span.swc-stderr | 2 +- .../supports/non-standard-prelude/output.json | 8 +- .../non-standard-prelude/span.swc-stderr | 8 +- .../recovery/cdo-and-cdc/span.swc-stderr | 2 +- .../declaration/important-1/span.swc-stderr | 2 +- .../declaration/important/span.swc-stderr | 32 +- .../declaration/wrong-name/span.swc-stderr | 2 +- .../delim-token/at-sign/span.swc-stderr | 2 +- .../tests/recovery/hacks/span.swc-stderr | 2 +- .../tests/recovery/ie-progid/output.json | 4 +- .../rules/unclosed-brackets/span.swc-stderr | 4 +- .../basic/span.swc-stderr | 4 +- crates/swc_css_prefixer/src/prefixer.rs | 112 ++- crates/swc_css_utils/src/lib.rs | 13 +- crates/swc_css_visit/src/lib.rs | 7 +- 53 files changed, 1479 insertions(+), 749 deletions(-) mode change 100644 => 100755 crates/swc_atoms/scripts/add-from-cargo-check.sh diff --git a/crates/jsdoc/tests/fixtures/constanttag.debug b/crates/jsdoc/tests/fixtures/constanttag.debug index 512a15279aa5..4190cd79018a 100644 --- a/crates/jsdoc/tests/fixtures/constanttag.debug +++ b/crates/jsdoc/tests/fixtures/constanttag.debug @@ -42,7 +42,7 @@ ), ctxt: #0, }, - value: Atom('constant' type=dynamic), + value: Atom('constant' type=static), }, tag: Const( ConstTag { diff --git a/crates/swc_atoms/scripts/add-from-cargo-check.sh b/crates/swc_atoms/scripts/add-from-cargo-check.sh old mode 100644 new mode 100755 diff --git a/crates/swc_atoms/words.txt b/crates/swc_atoms/words.txt index f1fed1474c67..3460dd2b9199 100644 --- a/crates/swc_atoms/words.txt +++ b/crates/swc_atoms/words.txt @@ -85,6 +85,57 @@ -ms-high-contrast-adjust -ms-hyphens -ms-interpolation-mode +-moz-any +-moz-calc +-moz-document +-moz-keyframes +* +-infinity +-moz-activehyperlinktext +-moz-any +-moz-buttondefault +-moz-buttonhoverface +-moz-buttonhovertext +-moz-calc +-moz-cellhighlight +-moz-cellhighlighttext +-moz-combobox +-moz-comboboxtext +-moz-default-background-color +-moz-default-color +-moz-dialog +-moz-dialogtext +-moz-document +-moz-dragtargetzone +-moz-eventreerow +-moz-html-cellhighlight +-moz-html-cellhighlighttext +-moz-hyperlinktext +-moz-keyframes +-moz-mac-accentdarkestshadow +-moz-mac-accentdarkshadow +-moz-mac-accentface +-moz-mac-accentlightesthighlight +-moz-mac-accentlightshadow +-moz-mac-accentregularhighlight +-moz-mac-accentregularshadow +-moz-mac-chrome-active +-moz-mac-chrome-inactive +-moz-mac-focusring +-moz-mac-menuselect +-moz-mac-menushadow +-moz-mac-menutextselect +-moz-menubarhovertext +-moz-menubartext +-moz-menuhover +-moz-menuhovertext +-moz-nativehyperlinktext +-moz-oddtreerow +-moz-visitedhyperlinktext +-moz-win-accentcolor +-moz-win-accentcolortext +-moz-win-communicationstext +-moz-win-mediatext -ms-keyframes -ms-region-fragment -ms-scroll-chaining @@ -832,16 +883,22 @@ _extends _toConsumableArray a abbr +abs abstract accent-color accept accesskey +acos acronym action +activeborder +activecaption +activetext actuate add address after +aliceblue align-content align-items align-self @@ -877,7 +934,9 @@ animation-timing-function annotation annotation-xml anonymous +antiquewhite any +appWorkspace appearance apple-touch-icon apple-touch-icon-precomposed @@ -889,6 +948,8 @@ application/ld+json application/x-javascript application/xhtml+xml apply +aqua +aquamarine arcrole area arguments @@ -898,10 +959,13 @@ aria-owns article as aside +asin aspect-ratio assert asserts async +atan +atan2 attributeName attributeType attributename @@ -912,9 +976,11 @@ autocomplete avoid await azimuth +azure b backdrop-filter backface-visibility +background background-attachment background-blend-mode background-clip @@ -937,15 +1003,21 @@ bdi bdo before begin +beige bgsound big bigint +bisque +black +blanchedalmond blink block block-overflow block-size blocking blockquote +blue +blueviolet body bold boolean @@ -1017,24 +1089,38 @@ break break-after break-before break-inside +brown +burlywood button +buttonborder +buttonface +buttonhighlight +buttonshadow +buttontext +cadetblue calc calcMode calcmode call canvas canvastext +cap caption caption-side +captiontext caret-color caret-shape case catch center +ch character-variant charset +chartreuse +chocolate circle cite +clamp class classid clear @@ -1052,6 +1138,7 @@ colgroup collection color color-adjust +color-contrast color-index color-mix color-profile @@ -1073,6 +1160,7 @@ columns command concat const +constant constructor contain contain-intrinsic-block-size @@ -1085,12 +1173,23 @@ content-box content-security-policy contenteditable continue +coral +cornflowerblue +cornsilk +cos counter-increment counter-reset counter-set counter-style +cqb +cqh +cqi +cqmax +cqmin +cqw createClass createReactClass +crimson crossorigin cubic-bezier cue @@ -1100,12 +1199,34 @@ currentColor currentcolor cursor custom-media +cyan d +darkblue +darkcyan +darkgoldenrod +darkgray +darkgreen +darkgrey +darkkhaki +darkmagenta +darkolivegreen +darkorange +darkorchid +darkred +darksalmon +darkseagreen +darkslateblue +darkslategray +darkslategrey +darkturquoise +darkviolet data datalist dd debugger declare +deeppink +deepskyblue default definitionURL definitionurl @@ -1123,6 +1244,8 @@ dfn dialog diffuseConstant diffuseconstant +dimgray +dimgrey dir direction discard @@ -1133,6 +1256,7 @@ div dl do document +dodgerblue dpcm dpi dppx @@ -1143,6 +1267,7 @@ dvi dvmax dvmin dvw +e ease ease-in ease-in-out @@ -1163,6 +1288,7 @@ env eval even ex +exp export exportparts extends @@ -1218,7 +1344,9 @@ fespecularlighting fespotlight fetile feturbulence +field fieldset +fieldtext figcaption figure file @@ -1229,6 +1357,7 @@ filter filterUnits filterunits finally +firebrick first-child first-letter first-line @@ -1242,6 +1371,7 @@ flex-grow flex-shrink flex-wrap float +floralwhite flow flow-from flow-into @@ -1277,26 +1407,38 @@ for forced-color-adjust foreignObject foreignobject +forestgreen form formaction format +fr frame frameset from from-image +fuchsia function future g +gainsboro get +ghostwhite global glyph glyphRef glyphref +gold +goldenrod grad gradientTransform gradientUnits gradienttransform gradientunits +gray +graytext +green +greenyellow +grey grid grid-auto-columns grid-auto-flow @@ -1325,11 +1467,14 @@ headers height hgroup highlight +highlighttext historical-forms hkern +honeydew horizontal-tb host host-context +hotpink hr href hsl @@ -1339,6 +1484,7 @@ http-equiv hwb hyphenate-character hyphens +hypot hz i ic @@ -1359,7 +1505,15 @@ import important importmap in +inactiveborder +inactivecaption +inactivecaptiontext +indianred +indigo infer +infinity +infobackground +infotext inherit initial initial-letter @@ -1388,6 +1542,7 @@ itemprop itemref itemtype iterator +ivory jump-end jump-start justify-content @@ -1411,12 +1566,17 @@ keypoints keysplines keytimes keywords +khaki khz +lab label lang language last-child last-of-type +lavender +lavenderblush +lawngreen layer lch left @@ -1425,6 +1585,7 @@ left-middle left-top legacy legend +lemonchiffon length lengthAdjust lengthadjust @@ -1432,6 +1593,23 @@ let letter-spacing lh li +lightblue +lightcoral +lightcyan +lightgoldenrodyellow +lightgray +lightgreen +lightgrey +lightpink +lightsalmon +lightseagreen +lightskyblue +lightslategray +lightslategrey +lightsteelblue +lightyellow +lime +limegreen limitingConeAngle limitingconeangle line @@ -1443,12 +1621,15 @@ line-through linear linearGradient lineargradient +linen link +linktext list-item list-style-image list-style-type listing local +log longdesc lr lr-tb @@ -1460,6 +1641,7 @@ lvi lvmax lvmin lvw +magenta main malignmark manual @@ -1484,6 +1666,8 @@ markerWidth markerheight markerunits markerwidth +marktext +maroon marquee mask mask-border @@ -1515,6 +1699,7 @@ math-shift math-style matrix matrix3d +max max-aspect-ratio max-block-size max-color @@ -1531,12 +1716,24 @@ max-width maxlength media medium +mediumaquamarine +mediumblue +mediumorchid +mediumpurple +mediumseagreen +mediumslateblue +mediumspringgreen +mediumturquoise +mediumvioletred menu +menutext meta metadata meter mglyph mi +midnightblue +min min-aspect-ratio min-block-size min-color @@ -1549,12 +1746,16 @@ min-inline-size min-monochrome min-resolution min-width +mintcream missing-glyph +mistyrose mix-blend-mode mixed mm mn mo +moccasin +mod module monochrome mozmm @@ -1563,7 +1764,10 @@ ms mtext name namespace +nan nav +navajowhite +navy nest never new @@ -1599,6 +1803,9 @@ offset-rotate oklab oklch ol +oldlace +olive +olivedrab onabort onafterprint onautocomplete @@ -1704,6 +1911,9 @@ opentype optgroup option or +orange +orangered +orchid order ornaments orphans @@ -1746,7 +1956,12 @@ page-break-after page-break-before page-break-inside paint-order +palegoldenrod +palegreen +paleturquoise +palevioletred panose-1 +papayawhip param part past @@ -1761,15 +1976,20 @@ patterncontentunits patterntransform patternunits pc +peachpuff perspective perspective-origin +peru +pi picture ping +pink place-content place-items place-self placeholder plaintext +plum pointer-events points pointsAtX @@ -1782,6 +2002,8 @@ polygon polyline position poster +pow +powderblue pre preload preserveAlpha @@ -1799,6 +2021,7 @@ property protected pt public +purple px q rad @@ -1809,7 +2032,9 @@ rbc rcap rch readonly +rebeccapurple rect +red refX refY refx @@ -1846,6 +2071,7 @@ right-top rl rlh role +rosybrown rotate rotate3d rotateX @@ -1860,6 +2086,7 @@ row-gap row-reverse rows rowspan +royalblue rp rt rtc @@ -1872,14 +2099,20 @@ ruby-position ruby-text run-in s +saddlebrown +salmon samp sandbox +sandybrown satisfies scale scale3d scaleX scaleY scaleZ +scalex +scaley +scalez script scroll scroll-behavior @@ -1916,11 +2149,17 @@ scroll-snap-type-x scroll-snap-type-y scroll-timeline-axis scroll-timeline-name +scrollbar scrollbar-color scrollbar-gutter scrollbar-width +seagreen +seashell section select +selecteditem +selecteditemtext +selector separate set shadow @@ -1930,6 +2169,10 @@ shape-outside show sideways-lr sideways-rl +sienna +sign +silver +sin size sizes skew @@ -1937,10 +2180,15 @@ skewX skewY skewx skewy +skyblue +slateblue +slategray +slategrey slice slot slotted small +snow solid solidColor source @@ -1955,6 +2203,8 @@ specularexponent speculationrules spreadMethod spreadmethod +springgreen +sqrt src srcdoc srcset @@ -1964,6 +2214,7 @@ startoffset static stdDeviation stddeviation +steelblue step-end step-start steps @@ -1986,6 +2237,7 @@ super supports surfaceScale surfacescale +svb svg svh svi @@ -2005,6 +2257,7 @@ table-cell table-layout tableValues tablevalues +tan target targetX targetY @@ -2015,6 +2268,7 @@ tb-lr tb-rl tbody td +teal template text text-align-last @@ -2055,11 +2309,18 @@ tfoot th thead this +thistle +threeddarkshadow +threedface +threedhighlight +threedlightshadow +threedshadow throw time title to toString +tomato top top-center top-left @@ -2083,6 +2344,8 @@ translate3d translateX translateY translateZ +translatey +translatez transparent tref true @@ -2091,6 +2354,7 @@ try tspan tt turn +turquoise type typeof u @@ -2122,6 +2386,8 @@ viewTarget viewbox viewport viewtarget +violet +visitedtext vkern vmax vmin @@ -2129,12 +2395,18 @@ void vw wbr weight +wheat where while +white white-space +whitesmoke widows width will-change +window +windowframe +windowtext with woff woff2 @@ -2161,8 +2433,13 @@ xml:space xmlns xmlns:xlink xmp +xyz +xyz-d50 +xyz-d65 yChannelSelector ychannelselector +yellow +yellowgreen yield z-index zoom diff --git a/crates/swc_css_ast/src/at_rule.rs b/crates/swc_css_ast/src/at_rule.rs index 8b6cddfef553..c7559569ee0a 100644 --- a/crates/swc_css_ast/src/at_rule.rs +++ b/crates/swc_css_ast/src/at_rule.rs @@ -36,6 +36,15 @@ impl PartialEq for AtRuleName { } } +impl PartialEq for AtRuleName { + fn eq(&self, other: &JsWord) -> bool { + match self { + AtRuleName::DashedIdent(v) => v.value == *other, + AtRuleName::Ident(v) => v.value == *other, + } + } +} + #[ast_node] #[derive(Eq, Hash, Is, EqIgnoreSpan)] pub enum AtRulePrelude { diff --git a/crates/swc_css_ast/src/base.rs b/crates/swc_css_ast/src/base.rs index 215e51b37201..473088e3cbdd 100644 --- a/crates/swc_css_ast/src/base.rs +++ b/crates/swc_css_ast/src/base.rs @@ -1,4 +1,5 @@ use is_macro::Is; +use swc_atoms::JsWord; use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span}; use crate::{ @@ -100,12 +101,39 @@ impl Take for SimpleBlock { } } +#[ast_node] +#[derive(Eq, Hash, Is, EqIgnoreSpan)] +pub enum FunctionName { + #[tag("Ident")] + Ident(Ident), + #[tag("DashedIdent")] + DashedIdent(DashedIdent), +} + +impl PartialEq for FunctionName { + fn eq(&self, other: &str) -> bool { + match self { + FunctionName::DashedIdent(v) => *v == *other, + FunctionName::Ident(v) => *v == *other, + } + } +} + +impl PartialEq for FunctionName { + fn eq(&self, other: &JsWord) -> bool { + match self { + FunctionName::DashedIdent(v) => v.value == *other, + FunctionName::Ident(v) => v.value == *other, + } + } +} + #[ast_node("Function")] #[derive(Eq, Hash, EqIgnoreSpan)] pub struct Function { /// Span starting from the `lo` of identifier and to the end of `)`. pub span: Span, - pub name: Ident, + pub name: FunctionName, pub value: Vec, } @@ -267,6 +295,24 @@ pub enum DeclarationName { DashedIdent(DashedIdent), } +impl PartialEq for DeclarationName { + fn eq(&self, other: &str) -> bool { + match self { + DeclarationName::DashedIdent(v) => *v == *other, + DeclarationName::Ident(v) => *v == *other, + } + } +} + +impl PartialEq for DeclarationName { + fn eq(&self, other: &JsWord) -> bool { + match self { + DeclarationName::DashedIdent(v) => v.value == *other, + DeclarationName::Ident(v) => v.value == *other, + } + } +} + #[ast_node("ImportantFlag")] #[derive(Eq, Hash, EqIgnoreSpan)] pub struct ImportantFlag { diff --git a/crates/swc_css_ast/src/lib.rs b/crates/swc_css_ast/src/lib.rs index b48c7adf2b9e..8173f6d8dcf4 100644 --- a/crates/swc_css_ast/src/lib.rs +++ b/crates/swc_css_ast/src/lib.rs @@ -32,3 +32,26 @@ macro_rules! matches_eq_ignore_ascii_case { )* false }}; } + +/// Returns true if the given value matches one of the given patterns. +/// +/// The type of value and patterns should be identical. +/// +/// # Examples +/// +/// ``` +/// use swc_atoms::JsWord; +/// use swc_atoms::js_word; +/// use swc_css_ast::*; +/// +/// assert!(matches_eq!(JsWord::from("a"), js_word!("a"))); +/// assert!(matches_eq!("a", "a")); +/// ``` +#[macro_export] +macro_rules! matches_eq { + ($value:expr, $($pat:expr),*) => {{ + $( + $value == $pat || + )* false + }}; +} diff --git a/crates/swc_css_codegen/src/lib.rs b/crates/swc_css_codegen/src/lib.rs index db2db4d50f0f..96e41730282a 100644 --- a/crates/swc_css_codegen/src/lib.rs +++ b/crates/swc_css_codegen/src/lib.rs @@ -1315,6 +1315,14 @@ where write_raw!(self, ")"); } + #[emitter] + fn emit_function_name(&mut self, n: &FunctionName) -> Result { + match n { + FunctionName::Ident(n) => emit!(self, n), + FunctionName::DashedIdent(n) => emit!(self, n), + } + } + #[emitter] fn emit_color_profile_name(&mut self, n: &ColorProfileName) -> Result { match n { diff --git a/crates/swc_css_codegen/tests/fixture.rs b/crates/swc_css_codegen/tests/fixture.rs index cbfdae7cad2e..84bcd6a5a9a8 100644 --- a/crates/swc_css_codegen/tests/fixture.rs +++ b/crates/swc_css_codegen/tests/fixture.rs @@ -286,12 +286,6 @@ impl VisitMut for NormalizeTest { } } - fn visit_mut_function(&mut self, n: &mut Function) { - n.visit_mut_children_with(self); - - n.name.value = n.name.value.to_lowercase().into(); - } - fn visit_mut_pseudo_class_selector(&mut self, n: &mut PseudoClassSelector) { n.visit_mut_children_with(self); diff --git a/crates/swc_css_compat/src/compiler/color_alpha_parameter.rs b/crates/swc_css_compat/src/compiler/color_alpha_parameter.rs index 0bd68e11f1e3..a2af9c491316 100644 --- a/crates/swc_css_compat/src/compiler/color_alpha_parameter.rs +++ b/crates/swc_css_compat/src/compiler/color_alpha_parameter.rs @@ -1,45 +1,42 @@ use swc_atoms::js_word; -use swc_css_ast::{AbsoluteColorBase, ComponentValue}; +use swc_css_ast::{AbsoluteColorBase, ComponentValue, FunctionName}; use crate::compiler::Compiler; impl Compiler { pub(crate) fn process_color_alpha_parameter(&mut self, n: &mut AbsoluteColorBase) { if let AbsoluteColorBase::Function(function) = n { - let name = function.name.value.to_ascii_lowercase(); - if let Some(ComponentValue::AlphaValue(_) | ComponentValue::Function(_)) = function.value.last() { - if !matches!( - name, - js_word!("rgb") | js_word!("rgba") | js_word!("hsl") | js_word!("hsla") - ) { - return; - } - - match name { - js_word!("rgb") => { - function.name.value = js_word!("rgba"); - function.name.raw = None; - } - js_word!("hsl") => { - function.name.value = js_word!("hsla"); - function.name.raw = None; + let name = match &mut function.name { + FunctionName::Ident(name) => name, + _ => { + return; } - _ => {} + }; + + if name.value == js_word!("rgb") { + name.value = js_word!("rgba"); + name.raw = None; + } else if name.value == js_word!("hsl") { + name.value = js_word!("hsla"); + name.raw = None; } } else { - match name { - js_word!("rgba") => { - function.name.value = js_word!("rgb"); - function.name.raw = None; - } - js_word!("hsla") => { - function.name.value = js_word!("hsl"); - function.name.raw = None; + let name = match &mut function.name { + FunctionName::Ident(name) => name, + _ => { + return; } - _ => {} + }; + + if name.value == js_word!("rgba") { + name.value = js_word!("rgb"); + name.raw = None; + } else if name.value == js_word!("hsla") { + name.value = js_word!("hsl"); + name.raw = None; } } } diff --git a/crates/swc_css_compat/src/compiler/color_hex_alpha.rs b/crates/swc_css_compat/src/compiler/color_hex_alpha.rs index b6887e4e09c7..6cd80841dabb 100644 --- a/crates/swc_css_compat/src/compiler/color_hex_alpha.rs +++ b/crates/swc_css_compat/src/compiler/color_hex_alpha.rs @@ -2,7 +2,7 @@ use swc_atoms::js_word; use swc_common::DUMMY_SP; use swc_css_ast::{ AbsoluteColorBase, AlphaValue, Color, ComponentValue, Delimiter, DelimiterValue, Function, - Ident, Number, + FunctionName, Ident, Number, }; use swc_css_utils::{hex_to_rgba, round_alpha}; @@ -43,11 +43,11 @@ impl Compiler { *n = ComponentValue::Color(Box::new(Color::AbsoluteColorBase( AbsoluteColorBase::Function(Function { span: hex_color.span, - name: Ident { + name: FunctionName::Ident(Ident { span: DUMMY_SP, value: js_word!("rgba"), raw: None, - }, + }), value: vec![ ComponentValue::Number(Box::new(Number { span: DUMMY_SP, diff --git a/crates/swc_css_compat/src/compiler/color_hwb.rs b/crates/swc_css_compat/src/compiler/color_hwb.rs index 645e58e00421..91a1acc5aa97 100644 --- a/crates/swc_css_compat/src/compiler/color_hwb.rs +++ b/crates/swc_css_compat/src/compiler/color_hwb.rs @@ -1,7 +1,7 @@ use swc_atoms::js_word; use swc_css_ast::{ - AbsoluteColorBase, AlphaValue, Angle, ComponentValue, Delimiter, DelimiterValue, Hue, Ident, - Number, Percentage, + AbsoluteColorBase, AlphaValue, Angle, ComponentValue, Delimiter, DelimiterValue, FunctionName, + Hue, Ident, Number, Percentage, }; use swc_css_utils::{angle_to_deg, hwb_to_rgb, to_rgb255}; @@ -95,7 +95,7 @@ impl Compiler { pub(crate) fn process_color_hwb(&mut self, n: &mut AbsoluteColorBase) { if let AbsoluteColorBase::Function(function) = n { - if function.name.value != js_word!("hwb") { + if function.name != js_word!("hwb") { return; } @@ -120,11 +120,11 @@ impl Compiler { if a == 1.0 { *n = AbsoluteColorBase::Function(swc_css_ast::Function { - name: Ident { + name: FunctionName::Ident(Ident { value: js_word!("rgb"), span: Default::default(), raw: None, - }, + }), value: vec![ ComponentValue::Number(Box::new(Number { value: rgb[0].round(), @@ -154,11 +154,11 @@ impl Compiler { }); } else { *n = AbsoluteColorBase::Function(swc_css_ast::Function { - name: Ident { + name: FunctionName::Ident(Ident { value: js_word!("rgba"), span: Default::default(), raw: None, - }, + }), value: vec![ ComponentValue::Number(Box::new(Number { value: rgb[0].round(), diff --git a/crates/swc_css_compat/src/compiler/color_space_separated_parameters.rs b/crates/swc_css_compat/src/compiler/color_space_separated_parameters.rs index 2398050edf8a..d5b46e44fb8f 100644 --- a/crates/swc_css_compat/src/compiler/color_space_separated_parameters.rs +++ b/crates/swc_css_compat/src/compiler/color_space_separated_parameters.rs @@ -2,7 +2,7 @@ use std::mem::take; use swc_atoms::js_word; use swc_common::DUMMY_SP; -use swc_css_ast::{AbsoluteColorBase, ComponentValue, Delimiter, DelimiterValue}; +use swc_css_ast::{matches_eq, AbsoluteColorBase, ComponentValue, Delimiter, DelimiterValue}; use crate::compiler::Compiler; @@ -12,11 +12,12 @@ impl Compiler { n: &mut AbsoluteColorBase, ) { if let AbsoluteColorBase::Function(function) = n { - let name = function.name.value.to_ascii_lowercase(); - - if !matches!( - name, - js_word!("rgb") | js_word!("rgba") | js_word!("hsl") | js_word!("hsla") + if !matches_eq!( + function.name, + js_word!("rgb"), + js_word!("rgba"), + js_word!("hsl"), + js_word!("hsla") ) { return; } diff --git a/crates/swc_css_compat/src/compiler/legacy_rgb_and_hsl.rs b/crates/swc_css_compat/src/compiler/legacy_rgb_and_hsl.rs index a3eeffaf71d9..9446cccf0a86 100644 --- a/crates/swc_css_compat/src/compiler/legacy_rgb_and_hsl.rs +++ b/crates/swc_css_compat/src/compiler/legacy_rgb_and_hsl.rs @@ -1,7 +1,9 @@ use std::f64::consts::PI; use swc_atoms::js_word; -use swc_css_ast::{AbsoluteColorBase, AlphaValue, Angle, ComponentValue, Hue, Number, Percentage}; +use swc_css_ast::{ + matches_eq, AbsoluteColorBase, AlphaValue, Angle, ComponentValue, Hue, Number, Percentage, +}; use swc_css_utils::{clamp_unit_f64, round_alpha}; use crate::compiler::Compiler; @@ -9,10 +11,8 @@ use crate::compiler::Compiler; impl Compiler { pub(crate) fn process_rgb_and_hsl(&mut self, n: &mut AbsoluteColorBase) { if let AbsoluteColorBase::Function(function) = n { - let name = function.name.value.to_ascii_lowercase(); - - let is_rgb = matches!(name, js_word!("rgb") | js_word!("rgba")); - let is_hsl = matches!(name, js_word!("hsl") | js_word!("hsla")); + let is_rgb = matches_eq!(function.name, js_word!("rgb"), js_word!("rgba")); + let is_hsl = matches_eq!(function.name, js_word!("hsl"), js_word!("hsla")); if is_rgb { function.value = function diff --git a/crates/swc_css_lints/src/rules/custom_property_no_missing_var_function.rs b/crates/swc_css_lints/src/rules/custom_property_no_missing_var_function.rs index 600f0304a21f..e6023bee14f0 100644 --- a/crates/swc_css_lints/src/rules/custom_property_no_missing_var_function.rs +++ b/crates/swc_css_lints/src/rules/custom_property_no_missing_var_function.rs @@ -1,3 +1,4 @@ +use swc_atoms::js_word; use swc_css_ast::*; use swc_css_visit::{Visit, VisitWith}; @@ -37,8 +38,7 @@ impl Visit for CustomPropertyNoMissingVarFunction { } fn visit_function(&mut self, function: &Function) { - self.in_var_function - .push(function.name.value.eq_str_ignore_ascii_case("var")); + self.in_var_function.push(function.name == js_word!("var")); function.visit_children_with(self); self.in_var_function.pop(); } diff --git a/crates/swc_css_lints/tests/rules/fail/custom-property-no-missing-var-function/output.swc-stderr b/crates/swc_css_lints/tests/rules/fail/custom-property-no-missing-var-function/output.swc-stderr index f26dc8c6a6ba..807c7b1a4907 100644 --- a/crates/swc_css_lints/tests/rules/fail/custom-property-no-missing-var-function/output.swc-stderr +++ b/crates/swc_css_lints/tests/rules/fail/custom-property-no-missing-var-function/output.swc-stderr @@ -46,9 +46,9 @@ 7 | :root { --bar: 0; } a { color: --foo(--bar); } `---- - x Unexpected missing var function for '--bar'. + x Unexpected missing var function for '--foo'. ,-[$DIR/tests/rules/fail/custom-property-no-missing-var-function/input.css:6:1] 6 | :root { --foo: pink; } a { color: --foo, red; } 7 | :root { --bar: 0; } a { color: --foo(--bar); } - : ^^^^^ + : ^^^^^ `---- diff --git a/crates/swc_css_minifier/src/compressor/color.rs b/crates/swc_css_minifier/src/compressor/color.rs index 5da0a2b55fad..75c5c3672863 100644 --- a/crates/swc_css_minifier/src/compressor/color.rs +++ b/crates/swc_css_minifier/src/compressor/color.rs @@ -119,11 +119,11 @@ macro_rules! make_color { Color::AbsoluteColorBase(AbsoluteColorBase::Function(Function { span: $span, - name: Ident { + name: FunctionName::Ident(Ident { span: DUMMY_SP, value: js_word!("rgba"), raw: None, - }, + }), value: vec![ ComponentValue::Number(Box::new(Number { span: DUMMY_SP, @@ -387,7 +387,7 @@ impl Compressor { name, value, .. - })) if matches!(&*name.value, "rgb" | "rgba") => { + })) if name == &js_word!("rgb") || name == &js_word!("rgba") => { let rgba: Vec<_> = value .iter() .filter(|n| { @@ -425,7 +425,7 @@ impl Compressor { name, value, .. - })) if matches!(&*name.value, "hsl" | "hsla") => { + })) if name == &js_word!("hsl") || name == &js_word!("hsla") => { let hsla: Vec<_> = value .iter() .filter(|n| { @@ -465,7 +465,7 @@ impl Compressor { name, value, .. - })) if matches!(&*name.value, "hwb") => { + })) if name == &js_word!("hwb") => { let h = match self.get_hue(value.get(0).as_ref()) { Some(value) => value, _ => return, diff --git a/crates/swc_css_minifier/src/compressor/easing_function.rs b/crates/swc_css_minifier/src/compressor/easing_function.rs index 5bfdd7f6a359..e49950fc1c5c 100644 --- a/crates/swc_css_minifier/src/compressor/easing_function.rs +++ b/crates/swc_css_minifier/src/compressor/easing_function.rs @@ -10,9 +10,7 @@ impl Compressor { name, value: function_value, span, - }) if name.value.eq_ignore_ascii_case(&js_word!("cubic-bezier")) - && function_value.len() == 7 => - { + }) if name == &js_word!("cubic-bezier") && function_value.len() == 7 => { if let ( first, second, @@ -81,9 +79,7 @@ impl Compressor { name, value: function_value, span, - }) if name.value.eq_ignore_ascii_case(&js_word!("steps")) - && function_value.len() == 3 => - { + }) if name == &js_word!("steps") && function_value.len() == 3 => { match (&function_value[0], &function_value[2]) { ( ComponentValue::Integer(box Integer { diff --git a/crates/swc_css_minifier/src/compressor/math/mod.rs b/crates/swc_css_minifier/src/compressor/math/mod.rs index 34b03b164534..81572781006d 100644 --- a/crates/swc_css_minifier/src/compressor/math/mod.rs +++ b/crates/swc_css_minifier/src/compressor/math/mod.rs @@ -1,13 +1,10 @@ use swc_atoms::js_word; use swc_css_ast::*; -pub fn is_calc_function_name(ident: &Ident) -> bool { - matches_eq_ignore_ascii_case!( - ident.value, - js_word!("calc"), - js_word!("-webkit-calc"), - js_word!("-moz-calc") - ) +pub fn is_calc_function_name(function_name: &FunctionName) -> bool { + *function_name == js_word!("calc") + || *function_name == js_word!("-webkit-calc") + || *function_name == js_word!("-moz-calc") } pub fn transform_calc_value_into_component_value(calc_value: &CalcValue) -> Option { diff --git a/crates/swc_css_minifier/src/compressor/mod.rs b/crates/swc_css_minifier/src/compressor/mod.rs index cecde666d895..6541243638a7 100644 --- a/crates/swc_css_minifier/src/compressor/mod.rs +++ b/crates/swc_css_minifier/src/compressor/mod.rs @@ -341,8 +341,8 @@ impl VisitMut for Compressor { } fn visit_mut_function(&mut self, n: &mut Function) { - if matches_eq_ignore_ascii_case!( - n.name.value, + if matches_eq!( + n.name, js_word!("rotate"), js_word!("skew"), js_word!("skewx"), diff --git a/crates/swc_css_minifier/src/compressor/transform_function.rs b/crates/swc_css_minifier/src/compressor/transform_function.rs index 056c4534adbc..d57ab4c2d7b1 100644 --- a/crates/swc_css_minifier/src/compressor/transform_function.rs +++ b/crates/swc_css_minifier/src/compressor/transform_function.rs @@ -1,4 +1,5 @@ use swc_atoms::js_word; +use swc_common::Spanned; use swc_css_ast::*; use super::Compressor; @@ -10,9 +11,7 @@ impl Compressor { name, value: function_value, .. - }) if name.value.eq_ignore_ascii_case(&js_word!("translate")) - && function_value.len() == 3 => - { + }) if name == &js_word!("translate") && function_value.len() == 3 => { match (function_value.get(0), function_value.get(2)) { ( Some(first), @@ -30,11 +29,11 @@ impl Compressor { })), Some(second), ) if *first_number == 0 => { - *name = Ident { - span: name.span, - value: js_word!("translateY"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("translatey"), raw: None, - }; + }); *function_value = vec![second.clone()]; } _ => {} @@ -44,9 +43,7 @@ impl Compressor { name, value: function_value, .. - }) if name.value.eq_ignore_ascii_case(&js_word!("translate3d")) - && function_value.len() == 5 => - { + }) if name == &js_word!("translate3d") && function_value.len() == 5 => { match ( function_value.get(0), function_value.get(2), @@ -63,11 +60,11 @@ impl Compressor { })), Some(third), ) if *first_number == 0 && *second_number == 0 => { - *name = Ident { - span: name.span, - value: js_word!("translateZ"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("translatez"), raw: None, - }; + }); *function_value = vec![third.clone()]; } _ => {} @@ -77,9 +74,7 @@ impl Compressor { name, value: function_value, .. - }) if name.value.eq_ignore_ascii_case(&js_word!("scale")) - && function_value.len() == 3 => - { + }) if name == &js_word!("scale") && function_value.len() == 3 => { match (function_value.get(0), function_value.get(2)) { ( Some( @@ -102,11 +97,11 @@ impl Compressor { .. })), ) if *second_number == 1 => { - *name = Ident { - span: name.span, - value: js_word!("scaleX"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("scalex"), raw: None, - }; + }); *function_value = vec![first.clone()]; } ( @@ -116,11 +111,11 @@ impl Compressor { })), Some(second), ) if *first_number == 1 => { - *name = Ident { - span: name.span, - value: js_word!("scaleY"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("scaley"), raw: None, - }; + }); *function_value = vec![second.clone()]; } _ => {} @@ -130,9 +125,7 @@ impl Compressor { name, value: function_value, .. - }) if name.value.eq_ignore_ascii_case(&js_word!("scale3d")) - && function_value.len() == 5 => - { + }) if name == &js_word!("scale3d") && function_value.len() == 5 => { match ( function_value.get(0), function_value.get(2), @@ -149,11 +142,11 @@ impl Compressor { .. })), ) if *second_number == 1 && *third_number == 1 => { - *name = Ident { - span: name.span, - value: js_word!("scaleX"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("scalex"), raw: None, - }; + }); *function_value = vec![first.clone()]; } ( @@ -167,11 +160,11 @@ impl Compressor { .. })), ) if *first_number == 1 && *third_number == 1 => { - *name = Ident { - span: name.span, - value: js_word!("scaleY"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("scaley"), raw: None, - }; + }); *function_value = vec![second.clone()]; } ( @@ -185,11 +178,11 @@ impl Compressor { })), Some(third), ) if *first_number == 1 && *second_number == 1 => { - *name = Ident { - span: name.span, - value: js_word!("scaleZ"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("scalez"), raw: None, - }; + }); *function_value = vec![third.clone()]; } _ => {} @@ -199,9 +192,7 @@ impl Compressor { name, value: function_value, .. - }) if name.value.eq_ignore_ascii_case(&js_word!("matrix3d")) - && function_value.len() == 31 => - { + }) if name == &js_word!("matrix3d") && function_value.len() == 31 => { match ( function_value.get(0), function_value.get(1), @@ -288,11 +279,11 @@ impl Compressor { && *fifteenth_number == 0 && *sixteenth_number == 1 => { - *name = Ident { - span: name.span, + *name = FunctionName::Ident(Ident { + span: name.span(), value: js_word!("matrix"), raw: None, - }; + }); *function_value = vec![ first.clone(), first_comma.clone(), @@ -314,9 +305,7 @@ impl Compressor { name, value: function_value, .. - }) if name.value.eq_ignore_ascii_case(&js_word!("rotate3d")) - && function_value.len() == 7 => - { + }) if name == &js_word!("rotate3d") && function_value.len() == 7 => { match ( function_value.get(0), function_value.get(2), @@ -338,11 +327,11 @@ impl Compressor { })), Some(fourth_value), ) if *first_number == 1 && *second_number == 0 && *third_number == 0 => { - *name = Ident { - span: name.span, - value: js_word!("rotateX"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("rotatex"), raw: None, - }; + }); *function_value = vec![fourth_value.clone()]; } ( @@ -360,11 +349,11 @@ impl Compressor { })), Some(fourth_value), ) if *first_number == 0 && *second_number == 1 && *third_number == 0 => { - *name = Ident { - span: name.span, - value: js_word!("rotateY"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("rotatey"), raw: None, - }; + }); *function_value = vec![fourth_value.clone()]; } ( @@ -382,11 +371,11 @@ impl Compressor { })), Some(fourth_value), ) if *first_number == 0 && *second_number == 0 && *third_number == 1 => { - *name = Ident { - span: name.span, + *name = FunctionName::Ident(Ident { + span: name.span(), value: js_word!("rotate"), raw: None, - }; + }); *function_value = vec![fourth_value.clone()]; } _ => {} @@ -396,23 +385,19 @@ impl Compressor { name, value: function_value, .. - }) if name.value.eq_ignore_ascii_case(&js_word!("rotatez")) - && function_value.len() == 1 => - { - *name = Ident { - span: name.span, + }) if name == &js_word!("rotatez") && function_value.len() == 1 => { + *name = FunctionName::Ident(Ident { + span: name.span(), value: js_word!("rotate"), raw: None, - }; + }); } ComponentValue::Function(box Function { name, value: function_value, .. - }) if name.value.eq_ignore_ascii_case(&js_word!("skew")) - && function_value.len() == 3 => - { + }) if name == &js_word!("skew") && function_value.len() == 3 => { match (function_value.get(0), function_value.get(2)) { ( Some(first), @@ -421,11 +406,11 @@ impl Compressor { .. })), ) if *second_number == 0 => { - *name = Ident { - span: name.span, - value: js_word!("skewX"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("skewx"), raw: None, - }; + }); *function_value = vec![first.clone()]; } @@ -436,11 +421,11 @@ impl Compressor { })), Some(second), ) if *first_number == 0 => { - *name = Ident { - span: name.span, - value: js_word!("skewY"), + *name = FunctionName::Ident(Ident { + span: name.span(), + value: js_word!("skewy"), raw: None, - }; + }); *function_value = vec![second.clone()]; } _ => {} diff --git a/crates/swc_css_minifier/tests/fixture/compress_angle/output.min.css b/crates/swc_css_minifier/tests/fixture/compress_angle/output.min.css index 8f8ba42ef958..0f8956d30464 100644 --- a/crates/swc_css_minifier/tests/fixture/compress_angle/output.min.css +++ b/crates/swc_css_minifier/tests/fixture/compress_angle/output.min.css @@ -1 +1 @@ -.deg{transform:rotate(0);transform:rotate(9deg);transform:rotate(-9deg);transform:rotate(10deg);transform:rotate(180deg);transform:rotate(0);transform:rotate(350deg);transform:rotate(-9deg);transform:rotate(0);transform:rotate(360.5deg);transform:rotate(-360.5deg);transform:rotate(1deg);transform:rotate(-1deg)}.grad{transform:rotate(0);transform:rotate(9grad);transform:rotate(-9grad);transform:rotate(9deg);transform:rotate(180deg);transform:rotate(0);transform:rotate(800.5grad);transform:rotate(-800.5grad);transform:rotate(821grad);transform:rotate(-821grad)}.rad{transform:rotate(0);transform:rotate(1rad);transform:rotate(1.5rad);transform:rotate(-1.5rad)}.turn{transform:rotate(0);transform:rotate(180deg);transform:rotate(0);transform:rotate(180deg);transform:rotate(0);transform:rotate(180deg);transform:rotate(0)}.cross{transform:rotate(90deg);transform:rotate(1.57rad);transform:rotate(3.1416rad)}.class1{transform:rotate(0)}.class2{transform:skew(0,0)}.class3{transform:skewx(0)}.class4{transform:skewy(0)}.class5{transform:rotate3d(10,10,10,0)}.class6{transform:rotatex(0)}.class7{transform:rotatey(0)}.class8{transform:rotate(0)}.class9,.class10{transform:rotate(0)}.class11{transform:rotate(0)}@keyframes spinner-border{to{transform:rotate(360deg)}} +.deg{transform:rotate(0);transform:rotate(9deg);transform:rotate(-9deg);transform:rotate(10deg);transform:rotate(180deg);transform:rotate(0);transform:rotate(350deg);transform:rotate(-9deg);transform:rotate(0);transform:rotate(360.5deg);transform:rotate(-360.5deg);transform:rotate(1deg);transform:rotate(-1deg)}.grad{transform:rotate(0);transform:rotate(9grad);transform:rotate(-9grad);transform:rotate(9deg);transform:rotate(180deg);transform:rotate(0);transform:rotate(800.5grad);transform:rotate(-800.5grad);transform:rotate(821grad);transform:rotate(-821grad)}.rad{transform:rotate(0);transform:rotate(1rad);transform:rotate(1.5rad);transform:rotate(-1.5rad)}.turn{transform:rotate(0);transform:rotate(180deg);transform:rotate(0);transform:rotate(180deg);transform:rotate(0);transform:rotate(180deg);transform:rotate(0)}.cross{transform:rotate(90deg);transform:rotate(1.57rad);transform:rotate(3.1416rad)}.class1{transform:rotate(0)}.class2{transform:skew(0,0)}.class3{transform:skewx(0)}.class4{transform:skewy(0)}.class5{transform:rotate3d(10,10,10,0)}.class6{transform:rotatex(0)}.class7{transform:rotatey(0)}.class8,.class9,.class10,.class11{transform:rotate(0)}@keyframes spinner-border{to{transform:rotate(360deg)}} diff --git a/crates/swc_css_modules/tests/fixture/index-loader-syntax.modules.transform.json b/crates/swc_css_modules/tests/fixture/index-loader-syntax.modules.transform.json index ac5e71c741ef..eb1843d7a3c6 100644 --- a/crates/swc_css_modules/tests/fixture/index-loader-syntax.modules.transform.json +++ b/crates/swc_css_modules/tests/fixture/index-loader-syntax.modules.transform.json @@ -1,14 +1,14 @@ { - "blue": [ + "foo": [ { "type": "local", - "name": "__local__blue" + "name": "__local__foo" } ], - "foo": [ + "blue": [ { "type": "local", - "name": "__local__foo" + "name": "__local__blue" } ] } diff --git a/crates/swc_css_parser/src/parser/input.rs b/crates/swc_css_parser/src/parser/input.rs index adced3631088..96634ea0a5cb 100644 --- a/crates/swc_css_parser/src/parser/input.rs +++ b/crates/swc_css_parser/src/parser/input.rs @@ -1,8 +1,8 @@ use std::{borrow::Cow, fmt::Debug, mem::take}; -use swc_atoms::{Atom, JsWord}; +use swc_atoms::Atom; use swc_common::{BytePos, Span, Spanned, SyntaxContext}; -use swc_css_ast::{ComponentValue, ListOfComponentValues, Token, TokenAndSpan}; +use swc_css_ast::{ComponentValue, FunctionName, ListOfComponentValues, Token, TokenAndSpan}; use super::PResult; use crate::error::{Error, ErrorKind}; @@ -224,7 +224,7 @@ type SpanLike = (BytePos, BytePos); #[derive(Debug)] enum TokenOrBlock<'a> { Token(&'a TokenAndSpan), - Function(Box<(Span, JsWord, Atom)>), + Function(Box<(Span, FunctionName)>), LBracket(SpanLike), LParen(SpanLike), LBrace(SpanLike), @@ -279,11 +279,7 @@ impl<'a> Input<'a> { function.name.span_hi() + BytePos(1), Default::default(), ), - function.name.value.clone(), - match &function.name.raw { - Some(raw) => raw.clone(), - _ => Atom::from(function.name.value.clone()), - }, + function.name.clone(), )))); } @@ -381,13 +377,26 @@ impl<'a> Input<'a> { TokenOrBlock::Token(token_and_span) => { return Ok(Cow::Borrowed(token_and_span)) } - TokenOrBlock::Function(function) => TokenAndSpan { - span: function.0, - token: Token::Function { - value: function.1, - raw: function.2, - }, - }, + TokenOrBlock::Function(function) => { + let name = match function.1 { + FunctionName::Ident(name) => match name.raw { + Some(raw) => (name.value, raw), + _ => (name.value.clone(), Atom::from(name.value)), + }, + FunctionName::DashedIdent(name) => match name.raw { + Some(raw) => (format!("--{}", name.value).into(), raw), + _ => (name.value.clone(), Atom::from(name.value)), + }, + }; + + TokenAndSpan { + span: function.0, + token: Token::Function { + value: name.0, + raw: name.1, + }, + } + } TokenOrBlock::LBracket(span) => TokenAndSpan { span: Span::new(span.0, span.1, Default::default()), token: Token::LBracket, diff --git a/crates/swc_css_parser/src/parser/syntax/mod.rs b/crates/swc_css_parser/src/parser/syntax/mod.rs index 7e62d22675cc..d5ac775d6263 100644 --- a/crates/swc_css_parser/src/parser/syntax/mod.rs +++ b/crates/swc_css_parser/src/parser/syntax/mod.rs @@ -196,7 +196,7 @@ where at_rule.span = span!(self, span.lo); // Canonicalization against a grammar - if self.ctx.need_canonicalize { + if !is_dashed_ident && self.ctx.need_canonicalize { at_rule = self.canonicalize_at_rule_prelude(at_rule)?; } @@ -214,7 +214,7 @@ where at_rule.span = span!(self, span.lo); // Canonicalization against a grammar - if self.ctx.need_canonicalize { + if !is_dashed_ident && self.ctx.need_canonicalize { at_rule = self.canonicalize_at_rule_prelude(at_rule)?; at_rule = self.canonicalize_at_rule_block(at_rule)?; } @@ -605,14 +605,17 @@ where // // Return nothing. let span = self.input.cur_span(); - let is_dashed_ident = match cur!(self) { - Token::Ident { value, .. } => value.starts_with("--"), + let declaration_name = match cur!(self) { + Token::Ident { value, .. } => value, _ => { return Err(Error::new(span, ErrorKind::Expected("ident"))); } }; + let is_dashed_ident = declaration_name.starts_with("--"); let name = if is_dashed_ident { - DeclarationName::DashedIdent(self.parse()?) + let ident = self.parse()?; + + DeclarationName::DashedIdent(ident) } else { let mut ident: Ident = self.parse()?; @@ -923,16 +926,25 @@ where // Create a function with its name equal to the value of the current input token // and with its value initially set to an empty list. let span = self.input.cur_span(); - let ident = match bump!(self) { + let function_name = match bump!(self) { Token::Function { value, raw } => (value, raw), _ => { unreachable!() } }; - let name = Ident { - span: Span::new(span.lo, span.hi - BytePos(1), Default::default()), - value: ident.0, - raw: Some(ident.1), + let is_dashed_ident = function_name.0.starts_with("--"); + let name = if is_dashed_ident { + FunctionName::DashedIdent(DashedIdent { + span: Span::new(span.lo, span.hi - BytePos(1), Default::default()), + value: function_name.0[2..].into(), + raw: Some(function_name.1), + }) + } else { + FunctionName::Ident(Ident { + span: Span::new(span.lo, span.hi - BytePos(1), Default::default()), + value: function_name.0.to_ascii_lowercase(), + raw: Some(function_name.1), + }) }; let mut function = Function { span: Default::default(), @@ -975,7 +987,7 @@ where function.span = span!(self, span.lo); // Canonicalization against a grammar - if self.ctx.need_canonicalize { + if !is_dashed_ident && self.ctx.need_canonicalize { function = self.canonicalize_function_value(function)?; } diff --git a/crates/swc_css_parser/src/parser/util.rs b/crates/swc_css_parser/src/parser/util.rs index 59aa82996c11..5c172ddf52eb 100644 --- a/crates/swc_css_parser/src/parser/util.rs +++ b/crates/swc_css_parser/src/parser/util.rs @@ -267,11 +267,10 @@ where &mut self, mut function: Function, ) -> PResult { - let function_name = function.name.value.to_ascii_lowercase(); let locv = self.create_locv(function.value); function.value = match self.parse_according_to_grammar(&locv, |parser| { - parser.parse_function_values(&function_name) + parser.parse_function_values(&function.name) }) { Ok(values) => values, Err(err) => { diff --git a/crates/swc_css_parser/src/parser/values_and_units/mod.rs b/crates/swc_css_parser/src/parser/values_and_units/mod.rs index c88b2a0507a1..22dbf72676e8 100644 --- a/crates/swc_css_parser/src/parser/values_and_units/mod.rs +++ b/crates/swc_css_parser/src/parser/values_and_units/mod.rs @@ -1,4 +1,4 @@ -use swc_atoms::js_word; +use swc_atoms::{js_word, JsWord}; use swc_common::{BytePos, Span}; use swc_css_ast::*; @@ -48,12 +48,23 @@ where return Ok(ComponentValue::Url(self.parse()?)); } - Token::Function { value, .. } => match &*value.to_ascii_lowercase() { - "url" | "src" => { + Token::Function { value, .. } => match value.to_ascii_lowercase() { + js_word!("url") | js_word!("src") => { return Ok(ComponentValue::Url(self.parse()?)); } - "rgb" | "rgba" | "hsl" | "hsla" | "hwb" | "lab" | "lch" | "oklab" | "oklch" - | "color" | "device-cmyk" | "color-mix" | "color-contrast" => { + js_word!("rgb") + | js_word!("rgba") + | js_word!("hsl") + | js_word!("hsla") + | js_word!("hwb") + | js_word!("lab") + | js_word!("lch") + | js_word!("oklab") + | js_word!("oklch") + | js_word!("color") + | js_word!("device-cmyk") + | js_word!("color-mix") + | js_word!("color-contrast") => { return Ok(ComponentValue::Color(self.parse()?)); } _ => { @@ -184,12 +195,33 @@ where } // TODO use `JsWord` - pub fn parse_function_values(&mut self, function_name: &str) -> PResult> { + pub fn parse_function_values( + &mut self, + function_name: &FunctionName, + ) -> PResult> { + let function_name = match function_name { + FunctionName::Ident(name) => &name.value, + FunctionName::DashedIdent(_) => { + return Err(Error::new(Default::default(), ErrorKind::Ignore)) + } + }; + let mut values = vec![]; - match function_name { - "calc" | "-moz-calc" | "-webkit-calc" | "sin" | "cos" | "tan" | "asin" | "acos" - | "atan" | "sqrt" | "exp" | "abs" | "sign" => { + match *function_name { + js_word!("calc") + | js_word!("-moz-calc") + | js_word!("-webkit-calc") + | js_word!("sin") + | js_word!("cos") + | js_word!("tan") + | js_word!("asin") + | js_word!("acos") + | js_word!("atan") + | js_word!("sqrt") + | js_word!("exp") + | js_word!("abs") + | js_word!("sign") => { self.input.skip_ws(); let calc_sum = ComponentValue::CalcSum(self.parse()?); @@ -204,7 +236,7 @@ where return Err(Error::new(span, ErrorKind::Unexpected("value"))); } } - "min" | "max" | "hypot" => { + js_word!("min") | js_word!("max") | js_word!("hypot") => { self.input.skip_ws(); let calc_sum = ComponentValue::CalcSum(self.parse()?); @@ -233,7 +265,7 @@ where return Err(Error::new(span, ErrorKind::Unexpected("value"))); } } - "clamp" => { + js_word!("clamp") => { self.input.skip_ws(); let calc_sum = ComponentValue::CalcSum(self.parse()?); @@ -274,7 +306,7 @@ where self.input.skip_ws(); } - "round" => { + js_word!("round") => { self.input.skip_ws(); if is!(self, "ident") { @@ -318,7 +350,7 @@ where self.input.skip_ws(); } - "mod" | "rem" | "atan2" | "pow" => { + js_word!("mod") | js_word!("rem") | js_word!("atan2") | js_word!("pow") => { self.input.skip_ws(); let calc_sum = ComponentValue::CalcSum(self.parse()?); @@ -343,7 +375,7 @@ where self.input.skip_ws(); } - "log" => { + js_word!("log") => { self.input.skip_ws(); let calc_sum = ComponentValue::CalcSum(self.parse()?); @@ -364,7 +396,7 @@ where self.input.skip_ws(); } } - "rgb" | "rgba" | "hsl" | "hsla" => { + js_word!("rgb") | js_word!("rgba") | js_word!("hsl") | js_word!("hsla") => { self.input.skip_ws(); let mut has_variable = false; @@ -394,8 +426,8 @@ where _ => {} } - match function_name { - "rgb" | "rgba" => { + match *function_name { + js_word!("rgb") | js_word!("rgba") => { let percentage_or_number_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -442,7 +474,7 @@ where self.input.skip_ws(); } - "hsl" | "hsla" => { + js_word!("hsl") | js_word!("hsla") => { let hue_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("number") | tok!("dimension") => { @@ -507,8 +539,8 @@ where is_legacy_syntax = false; } - match function_name { - "rgb" | "rgba" => { + match *function_name { + js_word!("rgb") | js_word!("rgba") => { let percentage_or_number = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -553,7 +585,7 @@ where self.input.skip_ws(); } - "hsl" | "hsla" => { + js_word!("hsl") | js_word!("hsla") => { let percentage_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -623,8 +655,8 @@ where } } - match function_name { - "rgb" | "rgba" => { + match *function_name { + js_word!("rgb") | js_word!("rgba") => { let percentage_or_number = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -669,7 +701,7 @@ where self.input.skip_ws(); } - "hsl" | "hsla" => { + js_word!("hsl") | js_word!("hsla") => { let percentage_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -801,7 +833,12 @@ where self.input.skip_ws(); } } - "hwb" | "lab" | "lch" | "oklab" | "oklch" | "device-cmyk" => { + js_word!("hwb") + | js_word!("lab") + | js_word!("lch") + | js_word!("oklab") + | js_word!("oklch") + | js_word!("device-cmyk") => { self.input.skip_ws(); let mut has_variable = false; @@ -809,7 +846,7 @@ where match cur!(self) { Token::Ident { value, .. } if matches_eq_ignore_ascii_case!(value, js_word!("from")) - && function_name != "device-cmyk" => + && *function_name != js_word!("device-cmyk") => { values.push(ComponentValue::Ident(self.parse()?)); @@ -829,8 +866,8 @@ where _ => {} } - match function_name { - "hwb" => { + match *function_name { + js_word!("hwb") => { let hue_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("number") | tok!("dimension") => { @@ -874,7 +911,7 @@ where self.input.skip_ws(); } - "lab" | "lch" | "oklab" | "oklch" => { + js_word!("lab") | js_word!("lch") | js_word!("oklab") | js_word!("oklch") => { let percentage_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -919,7 +956,7 @@ where self.input.skip_ws(); } - "device-cmyk" => { + js_word!("device-cmyk") => { let cmyk_component = self.try_parse_variable_function( |parser, _| Ok(Some(ComponentValue::CmykComponent(parser.parse()?))), &mut has_variable, @@ -937,8 +974,8 @@ where } if !is_one_of!(self, EOF, "/") { - match function_name { - "hwb" => { + match *function_name { + js_word!("hwb") => { let percentage_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -984,7 +1021,10 @@ where self.input.skip_ws(); } - "lab" | "lch" | "oklab" | "oklch" => { + js_word!("lab") + | js_word!("lch") + | js_word!("oklab") + | js_word!("oklch") => { let number_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -1033,7 +1073,7 @@ where self.input.skip_ws(); } - "device-cmyk" => { + js_word!("device-cmyk") => { let cmyk_component = self.try_parse_variable_function( |parser, _| { Ok(Some(ComponentValue::CmykComponent(parser.parse()?))) @@ -1054,8 +1094,8 @@ where } if !is_one_of!(self, EOF, "/") { - match function_name { - "hwb" => { + match *function_name { + js_word!("hwb") => { let percentage_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -1101,7 +1141,7 @@ where self.input.skip_ws(); } - "lab" | "oklab" => { + js_word!("lab") | js_word!("oklab") => { let number_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("percentage") => { @@ -1150,7 +1190,7 @@ where self.input.skip_ws(); } - "lch" | "oklch" => { + js_word!("lch") | js_word!("oklch") => { let hue_or_none = self.try_parse_variable_function( |parser, has_variable_before| match cur!(parser) { tok!("number") | tok!("dimension") => { @@ -1196,7 +1236,7 @@ where self.input.skip_ws(); } - "device-cmyk" => { + js_word!("device-cmyk") => { let cmyk_component = self.try_parse_variable_function( |parser, _| { Ok(Some(ComponentValue::CmykComponent(parser.parse()?))) @@ -1242,7 +1282,7 @@ where Token::Function { value, .. } if is_math_function(value) => { Ok(Some(ComponentValue::Function(parser.parse()?))) } - tok!("ident") if !matches!(function_name, "device-cmyk") => { + tok!("ident") if !matches!(*function_name, js_word!("device-cmyk")) => { let ident: Box = parser.parse()?; if ident.value.eq_str_ignore_ascii_case("none") { @@ -1278,7 +1318,7 @@ where self.input.skip_ws(); } } - "color" => { + js_word!("color") => { self.input.skip_ws(); let mut has_variable = false; @@ -1317,7 +1357,10 @@ where Ok(Some(ComponentValue::DashedIdent(parser.parse()?))) } else { if matches_eq_ignore_ascii_case!( - &**value, "xyz", "xyz-d50", "xyz-d65" + value, + js_word!("xyz"), + js_word!("xyz-d50"), + js_word!("xyz-d65") ) { is_xyz = true } else { @@ -1403,7 +1446,10 @@ where Token::Function { value, .. } if is_math_function(value) || matches_eq_ignore_ascii_case!( - &**value, "var", "env", "constant" + value, + js_word!("var"), + js_word!("env"), + js_word!("constant") ) => { ComponentValue::Function(self.parse()?) @@ -1532,7 +1578,7 @@ where Token::Function { value, .. } if is_math_function(value) => { Ok(Some(ComponentValue::Function(parser.parse()?))) } - tok!("ident") if !matches!(function_name, "device-cmyk") => { + tok!("ident") if !matches!(*function_name, js_word!("device-cmyk")) => { let ident: Box = parser.parse()?; if ident.value.eq_str_ignore_ascii_case("none") { @@ -1570,7 +1616,7 @@ where self.input.skip_ws(); } - "selector" if self.ctx.in_supports_at_rule => { + js_word!("selector") if self.ctx.in_supports_at_rule => { self.input.skip_ws(); let selector = ComponentValue::ComplexSelector(self.parse()?); @@ -1579,7 +1625,7 @@ where self.input.skip_ws(); } - "layer" if self.ctx.in_import_at_rule => { + js_word!("layer") if self.ctx.in_import_at_rule => { self.input.skip_ws(); if is!(self, EOF) { @@ -1612,7 +1658,7 @@ where )); } } - "supports" if self.ctx.in_import_at_rule => { + js_word!("supports") if self.ctx.in_import_at_rule => { self.input.skip_ws(); if !is!(self, EOF) { @@ -1678,7 +1724,12 @@ where match cur!(self) { Token::Function { value, .. } - if matches_eq_ignore_ascii_case!(&**value, "var", "env", "constant") => + if matches_eq_ignore_ascii_case!( + value, + js_word!("var"), + js_word!("env"), + js_word!("constant") + ) => { *has_before_variable = true; @@ -1812,7 +1863,12 @@ where match bump!(self) { Token::Ident { value, raw, .. } => { if matches_eq_ignore_ascii_case!( - &*value, "initial", "inherit", "unset", "revert", "default" + value, + js_word!("initial"), + js_word!("inherit"), + js_word!("unset"), + js_word!("revert"), + js_word!("default") ) { return Err(Error::new(span, ErrorKind::InvalidCustomIdent(value))); } @@ -3205,8 +3261,12 @@ where tok!("dimension") => Ok(CalcValue::Dimension(self.parse()?)), tok!("percentage") => Ok(CalcValue::Percentage(self.parse()?)), Token::Ident { value, .. } => { - match &*value.to_ascii_lowercase() { - "e" | "pi" | "infinity" | "-infinity" | "nan" => {} + match value.to_ascii_lowercase() { + js_word!("e") + | js_word!("pi") + | js_word!("infinity") + | js_word!("-infinity") + | js_word!("nan") => {} _ => { let span = self.input.cur_span(); @@ -3292,338 +3352,389 @@ where } } -pub(crate) fn is_math_function(name: &str) -> bool { - matches!( - &*name.to_ascii_lowercase(), - "calc" - | "-moz-calc" - | "-webkit-calc" - | "sin" - | "cos" - | "tan" - | "asin" - | "acos" - | "atan" - | "sqrt" - | "exp" - | "abs" - | "sign" - | "min" - | "max" - | "hypot" - | "clamp" - | "round" - | "mod" - | "rem" - | "atan2" - | "pow" - | "log" +pub(crate) fn is_math_function(name: &JsWord) -> bool { + matches_eq_ignore_ascii_case!( + name, + js_word!("calc"), + js_word!("-moz-calc"), + js_word!("-webkit-calc"), + js_word!("sin"), + js_word!("cos"), + js_word!("tan"), + js_word!("asin"), + js_word!("acos"), + js_word!("atan"), + js_word!("sqrt"), + js_word!("exp"), + js_word!("abs"), + js_word!("sign"), + js_word!("min"), + js_word!("max"), + js_word!("hypot"), + js_word!("clamp"), + js_word!("round"), + js_word!("mod"), + js_word!("rem"), + js_word!("atan2"), + js_word!("pow"), + js_word!("log") ) } -fn is_absolute_color_base_function(name: &str) -> bool { - matches!( - &*name.to_ascii_lowercase(), - "rgb" - | "rgba" - | "hsl" - | "hsla" - | "hwb" - | "lab" - | "lch" - | "oklab" - | "oklch" - | "color" - | "color-mix" - | "color-contrast" +fn is_absolute_color_base_function(name: &JsWord) -> bool { + matches_eq_ignore_ascii_case!( + name, + js_word!("rgb"), + js_word!("rgba"), + js_word!("hsl"), + js_word!("hsla"), + js_word!("hwb"), + js_word!("lab"), + js_word!("lch"), + js_word!("oklab"), + js_word!("oklch"), + js_word!("color"), + js_word!("color-mix"), + js_word!("color-contrast") ) } -fn is_system_color(name: &str) -> bool { - matches!( - &*name.to_ascii_lowercase(), - "canvas" - | "canvastext" - | "linktext" - | "visitedtext" - | "activetext" - | "buttonface" - | "buttontext" - | "buttonborder" - | "field" - | "fieldtext" - | "highlight" - | "highlighttext" - | "selecteditem" - | "selecteditemtext" - | "mark" - | "marktext" - | "graytext" - // Deprecated - | "activeborder" - | "activecaption" - | "appWorkspace" - | "background" - | "buttonhighlight" - | "buttonshadow" - | "captiontext" - | "inactiveborder" - | "inactivecaption" - | "inactivecaptiontext" - | "infobackground" - | "infotext" - | "menu" - | "menutext" - | "scrollbar" - | "threeddarkshadow" - | "threedface" - | "threedhighlight" - | "threedlightshadow" - | "threedshadow" - | "window" - | "windowframe" - | "windowtext" - // Mozilla System Color Extensions - | "-moz-buttondefault" - | "-moz-buttonhoverface" - | "-moz-buttonhovertext" - | "-moz-cellhighlight" - | "-moz-cellhighlighttext" - | "-moz-combobox" - | "-moz-comboboxtext" - | "-moz-dialog" - | "-moz-dialogtext" - | "-moz-dragtargetzone" - | "-moz-eventreerow" - | "-moz-html-cellhighlight" - | "-moz-html-cellhighlighttext" - | "-moz-mac-accentdarkestshadow" - | "-moz-mac-accentdarkshadow" - | "-moz-mac-accentface" - | "-moz-mac-accentlightesthighlight" - | "-moz-mac-accentlightshadow" - | "-moz-mac-accentregularhighlight" - | "-moz-mac-accentregularshadow" - | "-moz-mac-chrome-active" - | "-moz-mac-chrome-inactive" - | "-moz-mac-focusring" - | "-moz-mac-menuselect" - | "-moz-mac-menushadow" - | "-moz-mac-menutextselect" - | "-moz-menuhover" - | "-moz-menuhovertext" - | "-moz-menubartext" - | "-moz-menubarhovertext" - | "-moz-nativehyperlinktext" - | "-moz-oddtreerow" - | "-moz-win-communicationstext" - | "-moz-win-mediatext" - | "-moz-win-accentcolor" - | "-moz-win-accentcolortext" - // Mozilla Color Preference Extensions - | "-moz-activehyperlinktext" - | "-moz-default-background-color" - | "-moz-default-color" - | "-moz-hyperlinktext" - | "-moz-visitedhyperlinktext" +fn is_system_color(name: &JsWord) -> bool { + matches_eq_ignore_ascii_case!( + name, + js_word!("canvas"), + js_word!("canvastext"), + js_word!("linktext"), + js_word!("visitedtext"), + js_word!("activetext"), + js_word!("buttonface"), + js_word!("buttontext"), + js_word!("buttonborder"), + js_word!("field"), + js_word!("fieldtext"), + js_word!("highlight"), + js_word!("highlighttext"), + js_word!("selecteditem"), + js_word!("selecteditemtext"), + js_word!("mark"), + js_word!("marktext"), + js_word!("graytext"), + // Deprecated + js_word!("activeborder"), + js_word!("activecaption"), + js_word!("appWorkspace"), + js_word!("background"), + js_word!("buttonhighlight"), + js_word!("buttonshadow"), + js_word!("captiontext"), + js_word!("inactiveborder"), + js_word!("inactivecaption"), + js_word!("inactivecaptiontext"), + js_word!("infobackground"), + js_word!("infotext"), + js_word!("menu"), + js_word!("menutext"), + js_word!("scrollbar"), + js_word!("threeddarkshadow"), + js_word!("threedface"), + js_word!("threedhighlight"), + js_word!("threedlightshadow"), + js_word!("threedshadow"), + js_word!("window"), + js_word!("windowframe"), + js_word!("windowtext"), + // Mozilla System Color Extensions + js_word!("-moz-buttondefault"), + js_word!("-moz-buttonhoverface"), + js_word!("-moz-buttonhovertext"), + js_word!("-moz-cellhighlight"), + js_word!("-moz-cellhighlighttext"), + js_word!("-moz-combobox"), + js_word!("-moz-comboboxtext"), + js_word!("-moz-dialog"), + js_word!("-moz-dialogtext"), + js_word!("-moz-dragtargetzone"), + js_word!("-moz-eventreerow"), + js_word!("-moz-html-cellhighlight"), + js_word!("-moz-html-cellhighlighttext"), + js_word!("-moz-mac-accentdarkestshadow"), + js_word!("-moz-mac-accentdarkshadow"), + js_word!("-moz-mac-accentface"), + js_word!("-moz-mac-accentlightesthighlight"), + js_word!("-moz-mac-accentlightshadow"), + js_word!("-moz-mac-accentregularhighlight"), + js_word!("-moz-mac-accentregularshadow"), + js_word!("-moz-mac-chrome-active"), + js_word!("-moz-mac-chrome-inactive"), + js_word!("-moz-mac-focusring"), + js_word!("-moz-mac-menuselect"), + js_word!("-moz-mac-menushadow"), + js_word!("-moz-mac-menutextselect"), + js_word!("-moz-menuhover"), + js_word!("-moz-menuhovertext"), + js_word!("-moz-menubartext"), + js_word!("-moz-menubarhovertext"), + js_word!("-moz-nativehyperlinktext"), + js_word!("-moz-oddtreerow"), + js_word!("-moz-win-communicationstext"), + js_word!("-moz-win-mediatext"), + js_word!("-moz-win-accentcolor"), + js_word!("-moz-win-accentcolortext"), + // Mozilla Color Preference Extensions + js_word!("-moz-activehyperlinktext"), + js_word!("-moz-default-background-color"), + js_word!("-moz-default-color"), + js_word!("-moz-hyperlinktext"), + js_word!("-moz-visitedhyperlinktext") ) } -fn is_named_color(name: &str) -> bool { - matches!( - &*name.to_ascii_lowercase(), - "aliceblue" - | "antiquewhite" - | "aqua" - | "aquamarine" - | "azure" - | "beige" - | "bisque" - | "black" - | "blanchedalmond" - | "blue" - | "blueviolet" - | "brown" - | "burlywood" - | "cadetblue" - | "chartreuse" - | "chocolate" - | "coral" - | "cornflowerblue" - | "cornsilk" - | "crimson" - | "cyan" - | "darkblue" - | "darkcyan" - | "darkgoldenrod" - | "darkgray" - | "darkgreen" - | "darkgrey" - | "darkkhaki" - | "darkmagenta" - | "darkolivegreen" - | "darkorange" - | "darkorchid" - | "darkred" - | "darksalmon" - | "darkseagreen" - | "darkslateblue" - | "darkslategray" - | "darkslategrey" - | "darkturquoise" - | "darkviolet" - | "deeppink" - | "deepskyblue" - | "dimgray" - | "dimgrey" - | "dodgerblue" - | "firebrick" - | "floralwhite" - | "forestgreen" - | "fuchsia" - | "gainsboro" - | "ghostwhite" - | "gold" - | "goldenrod" - | "gray" - | "green" - | "greenyellow" - | "grey" - | "honeydew" - | "hotpink" - | "indianred" - | "indigo" - | "ivory" - | "khaki" - | "lavender" - | "lavenderblush" - | "lawngreen" - | "lemonchiffon" - | "lightblue" - | "lightcoral" - | "lightcyan" - | "lightgoldenrodyellow" - | "lightgray" - | "lightgreen" - | "lightgrey" - | "lightpink" - | "lightsalmon" - | "lightseagreen" - | "lightskyblue" - | "lightslategray" - | "lightslategrey" - | "lightsteelblue" - | "lightyellow" - | "lime" - | "limegreen" - | "linen" - | "magenta" - | "maroon" - | "mediumaquamarine" - | "mediumblue" - | "mediumorchid" - | "mediumpurple" - | "mediumseagreen" - | "mediumslateblue" - | "mediumspringgreen" - | "mediumturquoise" - | "mediumvioletred" - | "midnightblue" - | "mintcream" - | "mistyrose" - | "moccasin" - | "navajowhite" - | "navy" - | "oldlace" - | "olive" - | "olivedrab" - | "orange" - | "orangered" - | "orchid" - | "palegoldenrod" - | "palegreen" - | "paleturquoise" - | "palevioletred" - | "papayawhip" - | "peachpuff" - | "peru" - | "pink" - | "plum" - | "powderblue" - | "purple" - | "rebeccapurple" - | "red" - | "rosybrown" - | "royalblue" - | "saddlebrown" - | "salmon" - | "sandybrown" - | "seagreen" - | "seashell" - | "sienna" - | "silver" - | "skyblue" - | "slateblue" - | "slategray" - | "slategrey" - | "snow" - | "springgreen" - | "steelblue" - | "tan" - | "teal" - | "thistle" - | "tomato" - | "turquoise" - | "violet" - | "wheat" - | "white" - | "whitesmoke" - | "yellow" - | "yellowgreen" +fn is_named_color(name: &JsWord) -> bool { + matches_eq_ignore_ascii_case!( + name, + js_word!("aliceblue"), + js_word!("antiquewhite"), + js_word!("aqua"), + js_word!("aquamarine"), + js_word!("azure"), + js_word!("beige"), + js_word!("bisque"), + js_word!("black"), + js_word!("blanchedalmond"), + js_word!("blue"), + js_word!("blueviolet"), + js_word!("brown"), + js_word!("burlywood"), + js_word!("cadetblue"), + js_word!("chartreuse"), + js_word!("chocolate"), + js_word!("coral"), + js_word!("cornflowerblue"), + js_word!("cornsilk"), + js_word!("crimson"), + js_word!("cyan"), + js_word!("darkblue"), + js_word!("darkcyan"), + js_word!("darkgoldenrod"), + js_word!("darkgray"), + js_word!("darkgreen"), + js_word!("darkgrey"), + js_word!("darkkhaki"), + js_word!("darkmagenta"), + js_word!("darkolivegreen"), + js_word!("darkorange"), + js_word!("darkorchid"), + js_word!("darkred"), + js_word!("darksalmon"), + js_word!("darkseagreen"), + js_word!("darkslateblue"), + js_word!("darkslategray"), + js_word!("darkslategrey"), + js_word!("darkturquoise"), + js_word!("darkviolet"), + js_word!("deeppink"), + js_word!("deepskyblue"), + js_word!("dimgray"), + js_word!("dimgrey"), + js_word!("dodgerblue"), + js_word!("firebrick"), + js_word!("floralwhite"), + js_word!("forestgreen"), + js_word!("fuchsia"), + js_word!("gainsboro"), + js_word!("ghostwhite"), + js_word!("gold"), + js_word!("goldenrod"), + js_word!("gray"), + js_word!("green"), + js_word!("greenyellow"), + js_word!("grey"), + js_word!("honeydew"), + js_word!("hotpink"), + js_word!("indianred"), + js_word!("indigo"), + js_word!("ivory"), + js_word!("khaki"), + js_word!("lavender"), + js_word!("lavenderblush"), + js_word!("lawngreen"), + js_word!("lemonchiffon"), + js_word!("lightblue"), + js_word!("lightcoral"), + js_word!("lightcyan"), + js_word!("lightgoldenrodyellow"), + js_word!("lightgray"), + js_word!("lightgreen"), + js_word!("lightgrey"), + js_word!("lightpink"), + js_word!("lightsalmon"), + js_word!("lightseagreen"), + js_word!("lightskyblue"), + js_word!("lightslategray"), + js_word!("lightslategrey"), + js_word!("lightsteelblue"), + js_word!("lightyellow"), + js_word!("lime"), + js_word!("limegreen"), + js_word!("linen"), + js_word!("magenta"), + js_word!("maroon"), + js_word!("mediumaquamarine"), + js_word!("mediumblue"), + js_word!("mediumorchid"), + js_word!("mediumpurple"), + js_word!("mediumseagreen"), + js_word!("mediumslateblue"), + js_word!("mediumspringgreen"), + js_word!("mediumturquoise"), + js_word!("mediumvioletred"), + js_word!("midnightblue"), + js_word!("mintcream"), + js_word!("mistyrose"), + js_word!("moccasin"), + js_word!("navajowhite"), + js_word!("navy"), + js_word!("oldlace"), + js_word!("olive"), + js_word!("olivedrab"), + js_word!("orange"), + js_word!("orangered"), + js_word!("orchid"), + js_word!("palegoldenrod"), + js_word!("palegreen"), + js_word!("paleturquoise"), + js_word!("palevioletred"), + js_word!("papayawhip"), + js_word!("peachpuff"), + js_word!("peru"), + js_word!("pink"), + js_word!("plum"), + js_word!("powderblue"), + js_word!("purple"), + js_word!("rebeccapurple"), + js_word!("red"), + js_word!("rosybrown"), + js_word!("royalblue"), + js_word!("saddlebrown"), + js_word!("salmon"), + js_word!("sandybrown"), + js_word!("seagreen"), + js_word!("seashell"), + js_word!("sienna"), + js_word!("silver"), + js_word!("skyblue"), + js_word!("slateblue"), + js_word!("slategray"), + js_word!("slategrey"), + js_word!("snow"), + js_word!("springgreen"), + js_word!("steelblue"), + js_word!("tan"), + js_word!("teal"), + js_word!("thistle"), + js_word!("tomato"), + js_word!("turquoise"), + js_word!("violet"), + js_word!("wheat"), + js_word!("white"), + js_word!("whitesmoke"), + js_word!("yellow"), + js_word!("yellowgreen") ) } -fn is_length_unit(unit: &str) -> bool { - matches!( - &*unit.to_ascii_lowercase(), - "em" | "rem" | - "ex" | "rex" | - "cap" | "rcap" | - "ch" | "rch" | - "ic" | "ric" | - "lh" | "rlh" | +fn is_length_unit(unit: &JsWord) -> bool { + matches_eq_ignore_ascii_case!( + unit, + js_word!("em"), + js_word!("rem"), + js_word!("ex"), + js_word!("rex"), + js_word!("cap"), + js_word!("rcap"), + js_word!("ch"), + js_word!("rch"), + js_word!("ic"), + js_word!("ric"), + js_word!("lh"), + js_word!("rlh"), // Viewport-percentage Lengths - "vw" | "svw" | "lvw" | "dvw" | - "vh" | "svh" | "lvh" | "dvh" | - "vi" | "svi" | "lvi" | "dvi" | - "vb" | "svb" | "lvb" | "dvb" | - "vmin" | "svmin" | "lvmin" | "dvmin" | - "vmax" | "svmax" | "lvmax" | "dvmax" | + js_word!("vw"), + js_word!("svw"), + js_word!("lvw"), + js_word!("dvw"), + js_word!("vh"), + js_word!("svh"), + js_word!("lvh"), + js_word!("dvh"), + js_word!("vi"), + js_word!("svi"), + js_word!("lvi"), + js_word!("dvi"), + js_word!("vb"), + js_word!("svb"), + js_word!("lvb"), + js_word!("dvb"), + js_word!("vmin"), + js_word!("svmin"), + js_word!("lvmin"), + js_word!("dvmin"), + js_word!("vmax"), + js_word!("svmax"), + js_word!("lvmax"), + js_word!("dvmax"), // Absolute lengths - "cm" | "mm" | "q" | "in" | "pc" | "pt" | "px" | "mozmm" + js_word!("cm"), + js_word!("mm"), + js_word!("q"), + js_word!("in"), + js_word!("pc"), + js_word!("pt"), + js_word!("px"), + js_word!("mozmm") ) } -fn is_container_lengths_unit(unit: &str) -> bool { - matches_eq_ignore_ascii_case!(unit, "cqw", "cqh", "cqi", "cqb", "cqmin", "cqmax") +fn is_container_lengths_unit(unit: &JsWord) -> bool { + matches_eq_ignore_ascii_case!( + unit, + js_word!("cqw"), + js_word!("cqh"), + js_word!("cqi"), + js_word!("cqb"), + js_word!("cqmin"), + js_word!("cqmax") + ) } -fn is_angle_unit(unit: &str) -> bool { - matches_eq_ignore_ascii_case!(unit, "deg", "grad", "rad", "turn") +fn is_angle_unit(unit: &JsWord) -> bool { + matches_eq_ignore_ascii_case!( + unit, + js_word!("deg"), + js_word!("grad"), + js_word!("rad"), + js_word!("turn") + ) } -fn is_time_unit(unit: &str) -> bool { - matches_eq_ignore_ascii_case!(unit, "s", "ms") +fn is_time_unit(unit: &JsWord) -> bool { + matches_eq_ignore_ascii_case!(unit, js_word!("s"), js_word!("ms")) } -fn is_frequency_unit(unit: &str) -> bool { - matches_eq_ignore_ascii_case!(unit, "hz", "khz") +fn is_frequency_unit(unit: &JsWord) -> bool { + matches_eq_ignore_ascii_case!(unit, js_word!("hz"), js_word!("khz")) } -fn is_resolution_unit(unit: &str) -> bool { - matches_eq_ignore_ascii_case!(unit, "dpi", "dpcm", "dppx", "x") +fn is_resolution_unit(unit: &JsWord) -> bool { + matches_eq_ignore_ascii_case!( + unit, + js_word!("dpi"), + js_word!("dpcm"), + js_word!("dppx"), + js_word!("x") + ) } -fn is_flex_unit(unit: &str) -> bool { - matches_eq_ignore_ascii_case!(unit, "fr") +fn is_flex_unit(unit: &JsWord) -> bool { + matches_eq_ignore_ascii_case!(unit, js_word!("fr")) } diff --git a/crates/swc_css_parser/tests/fixture/at-rule/import/output.json b/crates/swc_css_parser/tests/fixture/at-rule/import/output.json index 9fcaa41f6130..33020656e060 100644 --- a/crates/swc_css_parser/tests/fixture/at-rule/import/output.json +++ b/crates/swc_css_parser/tests/fixture/at-rule/import/output.json @@ -1057,7 +1057,7 @@ "end": 494, "ctxt": 0 }, - "value": "LAYER", + "value": "layer", "raw": "LAYER" }, "value": [ @@ -1547,7 +1547,7 @@ "end": 709, "ctxt": 0 }, - "value": "SUPPORTS", + "value": "supports", "raw": "SUPPORTS" }, "value": [ @@ -9192,7 +9192,7 @@ "end": 4755, "ctxt": 0 }, - "value": "LAYER", + "value": "layer", "raw": "LAYER" }, "value": [ @@ -9239,7 +9239,7 @@ "end": 4773, "ctxt": 0 }, - "value": "SUPPORTS", + "value": "supports", "raw": "SUPPORTS" }, "value": [ diff --git a/crates/swc_css_parser/tests/fixture/at-rule/keyframe/output.json b/crates/swc_css_parser/tests/fixture/at-rule/keyframe/output.json index 870904bc1efd..62f1780e07de 100644 --- a/crates/swc_css_parser/tests/fixture/at-rule/keyframe/output.json +++ b/crates/swc_css_parser/tests/fixture/at-rule/keyframe/output.json @@ -256,7 +256,7 @@ "end": 158, "ctxt": 0 }, - "value": "translateX", + "value": "translatex", "raw": "translateX" }, "value": [ @@ -354,7 +354,7 @@ "end": 209, "ctxt": 0 }, - "value": "translateX", + "value": "translatex", "raw": "translateX" }, "value": [ @@ -1566,7 +1566,7 @@ "end": 718, "ctxt": 0 }, - "value": "translateX", + "value": "translatex", "raw": "translateX" }, "value": [ @@ -1664,7 +1664,7 @@ "end": 769, "ctxt": 0 }, - "value": "translateX", + "value": "translatex", "raw": "translateX" }, "value": [ diff --git a/crates/swc_css_parser/tests/fixture/at-rule/supports/output.json b/crates/swc_css_parser/tests/fixture/at-rule/supports/output.json index f09a10f36d01..8a3c4d7b4854 100644 --- a/crates/swc_css_parser/tests/fixture/at-rule/supports/output.json +++ b/crates/swc_css_parser/tests/fixture/at-rule/supports/output.json @@ -4161,13 +4161,13 @@ "ctxt": 0 }, "name": { - "type": "Ident", + "type": "DashedIdent", "span": { "start": 1709, "end": 1718, "ctxt": 0 }, - "value": "--element", + "value": "element", "raw": "--element" }, "value": [ diff --git a/crates/swc_css_parser/tests/fixture/at-rule/supports/span.swc-stderr b/crates/swc_css_parser/tests/fixture/at-rule/supports/span.swc-stderr index b9ddb238f2a5..faabc5086200 100644 --- a/crates/swc_css_parser/tests/fixture/at-rule/supports/span.swc-stderr +++ b/crates/swc_css_parser/tests/fixture/at-rule/supports/span.swc-stderr @@ -6331,7 +6331,7 @@ 52 | [--self] { `---- - x Ident + x DashedIdent ,-[$DIR/tests/fixture/at-rule/supports/input.css:50:1] 50 | 51 | @supports (--element(".minwidth")) { @@ -8977,7 +8977,7 @@ 89 | } `---- - x Ident { value: Atom('black' type=inline), raw: "black" } + x Ident { value: Atom('black' type=static), raw: "black" } ,-[$DIR/tests/fixture/at-rule/supports/input.css:87:1] 87 | from { 88 | color: black; @@ -9163,7 +9163,7 @@ 92 | } `---- - x Ident { value: Atom('white' type=inline), raw: "white" } + x Ident { value: Atom('white' type=static), raw: "white" } ,-[$DIR/tests/fixture/at-rule/supports/input.css:90:1] 90 | to { 91 | color: white @@ -9527,7 +9527,7 @@ 101 | body { `---- - x Ident { value: Atom('green' type=inline), raw: "green" } + x Ident { value: Atom('green' type=static), raw: "green" } ,-[$DIR/tests/fixture/at-rule/supports/input.css:99:1] 99 | 100 | @supports (--foo: green) { @@ -11493,7 +11493,7 @@ 126 | } `---- - x Ident { value: Atom('black' type=inline), raw: "black" } + x Ident { value: Atom('black' type=static), raw: "black" } ,-[$DIR/tests/fixture/at-rule/supports/input.css:124:1] 124 | from { 125 | color: black; @@ -11679,7 +11679,7 @@ 129 | } `---- - x Ident { value: Atom('white' type=inline), raw: "white" } + x Ident { value: Atom('white' type=static), raw: "white" } ,-[$DIR/tests/fixture/at-rule/supports/input.css:127:1] 127 | to { 128 | color: white diff --git a/crates/swc_css_parser/tests/fixture/at-rule/unknown/span.swc-stderr b/crates/swc_css_parser/tests/fixture/at-rule/unknown/span.swc-stderr index a4d2759ae0ce..2c976df68a55 100644 --- a/crates/swc_css_parser/tests/fixture/at-rule/unknown/span.swc-stderr +++ b/crates/swc_css_parser/tests/fixture/at-rule/unknown/span.swc-stderr @@ -6686,7 +6686,7 @@ 50 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/fixture/at-rule/unknown/input.css:48:1] 48 | 49 | color: red; diff --git a/crates/swc_css_parser/tests/fixture/dashed-ident/input.css b/crates/swc_css_parser/tests/fixture/dashed-ident/input.css index 92fc81675e16..8e888d367ef4 100644 --- a/crates/swc_css_parser/tests/fixture/dashed-ident/input.css +++ b/crates/swc_css_parser/tests/fixture/dashed-ident/input.css @@ -13,3 +13,7 @@ @--custom {} @--library1-custom {} + +.class { + --vendor-property: --vendor-function("test"); +} diff --git a/crates/swc_css_parser/tests/fixture/dashed-ident/output.json b/crates/swc_css_parser/tests/fixture/dashed-ident/output.json index 20e8d17b559a..434e83ac4231 100644 --- a/crates/swc_css_parser/tests/fixture/dashed-ident/output.json +++ b/crates/swc_css_parser/tests/fixture/dashed-ident/output.json @@ -2,7 +2,7 @@ "type": "Stylesheet", "span": { "start": 1, - "end": 172, + "end": 234, "ctxt": 0 }, "rules": [ @@ -559,6 +559,138 @@ }, "value": [] } + }, + { + "type": "QualifiedRule", + "span": { + "start": 173, + "end": 233, + "ctxt": 0 + }, + "prelude": { + "type": "SelectorList", + "span": { + "start": 173, + "end": 179, + "ctxt": 0 + }, + "children": [ + { + "type": "ComplexSelector", + "span": { + "start": 173, + "end": 179, + "ctxt": 0 + }, + "children": [ + { + "type": "CompoundSelector", + "span": { + "start": 173, + "end": 179, + "ctxt": 0 + }, + "nestingSelector": null, + "typeSelector": null, + "subclassSelectors": [ + { + "type": "ClassSelector", + "span": { + "start": 173, + "end": 179, + "ctxt": 0 + }, + "text": { + "type": "Ident", + "span": { + "start": 174, + "end": 179, + "ctxt": 0 + }, + "value": "class", + "raw": "class" + } + } + ] + } + ] + } + ] + }, + "block": { + "type": "SimpleBlock", + "span": { + "start": 180, + "end": 233, + "ctxt": 0 + }, + "name": { + "type": "PreservedToken", + "span": { + "start": 180, + "end": 181, + "ctxt": 0 + }, + "token": "LBrace" + }, + "value": [ + { + "type": "Declaration", + "span": { + "start": 186, + "end": 230, + "ctxt": 0 + }, + "name": { + "type": "DashedIdent", + "span": { + "start": 186, + "end": 203, + "ctxt": 0 + }, + "value": "vendor-property", + "raw": "--vendor-property" + }, + "value": [ + { + "type": "Function", + "span": { + "start": 205, + "end": 230, + "ctxt": 0 + }, + "name": { + "type": "DashedIdent", + "span": { + "start": 205, + "end": 222, + "ctxt": 0 + }, + "value": "vendor-function", + "raw": "--vendor-function" + }, + "value": [ + { + "type": "PreservedToken", + "span": { + "start": 223, + "end": 229, + "ctxt": 0 + }, + "token": { + "String": { + "value": "test", + "raw": "\"test\"" + } + } + } + ] + } + ], + "important": null + } + ] + } } ] } diff --git a/crates/swc_css_parser/tests/fixture/dashed-ident/span.swc-stderr b/crates/swc_css_parser/tests/fixture/dashed-ident/span.swc-stderr index b8ca49d6dc76..1fde1c51f008 100644 --- a/crates/swc_css_parser/tests/fixture/dashed-ident/span.swc-stderr +++ b/crates/swc_css_parser/tests/fixture/dashed-ident/span.swc-stderr @@ -15,7 +15,11 @@ 12 | | } 13 | | 14 | | @--custom {} - 15 | `-> @--library1-custom {} + 15 | | @--library1-custom {} + 16 | | + 17 | | .class { + 18 | | --vendor-property: --vendor-function("test"); + 19 | `-> } `---- x Rule @@ -307,7 +311,7 @@ 8 | } `---- - x Ident { value: Atom('blue' type=inline), raw: "blue" } + x Ident { value: Atom('blue' type=static), raw: "blue" } ,-[$DIR/tests/fixture/dashed-ident/input.css:6:1] 6 | .foo { 7 | --fg-color: blue; @@ -634,3 +638,155 @@ 15 | @--library1-custom {} : ^ `---- + + x Rule + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | ,-> .class { + 18 | | --vendor-property: --vendor-function("test"); + 19 | `-> } + `---- + + x QualifiedRule + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | ,-> .class { + 18 | | --vendor-property: --vendor-function("test"); + 19 | `-> } + `---- + + x SelectorList + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | .class { + : ^^^^^^ + 18 | --vendor-property: --vendor-function("test"); + `---- + + x ComplexSelector + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | .class { + : ^^^^^^ + 18 | --vendor-property: --vendor-function("test"); + `---- + + x CompoundSelector + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | .class { + : ^^^^^^ + 18 | --vendor-property: --vendor-function("test"); + `---- + + x SubclassSelector + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | .class { + : ^^^^^^ + 18 | --vendor-property: --vendor-function("test"); + `---- + + x ClassSelector + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | .class { + : ^^^^^^ + 18 | --vendor-property: --vendor-function("test"); + `---- + + x Ident + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | .class { + : ^^^^^ + 18 | --vendor-property: --vendor-function("test"); + `---- + + x SimpleBlock + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | ,-> .class { + 18 | | --vendor-property: --vendor-function("test"); + 19 | `-> } + `---- + + x LBrace + ,-[$DIR/tests/fixture/dashed-ident/input.css:16:1] + 16 | + 17 | .class { + : ^ + 18 | --vendor-property: --vendor-function("test"); + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 19 | } + `---- + + x Declaration + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 19 | } + `---- + + x DeclarationName + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^^^^^^^^^^^^ + 19 | } + `---- + + x DashedIdent + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^^^^^^^^^^^^ + 19 | } + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^^^^^^^^^^^^^^^^^^^^ + 19 | } + `---- + + x Function + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^^^^^^^^^^^^^^^^^^^^ + 19 | } + `---- + + x DashedIdent + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^^^^^^^^^^^^ + 19 | } + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^ + 19 | } + `---- + + x String { value: Atom('test' type=inline), raw: "\"test\"" } + ,-[$DIR/tests/fixture/dashed-ident/input.css:17:1] + 17 | .class { + 18 | --vendor-property: --vendor-function("test"); + : ^^^^^^ + 19 | } + `---- diff --git a/crates/swc_css_parser/tests/fixture/function/unknown/output.json b/crates/swc_css_parser/tests/fixture/function/unknown/output.json index bc1b4957efad..082571e076ae 100644 --- a/crates/swc_css_parser/tests/fixture/function/unknown/output.json +++ b/crates/swc_css_parser/tests/fixture/function/unknown/output.json @@ -182,42 +182,31 @@ "ctxt": 0 }, "name": { - "type": "Ident", + "type": "DashedIdent", "span": { "start": 38, "end": 42, "ctxt": 0 }, - "value": "--fn", + "value": "fn", "raw": "--fn" }, "value": [ { - "type": "Length", + "type": "PreservedToken", "span": { "start": 43, "end": 48, "ctxt": 0 }, - "value": { - "type": "Number", - "span": { - "start": 43, - "end": 46, - "ctxt": 0 - }, - "value": 100.0, - "raw": "100" - }, - "unit": { - "type": "Ident", - "span": { - "start": 46, - "end": 48, - "ctxt": 0 - }, - "value": "px", - "raw": "px" + "token": { + "Dimension": { + "value": 100.0, + "raw_value": "100", + "unit": "px", + "type": "integer", + "raw_unit": "px" + } } } ] @@ -251,42 +240,31 @@ "ctxt": 0 }, "name": { - "type": "Ident", + "type": "DashedIdent", "span": { "start": 61, "end": 69, "ctxt": 0 }, - "value": "--fn--fn", + "value": "fn--fn", "raw": "--fn--fn" }, "value": [ { - "type": "Length", + "type": "PreservedToken", "span": { "start": 70, "end": 75, "ctxt": 0 }, - "value": { - "type": "Number", - "span": { - "start": 70, - "end": 73, - "ctxt": 0 - }, - "value": 100.0, - "raw": "100" - }, - "unit": { - "type": "Ident", - "span": { - "start": 73, - "end": 75, - "ctxt": 0 - }, - "value": "px", - "raw": "px" + "token": { + "Dimension": { + "value": 100.0, + "raw_value": "100", + "unit": "px", + "type": "integer", + "raw_unit": "px" + } } } ] diff --git a/crates/swc_css_parser/tests/fixture/function/unknown/span.swc-stderr b/crates/swc_css_parser/tests/fixture/function/unknown/span.swc-stderr index 3a96280fd479..f68d505f0b51 100644 --- a/crates/swc_css_parser/tests/fixture/function/unknown/span.swc-stderr +++ b/crates/swc_css_parser/tests/fixture/function/unknown/span.swc-stderr @@ -235,7 +235,7 @@ 4 | prod: --fn--fn(100px); `---- - x Ident + x DashedIdent ,-[$DIR/tests/fixture/function/unknown/input.css:2:1] 2 | prod: fn(100px); 3 | prod: --fn(100px); @@ -251,15 +251,7 @@ 4 | prod: --fn--fn(100px); `---- - x Dimension - ,-[$DIR/tests/fixture/function/unknown/input.css:2:1] - 2 | prod: fn(100px); - 3 | prod: --fn(100px); - : ^^^^^ - 4 | prod: --fn--fn(100px); - `---- - - x Length + x Dimension(DimensionToken { value: 100.0, raw_value: "100", unit: Atom('px' type=static), type_flag: Integer, raw_unit: "px" }) ,-[$DIR/tests/fixture/function/unknown/input.css:2:1] 2 | prod: fn(100px); 3 | prod: --fn(100px); @@ -267,22 +259,6 @@ 4 | prod: --fn--fn(100px); `---- - x Number - ,-[$DIR/tests/fixture/function/unknown/input.css:2:1] - 2 | prod: fn(100px); - 3 | prod: --fn(100px); - : ^^^ - 4 | prod: --fn--fn(100px); - `---- - - x Ident - ,-[$DIR/tests/fixture/function/unknown/input.css:2:1] - 2 | prod: fn(100px); - 3 | prod: --fn(100px); - : ^^ - 4 | prod: --fn--fn(100px); - `---- - x ComponentValue ,-[$DIR/tests/fixture/function/unknown/input.css:3:1] 3 | prod: --fn(100px); @@ -331,7 +307,7 @@ 5 | } `---- - x Ident + x DashedIdent ,-[$DIR/tests/fixture/function/unknown/input.css:3:1] 3 | prod: --fn(100px); 4 | prod: --fn--fn(100px); @@ -347,34 +323,10 @@ 5 | } `---- - x Dimension - ,-[$DIR/tests/fixture/function/unknown/input.css:3:1] - 3 | prod: --fn(100px); - 4 | prod: --fn--fn(100px); - : ^^^^^ - 5 | } - `---- - - x Length + x Dimension(DimensionToken { value: 100.0, raw_value: "100", unit: Atom('px' type=static), type_flag: Integer, raw_unit: "px" }) ,-[$DIR/tests/fixture/function/unknown/input.css:3:1] 3 | prod: --fn(100px); 4 | prod: --fn--fn(100px); : ^^^^^ 5 | } `---- - - x Number - ,-[$DIR/tests/fixture/function/unknown/input.css:3:1] - 3 | prod: --fn(100px); - 4 | prod: --fn--fn(100px); - : ^^^ - 5 | } - `---- - - x Ident - ,-[$DIR/tests/fixture/function/unknown/input.css:3:1] - 3 | prod: --fn(100px); - 4 | prod: --fn--fn(100px); - : ^^ - 5 | } - `---- diff --git a/crates/swc_css_parser/tests/fixture/value/color/output.json b/crates/swc_css_parser/tests/fixture/value/color/output.json index 801b97e22d17..8312047f21e4 100644 --- a/crates/swc_css_parser/tests/fixture/value/color/output.json +++ b/crates/swc_css_parser/tests/fixture/value/color/output.json @@ -491,7 +491,7 @@ "end": 171, "ctxt": 0 }, - "value": "rGb", + "value": "rgb", "raw": "rGb" }, "value": [ @@ -2419,7 +2419,7 @@ "end": 812, "ctxt": 0 }, - "value": "rGbA", + "value": "rgba", "raw": "rGbA" }, "value": [ @@ -3850,7 +3850,7 @@ "end": 1299, "ctxt": 0 }, - "value": "HsL", + "value": "hsl", "raw": "HsL" }, "value": [ diff --git a/crates/swc_css_parser/tests/recovery/at-rule/media/wrong-stylesheet/span.swc-stderr b/crates/swc_css_parser/tests/recovery/at-rule/media/wrong-stylesheet/span.swc-stderr index 6ff43bff90de..cc71c206b1ca 100644 --- a/crates/swc_css_parser/tests/recovery/at-rule/media/wrong-stylesheet/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/at-rule/media/wrong-stylesheet/span.swc-stderr @@ -164,7 +164,7 @@ 3 | main { `---- - x Ident { value: Atom('teal' type=inline), raw: "teal" } + x Ident { value: Atom('teal' type=static), raw: "teal" } ,-[$DIR/tests/recovery/at-rule/media/wrong-stylesheet/input.css:1:1] 1 | @media print { 2 | color: teal; diff --git a/crates/swc_css_parser/tests/recovery/at-rule/page/without-page/span.swc-stderr b/crates/swc_css_parser/tests/recovery/at-rule/page/without-page/span.swc-stderr index 21884afd8628..50c6c382ce15 100644 --- a/crates/swc_css_parser/tests/recovery/at-rule/page/without-page/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/at-rule/page/without-page/span.swc-stderr @@ -232,7 +232,7 @@ 4 | } `---- - x Ident { value: Atom('blue' type=inline), raw: "blue" } + x Ident { value: Atom('blue' type=static), raw: "blue" } ,-[$DIR/tests/recovery/at-rule/page/without-page/input.css:2:1] 2 | content: "foo"; 3 | color: blue; diff --git a/crates/swc_css_parser/tests/recovery/at-rule/supports/non-standard-prelude/output.json b/crates/swc_css_parser/tests/recovery/at-rule/supports/non-standard-prelude/output.json index b70b5d1f831a..a29094f1b5cb 100644 --- a/crates/swc_css_parser/tests/recovery/at-rule/supports/non-standard-prelude/output.json +++ b/crates/swc_css_parser/tests/recovery/at-rule/supports/non-standard-prelude/output.json @@ -47,13 +47,13 @@ "ctxt": 0 }, "name": { - "type": "Ident", + "type": "DashedIdent", "span": { "start": 12, "end": 21, "ctxt": 0 }, - "value": "--element", + "value": "element", "raw": "--element" }, "value": [ @@ -1496,13 +1496,13 @@ "ctxt": 0 }, "name": { - "type": "Ident", + "type": "DashedIdent", "span": { "start": 356, "end": 362, "ctxt": 0 }, - "value": "--func", + "value": "func", "raw": "--func" }, "value": [ diff --git a/crates/swc_css_parser/tests/recovery/at-rule/supports/non-standard-prelude/span.swc-stderr b/crates/swc_css_parser/tests/recovery/at-rule/supports/non-standard-prelude/span.swc-stderr index fef4cfbacf92..ddab4187ca14 100644 --- a/crates/swc_css_parser/tests/recovery/at-rule/supports/non-standard-prelude/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/at-rule/supports/non-standard-prelude/span.swc-stderr @@ -95,7 +95,7 @@ 2 | [--self] { `---- - x Ident + x DashedIdent ,-[$DIR/tests/recovery/at-rule/supports/non-standard-prelude/input.css:1:1] 1 | @supports (--element(".minwidth", { "minWidth": 300 })) { : ^^^^^^^^^ @@ -1428,7 +1428,7 @@ 20 | * { background: red; } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/at-rule/supports/non-standard-prelude/input.css:18:1] 18 | 19 | @supports ([color: red]) { @@ -1836,7 +1836,7 @@ 24 | * { background: red; } `---- - x Ident + x DashedIdent ,-[$DIR/tests/recovery/at-rule/supports/non-standard-prelude/input.css:22:1] 22 | 23 | @supports ([[[[[{ --func(color: { red }) }]]]]]) { @@ -1940,7 +1940,7 @@ 24 | * { background: red; } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/at-rule/supports/non-standard-prelude/input.css:22:1] 22 | 23 | @supports ([[[[[{ --func(color: { red }) }]]]]]) { diff --git a/crates/swc_css_parser/tests/recovery/cdo-and-cdc/span.swc-stderr b/crates/swc_css_parser/tests/recovery/cdo-and-cdc/span.swc-stderr index 0097a5c9a9a1..32284f02ee53 100644 --- a/crates/swc_css_parser/tests/recovery/cdo-and-cdc/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/cdo-and-cdc/span.swc-stderr @@ -651,7 +651,7 @@ 21 | } `---- - x Ident { value: Atom('blue' type=inline), raw: "blue" } + x Ident { value: Atom('blue' type=static), raw: "blue" } ,-[$DIR/tests/recovery/cdo-and-cdc/input.css:19:1] 19 | 20 | color: blue; diff --git a/crates/swc_css_parser/tests/recovery/declaration/important-1/span.swc-stderr b/crates/swc_css_parser/tests/recovery/declaration/important-1/span.swc-stderr index 8148a37168b3..f48170bd0f89 100644 --- a/crates/swc_css_parser/tests/recovery/declaration/important-1/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/declaration/important-1/span.swc-stderr @@ -123,7 +123,7 @@ 3 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important-1/input.css:1:1] 1 | a { 2 | color: red !importan; diff --git a/crates/swc_css_parser/tests/recovery/declaration/important/span.swc-stderr b/crates/swc_css_parser/tests/recovery/declaration/important/span.swc-stderr index c13df6614162..233e5d5985ba 100644 --- a/crates/swc_css_parser/tests/recovery/declaration/important/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/declaration/important/span.swc-stderr @@ -136,7 +136,7 @@ 3 | } `---- - x Ident { value: Atom('white' type=inline), raw: "white" } + x Ident { value: Atom('white' type=static), raw: "white" } ,-[$DIR/tests/recovery/declaration/important/input.css:1:1] 1 | .a { 2 | color: white !!important; @@ -312,7 +312,7 @@ 7 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:5:1] 5 | .class { 6 | color: red red red !important !important; @@ -344,7 +344,7 @@ 7 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:5:1] 5 | .class { 6 | color: red red red !important !important; @@ -376,7 +376,7 @@ 7 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:5:1] 5 | .class { 6 | color: red red red !important !important; @@ -568,7 +568,7 @@ 11 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:9:1] 9 | .class { 10 | color: red red red !important!important ; @@ -600,7 +600,7 @@ 11 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:9:1] 9 | .class { 10 | color: red red red !important!important ; @@ -632,7 +632,7 @@ 11 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:9:1] 9 | .class { 10 | color: red red red !important!important ; @@ -824,7 +824,7 @@ 15 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:13:1] 13 | .class { 14 | color: red red red /* test*/ !important /*test*/ !important /*test*/ ; @@ -856,7 +856,7 @@ 15 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:13:1] 13 | .class { 14 | color: red red red /* test*/ !important /*test*/ !important /*test*/ ; @@ -888,7 +888,7 @@ 15 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:13:1] 13 | .class { 14 | color: red red red /* test*/ !important /*test*/ !important /*test*/ ; @@ -1096,7 +1096,7 @@ 19 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:17:1] 17 | .class { 18 | color: red red red !important !important!important; @@ -1128,7 +1128,7 @@ 19 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:17:1] 17 | .class { 18 | color: red red red !important !important!important; @@ -1160,7 +1160,7 @@ 19 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:17:1] 17 | .class { 18 | color: red red red !important !important!important; @@ -1400,7 +1400,7 @@ 23 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:21:1] 21 | .class { 22 | color: red red red /* test */ ! /*test */ important /* test */ ! /* test */ important /* test */; @@ -1432,7 +1432,7 @@ 23 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:21:1] 21 | .class { 22 | color: red red red /* test */ ! /*test */ important /* test */ ! /* test */ important /* test */; @@ -1464,7 +1464,7 @@ 23 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/important/input.css:21:1] 21 | .class { 22 | color: red red red /* test */ ! /*test */ important /* test */ ! /* test */ important /* test */; diff --git a/crates/swc_css_parser/tests/recovery/declaration/wrong-name/span.swc-stderr b/crates/swc_css_parser/tests/recovery/declaration/wrong-name/span.swc-stderr index 82785580a6f0..20a945caec17 100644 --- a/crates/swc_css_parser/tests/recovery/declaration/wrong-name/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/declaration/wrong-name/span.swc-stderr @@ -147,7 +147,7 @@ 3 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/declaration/wrong-name/input.css:1:1] 1 | a { 2 | 20: red; diff --git a/crates/swc_css_parser/tests/recovery/delim-token/at-sign/span.swc-stderr b/crates/swc_css_parser/tests/recovery/delim-token/at-sign/span.swc-stderr index 8e05da56c4a2..922af9c42c23 100644 --- a/crates/swc_css_parser/tests/recovery/delim-token/at-sign/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/delim-token/at-sign/span.swc-stderr @@ -155,7 +155,7 @@ 3 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/delim-token/at-sign/input.css:1:1] 1 | a { 2 | color: @ red; diff --git a/crates/swc_css_parser/tests/recovery/hacks/span.swc-stderr b/crates/swc_css_parser/tests/recovery/hacks/span.swc-stderr index 9b202a91121e..3b7e84b60e68 100644 --- a/crates/swc_css_parser/tests/recovery/hacks/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/hacks/span.swc-stderr @@ -19316,7 +19316,7 @@ 245 | _background: white; `---- - x Ident { value: Atom('black' type=inline), raw: "black" } + x Ident { value: Atom('black' type=static), raw: "black" } ,-[$DIR/tests/recovery/hacks/input.css:243:1] 243 | a { 244 | *color : black; diff --git a/crates/swc_css_parser/tests/recovery/ie-progid/output.json b/crates/swc_css_parser/tests/recovery/ie-progid/output.json index 4346cf1b2618..6b96b7803807 100644 --- a/crates/swc_css_parser/tests/recovery/ie-progid/output.json +++ b/crates/swc_css_parser/tests/recovery/ie-progid/output.json @@ -456,7 +456,7 @@ "end": 172, "ctxt": 0 }, - "value": "Blur", + "value": "blur", "raw": "Blur" }, "value": [ @@ -608,7 +608,7 @@ "end": 227, "ctxt": 0 }, - "value": "Wheel", + "value": "wheel", "raw": "Wheel" }, "value": [ diff --git a/crates/swc_css_parser/tests/recovery/rules/unclosed-brackets/span.swc-stderr b/crates/swc_css_parser/tests/recovery/rules/unclosed-brackets/span.swc-stderr index 6aae0fa43412..53916c801409 100644 --- a/crates/swc_css_parser/tests/recovery/rules/unclosed-brackets/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/rules/unclosed-brackets/span.swc-stderr @@ -285,7 +285,7 @@ : ^^^ `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/rules/unclosed-brackets/input.css:4:1] 4 | 5 | .class { color: red } @@ -448,7 +448,7 @@ : ^^^^ `---- - x Ident { value: Atom('blue' type=inline), raw: "blue" } + x Ident { value: Atom('blue' type=static), raw: "blue" } ,-[$DIR/tests/recovery/rules/unclosed-brackets/input.css:6:1] 6 | 7 | .class { color: blue } diff --git a/crates/swc_css_parser/tests/recovery/style-blocks-contents/basic/span.swc-stderr b/crates/swc_css_parser/tests/recovery/style-blocks-contents/basic/span.swc-stderr index f880d2694f33..16c03af5d304 100644 --- a/crates/swc_css_parser/tests/recovery/style-blocks-contents/basic/span.swc-stderr +++ b/crates/swc_css_parser/tests/recovery/style-blocks-contents/basic/span.swc-stderr @@ -399,7 +399,7 @@ 7 | } `---- - x Ident { value: Atom('green' type=inline), raw: "green" } + x Ident { value: Atom('green' type=static), raw: "green" } ,-[$DIR/tests/recovery/style-blocks-contents/basic/input.css:5:1] 5 | ident 6 | color: green; @@ -834,7 +834,7 @@ 15 | } `---- - x Ident { value: Atom('red' type=inline), raw: "red" } + x Ident { value: Atom('red' type=static), raw: "red" } ,-[$DIR/tests/recovery/style-blocks-contents/basic/input.css:13:1] 13 | ident 14 | color: red diff --git a/crates/swc_css_prefixer/src/prefixer.rs b/crates/swc_css_prefixer/src/prefixer.rs index ac9fcdcb60f3..b72788f9faaa 100644 --- a/crates/swc_css_prefixer/src/prefixer.rs +++ b/crates/swc_css_prefixer/src/prefixer.rs @@ -127,7 +127,7 @@ impl VisitMut for CrossFadeFunctionReplacerOnLegacyVariant<'_> { fn visit_mut_function(&mut self, n: &mut Function) { n.visit_mut_children_with(self); - if n.name.value.eq_str_ignore_ascii_case(self.from) { + if n.name == *self.from { let mut transparency_values = vec![]; for group in n.value.split_mut(|n| { @@ -217,8 +217,16 @@ impl VisitMut for CrossFadeFunctionReplacerOnLegacyVariant<'_> { n.value = new_value; - n.name.value = self.to.into(); - n.name.raw = None; + match &mut n.name { + FunctionName::Ident(name) => { + name.value = self.to.into(); + name.raw = None; + } + FunctionName::DashedIdent(name) => { + name.value = self.to.into(); + name.raw = None; + } + } } } } @@ -265,13 +273,21 @@ impl VisitMut for ImageSetFunctionReplacerOnLegacyVariant<'_> { fn visit_mut_function(&mut self, n: &mut Function) { let old_in_function = self.in_function; - self.in_function = n.name.value.eq_str_ignore_ascii_case(self.from); + self.in_function = n.name == *self.from; n.visit_mut_children_with(self); - if n.name.value.eq_str_ignore_ascii_case(self.from) { - n.name.value = self.to.into(); - n.name.raw = None; + if n.name == *self.from { + match &mut n.name { + FunctionName::Ident(name) => { + name.value = self.to.into(); + name.raw = None; + } + FunctionName::DashedIdent(name) => { + name.value = self.to.into(); + name.raw = None; + } + } } self.in_function = old_in_function; @@ -300,9 +316,17 @@ impl VisitMut for LinearGradientFunctionReplacerOnLegacyVariant<'_> { fn visit_mut_function(&mut self, n: &mut Function) { n.visit_mut_children_with(self); - if &*n.name.value.to_ascii_lowercase() == self.from { - n.name.value = self.to.into(); - n.name.raw = None; + if n.name == *self.from { + match &mut n.name { + FunctionName::Ident(name) => { + name.value = self.to.into(); + name.raw = None; + } + FunctionName::DashedIdent(name) => { + name.value = self.to.into(); + name.raw = None; + } + } let first = n.value.get(0); @@ -526,10 +550,8 @@ impl VisitMut for CalcReplacer<'_> { fn visit_mut_function(&mut self, n: &mut Function) { let old_inside_calc = self.inside_calc; - let name = n.name.value.to_ascii_lowercase(); - - let is_webkit_calc = matches!(name, js_word!("-webkit-calc")); - let is_moz_calc = matches!(name, js_word!("-moz-calc")); + let is_webkit_calc = n.name == js_word!("-webkit-calc"); + let is_moz_calc = n.name == js_word!("-moz-calc"); if self.to.is_none() && (is_webkit_calc || is_moz_calc) { return; @@ -541,14 +563,24 @@ impl VisitMut for CalcReplacer<'_> { return; } - self.inside_calc = matches!(name, js_word!("calc")) || is_webkit_calc || is_moz_calc; + let is_calc = n.name == js_word!("calc"); + + self.inside_calc = is_calc || is_webkit_calc || is_moz_calc; n.visit_mut_children_with(self); - if matches!(name, js_word!("calc")) { + if is_calc { if let Some(to) = self.to { - n.name.value = to.clone(); - n.name.raw = None; + match &mut n.name { + FunctionName::Ident(name) => { + name.value = to.into(); + name.raw = None; + } + FunctionName::DashedIdent(name) => { + name.value = to.into(); + name.raw = None; + } + } } } @@ -563,11 +595,11 @@ impl VisitMut for CalcReplacer<'_> { } if let CalcValue::Function(function) = n { - let name = function.name.value.to_ascii_lowercase(); - - if matches!( - name, - js_word!("calc") | js_word!("-webkit-calc") | js_word!("-moz-calc") + if matches_eq!( + function.name, + js_word!("calc"), + js_word!("-webkit-calc"), + js_word!("-moz-calc") ) { let calc_sum = match function.value.get(0) { Some(ComponentValue::CalcSum(calc_sum)) => *calc_sum.clone(), @@ -599,7 +631,7 @@ impl VisitMut for FontFaceFormatOldSyntax { fn visit_mut_function(&mut self, n: &mut Function) { n.visit_mut_children_with(self); - if !n.name.value.eq_ignore_ascii_case(&js_word!("format")) { + if !(n.name == js_word!("format")) { return; } @@ -2524,10 +2556,10 @@ impl VisitMut for Prefixer { } } - js_word!("filter") => match &n.value[0] { - ComponentValue::PreservedToken(_) => {} - ComponentValue::Function(function) - if function.name.value.eq_ignore_ascii_case(&js_word!("alpha")) => {} + js_word!("filter") => match &n.value.get(0) { + Some(ComponentValue::PreservedToken(_)) => {} + Some(ComponentValue::Function(function)) if function.name == js_word!("alpha") => {} + None => {} _ => { add_declaration!(Prefix::Webkit, js_word!("-webkit-filter"), None); } @@ -2708,18 +2740,18 @@ impl VisitMut for Prefixer { let has_3d_function = n.value.iter().any(|n| match n { ComponentValue::Function(function) - if matches_eq_ignore_ascii_case!( - &*function.name.value, - "matrix3d", - "translate3d", - "translatez", - "scale3d", - "scalez", - "rotate3d", - "rotatex", - "rotatey", - "rotatez", - "perspective" + if matches_eq!( + function.name, + js_word!("matrix3d"), + js_word!("translate3d"), + js_word!("translatez"), + js_word!("scale3d"), + js_word!("scalez"), + js_word!("rotate3d"), + js_word!("rotatex"), + js_word!("rotatey"), + js_word!("rotatez"), + js_word!("perspective") ) => { true diff --git a/crates/swc_css_utils/src/lib.rs b/crates/swc_css_utils/src/lib.rs index d20b60848efb..b47d7cc4a824 100644 --- a/crates/swc_css_utils/src/lib.rs +++ b/crates/swc_css_utils/src/lib.rs @@ -41,9 +41,16 @@ impl VisitMut for FunctionNameReplacer<'_> { fn visit_mut_function(&mut self, n: &mut Function) { n.visit_mut_children_with(self); - if n.name.value.eq_str_ignore_ascii_case(self.from) { - n.name.value = self.to.into(); - n.name.raw = None; + match &mut n.name { + FunctionName::Ident(name) if name.value.eq_str_ignore_ascii_case(self.from) => { + name.value = self.to.into(); + name.raw = None; + } + FunctionName::DashedIdent(name) if name.value.eq_str_ignore_ascii_case(self.from) => { + name.value = self.to.into(); + name.raw = None; + } + _ => {} } } } diff --git a/crates/swc_css_visit/src/lib.rs b/crates/swc_css_visit/src/lib.rs index 79ea37dbd2ae..27189d764aa5 100644 --- a/crates/swc_css_visit/src/lib.rs +++ b/crates/swc_css_visit/src/lib.rs @@ -154,9 +154,14 @@ define!({ pub value: DelimiterValue, } + pub enum FunctionName { + Ident(Ident), + DashedIdent(DashedIdent), + } + pub struct Function { pub span: Span, - pub name: Ident, + pub name: FunctionName, pub value: Vec, }