Skip to content

Commit

Permalink
Parse @container and @layer block rules nested within style rules
Browse files Browse the repository at this point in the history
Fixes #353
  • Loading branch information
devongovett committed Dec 9, 2022
1 parent 27cb9c2 commit 615893c
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 9 deletions.
69 changes: 69 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18696,6 +18696,75 @@ mod tests {
"#},
);

nesting_test(
r#"
.foo {
display: grid;

@container (min-width: 100px) {
grid-auto-flow: column;
}
}
"#,
indoc! {r#"
.foo {
display: grid;
}

@container (min-width: 100px) {
.foo {
grid-auto-flow: column;
}
}
"#},
);

nesting_test(
r#"
.foo {
display: grid;

@layer test {
grid-auto-flow: column;
}
}
"#,
indoc! {r#"
.foo {
display: grid;
}

@layer test {
.foo {
grid-auto-flow: column;
}
}
"#},
);

nesting_test(
r#"
.foo {
display: grid;

@layer {
grid-auto-flow: column;
}
}
"#,
indoc! {r#"
.foo {
display: grid;
}

@layer {
.foo {
grid-auto-flow: column;
}
}
"#},
);

nesting_test(
r#"
@namespace "http://example.com/foo";
Expand Down
48 changes: 44 additions & 4 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ pub enum AtRulePrelude<'i, T> {
Nest(SelectorList<'i>),
/// An @layer prelude.
Layer(Vec<LayerName<'i>>),
/// A @layer block prelude.
LayerBlock(Option<LayerName<'i>>),
/// An @property prelude.
Property(DashedIdent<'i>),
/// A @container prelude.
Expand Down Expand Up @@ -639,6 +641,7 @@ impl<'a, 'o, 'b, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for NestedRuleParser<
loc,
}))
}
AtRulePrelude::LayerBlock(..) => unreachable!(), // only used in nested style rules.
AtRulePrelude::Property(name) => Ok(CssRule::Property(PropertyRule::parse(name, input, loc)?)),
AtRulePrelude::Import(..)
| AtRulePrelude::Namespace(..)
Expand Down Expand Up @@ -850,6 +853,16 @@ impl<'a, 'o, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for StyleRuleParser<'a, '
let cond = SupportsCondition::parse(input)?;
Ok(AtRulePrelude::Supports(cond))
},
"container" => {
let name = input.try_parse(ContainerName::parse).ok();
let condition = MediaCondition::parse(input, true)?;
Ok(AtRulePrelude::Container(name, condition))
},
"layer" => {
// Only layer block rules are supported within style rules.
let name = input.try_parse(LayerName::parse).ok();
Ok(AtRulePrelude::LayerBlock(name))
},
"nest" => {
self.options.warn(input.new_custom_error(ParserError::DeprecatedNestRule));
let selector_parser = SelectorParser {
Expand Down Expand Up @@ -917,6 +930,35 @@ impl<'a, 'o, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for StyleRuleParser<'a, '
}));
Ok(())
}
AtRulePrelude::Container(name, condition) => {
self.rules.0.push(CssRule::Container(ContainerRule {
name,
condition,
rules: parse_nested_at_rule(
input,
self.options.source_index,
self.default_namespace,
self.namespace_prefixes,
self.options,
)?,
loc,
}));
Ok(())
}
AtRulePrelude::LayerBlock(name) => {
self.rules.0.push(CssRule::LayerBlock(LayerBlockRule {
name,
rules: parse_nested_at_rule(
input,
self.options.source_index,
self.default_namespace,
self.namespace_prefixes,
self.options,
)?,
loc,
}));
Ok(())
}
AtRulePrelude::Nest(selectors) => {
let (declarations, rules) = parse_declarations_and_nested_rules(
input,
Expand Down Expand Up @@ -956,9 +998,7 @@ impl<'a, 'o, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for StyleRuleParser<'a, '
Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid))
}
}
_ => {
unreachable!()
}
_ => Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)),
}
}

Expand Down Expand Up @@ -987,7 +1027,7 @@ impl<'a, 'o, 'i, T: AtRuleParser<'i>> AtRuleParser<'i> for StyleRuleParser<'a, '
Err(())
}
}
_ => unreachable!(),
_ => Err(()),
}
}
}
Expand Down
12 changes: 8 additions & 4 deletions src/rules/layer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The `@layer` rule.

use super::{CssRuleList, Location, MinifyContext};
use super::{CssRuleList, Location, MinifyContext, StyleContext, ToCssWithContext};
use crate::error::{MinifyError, ParserError, PrinterError};
use crate::parser::DefaultAtRule;
use crate::printer::Printer;
Expand Down Expand Up @@ -131,8 +131,12 @@ impl<'i, T> LayerBlockRule<'i, T> {
}
}

impl<'i, T: ToCss> ToCss for LayerBlockRule<'i, T> {
fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
impl<'a, 'i, T: ToCss> ToCssWithContext<'a, 'i, T> for LayerBlockRule<'i, T> {
fn to_css_with_context<W>(
&self,
dest: &mut Printer<W>,
context: Option<&StyleContext<'a, 'i, T>>,
) -> Result<(), PrinterError>
where
W: std::fmt::Write,
{
Expand All @@ -147,7 +151,7 @@ impl<'i, T: ToCss> ToCss for LayerBlockRule<'i, T> {
dest.write_char('{')?;
dest.indent();
dest.newline()?;
self.rules.to_css(dest)?;
self.rules.to_css_with_context(dest, context)?;
dest.dedent();
dest.newline()?;
dest.write_char('}')
Expand Down
2 changes: 1 addition & 1 deletion src/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl<'a, 'i, T: ToCss> ToCssWithContext<'a, 'i, T> for CssRule<'i, T> {
CssRule::Viewport(viewport) => viewport.to_css(dest),
CssRule::CustomMedia(custom_media) => custom_media.to_css(dest),
CssRule::LayerStatement(layer) => layer.to_css(dest),
CssRule::LayerBlock(layer) => layer.to_css(dest),
CssRule::LayerBlock(layer) => layer.to_css_with_context(dest, context),
CssRule::Property(property) => property.to_css(dest),
CssRule::Container(container) => container.to_css_with_context(dest, context),
CssRule::Unknown(unknown) => unknown.to_css(dest),
Expand Down

0 comments on commit 615893c

Please sign in to comment.