aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2017-05-14 23:12:25 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2017-05-17 14:12:58 +0200
commit9964b328b13ed46f0f4310006925a0feac96fe6f (patch)
tree6a07b0a4fa284ad4a57a734d7596554535861dca
parent1afc89e944c7ea7e4510b4b678a95a8faaa309b1 (diff)
downloadservo-9964b328b13ed46f0f4310006925a0feac96fe6f.tar.gz
servo-9964b328b13ed46f0f4310006925a0feac96fe6f.zip
Implement the hashless color quirk (fixes #15341)
-rw-r--r--Cargo.lock31
-rw-r--r--components/style/Cargo.toml3
-rw-r--r--components/style/lib.rs1
-rw-r--r--components/style/properties/longhand/background.mako.rs4
-rw-r--r--components/style/properties/longhand/border.mako.rs4
-rw-r--r--components/style/properties/longhand/color.mako.rs4
-rw-r--r--components/style/properties/shorthand/background.mako.rs8
-rw-r--r--components/style/values/specified/color.rs14
-rw-r--r--components/style/values/specified/mod.rs80
-rw-r--r--tests/wpt/metadata/quirks-mode/supports.html.ini3
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