/
counters.rs
122 lines (109 loc) · 3.73 KB
/
counters.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Specified types for counter properties.
#[cfg(feature = "servo")]
use computed_values::list_style_type::T as ListStyleType;
use cssparser::{Token, Parser};
use parser::{Parse, ParserContext};
use style_traits::{ParseError, StyleParseErrorKind};
use values::CustomIdent;
#[cfg(feature = "gecko")]
use values::generics::CounterStyleOrNone;
use values::generics::counters::CounterIncrement as GenericCounterIncrement;
use values::generics::counters::CounterReset as GenericCounterReset;
#[cfg(feature = "gecko")]
use values::specified::Attr;
use values::specified::Integer;
#[cfg(feature = "gecko")]
use values::specified::url::SpecifiedUrl;
/// A specified value for the `counter-increment` property.
pub type CounterIncrement = GenericCounterIncrement<Integer>;
impl Parse for CounterIncrement {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>
) -> Result<Self, ParseError<'i>> {
Ok(Self::new(parse_counters(context, input, 1)?))
}
}
/// A specified value for the `counter-increment` property.
pub type CounterReset = GenericCounterReset<Integer>;
impl Parse for CounterReset {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>
) -> Result<Self, ParseError<'i>> {
Ok(Self::new(parse_counters(context, input, 0)?))
}
}
fn parse_counters<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
default_value: i32,
) -> Result<Vec<(CustomIdent, Integer)>, ParseError<'i>> {
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
return Ok(vec![]);
}
let mut counters = Vec::new();
loop {
let location = input.current_source_location();
let counter_name = match input.next() {
Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(location, ident, &["none"])?,
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
Err(_) => break,
};
let counter_delta = input.try(|input| Integer::parse(context, input))
.unwrap_or(Integer::new(default_value));
counters.push((counter_name, counter_delta))
}
if !counters.is_empty() {
Ok(counters)
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
}
#[cfg(feature = "servo")]
type CounterStyleType = ListStyleType;
#[cfg(feature = "gecko")]
type CounterStyleType = CounterStyleOrNone;
/// The specified value for the `content` property.
///
/// https://drafts.csswg.org/css-content/#propdef-content
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub enum Content {
/// `normal` reserved keyword.
Normal,
/// `none` reserved keyword.
None,
/// `-moz-alt-content`.
#[cfg(feature = "gecko")]
MozAltContent,
/// Content items.
#[css(iterable)]
Items(Box<[ContentItem]>),
}
/// Items for the `content` property.
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)]
pub enum ContentItem {
/// Literal string content.
String(Box<str>),
/// `counter(name, style)`.
Counter(Box<str>, CounterStyleType),
/// `counters(name, separator, style)`.
Counters(Box<str>, Box<str>, CounterStyleType),
/// `open-quote`.
OpenQuote,
/// `close-quote`.
CloseQuote,
/// `no-open-quote`.
NoOpenQuote,
/// `no-close-quote`.
NoCloseQuote,
/// `attr([namespace? `|`]? ident)`
#[cfg(feature = "gecko")]
Attr(Attr),
/// `url(url)`
#[cfg(feature = "gecko")]
Url(SpecifiedUrl),
}