Skip to main content

css_parse/syntax/
declaration_group.rs

1use super::prelude::*;
2use crate::DeclarationOrBad;
3
4/// A group of declarations that can be interleaved with rules.
5///
6/// Per [CSS Syntax ยง 5.4.4](https://drafts.csswg.org/css-syntax-3/#consume-block-contents),
7/// blocks return a list containing either rules or lists of declarations. This allows
8/// declarations to be properly interleaved with nested rules while maintaining their order.
9///
10/// For example, in `a { color: red; b { } color: blue; }`, the declarations need to be
11/// grouped separately before and after the nested `b` rule.
12#[node]
13#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(transparent))]
15pub struct DeclarationGroup<'a, D, M>
16where
17	D: DeclarationValue<'a, M>,
18	M: NodeMetadata,
19{
20	pub declarations: Vec<'a, DeclarationOrBad<'a, D, M>>,
21}
22
23impl<'a, D, M> ToCursors for DeclarationGroup<'a, D, M>
24where
25	D: DeclarationValue<'a, M> + ToCursors,
26	M: NodeMetadata,
27{
28	fn to_cursors(&self, s: &mut impl CursorSink) {
29		for decl in &self.declarations {
30			decl.to_cursors(s);
31		}
32	}
33}
34
35impl<'a, D, M> ToSpan for DeclarationGroup<'a, D, M>
36where
37	D: DeclarationValue<'a, M> + ToSpan,
38	M: NodeMetadata,
39{
40	fn to_span(&self) -> Span {
41		self.declarations.to_span()
42	}
43}
44
45impl<'a, D, M> SemanticEq for DeclarationGroup<'a, D, M>
46where
47	D: DeclarationValue<'a, M>,
48	M: NodeMetadata,
49{
50	fn semantic_eq(&self, other: &Self) -> bool {
51		self.declarations.semantic_eq(&other.declarations)
52	}
53}
54
55impl<'a, D, M> NodeWithMetadata<M> for DeclarationGroup<'a, D, M>
56where
57	D: DeclarationValue<'a, M>,
58	M: NodeMetadata,
59{
60	fn metadata(&self) -> M {
61		let mut meta = M::default();
62		for decl in &self.declarations {
63			meta = meta.merge(decl.metadata());
64		}
65		meta
66	}
67}