Skip to content

Commit

Permalink
Implement the unitless length quirk for background-position
Browse files Browse the repository at this point in the history
  • Loading branch information
nox committed Apr 27, 2017
1 parent f68e2fd commit 080f74c
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 19 deletions.
4 changes: 2 additions & 2 deletions components/style/properties/shorthand/background.mako.rs
Expand Up @@ -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());
Expand All @@ -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;
Expand Down
35 changes: 23 additions & 12 deletions components/style/values/specified/length.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -1154,20 +1154,20 @@ 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()) {
Token::Dimension(ref value, ref unit) if num_context.is_ok(value.value) =>
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)
Expand All @@ -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)
}

Expand All @@ -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)
}

Expand All @@ -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)
}
}

Expand Down
17 changes: 17 additions & 0 deletions components/style/values/specified/mod.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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
}
}
31 changes: 26 additions & 5 deletions components/style/values/specified/position.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 080f74c

Please sign in to comment.