Skip to content

Commit 131c62d

Browse files
committed
Implement container queries
Closes parcel-bundler#158
1 parent 1be08bd commit 131c62d

File tree

11 files changed

+443
-8
lines changed

11 files changed

+443
-8
lines changed

src/declaration.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::properties::{
1414
animation::AnimationHandler,
1515
background::BackgroundHandler,
1616
border::BorderHandler,
17+
contain::ContainerHandler,
1718
display::DisplayHandler,
1819
flex::FlexHandler,
1920
font::FontHandler,
@@ -465,6 +466,7 @@ pub(crate) struct DeclarationHandler<'i> {
465466
transform: TransformHandler,
466467
box_shadow: BoxShadowHandler,
467468
mask: MaskHandler<'i>,
469+
container: ContainerHandler<'i>,
468470
fallback: FallbackHandler,
469471
prefix: PrefixHandler,
470472
decls: DeclarationList<'i>,
@@ -496,6 +498,7 @@ impl<'i> DeclarationHandler<'i> {
496498
transform: TransformHandler::new(targets),
497499
box_shadow: BoxShadowHandler::new(targets),
498500
mask: MaskHandler::default(),
501+
container: ContainerHandler::default(),
499502
fallback: FallbackHandler::new(targets),
500503
prefix: PrefixHandler::new(targets),
501504
decls: DeclarationList::new(),
@@ -536,6 +539,7 @@ impl<'i> DeclarationHandler<'i> {
536539
|| self.transform.handle_property(property, &mut self.decls, context)
537540
|| self.box_shadow.handle_property(property, &mut self.decls, context)
538541
|| self.mask.handle_property(property, &mut self.decls, context)
542+
|| self.container.handle_property(property, &mut self.decls, context)
539543
|| self.fallback.handle_property(property, &mut self.decls, context)
540544
|| self.prefix.handle_property(property, &mut self.decls, context)
541545
}
@@ -564,6 +568,7 @@ impl<'i> DeclarationHandler<'i> {
564568
self.transform.finalize(&mut self.decls, context);
565569
self.box_shadow.finalize(&mut self.decls, context);
566570
self.mask.finalize(&mut self.decls, context);
571+
self.container.finalize(&mut self.decls, context);
567572
self.fallback.finalize(&mut self.decls, context);
568573
self.prefix.finalize(&mut self.decls, context);
569574
}

src/lib.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19557,4 +19557,100 @@ mod tests {
1955719557
]
1955819558
)
1955919559
}
19560+
19561+
#[test]
19562+
fn test_container_queries() {
19563+
// with name
19564+
minify_test(
19565+
r#"
19566+
@container my-layout (inline-size > 45em) {
19567+
.foo {
19568+
color: red;
19569+
}
19570+
}
19571+
"#,
19572+
"@container my-layout (inline-size>45em){.foo{color:red}}",
19573+
);
19574+
19575+
// without name
19576+
minify_test(
19577+
r#"
19578+
@container (inline-size > 45em) {
19579+
.foo {
19580+
color: red;
19581+
}
19582+
}
19583+
"#,
19584+
"@container (inline-size>45em){.foo{color:red}}",
19585+
);
19586+
19587+
minify_test(
19588+
r#"
19589+
@container (inline-size > 45em) and (inline-size < 100em) {
19590+
.foo {
19591+
color: red;
19592+
}
19593+
}
19594+
"#,
19595+
"@container (inline-size>45em) and (inline-size<100em){.foo{color:red}}",
19596+
);
19597+
19598+
// merge adjacent
19599+
minify_test(
19600+
r#"
19601+
@container my-layout (inline-size > 45em) {
19602+
.foo {
19603+
color: red;
19604+
}
19605+
}
19606+
19607+
@container my-layout (inline-size > 45em) {
19608+
.foo {
19609+
background: yellow;
19610+
}
19611+
19612+
.bar {
19613+
color: white;
19614+
}
19615+
}
19616+
"#,
19617+
"@container my-layout (inline-size>45em){.foo{color:red;background:#ff0}.bar{color:#fff}}",
19618+
);
19619+
19620+
minify_test(
19621+
r#"
19622+
.foo {
19623+
container-name: foo bar;
19624+
container-type: size inline-size;
19625+
}
19626+
"#,
19627+
".foo{container:foo bar/size}",
19628+
);
19629+
minify_test(
19630+
r#"
19631+
.foo {
19632+
container-name: foo bar;
19633+
container-type: normal;
19634+
}
19635+
"#,
19636+
".foo{container:foo bar}",
19637+
);
19638+
minify_test(
19639+
".foo{ container-type: inline-size }",
19640+
".foo{container-type:inline-size}",
19641+
);
19642+
minify_test(".foo{ container-name: none; }", ".foo{container-name:none}");
19643+
minify_test(".foo{ container-name: foo; }", ".foo{container-name:foo}");
19644+
minify_test(".foo{ container: foo / normal; }", ".foo{container:foo}");
19645+
minify_test(
19646+
".foo{ container: foo / inline-size; }",
19647+
".foo{container:foo/inline-size}",
19648+
);
19649+
minify_test(".foo { width: calc(1cqw + 2cqw) }", ".foo{width:3cqw}");
19650+
minify_test(".foo { width: calc(1cqh + 2cqh) }", ".foo{width:3cqh}");
19651+
minify_test(".foo { width: calc(1cqi + 2cqi) }", ".foo{width:3cqi}");
19652+
minify_test(".foo { width: calc(1cqb + 2cqb) }", ".foo{width:3cqb}");
19653+
minify_test(".foo { width: calc(1cqmin + 2cqmin) }", ".foo{width:3cqmin}");
19654+
minify_test(".foo { width: calc(1cqmax + 2cqmax) }", ".foo{width:3cqmax}");
19655+
}
1956019656
}

src/macros.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,12 @@ pub(crate) use shorthand_property;
209209

210210
macro_rules! shorthand_handler {
211211
(
212-
$name: ident -> $shorthand: ident$(<$l: lifetime>)?
212+
$name: ident -> $shorthand: ident$(<$l: lifetime>)? $(fallbacks: $shorthand_fallback: literal)?
213213
{ $( $key: ident: $prop: ident($type: ty $(, fallback: $fallback: literal)?), )+ }
214214
) => {
215215
#[derive(Default)]
216216
pub(crate) struct $name$(<$l>)? {
217+
#[allow(dead_code)]
217218
targets: Option<Browsers>,
218219
$(
219220
pub $key: Option<$type>,
@@ -222,6 +223,7 @@ macro_rules! shorthand_handler {
222223
}
223224

224225
impl$(<$l>)? $name$(<$l>)? {
226+
#[allow(dead_code)]
225227
pub fn new(targets: Option<Browsers>) -> Self {
226228
Self {
227229
targets,
@@ -270,18 +272,23 @@ macro_rules! shorthand_handler {
270272
)+
271273

272274
if $( $key.is_some() && )* true {
275+
#[allow(unused_mut)]
273276
let mut shorthand = $shorthand {
274277
$(
275278
$key: $key.unwrap(),
276279
)+
277280
};
278281

279-
if let Some(targets) = self.targets {
280-
let fallbacks = shorthand.get_fallbacks(targets);
281-
for fallback in fallbacks {
282-
dest.push(Property::$shorthand(fallback));
282+
$(
283+
if $shorthand_fallback {
284+
if let Some(targets) = self.targets {
285+
let fallbacks = shorthand.get_fallbacks(targets);
286+
for fallback in fallbacks {
287+
dest.push(Property::$shorthand(fallback));
288+
}
289+
}
283290
}
284-
}
291+
)?
285292

286293
dest.push(Property::$shorthand(shorthand))
287294
} else {

src/parser.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::declaration::{parse_declaration, DeclarationBlock, DeclarationList};
22
use crate::error::{Error, ParserError};
33
use crate::media_query::*;
4+
use crate::rules::container::{ContainerName, ContainerRule};
45
use crate::rules::font_palette_values::FontPaletteValuesRule;
56
use crate::rules::layer::{LayerBlockRule, LayerStatementRule};
67
use crate::rules::property::PropertyRule;
@@ -130,6 +131,8 @@ pub enum AtRulePrelude<'i> {
130131
Layer(Vec<LayerName<'i>>),
131132
/// An @property prelude.
132133
Property(DashedIdent<'i>),
134+
/// A @container prelude.
135+
Container(Option<ContainerName<'i>>, MediaCondition<'i>),
133136
}
134137

135138
impl<'a, 'o, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a, 'o, 'i> {
@@ -446,6 +449,11 @@ impl<'a, 'o, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'o, 'i> {
446449
};
447450
Ok(AtRulePrelude::Layer(names))
448451
},
452+
"container" => {
453+
let name = input.try_parse(ContainerName::parse).ok();
454+
let condition = MediaCondition::parse(input, true)?;
455+
Ok(AtRulePrelude::Container(name, condition))
456+
},
449457
_ => Err(input.new_error(BasicParseErrorKind::AtRuleInvalid(name)))
450458
}
451459
}
@@ -503,6 +511,12 @@ impl<'a, 'o, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'o, 'i> {
503511
rules: self.parse_nested_rules(input)?,
504512
loc,
505513
})),
514+
AtRulePrelude::Container(name, condition) => Ok(CssRule::Container(ContainerRule {
515+
name,
516+
condition,
517+
rules: self.parse_nested_rules(input)?,
518+
loc,
519+
})),
506520
AtRulePrelude::Viewport(vendor_prefix) => {
507521
Ok(CssRule::Viewport(ViewportRule {
508522
vendor_prefix,

0 commit comments

Comments
 (0)