further refactor parsing of hex colors
This commit is contained in:
parent
00bd9f3847
commit
042935f362
@ -526,41 +526,38 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_hex(&mut self) -> SassResult<Spanned<Value>> {
|
fn parse_hex(&mut self) -> SassResult<Spanned<Value>> {
|
||||||
let mut s = String::with_capacity(8);
|
let mut s = String::with_capacity(7);
|
||||||
|
s.push('#');
|
||||||
if self
|
if self
|
||||||
.toks
|
.toks
|
||||||
.peek()
|
.peek()
|
||||||
.ok_or(("Expected identifier.", self.span_before))?
|
.ok_or(("Expected identifier.", self.span_before))?
|
||||||
.kind
|
.kind
|
||||||
.is_ascii_digit()
|
.is_ascii_hexdigit()
|
||||||
{
|
{
|
||||||
while let Some(c) = self.toks.peek() {
|
while let Some(c) = self.toks.peek() {
|
||||||
if !c.kind.is_ascii_hexdigit() || s.len() == 8 {
|
if !c.kind.is_ascii_hexdigit() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let tok = self.toks.next().unwrap();
|
let tok = self.toks.next().unwrap();
|
||||||
self.span_before = self.span_before.merge(tok.pos());
|
self.span_before = self.span_before.merge(tok.pos());
|
||||||
s.push(tok.kind);
|
s.push(tok.kind);
|
||||||
}
|
}
|
||||||
|
// this branch exists so that we can emit `#` combined with
|
||||||
|
// identifiers. e.g. `#ooobar` should be emitted exactly as written;
|
||||||
|
// that is, `#ooobar`.
|
||||||
} else {
|
} else {
|
||||||
let i = self.parse_identifier()?;
|
let ident = self.parse_identifier()?;
|
||||||
if i.node.chars().all(|c| c.is_ascii_hexdigit()) {
|
|
||||||
s = i.node;
|
|
||||||
self.span_before = self.span_before.merge(i.span);
|
|
||||||
} else {
|
|
||||||
return Ok(Spanned {
|
return Ok(Spanned {
|
||||||
node: Value::String(format!("#{}", i.node), QuoteKind::None),
|
node: Value::String(format!("#{}", ident.node), QuoteKind::None),
|
||||||
span: i.span,
|
span: ident.span,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
let v = match u32::from_str_radix(&s[1..], 16) {
|
||||||
let v = match u32::from_str_radix(&s, 16) {
|
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(_) => {
|
Err(_) => return Ok(Value::String(s, QuoteKind::None).span(self.span_before)),
|
||||||
return Ok(Value::String(format!("#{}", s), QuoteKind::None).span(self.span_before))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let (red, green, blue, alpha) = match s.len() {
|
let (red, green, blue, alpha) = match s.len().saturating_sub(1) {
|
||||||
3 => (
|
3 => (
|
||||||
(((v & 0x0f00) >> 8) * 0x11) as u8,
|
(((v & 0x0f00) >> 8) * 0x11) as u8,
|
||||||
(((v & 0x00f0) >> 4) * 0x11) as u8,
|
(((v & 0x00f0) >> 4) * 0x11) as u8,
|
||||||
@ -587,7 +584,7 @@ impl<'a> Parser<'a> {
|
|||||||
),
|
),
|
||||||
_ => return Err(("Expected hex digit.", self.span_before).into()),
|
_ => return Err(("Expected hex digit.", self.span_before).into()),
|
||||||
};
|
};
|
||||||
let color = Color::new(red, green, blue, alpha, format!("#{}", s));
|
let color = Color::new(red, green, blue, alpha, s);
|
||||||
Ok(Value::Color(Box::new(color)).span(self.span_before))
|
Ok(Value::Color(Box::new(color)).span(self.span_before))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,3 +582,18 @@ test!(
|
|||||||
"a {\n color: hsl(-1 -1 -1);\n}\n",
|
"a {\n color: hsl(-1 -1 -1);\n}\n",
|
||||||
"a {\n color: black;\n}\n"
|
"a {\n color: black;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
interpolation_after_hash_containing_only_hex_chars,
|
||||||
|
"a {\n color: ##{123};\n color: type-of(##{123});\n}\n",
|
||||||
|
"a {\n color: #123;\n color: string;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
non_hex_chars_after_hash_are_still_touching_hash,
|
||||||
|
"a {\n color: #ooobar;\n}\n",
|
||||||
|
"a {\n color: #ooobar;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
more_than_8_hex_chars_after_hash,
|
||||||
|
"a {\n color: #ffffffffff;\n}\n",
|
||||||
|
"a {\n color: #ffffffffff;\n}\n"
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user