From 199ac7461814553bab97c1f0f7b1c89f34897122 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Wed, 14 Dec 2022 18:05:35 +0300 Subject: [PATCH] feat(css/prefixer): Support font-face format (#6644) --- crates/swc_atoms/words.txt | 7 +++ .../data/prefixes_and_browsers.json | 16 +++++ crates/swc_css_prefixer/src/prefixer.rs | 59 ++++++++++++++++++- .../tests/fixture/font-face-format/input.css | 28 +++++++++ .../tests/fixture/font-face-format/output.css | 26 ++++++++ .../output.defaults-not-ie-11.css | 26 ++++++++ .../tests/fixture/image-set/input.css | 8 +++ .../tests/fixture/image-set/output.css | 8 +++ .../image-set/output.defaults-not-ie-11.css | 8 +++ 9 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 crates/swc_css_prefixer/tests/fixture/font-face-format/input.css create mode 100644 crates/swc_css_prefixer/tests/fixture/font-face-format/output.css create mode 100644 crates/swc_css_prefixer/tests/fixture/font-face-format/output.defaults-not-ie-11.css diff --git a/crates/swc_atoms/words.txt b/crates/swc_atoms/words.txt index d8c2753ab1cf..8f08fcc382e3 100644 --- a/crates/swc_atoms/words.txt +++ b/crates/swc_atoms/words.txt @@ -798,6 +798,7 @@ code codebase col colgroup +collection color color-index color-mix @@ -893,6 +894,7 @@ ellipse else em embed +embedded-opentype empty-cells encoding end @@ -1014,6 +1016,7 @@ foreignObject foreignobject form formaction +format frame frameset from @@ -1423,6 +1426,7 @@ onwebkitanimationstart onwebkittransitionend onwheel opacity +opentype optgroup option or @@ -1793,6 +1797,7 @@ translateZ transparent tref true +truetype try tspan tt @@ -1841,6 +1846,8 @@ widows width will-change with +woff +woff2 word-break word-spacing word-wrap diff --git a/crates/swc_css_prefixer/data/prefixes_and_browsers.json b/crates/swc_css_prefixer/data/prefixes_and_browsers.json index ce79784b901a..bc749bcd755f 100644 --- a/crates/swc_css_prefixer/data/prefixes_and_browsers.json +++ b/crates/swc_css_prefixer/data/prefixes_and_browsers.json @@ -3929,5 +3929,21 @@ "ios": "14.8", "firefox": "69" } + ], + "font-face-format-ident": [ + { + "chrome": "4", + "edge": "12", + "firefox": "2", + "samsung": "4", + "ios": "3.2", + "opera": "10", + "safari": "3.1", + "ie": "6" + }, + { + "safari": "3.2", + "ios": "4.3" + } ] } diff --git a/crates/swc_css_prefixer/src/prefixer.rs b/crates/swc_css_prefixer/src/prefixer.rs index 9f157bcae12f..2ed01c90504c 100644 --- a/crates/swc_css_prefixer/src/prefixer.rs +++ b/crates/swc_css_prefixer/src/prefixer.rs @@ -265,7 +265,7 @@ impl VisitMut for ImageSetFunctionReplacerOnLegacyVariant<'_> { fn visit_mut_function(&mut self, n: &mut Function) { let old_in_function = self.in_function; - self.in_function = true; + self.in_function = n.name.value.eq_str_ignore_ascii_case(self.from); n.visit_mut_children_with(self); @@ -591,6 +591,53 @@ where }); } +pub struct FontFaceFormatOldSyntax {} + +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")) { + return; + } + + if n.value.len() != 1 { + return; + } + + if let Some(ComponentValue::Ident(box ident)) = n.value.get(0) { + let new_value: JsWord = ident.value.to_ascii_lowercase(); + let new_value = match new_value { + js_word!("woff") + | js_word!("truetype") + | js_word!("opentype") + | js_word!("woff2") + | js_word!("embedded-opentype") + | js_word!("collection") + | js_word!("svg") => new_value, + _ => { + return; + } + }; + + let new_value = Str { + value: new_value, + span: ident.span, + raw: None, + }; + + n.value = vec![ComponentValue::Str(Box::new(new_value))]; + } + } +} + +pub fn font_face_format_old_syntax(node: &mut N) +where + N: VisitMutWith, +{ + node.visit_mut_with(&mut FontFaceFormatOldSyntax {}); +} + macro_rules! to_ident { ($val:expr) => {{ ComponentValue::Ident(Box::new(Ident { @@ -3294,6 +3341,16 @@ impl VisitMut for Prefixer { add_declaration!(Prefix::Moz, "-moz-border-radius-bottomleft", None); } + "src" if should_prefix("font-face-format-ident", self.env, true) => { + let mut new_declaration = n.clone(); + + font_face_format_old_syntax(&mut new_declaration); + + if n.value != new_declaration.value { + self.added_declarations.push(Box::new(new_declaration)); + } + } + // TODO add `grid` support https://github.com/postcss/autoprefixer/tree/main/lib/hacks (starting with grid) // TODO fix me https://github.com/postcss/autoprefixer/blob/main/test/cases/custom-prefix.out.css _ => {} diff --git a/crates/swc_css_prefixer/tests/fixture/font-face-format/input.css b/crates/swc_css_prefixer/tests/fixture/font-face-format/input.css new file mode 100644 index 000000000000..667bdbba6ae8 --- /dev/null +++ b/crates/swc_css_prefixer/tests/fixture/font-face-format/input.css @@ -0,0 +1,28 @@ +@font-face { + src: format(woff); +} + +@font-face { + src: url(a) format(woff), url(b) format(svg); +} + +@font-face { + src: format(woff), format(truetype), format(opentype), format(woff2), format(embedded-opentype), format(collection), format(svg); +} + +@Font-face { + src: FORMAT(WOFF) +} + +@font-face { + src: format("woff"); +} + +@font-face { + src: url(a) format("woff"), url(b) format(svg); +} + +@font-face { + src: url(a) format("woff"), url(b) format("svg"); +} + diff --git a/crates/swc_css_prefixer/tests/fixture/font-face-format/output.css b/crates/swc_css_prefixer/tests/fixture/font-face-format/output.css new file mode 100644 index 000000000000..0770c9bbc953 --- /dev/null +++ b/crates/swc_css_prefixer/tests/fixture/font-face-format/output.css @@ -0,0 +1,26 @@ +@font-face{ + src: format("woff"); + src: format(woff); +} +@font-face{ + src: url(a) format("woff"), url(b) format("svg"); + src: url(a) format(woff), url(b) format(svg); +} +@font-face{ + src: format("woff"), format("truetype"), format("opentype"), format("woff2"), format("embedded-opentype"), format("collection"), format("svg"); + src: format(woff), format(truetype), format(opentype), format(woff2), format(embedded-opentype), format(collection), format(svg); +} +@Font-face{ + src: FORMAT("woff"); + src: FORMAT(WOFF); +} +@font-face{ + src: format("woff"); +} +@font-face{ + src: url(a) format("woff"), url(b) format("svg"); + src: url(a) format("woff"), url(b) format(svg); +} +@font-face{ + src: url(a) format("woff"), url(b) format("svg"); +} diff --git a/crates/swc_css_prefixer/tests/fixture/font-face-format/output.defaults-not-ie-11.css b/crates/swc_css_prefixer/tests/fixture/font-face-format/output.defaults-not-ie-11.css new file mode 100644 index 000000000000..0770c9bbc953 --- /dev/null +++ b/crates/swc_css_prefixer/tests/fixture/font-face-format/output.defaults-not-ie-11.css @@ -0,0 +1,26 @@ +@font-face{ + src: format("woff"); + src: format(woff); +} +@font-face{ + src: url(a) format("woff"), url(b) format("svg"); + src: url(a) format(woff), url(b) format(svg); +} +@font-face{ + src: format("woff"), format("truetype"), format("opentype"), format("woff2"), format("embedded-opentype"), format("collection"), format("svg"); + src: format(woff), format(truetype), format(opentype), format(woff2), format(embedded-opentype), format(collection), format(svg); +} +@Font-face{ + src: FORMAT("woff"); + src: FORMAT(WOFF); +} +@font-face{ + src: format("woff"); +} +@font-face{ + src: url(a) format("woff"), url(b) format("svg"); + src: url(a) format("woff"), url(b) format(svg); +} +@font-face{ + src: url(a) format("woff"), url(b) format("svg"); +} diff --git a/crates/swc_css_prefixer/tests/fixture/image-set/input.css b/crates/swc_css_prefixer/tests/fixture/image-set/input.css index 053b0efc6c48..fb9f942ffbb4 100644 --- a/crates/swc_css_prefixer/tests/fixture/image-set/input.css +++ b/crates/swc_css_prefixer/tests/fixture/image-set/input.css @@ -36,4 +36,12 @@ h1 { .broken { content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x) "test"; +} + +a { + background-image: image-set("foo@1x.png" 1x, url(foo@2x.png) 2x); +} + +a { + background-image: image-set(url(foo@1x.png) 1x, unknown("foo@2x.png") 2x); } \ No newline at end of file diff --git a/crates/swc_css_prefixer/tests/fixture/image-set/output.css b/crates/swc_css_prefixer/tests/fixture/image-set/output.css index 1c7383bdcc50..0827ac23077e 100644 --- a/crates/swc_css_prefixer/tests/fixture/image-set/output.css +++ b/crates/swc_css_prefixer/tests/fixture/image-set/output.css @@ -43,3 +43,11 @@ h1 { content: -webkit-image-set(url("foo@1x.png") 1x, url("foo@2x.png") 2x) "test"; content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x) "test"; } +a { + background-image: -webkit-image-set(url("foo@1x.png") 1x, url(foo@2x.png) 2x); + background-image: image-set("foo@1x.png" 1x, url(foo@2x.png) 2x); +} +a { + background-image: -webkit-image-set(url(foo@1x.png) 1x, unknown("foo@2x.png") 2x); + background-image: image-set(url(foo@1x.png) 1x, unknown("foo@2x.png") 2x); +} diff --git a/crates/swc_css_prefixer/tests/fixture/image-set/output.defaults-not-ie-11.css b/crates/swc_css_prefixer/tests/fixture/image-set/output.defaults-not-ie-11.css index 9dee98e83ddd..2989139dd2e5 100644 --- a/crates/swc_css_prefixer/tests/fixture/image-set/output.defaults-not-ie-11.css +++ b/crates/swc_css_prefixer/tests/fixture/image-set/output.defaults-not-ie-11.css @@ -40,3 +40,11 @@ h1 { content: -webkit-image-set(url("foo@1x.png") 1x, url("foo@2x.png") 2x) "test"; content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x) "test"; } +a { + background-image: -webkit-image-set(url("foo@1x.png") 1x, url(foo@2x.png) 2x); + background-image: image-set("foo@1x.png" 1x, url(foo@2x.png) 2x); +} +a { + background-image: -webkit-image-set(url(foo@1x.png) 1x, unknown("foo@2x.png") 2x); + background-image: image-set(url(foo@1x.png) 1x, unknown("foo@2x.png") 2x); +}