mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
style: Parse the legacy bgcolor
attribute per the HTML5 specification.
Additionally, this patch cleans up some miscellaneous formatting issues.
This commit is contained in:
parent
10f1ed5e31
commit
14bafb11be
19 changed files with 370 additions and 36 deletions
|
@ -7,6 +7,9 @@ authors = ["The Servo Project Developers"]
|
|||
name = "util"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.cssparser]
|
||||
git = "https://github.com/servo/rust-cssparser"
|
||||
|
||||
[dependencies.geom]
|
||||
git = "https://github.com/servo/rust-geom"
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ extern crate log;
|
|||
|
||||
extern crate alloc;
|
||||
extern crate collections;
|
||||
extern crate cssparser;
|
||||
extern crate geom;
|
||||
extern crate getopts;
|
||||
extern crate layers;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
use geometry::Au;
|
||||
|
||||
use cssparser::{mod, RGBAColor};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::from_str::FromStr;
|
||||
use std::iter::Filter;
|
||||
use std::str::{CharEq, CharSplits};
|
||||
|
@ -184,6 +186,137 @@ pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto {
|
|||
}
|
||||
}
|
||||
|
||||
/// A "simple color" per HTML5 § 2.4.6.
|
||||
#[deriving(Show)]
|
||||
pub struct SimpleColor {
|
||||
/// The red component of the color, [0, 255].
|
||||
pub red: u8,
|
||||
/// The green component of the color, [0, 255].
|
||||
pub green: u8,
|
||||
/// The blue component of the color, [0, 255].
|
||||
pub blue: u8,
|
||||
}
|
||||
|
||||
/// Parses a legacy color per HTML5 § 2.4.6. If unparseable, `Err` is returned.
|
||||
pub fn parse_legacy_color(mut input: &str) -> Result<SimpleColor,()> {
|
||||
// Steps 1 and 2.
|
||||
if input.len() == 0 {
|
||||
return Err(())
|
||||
}
|
||||
|
||||
// Step 3.
|
||||
input = input.trim_left_chars(Whitespace).trim_right_chars(Whitespace);
|
||||
|
||||
// Step 4.
|
||||
if input.eq_ignore_ascii_case("transparent") {
|
||||
return Err(())
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
match cssparser::parse_color_keyword(input) {
|
||||
Ok(RGBAColor(rgba)) => {
|
||||
return Ok(SimpleColor {
|
||||
red: (rgba.red * 255.0) as u8,
|
||||
green: (rgba.green * 255.0) as u8,
|
||||
blue: (rgba.blue * 255.0) as u8,
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if input.len() == 4 {
|
||||
match (input.char_at(0),
|
||||
hex(input.char_at(1)),
|
||||
hex(input.char_at(2)),
|
||||
hex(input.char_at(3))) {
|
||||
('#', Ok(r), Ok(g), Ok(b)) => {
|
||||
return Ok(SimpleColor {
|
||||
red: r * 17,
|
||||
green: g * 17,
|
||||
blue: b * 17,
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 7.
|
||||
let mut new_input = String::new();
|
||||
for ch in input.chars() {
|
||||
if ch as u32 > 0xffff {
|
||||
new_input.push_str("00")
|
||||
} else {
|
||||
new_input.push(ch)
|
||||
}
|
||||
}
|
||||
let mut input = new_input.as_slice();
|
||||
|
||||
// Step 8.
|
||||
if input.len() > 128 {
|
||||
input = input.slice_to(128)
|
||||
}
|
||||
|
||||
// Step 9.
|
||||
if input.char_at(0) == '#' {
|
||||
input = input.slice_from(1)
|
||||
}
|
||||
|
||||
// Step 10.
|
||||
let mut new_input = Vec::new();
|
||||
for ch in input.chars() {
|
||||
if hex(ch).is_ok() {
|
||||
new_input.push(ch as u8)
|
||||
} else {
|
||||
new_input.push(b'0')
|
||||
}
|
||||
}
|
||||
let mut input = new_input;
|
||||
|
||||
// Step 11.
|
||||
while input.len() == 0 || (input.len() % 3) != 0 {
|
||||
input.push(b'0')
|
||||
}
|
||||
|
||||
// Step 12.
|
||||
let mut length = input.len() / 3;
|
||||
let (mut red, mut green, mut blue) = (input.slice_to(length),
|
||||
input.slice(length, length * 2),
|
||||
input.slice_from(length * 2));
|
||||
|
||||
// Step 13.
|
||||
if length > 8 {
|
||||
red = red.slice_from(length - 8);
|
||||
green = green.slice_from(length - 8);
|
||||
blue = blue.slice_from(length - 8);
|
||||
length = 8
|
||||
}
|
||||
|
||||
// Step 14.
|
||||
while length > 2 && red[0] == b'0' && green[0] == b'0' && blue[0] == b'0' {
|
||||
red = red.slice_from(1);
|
||||
green = green.slice_from(1);
|
||||
blue = blue.slice_from(1);
|
||||
length -= 1
|
||||
}
|
||||
|
||||
// Steps 15-20.
|
||||
return Ok(SimpleColor {
|
||||
red: (hex(red[0] as char).unwrap() << 4) | hex(red[1] as char).unwrap(),
|
||||
green: (hex(green[0] as char).unwrap() << 4) | hex(green[1] as char).unwrap(),
|
||||
blue: (hex(blue[0] as char).unwrap() << 4) | hex(blue[1] as char).unwrap(),
|
||||
});
|
||||
|
||||
fn hex(ch: char) -> Result<u8,()> {
|
||||
match ch {
|
||||
'0'...'9' => Ok((ch as u8) - b'0'),
|
||||
'a'...'f' => Ok((ch as u8) - b'a' + 10),
|
||||
'A'...'F' => Ok((ch as u8) - b'A' + 10),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[deriving(Clone, Eq, PartialEq, Hash, Show)]
|
||||
pub struct LowercaseString {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue