Skip to content

Commit b1656ac

Browse files
committed
Add tracking of var() functions.
This helps implementing CSS Custom Properties in Servo.
1 parent 440a30f commit b1656ac

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

src/parser.rs

+13
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,19 @@ impl<'i, 't> Parser<'i, 't> {
220220
self.at_start_of = new_position.at_start_of;
221221
}
222222

223+
/// Start looking for `var()` functions. (See the `.seen_var_functions()` method.)
224+
#[inline]
225+
pub fn look_for_var_functions(&mut self) {
226+
self.tokenizer.look_for_var_functions()
227+
}
228+
229+
/// Return whether a `var()` function has been seen by the tokenizer since
230+
/// either `look_for_var_functions` was called, and stop looking.
231+
#[inline]
232+
pub fn seen_var_functions(&mut self) -> bool {
233+
self.tokenizer.seen_var_functions()
234+
}
235+
223236
/// Execute the given closure, passing it the parser.
224237
/// If the result (returned unchanged) is `Err`,
225238
/// the internal state of the parser (including position within the input)

src/tokenizer.rs

+30-2
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,14 @@ pub struct Tokenizer<'a> {
211211
position: usize,
212212
/// Cache for `source_location()`
213213
last_known_line_break: Cell<(usize, usize)>,
214+
var_functions: VarFunctions,
215+
}
216+
217+
#[derive(Copy, Clone, PartialEq, Eq)]
218+
enum VarFunctions {
219+
DontCare,
220+
LookingForThem,
221+
SeenAtLeastOne,
214222
}
215223

216224

@@ -221,9 +229,22 @@ impl<'a> Tokenizer<'a> {
221229
input: input,
222230
position: 0,
223231
last_known_line_break: Cell::new((1, 0)),
232+
var_functions: VarFunctions::DontCare,
224233
}
225234
}
226235

236+
#[inline]
237+
pub fn look_for_var_functions(&mut self) {
238+
self.var_functions = VarFunctions::LookingForThem;
239+
}
240+
241+
#[inline]
242+
pub fn seen_var_functions(&mut self) -> bool {
243+
let seen = self.var_functions == VarFunctions::SeenAtLeastOne;
244+
self.var_functions = VarFunctions::DontCare;
245+
seen
246+
}
247+
227248
#[inline]
228249
pub fn next(&mut self) -> Result<Token<'a>, ()> {
229250
next_token(self).ok_or(())
@@ -606,8 +627,15 @@ fn consume_ident_like<'a>(tokenizer: &mut Tokenizer<'a>) -> Token<'a> {
606627
let value = consume_name(tokenizer);
607628
if !tokenizer.is_eof() && tokenizer.next_char() == '(' {
608629
tokenizer.advance(1);
609-
if value.eq_ignore_ascii_case("url") { consume_url(tokenizer) }
610-
else { Function(value) }
630+
if value.eq_ignore_ascii_case("url") {
631+
consume_url(tokenizer)
632+
} else {
633+
if tokenizer.var_functions == VarFunctions::LookingForThem &&
634+
value.eq_ignore_ascii_case("var") {
635+
tokenizer.var_functions = VarFunctions::SeenAtLeastOne;
636+
}
637+
Function(value)
638+
}
611639
} else {
612640
Ident(value)
613641
}

0 commit comments

Comments
 (0)