From c0ba15e36e3d9f42f4713cdc932a1f2d102f01f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=9D?= Date: Mon, 11 Jul 2022 12:52:54 +0800 Subject: [PATCH 1/2] test: add more @container tests --- .gitignore | 3 +- src/lib.rs | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4f44a6d5..e82b6873 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.DS_Store *.node node_modules/ target/ @@ -6,4 +7,4 @@ dist/ .parcel-cache node/*.flow artifacts -npm +npm \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 016a709c..93264483 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19572,6 +19572,39 @@ mod tests { "@container my-layout (inline-size>45em){.foo{color:red}}", ); + minify_test( + r#" + @container my-layout ( not (width > 500px) ) { + .foo { + color: red; + } + } + "#, + "@container my-layout (not (width>500px)){.foo{color:red}}", + ); + + minify_test( + r#" + @container my-layout ((width: 100px) and (not (height: 100px))) { + .foo { + color: red; + } + } + "#, + "@container my-layout ((width:100px) and (not (height:100px))){.foo{color:red}}", + ); + + minify_test( + r#" + @container my-layout (width = max(10px, 10em)) { + .foo { + color: red; + } + } + "#, + "@container my-layout (width=max(10px,10em)){.foo{color:red}}", + ); + // without name minify_test( r#" @@ -19595,6 +19628,31 @@ mod tests { "@container (inline-size>45em) and (inline-size<100em){.foo{color:red}}", ); + + // calc() + minify_test( + r#" + @container (width > calc(100vw - 50px)) { + .foo { + color: red; + } + } + "#, + "@container (width>calc(100vw - 50px)){.foo{color:red}}", + ); + + minify_test( + r#" + @container (calc(100vh - 50px) <= height ) { + .foo { + color: red; + } + } + "#, + "@container (height>=calc(100vh - 50px)){.foo{color:red}}", + ); + + // merge adjacent minify_test( r#" @@ -19652,5 +19710,85 @@ mod tests { minify_test(".foo { width: calc(1cqb + 2cqb) }", ".foo{width:3cqb}"); minify_test(".foo { width: calc(1cqmin + 2cqmin) }", ".foo{width:3cqmin}"); minify_test(".foo { width: calc(1cqmax + 2cqmax) }", ".foo{width:3cqmax}"); + + // Unlike in @media, there is no need to convert the range syntax in @container, + // because browsers all support this syntax. + prefix_test( + r#" + @container (width > 100px) { + .foo { padding: 5px; } + } + "#, + indoc! { r#" + @container (width > 100px) { + .foo { + padding: 5px; + } + } + "#}, + Browsers { + chrome: Some(105 << 16), + ..Browsers::default() + }, + ); + prefix_test( + r#" + @container (min-width: 100px) { + .foo { padding: 5px; } + } + "#, + indoc! { r#" + @container (min-width: 100px) { + .foo { + padding: 5px; + } + } + "#}, + Browsers { + chrome: Some(105 << 16), + ..Browsers::default() + }, + ); + + // Disallow 'none', 'not', 'and', 'or' as a `` + // https://github.com/w3c/csswg-drafts/issues/7203#issuecomment-1144257312 + // https://chromium-review.googlesource.com/c/chromium/src/+/3698402 + error_test( + "@container none (width < 100vw) {}", + ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("none".into())), + ); + + error_test( + "@container and (width < 100vw) {}", + ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("and".into())), + ); + + error_test( + "@container not (width < 100vw) {}", + ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("not".into())), + ); + + error_test( + "@container or (width < 100vw) {}", + ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("or".into())), + ); + + // Disallow CSS wide keywords as a `` + error_test( + "@container revert-layer (width < 100vw) {}", + ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("revert-layer".into())), + ); + + error_test( + "@container initial (width < 100vw) {}", + ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("initial".into())), + ); + + // contains spaces + // https://github.com/web-platform-tests/wpt/blob/39f0da08fbbe33d0582a35749b6dbf8bd067a52d/css/css-contain/container-queries/at-container-parsing.html#L160-L178 + error_test( + "@container foo bar (width < 100vw) {}", + ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("bar".into())), + ); } } From 115ce13fda01378c54904e081dc0abe57b905abf Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Thu, 14 Jul 2022 08:23:14 -0700 Subject: [PATCH 2/2] Make tests pass --- src/lib.rs | 29 ++++++++++++++++++++++------- src/rules/container.rs | 8 +++++++- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 93264483..17365b1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19583,6 +19583,28 @@ mod tests { "@container my-layout (not (width>500px)){.foo{color:red}}", ); + minify_test( + r#" + @container my-layout not (width > 500px) { + .foo { + color: red; + } + } + "#, + "@container my-layout not (width>500px){.foo{color:red}}", + ); + + minify_test( + r#" + @container not (width > 500px) { + .foo { + color: red; + } + } + "#, + "@container not (width>500px){.foo{color:red}}", + ); + minify_test( r#" @container my-layout ((width: 100px) and (not (height: 100px))) { @@ -19628,7 +19650,6 @@ mod tests { "@container (inline-size>45em) and (inline-size<100em){.foo{color:red}}", ); - // calc() minify_test( r#" @@ -19652,7 +19673,6 @@ mod tests { "@container (height>=calc(100vh - 50px)){.foo{color:red}}", ); - // merge adjacent minify_test( r#" @@ -19763,11 +19783,6 @@ mod tests { ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("and".into())), ); - error_test( - "@container not (width < 100vw) {}", - ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("not".into())), - ); - error_test( "@container or (width < 100vw) {}", ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("or".into())), diff --git a/src/rules/container.rs b/src/rules/container.rs index ad6eadf4..c3a71fc1 100644 --- a/src/rules/container.rs +++ b/src/rules/container.rs @@ -1,4 +1,4 @@ -//! The `@media` rule. +//! The `@container` rule. use cssparser::*; @@ -76,7 +76,13 @@ impl<'a, 'i> ToCssWithContext<'a, 'i> for ContainerRule<'i> { name.to_css(dest)?; dest.write_char(' ')?; } + + // Don't downlevel range syntax in container queries. + let mut targets = None; + std::mem::swap(&mut targets, &mut dest.targets); self.condition.to_css(dest)?; + std::mem::swap(&mut targets, &mut dest.targets); + dest.whitespace()?; dest.write_char('{')?; dest.indent();