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