Skip to content

Commit 615893c

Browse files
committed
Parse @container and @layer block rules nested within style rules
Fixes parcel-bundler#353
1 parent 27cb9c2 commit 615893c

File tree

4 files changed

+122
-9
lines changed

4 files changed

+122
-9
lines changed

src/lib.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18696,6 +18696,75 @@ mod tests {
1869618696
"#},
1869718697
);
1869818698

18699+
nesting_test(
18700+
r#"
18701+
.foo {
18702+
display: grid;
18703+
18704+
@container (min-width: 100px) {
18705+
grid-auto-flow: column;
18706+
}
18707+
}
18708+
"#,
18709+
indoc! {r#"
18710+
.foo {
18711+
display: grid;
18712+
}
18713+
18714+
@container (min-width: 100px) {
18715+
.foo {
18716+
grid-auto-flow: column;
18717+
}
18718+
}
18719+
"#},
18720+
);
18721+
18722+
nesting_test(
18723+
r#"
18724+
.foo {
18725+
display: grid;
18726+
18727+
@layer test {
18728+
grid-auto-flow: column;
18729+
}
18730+
}
18731+
"#,
18732+
indoc! {r#"
18733+
.foo {
18734+
display: grid;
18735+
}
18736+
18737+
@layer test {
18738+
.foo {
18739+
grid-auto-flow: column;
18740+
}
18741+
}
18742+
"#},
18743+
);
18744+
18745+
nesting_test(
18746+
r#"
18747+
.foo {
18748+
display: grid;
18749+
18750+
@layer {
18751+
grid-auto-flow: column;
18752+
}
18753+
}
18754+
"#,
18755+
indoc! {r#"
18756+
.foo {
18757+
display: grid;
18758+
}
18759+
18760+
@layer {
18761+
.foo {
18762+
grid-auto-flow: column;
18763+
}
18764+
}
18765+
"#},
18766+
);
18767+
1869918768
nesting_test(
1870018769
r#"
1870118770
@namespace "http://example.com/foo";

src/parser.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ pub enum AtRulePrelude<'i, T> {
192192
Nest(SelectorList<'i>),
193193
/// An @layer prelude.
194194
Layer(Vec<LayerName<'i>>),
195+
/// A @layer block prelude.
196+
LayerBlock(Option<LayerName<'i>>),
195197
/// An @property prelude.
196198
Property(DashedIdent<'i>),
197199
/// A @container prelude.
@@ -639,6 +641,7 @@ impl<'a, 'o, 'b, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for NestedRuleParser<
639641
loc,
640642
}))
641643
}
644+
AtRulePrelude::LayerBlock(..) => unreachable!(), // only used in nested style rules.
642645
AtRulePrelude::Property(name) => Ok(CssRule::Property(PropertyRule::parse(name, input, loc)?)),
643646
AtRulePrelude::Import(..)
644647
| AtRulePrelude::Namespace(..)
@@ -850,6 +853,16 @@ impl<'a, 'o, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for StyleRuleParser<'a, '
850853
let cond = SupportsCondition::parse(input)?;
851854
Ok(AtRulePrelude::Supports(cond))
852855
},
856+
"container" => {
857+
let name = input.try_parse(ContainerName::parse).ok();
858+
let condition = MediaCondition::parse(input, true)?;
859+
Ok(AtRulePrelude::Container(name, condition))
860+
},
861+
"layer" => {
862+
// Only layer block rules are supported within style rules.
863+
let name = input.try_parse(LayerName::parse).ok();
864+
Ok(AtRulePrelude::LayerBlock(name))
865+
},
853866
"nest" => {
854867
self.options.warn(input.new_custom_error(ParserError::DeprecatedNestRule));
855868
let selector_parser = SelectorParser {
@@ -917,6 +930,35 @@ impl<'a, 'o, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for StyleRuleParser<'a, '
917930
}));
918931
Ok(())
919932
}
933+
AtRulePrelude::Container(name, condition) => {
934+
self.rules.0.push(CssRule::Container(ContainerRule {
935+
name,
936+
condition,
937+
rules: parse_nested_at_rule(
938+
input,
939+
self.options.source_index,
940+
self.default_namespace,
941+
self.namespace_prefixes,
942+
self.options,
943+
)?,
944+
loc,
945+
}));
946+
Ok(())
947+
}
948+
AtRulePrelude::LayerBlock(name) => {
949+
self.rules.0.push(CssRule::LayerBlock(LayerBlockRule {
950+
name,
951+
rules: parse_nested_at_rule(
952+
input,
953+
self.options.source_index,
954+
self.default_namespace,
955+
self.namespace_prefixes,
956+
self.options,
957+
)?,
958+
loc,
959+
}));
960+
Ok(())
961+
}
920962
AtRulePrelude::Nest(selectors) => {
921963
let (declarations, rules) = parse_declarations_and_nested_rules(
922964
input,
@@ -956,9 +998,7 @@ impl<'a, 'o, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for StyleRuleParser<'a, '
956998
Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid))
957999
}
9581000
}
959-
_ => {
960-
unreachable!()
961-
}
1001+
_ => Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)),
9621002
}
9631003
}
9641004

@@ -987,7 +1027,7 @@ impl<'a, 'o, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for StyleRuleParser<'a, '
9871027
Err(())
9881028
}
9891029
}
990-
_ => unreachable!(),
1030+
_ => Err(()),
9911031
}
9921032
}
9931033
}

src/rules/layer.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! The `@layer` rule.
22
3-
use super::{CssRuleList, Location, MinifyContext};
3+
use super::{CssRuleList, Location, MinifyContext, StyleContext, ToCssWithContext};
44
use crate::error::{MinifyError, ParserError, PrinterError};
55
use crate::parser::DefaultAtRule;
66
use crate::printer::Printer;
@@ -131,8 +131,12 @@ impl<'i, T> LayerBlockRule<'i, T> {
131131
}
132132
}
133133

134-
impl<'i, T: ToCss> ToCss for LayerBlockRule<'i, T> {
135-
fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
134+
impl<'a, 'i, T: ToCss> ToCssWithContext<'a, 'i, T> for LayerBlockRule<'i, T> {
135+
fn to_css_with_context<W>(
136+
&self,
137+
dest: &mut Printer<W>,
138+
context: Option<&StyleContext<'a, 'i, T>>,
139+
) -> Result<(), PrinterError>
136140
where
137141
W: std::fmt::Write,
138142
{
@@ -147,7 +151,7 @@ impl<'i, T: ToCss> ToCss for LayerBlockRule<'i, T> {
147151
dest.write_char('{')?;
148152
dest.indent();
149153
dest.newline()?;
150-
self.rules.to_css(dest)?;
154+
self.rules.to_css_with_context(dest, context)?;
151155
dest.dedent();
152156
dest.newline()?;
153157
dest.write_char('}')

src/rules/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ impl<'a, 'i, T: ToCss> ToCssWithContext<'a, 'i, T> for CssRule<'i, T> {
199199
CssRule::Viewport(viewport) => viewport.to_css(dest),
200200
CssRule::CustomMedia(custom_media) => custom_media.to_css(dest),
201201
CssRule::LayerStatement(layer) => layer.to_css(dest),
202-
CssRule::LayerBlock(layer) => layer.to_css(dest),
202+
CssRule::LayerBlock(layer) => layer.to_css_with_context(dest, context),
203203
CssRule::Property(property) => property.to_css(dest),
204204
CssRule::Container(container) => container.to_css_with_context(dest, context),
205205
CssRule::Unknown(unknown) => unknown.to_css(dest),

0 commit comments

Comments
 (0)