css_ast/rules/
document.rs

1use super::prelude::*;
2
3// https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#at-document
4#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
6#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
7pub struct DocumentRule<'a> {
8	#[cfg_attr(feature = "visitable", visit(skip))]
9	#[atom(CssAtomSet::Document)]
10	pub name: T![AtKeyword],
11	pub prelude: DocumentMatcherList<'a>,
12	pub block: DocumentRuleBlock<'a>,
13}
14
15impl<'a> NodeWithMetadata<CssMetadata> for DocumentRule<'a> {
16	fn metadata(&self) -> CssMetadata {
17		let mut meta = self.block.0.metadata();
18		meta.used_at_rules |= AtRuleId::Document;
19		meta
20	}
21}
22
23#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
25#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable))]
26pub struct DocumentMatcherList<'a>(pub CommaSeparated<'a, DocumentMatcher>);
27
28#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
29#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
30#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
31pub enum DocumentMatcher {
32	Url(T![Url]),
33	#[atom(CssAtomSet::Url)]
34	UrlFunction(T![Function], T![String], T![')']),
35	#[atom(CssAtomSet::UrlPrefix)]
36	UrlPrefix(T![Function], T![String], T![')']),
37	#[atom(CssAtomSet::Domain)]
38	Domain(T![Function], T![String], T![')']),
39	#[atom(CssAtomSet::MediaDocument)]
40	MediaDocument(T![Function], T![String], T![')']),
41	#[atom(CssAtomSet::Regexp)]
42	Regexp(T![Function], T![String], T![')']),
43}
44
45#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
46#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
47#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable))]
48pub struct DocumentRuleBlock<'a>(pub RuleList<'a, Rule<'a>, CssMetadata>);
49
50#[cfg(test)]
51mod tests {
52	use super::*;
53	use crate::CssAtomSet;
54	use css_parse::assert_parse;
55
56	#[test]
57	fn size_test() {
58		assert_eq!(std::mem::size_of::<DocumentRule>(), 136);
59		assert_eq!(std::mem::size_of::<DocumentMatcher>(), 40);
60		assert_eq!(std::mem::size_of::<DocumentRuleBlock>(), 88);
61	}
62
63	#[test]
64	fn test_writes() {
65		assert_parse!(CssAtomSet::ATOMS, DocumentRule, r#"@document url("http://www.w3.org"){}"#);
66		assert_parse!(CssAtomSet::ATOMS, DocumentRule, r#"@document domain("mozilla.org"){}"#);
67		assert_parse!(CssAtomSet::ATOMS, DocumentRule, r#"@document url-prefix("http://www.w3.org/Style/"){}"#);
68		assert_parse!(CssAtomSet::ATOMS, DocumentRule, r#"@document media-document("video"){}"#);
69		assert_parse!(CssAtomSet::ATOMS, DocumentRule, r#"@document regexp("https:.*"){}"#);
70		assert_parse!(
71			CssAtomSet::ATOMS,
72			DocumentRule,
73			r#"@document url(http://www.w3.org),url-prefix("http://www.w3.org/Style/"),domain("mozilla.org"){}"#
74		);
75		assert_parse!(
76			CssAtomSet::ATOMS,
77			DocumentRule,
78			r#"@document url(http://www.w3.org),url-prefix("http://www.w3.org/Style/"),domain("mozilla.org"){body{color:black}}"#
79		);
80	}
81}