mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Implement the hashless color quirk (fixes #15341)
This commit is contained in:
parent
1afc89e944
commit
9964b328b1
10 changed files with 119 additions and 33 deletions
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_)",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue