diff --git a/src/media_query.rs b/src/media_query.rs index 1d471e75..be0be683 100644 --- a/src/media_query.rs +++ b/src/media_query.rs @@ -449,10 +449,19 @@ impl<'i> ToCss for MediaCondition<'i> { { match *self { MediaCondition::Feature(ref f) => f.to_css(dest), - MediaCondition::Not(ref c) => { - dest.write_str("not ")?; - c.to_css(dest) - } + MediaCondition::Not(ref c) => match **c { + MediaCondition::Feature(ref f) => { + dest.write_str("not ")?; + dest.in_negated_media_feature = true; + f.to_css(dest)?; + dest.in_negated_media_feature = false; + Ok(()) + } + _ => { + dest.write_str("not ")?; + c.to_css(dest) + } + }, MediaCondition::InParens(ref c) => { dest.write_char('(')?; c.to_css(dest)?; @@ -672,9 +681,16 @@ impl<'i> ToCss for MediaFeature<'i> { } => { if let Some(targets) = dest.targets { if !Feature::MediaIntervalSyntax.is_compatible(targets) { + if dest.in_negated_media_feature { + dest.write_char('(')?; + } write_min_max(&start_operator.opposite(), name, start, dest)?; dest.write_str(" and (")?; - return write_min_max(end_operator, name, end, dest); + write_min_max(end_operator, name, end, dest)?; + if dest.in_negated_media_feature { + dest.write_char(')')?; + } + return Ok(()); } } @@ -991,7 +1007,7 @@ fn process_condition<'i>( #[cfg(test)] mod tests { use super::*; - use crate::stylesheet::PrinterOptions; + use crate::{stylesheet::PrinterOptions, targets::Browsers}; fn parse(s: &str) -> MediaQuery { let mut input = ParserInput::new(&s); @@ -1038,4 +1054,20 @@ mod tests { assert_eq!(and("only screen", "all"), "only screen"); assert_eq!(and("print", "print"), "print"); } + + #[test] + fn test_negated_interval_parens() { + let media_query = parse("screen and not (200px <= width < 500px)"); + let printer_options = PrinterOptions { + targets: Some(Browsers { + firefox: Some(62 << 16), + ..Browsers::default() + }), + ..PrinterOptions::default() + }; + assert_eq!( + media_query.to_css_string(printer_options).unwrap(), + "screen and not ((min-width: 200px) and (max-width: 499.999px))" + ); + } } diff --git a/src/printer.rs b/src/printer.rs index 58ce88a9..a3dd5009 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -72,6 +72,7 @@ pub struct Printer<'a, 'b, 'c, W> { /// the vendor prefix of whatever is being printed. pub(crate) vendor_prefix: VendorPrefix, pub(crate) in_calc: bool, + pub(crate) in_negated_media_feature: bool, pub(crate) css_module: Option>, pub(crate) dependencies: Option>, pub(crate) remove_imports: bool, @@ -98,6 +99,7 @@ impl<'a, 'b, 'c, W: std::fmt::Write + Sized> Printer<'a, 'b, 'c, W> { targets: options.targets, vendor_prefix: VendorPrefix::empty(), in_calc: false, + in_negated_media_feature: false, css_module: None, dependencies: if options.analyze_dependencies.is_some() { Some(Vec::new())