Correctly handle parens

This commit is contained in:
Guillaume Gomez 2022-09-15 13:53:20 +02:00
parent a528f68e79
commit d3529ceb6c
2 changed files with 38 additions and 8 deletions

View File

@ -17,19 +17,31 @@ pub(crate) struct CssPath {
}
/// When encountering a `"` or a `'`, returns the whole string, including the quote characters.
fn get_string(iter: &mut Peekable<Chars<'_>>, string_start: char) -> String {
let mut s = String::with_capacity(2);
s.push(string_start);
fn get_string(iter: &mut Peekable<Chars<'_>>, string_start: char, buffer: &mut String) {
buffer.push(string_start);
while let Some(c) = iter.next() {
s.push(c);
buffer.push(c);
if c == '\\' {
iter.next();
} else if c == string_start {
break;
}
}
s
}
fn get_inside_paren(
iter: &mut Peekable<Chars<'_>>,
paren_start: char,
paren_end: char,
buffer: &mut String,
) {
buffer.push(paren_start);
while let Some(c) = iter.next() {
handle_common_chars(c, buffer, iter);
if c == paren_end {
break;
}
}
}
/// Skips a `/*` comment.
@ -52,9 +64,11 @@ fn skip_line_comment(iter: &mut Peekable<Chars<'_>>) {
fn handle_common_chars(c: char, buffer: &mut String, iter: &mut Peekable<Chars<'_>>) {
match c {
'"' | '\'' => buffer.push_str(&get_string(iter, c)),
'"' | '\'' => get_string(iter, c, buffer),
'/' if iter.peek() == Some(&'*') => skip_comment(iter),
'/' if iter.peek() == Some(&'/') => skip_line_comment(iter),
'(' => get_inside_paren(iter, c, ')', buffer),
'[' => get_inside_paren(iter, c, ']', buffer),
_ => buffer.push(c),
}
}

View File

@ -138,7 +138,6 @@ fn test_media() {
assert!(p.children.get("a:hover").is_some());
assert!(p.children.get("b").is_some());
eprintln!("{:?}", paths);
let p = paths.get("@media (max-width:1001px)");
assert!(p.is_some());
let p = p.unwrap();
@ -169,3 +168,20 @@ fn test_css_variables() {
get_differences(&other, &against, &mut ret);
assert_eq!(ret, vec![" Missing CSS variable `--b` in `:root`".to_owned()]);
}
#[test]
fn test_weird_rule_value() {
let x = r#"
a[text=("a")] {
b: url({;}.png);
c: #fff
}
"#;
let paths = load_css_paths(&x).unwrap();
let p = paths.get("a[text=(\"a\")]");
assert!(p.is_some());
let p = p.unwrap();
assert_eq!(p.rules.get("b"), Some(&"url({;}.png)".to_owned()));
assert_eq!(p.rules.get("c"), Some(&"#fff".to_owned()));
}