lightningcss/rules/
nesting.rs1use smallvec::SmallVec;
4
5use super::style::StyleRule;
6use super::Location;
7use super::MinifyContext;
8use crate::context::DeclarationContext;
9use crate::declaration::DeclarationBlock;
10use crate::error::{MinifyError, PrinterError};
11use crate::parser::DefaultAtRule;
12use crate::printer::Printer;
13use crate::targets::should_compile;
14use crate::traits::ToCss;
15#[cfg(feature = "visitor")]
16use crate::visitor::Visit;
17
18#[derive(Debug, PartialEq, Clone)]
20#[cfg_attr(feature = "visitor", derive(Visit))]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
23#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
24pub struct NestingRule<'i, R = DefaultAtRule> {
25 #[cfg_attr(feature = "serde", serde(borrow))]
27 pub style: StyleRule<'i, R>,
28 #[cfg_attr(feature = "visitor", skip_visit)]
30 pub loc: Location,
31}
32
33impl<'i, T: Clone> NestingRule<'i, T> {
34 pub(crate) fn minify(
35 &mut self,
36 context: &mut MinifyContext<'_, 'i>,
37 parent_is_unused: bool,
38 ) -> Result<bool, MinifyError> {
39 self.style.minify(context, parent_is_unused)
40 }
41}
42
43impl<'a, 'i, T: ToCss> ToCss for NestingRule<'i, T> {
44 fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
45 where
46 W: std::fmt::Write,
47 {
48 #[cfg(feature = "sourcemap")]
49 dest.add_mapping(self.loc);
50 if dest.context().is_none() {
51 dest.write_str("@nest ")?;
52 }
53 self.style.to_css(dest)
54 }
55}
56
57#[derive(Debug, PartialEq, Clone)]
59#[cfg_attr(feature = "visitor", derive(Visit))]
60#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
61#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
62#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
63pub struct NestedDeclarationsRule<'i> {
64 #[cfg_attr(feature = "serde", serde(borrow))]
66 pub declarations: DeclarationBlock<'i>,
67 #[cfg_attr(feature = "visitor", skip_visit)]
69 pub loc: Location,
70}
71
72impl<'i> NestedDeclarationsRule<'i> {
73 pub(crate) fn minify(&mut self, context: &mut MinifyContext<'_, 'i>, parent_is_unused: bool) -> bool {
74 if parent_is_unused {
75 return true;
76 }
77
78 context.handler_context.context = DeclarationContext::StyleRule;
79 self
80 .declarations
81 .minify(context.handler, context.important_handler, &mut context.handler_context);
82 context.handler_context.context = DeclarationContext::None;
83 return false;
84 }
85}
86
87impl<'i> ToCss for NestedDeclarationsRule<'i> {
88 fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
89 where
90 W: std::fmt::Write,
91 {
92 #[cfg(feature = "sourcemap")]
93 dest.add_mapping(self.loc);
94
95 if should_compile!(dest.targets.current, Nesting) {
96 if let Some(context) = dest.context() {
97 let has_printable_declarations = self.declarations.has_printable_declarations();
98 if has_printable_declarations {
99 dest.with_parent_context(|dest| context.selectors.to_css(dest))?;
100 dest.whitespace()?;
101 dest.write_char('{')?;
102 dest.indent();
103 dest.newline()?;
104 }
105
106 self
107 .declarations
108 .to_css_declarations(dest, false, &context.selectors, self.loc.source_index)?;
109
110 if has_printable_declarations {
111 dest.dedent();
112 dest.newline()?;
113 dest.write_char('}')?;
114 }
115 return Ok(());
116 }
117 }
118
119 self
120 .declarations
121 .to_css_declarations(dest, false, &parcel_selectors::SelectorList(SmallVec::new()), 0)
122 }
123}