From e23648685a4ced8960719d8c0e0d03690af12221 Mon Sep 17 00:00:00 2001 From: Margaret Meyerhofer Date: Thu, 19 Jul 2012 13:13:05 -0700 Subject: [PATCH] servo: Changed color parsing to return an option instead of defaulting to black Source-Repo: https://github.com/servo/servo Source-Revision: 830a41ad94a5d72d96cced9badebbb340784ed7b --- servo/src/servo/parser/css_builder.rs | 19 ++-- servo/src/servo/util/color.rs | 124 +++++++++++++------------- 2 files changed, 74 insertions(+), 69 deletions(-) diff --git a/servo/src/servo/parser/css_builder.rs b/servo/src/servo/parser/css_builder.rs index 81cab772dc72..2f551e5c6c54 100644 --- a/servo/src/servo/parser/css_builder.rs +++ b/servo/src/servo/parser/css_builder.rs @@ -157,16 +157,17 @@ impl parser_methods of parser_methods for TokenReader { alt tok { EndDescription { break; } Description(prop, val) { - alt prop { + let desc = alt prop { // TODO: have color parsing return an option instead of a real value - ~"background-color" { push(desc_list, BackgroundColor(parse_color(val))); } - ~"color" { push(desc_list, TextColor(parse_color(val))); } - ~"display" { parse_display_type(val).map(|res| push(desc_list, Display(res))); } - ~"font-size" { parse_font_size(val).map(|res| push(desc_list, FontSize(res))); } - ~"height" { parse_size(val).map(|res| push(desc_list, Height(res))); } - ~"width" { parse_size(val).map(|res| push(desc_list, Width(res))); } - _ { #debug["Recieved unknown style property '%s'", val]; } - } + ~"background-color" { parse_color(val).map(|res| BackgroundColor(res)) } + ~"color" { parse_color(val).map(|res| TextColor(res)) } + ~"display" { parse_display_type(val).map(|res| Display(res)) } + ~"font-size" { parse_font_size(val).map(|res| FontSize(res)) } + ~"height" { parse_size(val).map(|res| Height(res)) } + ~"width" { parse_size(val).map(|res| Width(res)) } + _ { #debug["Recieved unknown style property '%s'", val]; none } + }; + desc.map(|res| push(desc_list, res)); } Eof { ret none; } StartDescription | Descendant | Child | Sibling | Comma | Element(_) | Attr(_) { diff --git a/servo/src/servo/util/color.rs b/servo/src/servo/util/color.rs index 91bcc3c4ef54..0b2af220b039 100644 --- a/servo/src/servo/util/color.rs +++ b/servo/src/servo/util/color.rs @@ -66,16 +66,14 @@ impl methods for Color { mod parsing { export parse_color; - // TODO, fail by ignoring the rule instead of setting the - // color to black - fn fail_unrecognized(col : ~str) -> Color { + fn fail_unrecognized(col : ~str) -> option { #warn["Unrecognized color %s", col]; - ret black(); + ret none; } #[doc="Match an exact color keyword."] - fn parse_by_name(color : ~str) -> Color { - alt color.to_lower() { + fn parse_by_name(color : ~str) -> option { + let col = alt color.to_lower() { ~"black" { black() } ~"silver" { silver() } ~"gray" { gray() } @@ -93,12 +91,14 @@ mod parsing { ~"blue" { blue() } ~"teal" { teal() } ~"aqua" { aqua() } - _ { fail_unrecognized(color) } - } + _ { ret fail_unrecognized(color) } + }; + + ret some(col); } #[doc="Parses a color specification in the form rgb(foo,bar,baz)"] - fn parse_rgb(color : ~str) -> Color { + fn parse_rgb(color : ~str) -> option { // Shave off the rgb( and the ) let only_colors = color.substr(4u, color.len() - 5u); @@ -108,13 +108,13 @@ mod parsing { alt (u8::from_str(cols[0]), u8::from_str(cols[1]), u8::from_str(cols[2])) { - (some(r), some(g), some(b)) { rgb(r, g, b) } - _ { fail_unrecognized(color) } + (some(r), some(g), some(b)) { some(rgb(r, g, b)) } + _ { fail_unrecognized(color) } } } #[doc="Parses a color specification in the form rgba(foo,bar,baz,qux)"] - fn parse_rgba(color : ~str) -> Color { + fn parse_rgba(color : ~str) -> option { // Shave off the rgba( and the ) let only_vals = color.substr(5u, color.len() - 6u); @@ -124,13 +124,13 @@ mod parsing { alt (u8::from_str(cols[0]), u8::from_str(cols[1]), u8::from_str(cols[2]), float::from_str(cols[3])) { - (some(r), some(g), some(b), some(a)) { rgba(r, g, b, a) } + (some(r), some(g), some(b), some(a)) { some(rgba(r, g, b, a)) } _ { fail_unrecognized(color) } } } #[doc="Parses a color specification in the form hsl(foo,bar,baz)"] - fn parse_hsl(color : ~str) -> Color { + fn parse_hsl(color : ~str) -> option { // Shave off the hsl( and the ) let only_vals = color.substr(4u, color.len() - 5u); @@ -140,13 +140,13 @@ mod parsing { alt (float::from_str(vals[0]), float::from_str(vals[1]), float::from_str(vals[2])) { - (some(h), some(s), some(l)) { hsl(h, s, l) } - _ { fail_unrecognized(color) } + (some(h), some(s), some(l)) { some(hsl(h, s, l)) } + _ { fail_unrecognized(color) } } } #[doc="Parses a color specification in the form hsla(foo,bar,baz,qux)"] - fn parse_hsla(color : ~str) -> Color { + fn parse_hsla(color : ~str) -> option { // Shave off the hsla( and the ) let only_vals = color.substr(5u, color.len() - 6u); @@ -155,7 +155,7 @@ mod parsing { alt (float::from_str(vals[0]), float::from_str(vals[1]), float::from_str(vals[2]), float::from_str(vals[3])) { - (some(h), some(s), some(l), some(a)) { hsla(h, s, l, a) } + (some(h), some(s), some(l), some(a)) { some(hsla(h, s, l, a)) } _ { fail_unrecognized(color) } } } @@ -163,13 +163,13 @@ mod parsing { // Currently colors are supported in rgb(a,b,c) form and also by // keywords for several common colors. // TODO: extend this - fn parse_color(color : ~str) -> Color { + fn parse_color(color : ~str) -> option { alt color { c if c.starts_with(~"rgb(") { parse_rgb(c) } c if c.starts_with(~"rgba(") { parse_rgba(c) } c if c.starts_with(~"hsl(") { parse_hsl(c) } c if c.starts_with(~"hsla(") { parse_hsla(c) } - c { parse_by_name(c) } + c { parse_by_name(c) } } } } @@ -177,58 +177,62 @@ mod parsing { #[cfg(test)] mod test { import css_colors::*; + import option::unwrap; import parsing::parse_color; #[test] fn test_parse_by_name() { - assert red().eq(parse_color(~"red")); - assert lime().eq(parse_color(~"Lime")); - assert blue().eq(parse_color(~"BLUE")); - assert green().eq(parse_color(~"GreEN")); - assert white().eq(parse_color(~"white")); - assert black().eq(parse_color(~"Black")); - assert gray().eq(parse_color(~"Gray")); - assert silver().eq(parse_color(~"SiLvEr")); - assert maroon().eq(parse_color(~"maroon")); - assert purple().eq(parse_color(~"PURPLE")); - assert fuchsia().eq(parse_color(~"FUCHSIA")); - assert olive().eq(parse_color(~"oLiVe")); - assert yellow().eq(parse_color(~"yellow")); - assert navy().eq(parse_color(~"NAVY")); - assert teal().eq(parse_color(~"Teal")); - assert aqua().eq(parse_color(~"Aqua")); + assert red().eq(unwrap(parse_color(~"red"))); + assert lime().eq(unwrap(parse_color(~"Lime"))); + assert blue().eq(unwrap(parse_color(~"BLUE"))); + assert green().eq(unwrap(parse_color(~"GreEN"))); + assert white().eq(unwrap(parse_color(~"white"))); + assert black().eq(unwrap(parse_color(~"Black"))); + assert gray().eq(unwrap(parse_color(~"Gray"))); + assert silver().eq(unwrap(parse_color(~"SiLvEr"))); + assert maroon().eq(unwrap(parse_color(~"maroon"))); + assert purple().eq(unwrap(parse_color(~"PURPLE"))); + assert fuchsia().eq(unwrap(parse_color(~"FUCHSIA"))); + assert olive().eq(unwrap(parse_color(~"oLiVe"))); + assert yellow().eq(unwrap(parse_color(~"yellow"))); + assert navy().eq(unwrap(parse_color(~"NAVY"))); + assert teal().eq(unwrap(parse_color(~"Teal"))); + assert aqua().eq(unwrap(parse_color(~"Aqua"))); + assert none == parse_color(~"foobarbaz"); } #[test] fn test_parsing_rgb() { - assert red().eq(parse_color(~"rgb(255,0,0)")); - assert red().eq(parse_color(~"rgba(255,0,0,1.0)")); - assert red().eq(parse_color(~"rgba(255,0,0,1)")); - assert lime().eq(parse_color(~"rgba(0,255,0,1.00)")); - assert rgb(1u8,2u8,3u8).eq(parse_color(~"rgb(1,2,03)")); - assert rgba(15u8,250u8,3u8,0.5).eq(parse_color(~"rgba(15,250,3,.5)")); - assert rgba(15u8,250u8,3u8,0.5).eq(parse_color(~"rgba(15,250,3,0.5)")); + assert red().eq(unwrap(parse_color(~"rgb(255,0,0)"))); + assert red().eq(unwrap(parse_color(~"rgba(255,0,0,1.0)"))); + assert red().eq(unwrap(parse_color(~"rgba(255,0,0,1)"))); + assert lime().eq(unwrap(parse_color(~"rgba(0,255,0,1.00)"))); + assert rgb(1u8,2u8,3u8).eq(unwrap(parse_color(~"rgb(1,2,03)"))); + assert rgba(15u8,250u8,3u8,0.5).eq(unwrap(parse_color(~"rgba(15,250,3,.5)"))); + assert rgba(15u8,250u8,3u8,0.5).eq(unwrap(parse_color(~"rgba(15,250,3,0.5)"))); + assert none == parse_color(~"rbga(1,2,3)"); } #[test] fn test_parsing_hsl() { - assert red().eq(parse_color(~"hsl(0,1,.5)")); - assert lime().eq(parse_color(~"hsl(120.0,1.0,.5)")); - assert blue().eq(parse_color(~"hsl(240.0,1.0,.5)")); - assert green().eq(parse_color(~"hsl(120.0,1.0,.25)")); - assert white().eq(parse_color(~"hsl(1.0,1.,1.0)")); - assert white().eq(parse_color(~"hsl(129.0,0.3,1.0)")); - assert black().eq(parse_color(~"hsl(231.2,0.75,0.0)")); - assert black().eq(parse_color(~"hsl(11.2,0.0,0.0)")); - assert gray().eq(parse_color(~"hsl(0.0,0.0,0.5)")); - assert maroon().eq(parse_color(~"hsl(0.0,1.0,0.25)")); - assert purple().eq(parse_color(~"hsl(300.0,1.0,0.25)")); - assert fuchsia().eq(parse_color(~"hsl(300,1.0,0.5)")); - assert olive().eq(parse_color(~"hsl(60.,1.0,0.25)")); - assert yellow().eq(parse_color(~"hsl(60.,1.0,0.5)")); - assert navy().eq(parse_color(~"hsl(240.0,1.0,.25)")); - assert teal().eq(parse_color(~"hsl(180.0,1.0,.25)")); - assert aqua().eq(parse_color(~"hsl(180.0,1.0,.5)")); + assert red().eq(unwrap(parse_color(~"hsl(0,1,.5)"))); + assert lime().eq(unwrap(parse_color(~"hsl(120.0,1.0,.5)"))); + assert blue().eq(unwrap(parse_color(~"hsl(240.0,1.0,.5)"))); + assert green().eq(unwrap(parse_color(~"hsl(120.0,1.0,.25)"))); + assert white().eq(unwrap(parse_color(~"hsl(1.0,1.,1.0)"))); + assert white().eq(unwrap(parse_color(~"hsl(129.0,0.3,1.0)"))); + assert black().eq(unwrap(parse_color(~"hsl(231.2,0.75,0.0)"))); + assert black().eq(unwrap(parse_color(~"hsl(11.2,0.0,0.0)"))); + assert gray().eq(unwrap(parse_color(~"hsl(0.0,0.0,0.5)"))); + assert maroon().eq(unwrap(parse_color(~"hsl(0.0,1.0,0.25)"))); + assert purple().eq(unwrap(parse_color(~"hsl(300.0,1.0,0.25)"))); + assert fuchsia().eq(unwrap(parse_color(~"hsl(300,1.0,0.5)"))); + assert olive().eq(unwrap(parse_color(~"hsl(60.,1.0,0.25)"))); + assert yellow().eq(unwrap(parse_color(~"hsl(60.,1.0,0.5)"))); + assert navy().eq(unwrap(parse_color(~"hsl(240.0,1.0,.25)"))); + assert teal().eq(unwrap(parse_color(~"hsl(180.0,1.0,.25)"))); + assert aqua().eq(unwrap(parse_color(~"hsl(180.0,1.0,.5)"))); + assert none == parse_color(~"hsl(1,2,3,.4)"); } }