accessibility_tree/style/
declaration_block.rs1use crate::style::errors::PropertyParseErrorKind;
2use crate::style::properties::{property_data_by_name, LonghandDeclaration, PerPhase, Phase};
3use crate::style::values::{CssWideKeyword, Parse};
4use cssparser::{AtRuleParser, ParseError, Parser};
5use cssparser::{CowRcStr, DeclarationListParser, DeclarationParser};
6use std::iter::repeat;
7
8impl std::fmt::Debug for LonghandDeclaration {
9 fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
10 Ok(())
11 }
12}
13
14#[derive(Default, Debug)]
15pub struct DeclarationBlock {
16 declarations: Vec<LonghandDeclaration>,
17 important: smallbitvec::SmallBitVec,
18 any_important: PerPhase<bool>,
19 any_normal: PerPhase<bool>,
20}
21
22impl DeclarationBlock {
23 pub fn parse(parser: &mut Parser) -> Self {
24 let mut iter = DeclarationListParser::new(
25 parser,
26 LonghandDeclarationParser {
27 block: DeclarationBlock::default(),
28 },
29 );
30 loop {
31 let previous_len = iter.parser.block.declarations.len();
32 let result = if let Some(r) = iter.next() { r } else { break };
33 match result {
34 Ok(()) => {}
35 Err(_) => {
36 if iter.parser.block.declarations.len() == previous_len {
38 break;
40 }
41 }
42 }
43 debug_assert_eq!(
44 iter.parser.block.declarations.len(),
45 iter.parser.block.important.len()
46 );
47 }
48 debug_assert_eq!(
49 iter.parser.block.any_normal.early || iter.parser.block.any_normal.late,
50 !iter.parser.block.important.all_true()
51 );
52 debug_assert_eq!(
53 iter.parser.block.any_important.early || iter.parser.block.any_important.late,
54 !iter.parser.block.important.all_false()
55 );
56 iter.parser.block
57 }
58
59 pub fn cascade_normal(&self, phase: &mut impl Phase) {
60 self.cascade(false, self.any_normal, phase)
61 }
62
63 pub fn cascade_important(&self, phase: &mut impl Phase) {
64 self.cascade(true, self.any_important, phase)
65 }
66
67 fn cascade(&self, important: bool, any: PerPhase<bool>, phase: &mut impl Phase) {
68 if phase.select(any) {
69 self.declarations.iter().zip(&self.important).for_each(
70 move |(declaration, declaration_important)| {
71 if declaration_important == important {
72 phase.cascade(declaration)
73 }
74 },
75 )
76 }
77 }
78}
79
80struct LonghandDeclarationParser {
81 block: DeclarationBlock,
82}
83
84impl<'i> DeclarationParser<'i> for LonghandDeclarationParser {
85 type Declaration = ();
86 type Error = PropertyParseErrorKind<'i>;
87
88 fn parse_value<'t>(
89 &mut self,
90 name: CowRcStr<'i>,
91 parser: &mut Parser<'i, 't>,
92 ) -> Result<Self::Declaration, ParseError<'i, Self::Error>> {
93 if let Some(data) = property_data_by_name(&name) {
94 let previous_len = self.block.declarations.len();
95 let mut parsed;
96 if let Ok(keyword) = parser.r#try(CssWideKeyword::parse) {
97 parsed = PerPhase::default();
98 for &longhand in data.longhands {
99 self.block
100 .declarations
101 .push(LonghandDeclaration::CssWide(longhand, keyword));
102 if longhand.is_early() {
103 parsed.early = true
104 } else {
105 parsed.late = true
106 }
107 }
108 } else {
109 parsed = (data.parse)(parser, &mut self.block.declarations)?
110 }
111 let important = parser.r#try(cssparser::parse_important).is_ok();
112 let count = self.block.declarations.len() - previous_len;
113
114 if count > 0 {
115 self.block.important.extend(repeat(important).take(count));
116 let any = if important {
117 &mut self.block.any_important
118 } else {
119 &mut self.block.any_normal
120 };
121 any.early |= parsed.early;
122 any.late |= parsed.late;
123 Ok(())
124 } else {
125 Err(parser.new_custom_error(PropertyParseErrorKind::UnknownUnit(name)))
126 }
127 } else {
128 Err(parser.new_custom_error(PropertyParseErrorKind::UnknownProperty(name)))
129 }
130 }
131}
132
133impl<'i> AtRuleParser<'i> for LonghandDeclarationParser {
134 type PreludeNoBlock = ();
135 type PreludeBlock = ();
136 type AtRule = ();
137 type Error = PropertyParseErrorKind<'i>;
138}