mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
Implement the unitless length quirk for background-position
This commit is contained in:
parent
f68e2fded9
commit
080f74ca63
4 changed files with 68 additions and 19 deletions
|
@ -194,8 +194,8 @@
|
|||
sub_properties="background-position-x background-position-y"
|
||||
spec="https://drafts.csswg.org/css-backgrounds-4/#the-background-position">
|
||||
use properties::longhands::{background_position_x,background_position_y};
|
||||
use values::specified::AllowQuirks;
|
||||
use values::specified::position::Position;
|
||||
use parser::Parse;
|
||||
|
||||
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||
let mut position_x = background_position_x::SpecifiedValue(Vec::new());
|
||||
|
@ -204,7 +204,7 @@
|
|||
|
||||
try!(input.parse_comma_separated(|input| {
|
||||
loop {
|
||||
if let Ok(value) = input.try(|input| Position::parse(context, input)) {
|
||||
if let Ok(value) = input.try(|input| Position::parse_quirky(context, input, AllowQuirks::Yes)) {
|
||||
position_x.0.push(value.horizontal);
|
||||
position_y.0.push(value.vertical);
|
||||
any = true;
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::ops::Mul;
|
|||
use style_traits::ToCss;
|
||||
use style_traits::values::specified::AllowedLengthType;
|
||||
use stylesheets::CssRuleType;
|
||||
use super::{Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time, ToComputedValue};
|
||||
use super::{AllowQuirks, Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time, ToComputedValue};
|
||||
use values::{Auto, CSSFloat, Either, FONT_MEDIUM_PX, HasViewportPercentage, None_, Normal};
|
||||
use values::ExtremumLength;
|
||||
use values::computed::{ComputedValueAsSpecified, Context};
|
||||
|
@ -1154,7 +1154,10 @@ impl LengthOrPercentage {
|
|||
LengthOrPercentage::Length(NoCalcLength::zero())
|
||||
}
|
||||
|
||||
fn parse_internal(context: &ParserContext, input: &mut Parser, num_context: AllowedLengthType)
|
||||
fn parse_internal(context: &ParserContext,
|
||||
input: &mut Parser,
|
||||
num_context: AllowedLengthType,
|
||||
allow_quirks: AllowQuirks)
|
||||
-> Result<LengthOrPercentage, ()>
|
||||
{
|
||||
match try!(input.next()) {
|
||||
|
@ -1162,12 +1165,9 @@ impl LengthOrPercentage {
|
|||
NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentage::Length),
|
||||
Token::Percentage(ref value) if num_context.is_ok(value.unit_value) =>
|
||||
Ok(LengthOrPercentage::Percentage(Percentage(value.unit_value))),
|
||||
Token::Number(ref value) => {
|
||||
if value.value != 0. && !context.length_parsing_mode.allows_unitless_lengths() {
|
||||
return Err(())
|
||||
}
|
||||
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(AbsoluteLength::Px(value.value))))
|
||||
}
|
||||
Token::Number(value) if value.value == 0. ||
|
||||
(num_context.is_ok(value.value) && allow_quirks.allowed(context.quirks_mode)) =>
|
||||
Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value.value))),
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||
let calc = try!(input.parse_nested_block(|i| {
|
||||
CalcLengthOrPercentage::parse_length_or_percentage(context, i)
|
||||
|
@ -1181,14 +1181,14 @@ impl LengthOrPercentage {
|
|||
/// Parse a non-negative length.
|
||||
#[inline]
|
||||
pub fn parse_non_negative(context: &ParserContext, input: &mut Parser) -> Result<LengthOrPercentage, ()> {
|
||||
Self::parse_internal(context, input, AllowedLengthType::NonNegative)
|
||||
Self::parse_internal(context, input, AllowedLengthType::NonNegative, AllowQuirks::No)
|
||||
}
|
||||
|
||||
/// Parse a length, treating dimensionless numbers as pixels
|
||||
///
|
||||
/// https://www.w3.org/TR/SVG2/types.html#presentation-attribute-css-value
|
||||
pub fn parse_numbers_are_pixels(context: &ParserContext, input: &mut Parser) -> Result<LengthOrPercentage, ()> {
|
||||
if let Ok(lop) = input.try(|i| Self::parse_internal(context, i, AllowedLengthType::All)) {
|
||||
if let Ok(lop) = input.try(|i| Self::parse(context, i)) {
|
||||
return Ok(lop)
|
||||
}
|
||||
|
||||
|
@ -1204,7 +1204,7 @@ impl LengthOrPercentage {
|
|||
pub fn parse_numbers_are_pixels_non_negative(context: &ParserContext,
|
||||
input: &mut Parser)
|
||||
-> Result<LengthOrPercentage, ()> {
|
||||
if let Ok(lop) = input.try(|i| Self::parse_internal(context, i, AllowedLengthType::NonNegative)) {
|
||||
if let Ok(lop) = input.try(|i| Self::parse_non_negative(context, i)) {
|
||||
return Ok(lop)
|
||||
}
|
||||
|
||||
|
@ -1230,7 +1230,18 @@ impl LengthOrPercentage {
|
|||
impl Parse for LengthOrPercentage {
|
||||
#[inline]
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
Self::parse_internal(context, input, AllowedLengthType::All)
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
||||
impl LengthOrPercentage {
|
||||
/// Parses a length or a percentage, allowing the unitless length quirk.
|
||||
/// https://quirks.spec.whatwg.org/#the-unitless-length-quirk
|
||||
#[inline]
|
||||
pub fn parse_quirky(context: &ParserContext,
|
||||
input: &mut Parser,
|
||||
allow_quirks: AllowQuirks) -> Result<Self, ()> {
|
||||
Self::parse_internal(context, input, AllowedLengthType::All, allow_quirks)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//! TODO(emilio): Enhance docs.
|
||||
|
||||
use app_units::Au;
|
||||
use context::QuirksMode;
|
||||
use cssparser::{self, Parser, Token};
|
||||
use euclid::size::Size2D;
|
||||
use parser::{ParserContext, Parse};
|
||||
|
@ -1326,3 +1327,19 @@ pub type ClipRectOrAuto = Either<ClipRect, Auto>;
|
|||
|
||||
/// <color> | auto
|
||||
pub type ColorOrAuto = Either<CSSColor, Auto>;
|
||||
|
||||
/// Whether quirks are allowed in this context.
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum AllowQuirks {
|
||||
/// Quirks are allowed.
|
||||
Yes,
|
||||
/// Quirks are not allowed.
|
||||
No,
|
||||
}
|
||||
|
||||
impl AllowQuirks {
|
||||
/// Returns `true` if quirks are allowed in this context.
|
||||
pub fn allowed(self, quirks_mode: QuirksMode) -> bool {
|
||||
self == AllowQuirks::Yes && quirks_mode == QuirksMode::Quirks
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ use values::computed::position as computed_position;
|
|||
use values::generics::position::{Position as GenericPosition, PositionValue, PositionWithKeyword};
|
||||
use values::generics::position::HorizontalPosition as GenericHorizontalPosition;
|
||||
use values::generics::position::VerticalPosition as GenericVerticalPosition;
|
||||
use values::specified::{LengthOrPercentage, Percentage};
|
||||
use values::specified::{AllowQuirks, LengthOrPercentage, Percentage};
|
||||
|
||||
pub use values::generics::position::Keyword;
|
||||
|
||||
|
@ -132,13 +132,23 @@ impl Position {
|
|||
|
||||
impl Parse for Position {
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
let first = input.try(|i| PositionComponent::parse(context, i))?;
|
||||
let second = input.try(|i| PositionComponent::parse(context, i))
|
||||
Position::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
||||
impl Position {
|
||||
/// Parses, with quirks.
|
||||
pub fn parse_quirky(context: &ParserContext,
|
||||
input: &mut Parser,
|
||||
allow_quirks: AllowQuirks)
|
||||
-> Result<Self, ()> {
|
||||
let first = input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks))?;
|
||||
let second = input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks))
|
||||
.unwrap_or(Either::Second(Keyword::Center));
|
||||
|
||||
if let Ok(third) = input.try(|i| PositionComponent::parse(context, i)) {
|
||||
if let Ok(third) = input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks)) {
|
||||
// There's a 3rd value.
|
||||
if let Ok(fourth) = input.try(|i| PositionComponent::parse(context, i)) {
|
||||
if let Ok(fourth) = input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks)) {
|
||||
// There's a 4th value.
|
||||
Position::from_components(Some(second), Some(fourth), Some(first), Some(third))
|
||||
} else {
|
||||
|
@ -173,6 +183,17 @@ impl Parse for Position {
|
|||
}
|
||||
}
|
||||
|
||||
impl PositionComponent {
|
||||
/// Parses, with quirks.
|
||||
fn parse_quirky(context: &ParserContext,
|
||||
input: &mut Parser,
|
||||
allow_quirks: AllowQuirks) -> Result<Self, ()> {
|
||||
input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
|
||||
.map(Either::First)
|
||||
.or_else(|()| input.try(Keyword::parse).map(Either::Second))
|
||||
}
|
||||
}
|
||||
|
||||
impl PositionValue<LengthOrPercentage> {
|
||||
/// Generic function for the computed value of a position.
|
||||
fn computed_value(&self, context: &Context) -> ComputedLengthOrPercentage {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue