From 8f96a821f7b679267038fed2914b534dcad0821e Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Mon, 30 Mar 2020 00:18:37 -0400 Subject: [PATCH] allow id selectors to start with numbers --- src/selector.rs | 58 ++++++++++++++++++++++++++++++++++------------ tests/selectors.rs | 2 ++ 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/selector.rs b/src/selector.rs index 52a48be..280dd3f 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -257,14 +257,18 @@ impl<'a> SelectorParser<'a> { self.selectors.push(SelectorKind::Whitespace); return Ok(()); } - if let Some(Token { kind, .. }) = tokens.next() { + if let Some(Token { kind, .. }) = tokens.peek() { match kind { - v @ 'a'..='z' | v @ 'A'..='Z' | v @ '-' | v @ '_' => { - let s = format!("{}{}", v, eat_ident_no_interpolation(tokens)?); + 'a'..='z' | 'A'..='Z' | '-' | '_' | '0'..='9' | '\\' => { + let s = eat_ident_no_interpolation(tokens)?; self.selectors.push(SelectorKind::Element(s)) } - '.' => self.selectors.push(SelectorKind::Class), + '.' => { + tokens.next(); + self.selectors.push(SelectorKind::Class) + } '#' => { + tokens.next(); if tokens.peek().unwrap().kind == '{' { tokens.next(); self.is_interpolated = true; @@ -280,29 +284,53 @@ impl<'a> SelectorParser<'a> { self.selectors.push(SelectorKind::Id) } } - ':' => self.consume_pseudo_selector(tokens)?, + ':' => { + tokens.next(); + self.consume_pseudo_selector(tokens)? + } ',' => { + tokens.next(); self.selectors.push(SelectorKind::Multiple); if tokens.peek().unwrap().kind == '\n' { self.selectors.push(SelectorKind::Newline); devour_whitespace(tokens); } } - '>' => self.selectors.push(SelectorKind::ImmediateChild), - '+' => self.selectors.push(SelectorKind::Following), - '~' => self.selectors.push(SelectorKind::Preceding), - '*' => self.selectors.push(SelectorKind::Universal), - '%' => self.selectors.push(SelectorKind::Placeholder), + '>' => { + tokens.next(); + self.selectors.push(SelectorKind::ImmediateChild) + } + '+' => { + tokens.next(); + self.selectors.push(SelectorKind::Following) + } + '~' => { + tokens.next(); + self.selectors.push(SelectorKind::Preceding) + } + '*' => { + tokens.next(); + self.selectors.push(SelectorKind::Universal) + } + '%' => { + tokens.next(); + self.selectors.push(SelectorKind::Placeholder) + } '&' => self.selectors.push(if self.is_interpolated { + tokens.next(); SelectorKind::InterpolatedSuper } else { + tokens.next(); SelectorKind::Super }), - '[' => self.selectors.push(Attribute::from_tokens( - tokens, - self.scope, - self.super_selector, - )?), + '[' => { + tokens.next(); + self.selectors.push(Attribute::from_tokens( + tokens, + self.scope, + self.super_selector, + )?) + } _ => todo!("unimplemented selector"), }; } diff --git a/tests/selectors.rs b/tests/selectors.rs index 3e95e81..840dcfd 100644 --- a/tests/selectors.rs +++ b/tests/selectors.rs @@ -303,3 +303,5 @@ test!( // "#{&} a {\n color: red;\n}\n", // "a {\n color: red;\n}\n" // ); +test!(allows_id_start_with_number, "#2foo {\n color: red;\n}\n"); +test!(allows_id_only_number, "#2 {\n color: red;\n}\n");