From f9aaa418088444914b134208180ee0b703e1aa11 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Fri, 17 May 2024 08:46:53 +0800 Subject: [PATCH] add `keyframeSelectorNotation` option --- docs/config.md | 48 +++++++++++++++++ dprint_plugin/deployment/schema.json | 5 ++ dprint_plugin/src/config.rs | 17 ++++++ malva/src/config.rs | 12 +++++ malva/src/doc_gen/at_rule/keyframes.rs | 29 +++++++++-- .../fmt/css/at-rule/keyframes-keyword.css | 15 ++++++ .../fmt/css/at-rule/keyframes-keyword.snap | 52 +++++++++++++++++++ .../fmt/css/at-rule/keyframes-percentage.css | 14 +++++ .../fmt/css/at-rule/keyframes-percentage.snap | 47 +++++++++++++++++ 9 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 malva/tests/fmt/css/at-rule/keyframes-keyword.css create mode 100644 malva/tests/fmt/css/at-rule/keyframes-keyword.snap create mode 100644 malva/tests/fmt/css/at-rule/keyframes-percentage.css create mode 100644 malva/tests/fmt/css/at-rule/keyframes-percentage.snap diff --git a/docs/config.md b/docs/config.md index 3deff20..0a347fd 100644 --- a/docs/config.md +++ b/docs/config.md @@ -570,3 +570,51 @@ a { width: 0; } a { width: 0; height: 0; } ``` + +## `keyframeSelectorNotation` + +Control whether to use percentage or keyword (`from` and `to`) notation as keyframe selectors. + +Possible options: + +- `null`: Keyframe selector notation will be kept as-is. +- `"keyword"`: Use keyword notation. This only affects `0%` and `100%`. For other percentage values, they will be kept as-is. +- `"percentage"`: Use percentage notation. + +Default option is `null`. + +### Example for `null` + +[Playground](https://malva-play.vercel.app/?code=H4sIAAAAAAAAA3PITq1MK0rMTS1WSMvPV6jmUlBIK8rPVaiuBbJMDVQhDEMDCKsWABlFCDAvAAAA&config=H4sIAAAAAAAAA6uuBQBDv6ajAgAAAA%3D%3D&syntax=css) + +```css +@keyframes foo { + from {} + 50% {} + 100% {} +} +``` + +### Example for `"keyword"` + +[Playground](https://malva-play.vercel.app/?code=H4sIAAAAAAAAA3PITq1MK0rMTS1WSMvPV6jmUlBIK8rPVaiuBbJMDVQhDEMDCKsWABlFCDAvAAAA&config=H4sIAAAAAAAAA6vmUlBQyk6tTCtKzE0NTs1JTS7JL%2FLLL0ksyczPU7ICy5XnF6UocdUCACuoVucrAAAA&syntax=css) + +```css +@keyframes foo { + from {} + 50% {} + to {} +} +``` + +### Example for `"percentage"` + +[Playground](https://malva-play.vercel.app/?code=H4sIAAAAAAAAA3PITq1MK0rMTS1WSMvPV6jmUlBIK8rPVaiuBbJMDVQhDEMDCKsWABlFCDAvAAAA&config=H4sIAAAAAAAAA6vmUlBQyk6tTCtKzE0NTs1JTS7JL%2FLLL0ksyczPU7JSUCpILUpOzStJTE9V4qoFAIT8kDouAAAA&syntax=css) + +```css +@keyframes foo { + 0% {} + 50% {} + 100% {} +} +``` diff --git a/dprint_plugin/deployment/schema.json b/dprint_plugin/deployment/schema.json index 881f54d..293c44b 100644 --- a/dprint_plugin/deployment/schema.json +++ b/dprint_plugin/deployment/schema.json @@ -74,6 +74,11 @@ "type": ["integer", "null"], "default": null, "minimum": 0 + }, + "keyframeSelectorNotation": { + "type": ["string", "null"], + "enum": ["keyword", "percentage"], + "default": null } } } diff --git a/dprint_plugin/src/config.rs b/dprint_plugin/src/config.rs index e63de34..666fca9 100644 --- a/dprint_plugin/src/config.rs +++ b/dprint_plugin/src/config.rs @@ -174,6 +174,23 @@ pub(crate) fn resolve_config( "singleLineBlockThreshold", &mut diagnostics, ), + keyframe_selector_notation: get_nullable_value::( + &mut config, + "keyframeSelectorNotation", + &mut diagnostics, + ) + .as_deref() + .and_then(|value| match value { + "keyword" => Some(KeyframeSelectorNotation::Keyword), + "percentage" => Some(KeyframeSelectorNotation::Percentage), + _ => { + diagnostics.push(ConfigurationDiagnostic { + property_name: "keyframeSelectorNotation".into(), + message: "invalid value for config `keyframeSelectorNotation`".into(), + }); + None + } + }), }, }; diff --git a/malva/src/config.rs b/malva/src/config.rs index adc5a77..cfa303f 100644 --- a/malva/src/config.rs +++ b/malva/src/config.rs @@ -126,6 +126,10 @@ pub struct LanguageOptions { #[cfg_attr(feature = "config_serde", serde(alias = "singleLineBlockThreshold"))] /// See [`singleLineBlockThreshold`](https://github.com/g-plane/malva/blob/main/docs/config.md#singlelineblockthreshold) on GitHub pub single_line_block_threshold: Option, + + #[cfg_attr(feature = "config_serde", serde(alias = "keyframeSelectorNotation"))] + /// See [`keyframeSelectorNotation`](https://github.com/g-plane/malva/blob/main/docs/config.md#keyframeselectornotation) on GitHub + pub keyframe_selector_notation: Option, } #[derive(Clone, Debug, Default)] @@ -205,3 +209,11 @@ pub enum DeclarationOrder { /// Order properties applying outside the box model, moving inward to intrinsic changes. Concentric, } + +#[derive(Clone, Debug)] +#[cfg_attr(feature = "config_serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "config_serde", serde(rename_all = "kebab-case"))] +pub enum KeyframeSelectorNotation { + Keyword, + Percentage, +} diff --git a/malva/src/doc_gen/at_rule/keyframes.rs b/malva/src/doc_gen/at_rule/keyframes.rs index c60ba67..ae97600 100644 --- a/malva/src/doc_gen/at_rule/keyframes.rs +++ b/malva/src/doc_gen/at_rule/keyframes.rs @@ -36,17 +36,40 @@ impl<'s> DocGen<'s> for KeyframesName<'s> { impl<'s> DocGen<'s> for KeyframeSelector<'s> { fn doc(&self, ctx: &Ctx<'_, 's>) -> Doc<'s> { + use crate::config::KeyframeSelectorNotation; + match self { - KeyframeSelector::Percentage(percentage) => percentage.doc(ctx), + KeyframeSelector::Percentage(percentage) => { + match ( + percentage.value.value, + &ctx.options.keyframe_selector_notation, + ) { + (0.0, Some(KeyframeSelectorNotation::Keyword)) => Doc::text("from"), + (100.0, Some(KeyframeSelectorNotation::Keyword)) => Doc::text("to"), + _ => percentage.doc(ctx), + } + } KeyframeSelector::Ident(InterpolableIdent::Literal(Ident { name, .. })) if name.eq_ignore_ascii_case("from") => { - Doc::text("from") + if let Some(KeyframeSelectorNotation::Percentage) = + ctx.options.keyframe_selector_notation + { + Doc::text("0%") + } else { + Doc::text("from") + } } KeyframeSelector::Ident(InterpolableIdent::Literal(Ident { name, .. })) if name.eq_ignore_ascii_case("to") => { - Doc::text("to") + if let Some(KeyframeSelectorNotation::Percentage) = + ctx.options.keyframe_selector_notation + { + Doc::text("100%") + } else { + Doc::text("to") + } } KeyframeSelector::Ident(ident) => ident.doc(ctx), } diff --git a/malva/tests/fmt/css/at-rule/keyframes-keyword.css b/malva/tests/fmt/css/at-rule/keyframes-keyword.css new file mode 100644 index 0000000..82f0996 --- /dev/null +++ b/malva/tests/fmt/css/at-rule/keyframes-keyword.css @@ -0,0 +1,15 @@ +/*cfg keyframeSelectorNotation = "keyword" */ + +@keyframes foo { from {} } +@keyframes foo { to {} } +@keyframes foo { from {} to {} } +@keyframes foo { from {} from {} to {} } +@keyframes foo { from {} 50% {} to {} } +@keyframes foo { from, to {} } + +@keyframes foo { 0% {} } +@keyframes foo { 100% {} } +@keyframes foo { 0% {} 100% {} } +@keyframes foo { 0% {} 0% {} 100% {} } +@keyframes foo { 0% {} 50% {} 100% {} } +@keyframes foo { 0%, 100% {} } diff --git a/malva/tests/fmt/css/at-rule/keyframes-keyword.snap b/malva/tests/fmt/css/at-rule/keyframes-keyword.snap new file mode 100644 index 0000000..bf1ce4e --- /dev/null +++ b/malva/tests/fmt/css/at-rule/keyframes-keyword.snap @@ -0,0 +1,52 @@ +--- +source: malva/tests/fmt.rs +--- +/*cfg keyframeSelectorNotation = "keyword" */ + +@keyframes foo { + from {} +} +@keyframes foo { + to {} +} +@keyframes foo { + from {} + to {} +} +@keyframes foo { + from {} + from {} + to {} +} +@keyframes foo { + from {} + 50% {} + to {} +} +@keyframes foo { + from, to {} +} + +@keyframes foo { + from {} +} +@keyframes foo { + to {} +} +@keyframes foo { + from {} + to {} +} +@keyframes foo { + from {} + from {} + to {} +} +@keyframes foo { + from {} + 50% {} + to {} +} +@keyframes foo { + from, to {} +} diff --git a/malva/tests/fmt/css/at-rule/keyframes-percentage.css b/malva/tests/fmt/css/at-rule/keyframes-percentage.css new file mode 100644 index 0000000..c12da85 --- /dev/null +++ b/malva/tests/fmt/css/at-rule/keyframes-percentage.css @@ -0,0 +1,14 @@ +/*cfg keyframeSelectorNotation = "percentage" */ + +@keyframes foo { 0% {} } +@keyframes foo { 100% {} } +@keyframes foo { 0% {} 100% {} } +@keyframes foo { 0% {} 0% {} 100% {} } +@keyframes foo { 0%, 100% {} } + +@keyframes foo { from {} } +@keyframes foo { to {} } +@keyframes foo { from {} to {} } +@keyframes foo { from {} from {} to {} } +@keyframes foo { from {} 50% {} to {} } +@keyframes foo { from, to {} } diff --git a/malva/tests/fmt/css/at-rule/keyframes-percentage.snap b/malva/tests/fmt/css/at-rule/keyframes-percentage.snap new file mode 100644 index 0000000..41674f7 --- /dev/null +++ b/malva/tests/fmt/css/at-rule/keyframes-percentage.snap @@ -0,0 +1,47 @@ +--- +source: malva/tests/fmt.rs +--- +/*cfg keyframeSelectorNotation = "percentage" */ + +@keyframes foo { + 0% {} +} +@keyframes foo { + 100% {} +} +@keyframes foo { + 0% {} + 100% {} +} +@keyframes foo { + 0% {} + 0% {} + 100% {} +} +@keyframes foo { + 0%, 100% {} +} + +@keyframes foo { + 0% {} +} +@keyframes foo { + 100% {} +} +@keyframes foo { + 0% {} + 100% {} +} +@keyframes foo { + 0% {} + 0% {} + 100% {} +} +@keyframes foo { + 0% {} + 50% {} + 100% {} +} +@keyframes foo { + 0%, 100% {} +}