diff options
author | Anthony Ramine <n.oxyde@gmail.com> | 2017-05-14 23:12:25 +0200 |
---|---|---|
committer | Anthony Ramine <n.oxyde@gmail.com> | 2017-05-17 14:12:58 +0200 |
commit | 9964b328b13ed46f0f4310006925a0feac96fe6f (patch) | |
tree | 6a07b0a4fa284ad4a57a734d7596554535861dca | |
parent | 1afc89e944c7ea7e4510b4b678a95a8faaa309b1 (diff) | |
download | servo-9964b328b13ed46f0f4310006925a0feac96fe6f.tar.gz servo-9964b328b13ed46f0f4310006925a0feac96fe6f.zip |
Implement the hashless color quirk (fixes #15341)
-rw-r--r-- | Cargo.lock | 31 | ||||
-rw-r--r-- | components/style/Cargo.toml | 3 | ||||
-rw-r--r-- | components/style/lib.rs | 1 | ||||
-rw-r--r-- | components/style/properties/longhand/background.mako.rs | 4 | ||||
-rw-r--r-- | components/style/properties/longhand/border.mako.rs | 4 | ||||
-rw-r--r-- | components/style/properties/longhand/color.mako.rs | 4 | ||||
-rw-r--r-- | components/style/properties/shorthand/background.mako.rs | 8 | ||||
-rw-r--r-- | components/style/values/specified/color.rs | 14 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 80 | ||||
-rw-r--r-- | tests/wpt/metadata/quirks-mode/supports.html.ini | 3 |
10 files changed, 119 insertions, 33 deletions
diff --git a/Cargo.lock b/Cargo.lock index 7eea47f577f..158191ba7cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,7 +299,7 @@ version = "0.0.1" dependencies = [ "azure 0.15.0 (git+https://github.com/servo/rust-azure)", "canvas_traits 0.0.1", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -314,7 +314,7 @@ dependencies = [ name = "canvas_traits" version = "0.0.1" dependencies = [ - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -528,7 +528,7 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -959,7 +959,7 @@ name = "geckoservo" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1024,7 +1024,7 @@ dependencies = [ name = "gfx_tests" version = "0.0.1" dependencies = [ - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "gfx 0.0.1", "ipc-channel 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", @@ -1366,7 +1366,7 @@ dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "gfx 0.0.1", @@ -1700,7 +1700,7 @@ name = "msg" version = "0.0.1" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2299,7 +2299,7 @@ dependencies = [ "caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "deny_public_fields 0.0.1", "devtools_traits 0.0.1", "dom_struct 0.0.1", @@ -2368,7 +2368,7 @@ dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "heapsize 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2439,7 +2439,7 @@ name = "selectors" version = "0.18.0" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2792,13 +2792,14 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2832,7 +2833,7 @@ version = "0.0.1" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2851,7 +2852,7 @@ name = "style_traits" version = "0.0.1" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2864,7 +2865,7 @@ name = "stylo_tests" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "geckoservo 0.0.1", @@ -3416,7 +3417,7 @@ dependencies = [ "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624" "checksum core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ead017dcf77f503dc991f6b52de6084eeea60a94b0a652baa9bf88654a28e83f" "checksum core-text 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9719616a10f717628e074744f8c55df7b450f7a34d29c196d14f4498aad05d" -"checksum cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d2214de0e040001626d6a36020538d4b35a07cb260fcad0cf64f61fd1857e0e" +"checksum cssparser 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc7bd2a41b9c6c66456ac709d9efead1deb390d2c252c59e0ddfff9cdf0c94" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum dbus 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47f881971824401c27bc1ff9f641d54ac66e0f409631806fa7be8cad8e6be450" diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 57bc8e31a97..708488861e8 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -29,12 +29,13 @@ bitflags = "0.7" bit-vec = "0.4.3" byteorder = "1.0" cfg-if = "0.1.0" -cssparser = "0.13.3" +cssparser = "0.13.5" encoding = {version = "0.2", optional = true} euclid = "0.11" fnv = "1.0" heapsize = {version = "0.3.0", optional = true} heapsize_derive = {version = "0.1", optional = true} +itoa = "0.3" html5ever = {version = "0.16", optional = true} lazy_static = "0.2" log = "0.3" diff --git a/components/style/lib.rs b/components/style/lib.rs index 91c8727a2e7..4210304217f 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -50,6 +50,7 @@ extern crate fnv; #[cfg(feature = "gecko")] #[macro_use] pub mod gecko_string_cache; #[cfg(feature = "servo")] extern crate heapsize; #[cfg(feature = "servo")] #[macro_use] extern crate heapsize_derive; +extern crate itoa; #[cfg(feature = "servo")] #[macro_use] extern crate html5ever; #[macro_use] extern crate lazy_static; diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index e5c3d628f64..3b41a5714cf 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -10,7 +10,9 @@ ${helpers.predefined_type("background-color", "CSSColor", "::cssparser::Color::RGBA(::cssparser::RGBA::transparent())", initial_specified_value="SpecifiedValue::transparent()", spec="https://drafts.csswg.org/css-backgrounds/#background-color", - animation_value_type="IntermediateColor", complex_color=True)} + animation_value_type="IntermediateColor", + complex_color=True, + allow_quirks=True)} ${helpers.predefined_type("background-image", "ImageLayer", initial_value="Either::First(None_)", diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index f18ae154428..e5270e30fb9 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -20,7 +20,9 @@ "::cssparser::Color::CurrentColor", alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-color"), spec=maybe_logical_spec(side, "color"), - animation_value_type="IntermediateColor", logical = side[1])} + animation_value_type="IntermediateColor", + logical=side[1], + allow_quirks=not side[1])} ${helpers.predefined_type("border-%s-style" % side[0], "BorderStyle", "specified::BorderStyle::none", diff --git a/components/style/properties/longhand/color.mako.rs b/components/style/properties/longhand/color.mako.rs index 0a5dd2f8d63..e4c3ef4b1fb 100644 --- a/components/style/properties/longhand/color.mako.rs +++ b/components/style/properties/longhand/color.mako.rs @@ -14,7 +14,7 @@ use cssparser::RGBA; use std::fmt; use style_traits::ToCss; - use values::specified::{Color, CSSColor, CSSRGBA}; + use values::specified::{AllowQuirks, Color, CSSColor, CSSRGBA}; impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -50,7 +50,7 @@ RGBA::new(0, 0, 0, 255) // black } pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - CSSColor::parse(context, input).map(SpecifiedValue) + CSSColor::parse_quirky(context, input, AllowQuirks::Yes).map(SpecifiedValue) } // FIXME(#15973): Add servo support for system colors diff --git a/components/style/properties/shorthand/background.mako.rs b/components/style/properties/shorthand/background.mako.rs index 7732a84ff73..89874f82084 100644 --- a/components/style/properties/shorthand/background.mako.rs +++ b/components/style/properties/shorthand/background.mako.rs @@ -10,12 +10,12 @@ background-attachment background-image background-size background-origin background-clip" spec="https://drafts.csswg.org/css-backgrounds/#the-background"> - use properties::longhands::{background_color, background_position_x, background_position_y, background_repeat}; + use properties::longhands::{background_position_x, background_position_y, background_repeat}; use properties::longhands::{background_attachment, background_image, background_size, background_origin}; use properties::longhands::background_clip; use properties::longhands::background_clip::single_value::computed_value::T as Clip; use properties::longhands::background_origin::single_value::computed_value::T as Origin; - use values::specified::{Position, PositionComponent}; + use values::specified::{CSSColor, Position, PositionComponent}; use parser::Parse; impl From<background_origin::single_value::SpecifiedValue> for background_clip::single_value::SpecifiedValue { @@ -43,7 +43,7 @@ let mut ${name} = None; % endfor loop { - if let Ok(value) = input.try(|input| background_color::parse(context, input)) { + if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) { if background_color.is_none() { background_color = Some(value); continue @@ -109,7 +109,7 @@ })); Ok(Longhands { - background_color: unwrap_or_initial!(background_color), + background_color: background_color.unwrap_or(CSSColor::transparent()), background_image: background_image, background_position_x: background_position_x, background_position_y: background_position_y, diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index 4c0d50f0e54..0599563a494 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -53,13 +53,19 @@ mod gecko { no_viewport_percentage!(Color); + impl From<CSSParserColor> for Color { + fn from(value: CSSParserColor) -> Self { + match value { + CSSParserColor::CurrentColor => Color::CurrentColor, + CSSParserColor::RGBA(x) => Color::RGBA(x), + } + } + } + impl Parse for Color { fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> { if let Ok(value) = input.try(CSSParserColor::parse) { - match value { - CSSParserColor::CurrentColor => Ok(Color::CurrentColor), - CSSParserColor::RGBA(x) => Ok(Color::RGBA(x)), - } + Ok(value.into()) } else if let Ok(system) = input.try(SystemColor::parse) { Ok(Color::System(system)) } else { diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 04df41c542a..8726cb15334 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -10,12 +10,14 @@ use app_units::Au; use context::QuirksMode; use cssparser::{self, Parser, Token}; use euclid::size::Size2D; +use itoa; use parser::{ParserContext, Parse}; use self::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize}; use self::url::SpecifiedUrl; use std::ascii::AsciiExt; use std::f32; use std::fmt; +use std::io::Write; use style_traits::ToCss; use style_traits::values::specified::AllowedNumericType; use super::{Auto, CSSFloat, CSSInteger, HasViewportPercentage, Either, None_}; @@ -85,15 +87,89 @@ pub struct CSSColor { impl Parse for CSSColor { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + Self::parse_quirky(context, input, AllowQuirks::No) + } +} + +impl CSSColor { + /// Parse a color, with quirks. + /// + /// https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk + pub fn parse_quirky(context: &ParserContext, + input: &mut Parser, + allow_quirks: AllowQuirks) + -> Result<Self, ()> { let start_position = input.position(); let authored = match input.next() { Ok(Token::Ident(s)) => Some(s.into_owned().into_boxed_str()), _ => None, }; input.reset(start_position); + if let Ok(parsed) = input.try(|i| Parse::parse(context, i)) { + return Ok(CSSColor { + parsed: parsed, + authored: authored, + }); + } + if !allow_quirks.allowed(context.quirks_mode) { + return Err(()); + } + let (number, dimension) = match input.next()? { + Token::Number(number) => { + (number, None) + }, + Token::Dimension(number, dimension) => { + (number, Some(dimension)) + }, + Token::Ident(ident) => { + if ident.len() != 3 && ident.len() != 6 { + return Err(()); + } + return cssparser::Color::parse_hash(ident.as_bytes()).map(|color| { + Self { + parsed: color.into(), + authored: None + } + }); + } + _ => { + return Err(()); + }, + }; + let value = number.int_value.ok_or(())?; + if value < 0 { + return Err(()); + } + let length = if value <= 9 { + 1 + } else if value <= 99 { + 2 + } else if value <= 999 { + 3 + } else if value <= 9999 { + 4 + } else if value <= 99999 { + 5 + } else if value <= 999999 { + 6 + } else { + return Err(()) + }; + let total = length + dimension.as_ref().map_or(0, |d| d.len()); + if total > 6 { + return Err(()); + } + let mut serialization = [b'0'; 6]; + let space_padding = 6 - total; + let mut written = space_padding; + written += itoa::write(&mut serialization[written..], value).unwrap(); + if let Some(dimension) = dimension { + written += (&mut serialization[written..]).write(dimension.as_bytes()).unwrap(); + } + debug_assert!(written == 6); Ok(CSSColor { - parsed: try!(Parse::parse(context, input)), - authored: authored, + parsed: cssparser::Color::parse_hash(&serialization).map(From::from)?, + authored: None, }) } } diff --git a/tests/wpt/metadata/quirks-mode/supports.html.ini b/tests/wpt/metadata/quirks-mode/supports.html.ini index d3fb177270f..f1968d02eba 100644 --- a/tests/wpt/metadata/quirks-mode/supports.html.ini +++ b/tests/wpt/metadata/quirks-mode/supports.html.ini @@ -1,8 +1,5 @@ [supports.html] type: testharness - [@supports quirky color] - expected: FAIL - [Sanity check @supports length] expected: FAIL |