diff --git a/src/lib.rs b/src/lib.rs index 101756e..ec90cb1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,7 +106,7 @@ pub(crate) use crate::token::Token; use crate::{ builtin::modules::{ModuleConfig, Modules}, lexer::Lexer, - output::Css, + output::{AtRuleContext, Css}, parse::{ common::{ContextFlags, NeverEmptyVec}, Parser, @@ -295,7 +295,7 @@ fn from_string_with_file_name(input: String, file_name: &str, options: &Options) .parse() .map_err(|e| raw_to_parse_error(&map, *e, options.unicode_error_messages))?; - Css::from_stmts(stmts, false, options.allows_charset) + Css::from_stmts(stmts, AtRuleContext::None, options.allows_charset) .map_err(|e| raw_to_parse_error(&map, *e, options.unicode_error_messages))? .pretty_print(&map, options.style) .map_err(|e| raw_to_parse_error(&map, *e, options.unicode_error_messages)) diff --git a/src/output.rs b/src/output.rs index 2460c43..b84a9d8 100644 --- a/src/output.rs +++ b/src/output.rs @@ -125,16 +125,16 @@ impl Toplevel { #[derive(Debug, Clone)] pub(crate) struct Css { blocks: Vec, - in_at_rule: bool, + at_rule_context: AtRuleContext, allows_charset: bool, plain_imports: Vec, } impl Css { - pub const fn new(in_at_rule: bool, allows_charset: bool) -> Self { + pub const fn new(at_rule_context: AtRuleContext, allows_charset: bool) -> Self { Css { blocks: Vec::new(), - in_at_rule, + at_rule_context, allows_charset, plain_imports: Vec::new(), } @@ -142,10 +142,10 @@ impl Css { pub(crate) fn from_stmts( s: Vec, - in_at_rule: bool, + at_rule_context: AtRuleContext, allows_charset: bool, ) -> SassResult { - Css::new(in_at_rule, allows_charset).parse_stylesheet(s) + Css::new(at_rule_context, allows_charset).parse_stylesheet(s) } fn parse_stmt(&mut self, stmt: Stmt) -> SassResult> { @@ -381,7 +381,7 @@ impl Formatter for CompressedFormatter { } write!(buf, "{{")?; - let css = Css::from_stmts(body, true, css.allows_charset)?; + let css = Css::from_stmts(body, AtRuleContext::Unknown, css.allows_charset)?; self.write_css(buf, css, map)?; write!(buf, "}}")?; } @@ -400,7 +400,7 @@ impl Formatter for CompressedFormatter { } write!(buf, "{{")?; - let css = Css::from_stmts(body, true, css.allows_charset)?; + let css = Css::from_stmts(body, AtRuleContext::Keyframes, css.allows_charset)?; self.write_css(buf, css, map)?; write!(buf, "}}")?; } @@ -417,7 +417,7 @@ impl Formatter for CompressedFormatter { } write!(buf, "{{")?; - let css = Css::from_stmts(body, true, css.allows_charset)?; + let css = Css::from_stmts(body, AtRuleContext::Supports, css.allows_charset)?; self.write_css(buf, css, map)?; write!(buf, "}}")?; } @@ -427,7 +427,7 @@ impl Formatter for CompressedFormatter { } write!(buf, "@media {}{{", query)?; - let css = Css::from_stmts(body, true, css.allows_charset)?; + let css = Css::from_stmts(body, AtRuleContext::Media, css.allows_charset)?; self.write_css(buf, css, map)?; write!(buf, "}}")?; } @@ -495,6 +495,16 @@ struct Previous { is_group_end: bool, } +/// What kind of @-rule are we currently inside +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum AtRuleContext { + Media, + Supports, + Keyframes, + Unknown, + None, +} + impl Formatter for ExpandedFormatter { fn write_css(&mut self, buf: &mut Vec, css: Css, map: &CodeMap) -> SassResult<()> { let padding = " ".repeat(self.nesting); @@ -512,7 +522,9 @@ impl Formatter for ExpandedFormatter { if let Some(prev) = prev { writeln!(buf)?; - if prev.is_group_end && !css.in_at_rule { + if (prev.is_group_end && css.at_rule_context == AtRuleContext::None) + || css.at_rule_context == AtRuleContext::Supports + { writeln!(buf)?; } } @@ -570,7 +582,7 @@ impl Formatter for ExpandedFormatter { } writeln!(buf, " {{")?; - let css = Css::from_stmts(body, true, css.allows_charset)?; + let css = Css::from_stmts(body, AtRuleContext::Unknown, css.allows_charset)?; self.write_css(buf, css, map)?; write!(buf, "\n{}}}", padding)?; } @@ -590,7 +602,7 @@ impl Formatter for ExpandedFormatter { } writeln!(buf, " {{")?; - let css = Css::from_stmts(body, true, css.allows_charset)?; + let css = Css::from_stmts(body, AtRuleContext::Keyframes, css.allows_charset)?; self.write_css(buf, css, map)?; write!(buf, "\n{}}}", padding)?; } @@ -608,7 +620,7 @@ impl Formatter for ExpandedFormatter { } writeln!(buf, " {{")?; - let css = Css::from_stmts(body, true, css.allows_charset)?; + let css = Css::from_stmts(body, AtRuleContext::Supports, css.allows_charset)?; self.write_css(buf, css, map)?; write!(buf, "\n{}}}", padding)?; } @@ -619,7 +631,15 @@ impl Formatter for ExpandedFormatter { .. } => { writeln!(buf, "{}@media {} {{", padding, query)?; - let css = Css::from_stmts(body, inside_rule, css.allows_charset)?; + let css = Css::from_stmts( + body, + if inside_rule { + AtRuleContext::Media + } else { + AtRuleContext::None + }, + css.allows_charset, + )?; self.write_css(buf, css, map)?; write!(buf, "\n{}}}", padding)?; } diff --git a/tests/supports.rs b/tests/supports.rs index 59a6ba5..9dd662e 100644 --- a/tests/supports.rs +++ b/tests/supports.rs @@ -14,3 +14,16 @@ test!( }", "@supports (a: b) {\n a {\n color: red;\n }\n}\na {\n color: green;\n}\n" ); +test!( + newline_between_styles_inside, + "@supports (-ms-ime-align: auto) { + a { + color: red; + } + + b { + color: green; + } + }", + "@supports (-ms-ime-align: auto) {\n a {\n color: red;\n }\n\n b {\n color: green;\n }\n}\n" +);