Make AllowedLengthType.is_ok() returning true if parsing mode allows all numeric values.

Even if the type is NonNegative and the given value is a negative.
This commit is contained in:
Hiroyuki Ikezoe 2017-06-14 09:51:53 +09:00
parent 8bfed4cb3c
commit 7341574b66
3 changed files with 26 additions and 17 deletions

View file

@ -611,9 +611,9 @@ impl Length {
-> Result<Length, ParseError<'i>> { -> Result<Length, ParseError<'i>> {
let token = try!(input.next()); let token = try!(input.next());
match token { match token {
Token::Dimension(ref value, ref unit) if num_context.is_ok(value.value) => Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
Length::parse_dimension(context, value.value, unit), Length::parse_dimension(context, value.value, unit),
Token::Number(ref value) if num_context.is_ok(value.value) => { Token::Number(ref value) if num_context.is_ok(context.parsing_mode, value.value) => {
if value.value != 0. && if value.value != 0. &&
!context.parsing_mode.allows_unitless_lengths() && !context.parsing_mode.allows_unitless_lengths() &&
!allow_quirks.allowed(context.quirks_mode) { !allow_quirks.allowed(context.quirks_mode) {
@ -801,11 +801,11 @@ impl LengthOrPercentage {
{ {
let token = try!(input.next()); let token = try!(input.next());
match token { match token {
Token::Dimension(ref value, ref unit) if num_context.is_ok(value.value) => Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentage::Length), NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentage::Length),
Token::Percentage(ref value) if num_context.is_ok(value.unit_value) => Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) =>
return Ok(LengthOrPercentage::Percentage(Percentage(value.unit_value))), return Ok(LengthOrPercentage::Percentage(Percentage(value.unit_value))),
Token::Number(value) if num_context.is_ok(value.value) => { Token::Number(value) if num_context.is_ok(context.parsing_mode, value.value) => {
if value.value != 0. && if value.value != 0. &&
!context.parsing_mode.allows_unitless_lengths() && !context.parsing_mode.allows_unitless_lengths() &&
!allow_quirks.allowed(context.quirks_mode) { !allow_quirks.allowed(context.quirks_mode) {
@ -935,11 +935,11 @@ impl LengthOrPercentageOrAuto {
-> Result<Self, ParseError<'i>> { -> Result<Self, ParseError<'i>> {
let token = try!(input.next()); let token = try!(input.next());
match token { match token {
Token::Dimension(ref value, ref unit) if num_context.is_ok(value.value) => Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentageOrAuto::Length), NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentageOrAuto::Length),
Token::Percentage(ref value) if num_context.is_ok(value.unit_value) => Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) =>
Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))), Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))),
Token::Number(ref value) if num_context.is_ok(value.value) => { Token::Number(ref value) if num_context.is_ok(context.parsing_mode, value.value) => {
if value.value != 0. && if value.value != 0. &&
!context.parsing_mode.allows_unitless_lengths() && !context.parsing_mode.allows_unitless_lengths() &&
!allow_quirks.allowed(context.quirks_mode) { !allow_quirks.allowed(context.quirks_mode) {
@ -1031,11 +1031,11 @@ impl LengthOrPercentageOrNone {
{ {
let token = try!(input.next()); let token = try!(input.next());
match token { match token {
Token::Dimension(ref value, ref unit) if num_context.is_ok(value.value) => Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentageOrNone::Length), NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentageOrNone::Length),
Token::Percentage(ref value) if num_context.is_ok(value.unit_value) => Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) =>
Ok(LengthOrPercentageOrNone::Percentage(Percentage(value.unit_value))), Ok(LengthOrPercentageOrNone::Percentage(Percentage(value.unit_value))),
Token::Number(value) if num_context.is_ok(value.value) => { Token::Number(value) if num_context.is_ok(context.parsing_mode, value.value) => {
if value.value != 0. && !context.parsing_mode.allows_unitless_lengths() && if value.value != 0. && !context.parsing_mode.allows_unitless_lengths() &&
!allow_quirks.allowed(context.quirks_mode) { !allow_quirks.allowed(context.quirks_mode) {
return Err(StyleParseError::UnspecifiedError.into()) return Err(StyleParseError::UnspecifiedError.into())
@ -1113,10 +1113,10 @@ impl LengthOrPercentageOrAutoOrContent {
let num_context = AllowedLengthType::NonNegative; let num_context = AllowedLengthType::NonNegative;
let token = try!(input.next()); let token = try!(input.next());
match token { match token {
Token::Dimension(ref value, ref unit) if num_context.is_ok(value.value) => Token::Dimension(ref value, ref unit) if num_context.is_ok(context.parsing_mode, value.value) =>
NoCalcLength::parse_dimension(context, value.value, unit) NoCalcLength::parse_dimension(context, value.value, unit)
.map(LengthOrPercentageOrAutoOrContent::Length), .map(LengthOrPercentageOrAutoOrContent::Length),
Token::Percentage(ref value) if num_context.is_ok(value.unit_value) => Token::Percentage(ref value) if num_context.is_ok(context.parsing_mode, value.unit_value) =>
Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))), Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))),
Token::Number(ref value) if value.value == 0. => Token::Number(ref value) if value.value == 0. =>
Ok(Self::zero()), Ok(Self::zero()),

View file

@ -204,6 +204,7 @@ macro_rules! __define_css_keyword_enum__actual {
/// Helper types for the handling of specified values. /// Helper types for the handling of specified values.
pub mod specified { pub mod specified {
use ParsingMode;
use app_units::Au; use app_units::Au;
use std::cmp; use std::cmp;
@ -228,7 +229,10 @@ pub mod specified {
impl AllowedLengthType { impl AllowedLengthType {
/// Whether value is valid for this allowed length type. /// Whether value is valid for this allowed length type.
#[inline] #[inline]
pub fn is_ok(&self, value: f32) -> bool { pub fn is_ok(&self, parsing_mode: ParsingMode, value: f32) -> bool {
if parsing_mode.allows_all_numeric_values() {
return true;
}
match *self { match *self {
AllowedLengthType::All => true, AllowedLengthType::All => true,
AllowedLengthType::NonNegative => value >= 0., AllowedLengthType::NonNegative => value >= 0.,

View file

@ -9,7 +9,6 @@ use cssparser::{Parser, ToCss, ParseError as CssParseError, BasicParseError};
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::fmt; use std::fmt;
use values::specified::AllowedLengthType;
define_css_keyword_enum!(UserZoom: define_css_keyword_enum!(UserZoom:
"zoom" => Zoom, "zoom" => Zoom,
@ -141,12 +140,18 @@ impl Zoom {
/// ///
/// https://drafts.csswg.org/css-device-adapt/#descdef-viewport-zoom /// https://drafts.csswg.org/css-device-adapt/#descdef-viewport-zoom
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Zoom, ParseError<'i>> { pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Zoom, ParseError<'i>> {
use PARSING_MODE_DEFAULT;
use cssparser::Token; use cssparser::Token;
use values::specified::AllowedLengthType::NonNegative;
match try!(input.next()) { match try!(input.next()) {
Token::Percentage(ref value) if AllowedLengthType::NonNegative.is_ok(value.unit_value) => // TODO: This parse() method should take ParserContext as an
// argument, and pass ParsingMode owned by the ParserContext to
// is_ok() instead of using PARSING_MODE_DEFAULT directly.
// In order to do so, we might want to move these stuff into style::stylesheets::viewport_rule.
Token::Percentage(ref value) if NonNegative.is_ok(PARSING_MODE_DEFAULT, value.unit_value) =>
Ok(Zoom::Percentage(value.unit_value)), Ok(Zoom::Percentage(value.unit_value)),
Token::Number(ref value) if AllowedLengthType::NonNegative.is_ok(value.value) => Token::Number(ref value) if NonNegative.is_ok(PARSING_MODE_DEFAULT, value.value) =>
Ok(Zoom::Number(value.value)), Ok(Zoom::Number(value.value)),
Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
Ok(Zoom::Auto), Ok(Zoom::Auto),