mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #16283 - emilio:cleanup-parse-non-negative, r=Wafflespeanut
style: Multiple cleanups around parsing code. <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16283) <!-- Reviewable:end -->
This commit is contained in:
commit
208d5dbfb6
10 changed files with 184 additions and 215 deletions
|
@ -483,36 +483,23 @@ ${helpers.single_keyword("background-origin",
|
|||
}
|
||||
|
||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
|
||||
let width;
|
||||
if let Ok(value) = input.try(|input| {
|
||||
match input.next() {
|
||||
Err(_) => Err(()),
|
||||
Ok(Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("cover") => {
|
||||
Ok(SpecifiedValue::Cover)
|
||||
}
|
||||
Ok(Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("contain") => {
|
||||
Ok(SpecifiedValue::Contain)
|
||||
}
|
||||
Ok(_) => Err(()),
|
||||
}
|
||||
}) {
|
||||
return Ok(value)
|
||||
} else {
|
||||
width = try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input))
|
||||
if input.try(|input| input.expect_ident_matching("cover")).is_ok() {
|
||||
return Ok(SpecifiedValue::Cover);
|
||||
}
|
||||
|
||||
let height;
|
||||
if let Ok(value) = input.try(|input| {
|
||||
match input.next() {
|
||||
Err(_) => Ok(specified::LengthOrPercentageOrAuto::Auto),
|
||||
Ok(_) => Err(()),
|
||||
}
|
||||
}) {
|
||||
height = value
|
||||
} else {
|
||||
height = try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input));
|
||||
if input.try(|input| input.expect_ident_matching("contain")).is_ok() {
|
||||
return Ok(SpecifiedValue::Contain);
|
||||
}
|
||||
|
||||
let width =
|
||||
try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input));
|
||||
|
||||
let height = if input.is_exhausted() {
|
||||
specified::LengthOrPercentageOrAuto::Auto
|
||||
} else {
|
||||
try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input))
|
||||
};
|
||||
|
||||
Ok(SpecifiedValue::Explicit(ExplicitSize {
|
||||
width: width,
|
||||
height: height,
|
||||
|
|
|
@ -659,15 +659,17 @@ ${helpers.single_keyword("font-variant-caps",
|
|||
/// <length> | <percentage> | <absolute-size> | <relative-size>
|
||||
pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
if let Ok(lop) = input.try(specified::LengthOrPercentage::parse_non_negative) {
|
||||
Ok(SpecifiedValue::Length(lop))
|
||||
} else if let Ok(kw) = input.try(KeywordSize::parse) {
|
||||
Ok(SpecifiedValue::Keyword(kw))
|
||||
} else {
|
||||
match_ignore_ascii_case! {&*input.expect_ident()?,
|
||||
"smaller" => Ok(SpecifiedValue::Smaller),
|
||||
"larger" => Ok(SpecifiedValue::Larger),
|
||||
_ => Err(())
|
||||
}
|
||||
return Ok(SpecifiedValue::Length(lop))
|
||||
}
|
||||
|
||||
if let Ok(kw) = input.try(KeywordSize::parse) {
|
||||
return Ok(SpecifiedValue::Keyword(kw))
|
||||
}
|
||||
|
||||
match_ignore_ascii_case! {&*input.expect_ident()?,
|
||||
"smaller" => Ok(SpecifiedValue::Smaller),
|
||||
"larger" => Ok(SpecifiedValue::Larger),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
</%helpers:longhand>
|
||||
|
|
|
@ -45,31 +45,33 @@
|
|||
}
|
||||
}
|
||||
/// normal | <number> | <length> | <percentage>
|
||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
use cssparser::Token;
|
||||
use std::ascii::AsciiExt;
|
||||
// We try to parse as a Number first because, for 'line-height', we want "0" to be
|
||||
// parsed as a plain Number rather than a Length (0px); this matches the behaviour
|
||||
// of all major browsers
|
||||
input.try(specified::Number::parse_non_negative)
|
||||
.map(SpecifiedValue::Number)
|
||||
.or_else(|()| {
|
||||
input.try(specified::LengthOrPercentage::parse_non_negative)
|
||||
.map(SpecifiedValue::LengthOrPercentage)
|
||||
.or_else(|()| {
|
||||
match try!(input.next()) {
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("normal") => {
|
||||
Ok(SpecifiedValue::Normal)
|
||||
}
|
||||
% if product == "gecko":
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("-moz-block-height") => {
|
||||
Ok(SpecifiedValue::MozBlockHeight)
|
||||
}
|
||||
% endif
|
||||
_ => Err(()),
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// We try to parse as a Number first because, for 'line-height', we want
|
||||
// "0" to be parsed as a plain Number rather than a Length (0px); this
|
||||
// matches the behaviour of all major browsers
|
||||
if let Ok(number) = input.try(specified::Number::parse_non_negative) {
|
||||
return Ok(SpecifiedValue::Number(number))
|
||||
}
|
||||
|
||||
if let Ok(lop) = input.try(specified::LengthOrPercentage::parse_non_negative) {
|
||||
return Ok(SpecifiedValue::LengthOrPercentage(lop))
|
||||
}
|
||||
|
||||
|
||||
match try!(input.next()) {
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("normal") => {
|
||||
Ok(SpecifiedValue::Normal)
|
||||
}
|
||||
% if product == "gecko":
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("-moz-block-height") => {
|
||||
Ok(SpecifiedValue::MozBlockHeight)
|
||||
}
|
||||
% endif
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
pub mod computed_value {
|
||||
use app_units::Au;
|
||||
|
|
|
@ -142,7 +142,8 @@ ${helpers.predefined_type("flex-basis",
|
|||
"LengthOrPercentageOrAutoOrContent",
|
||||
"computed::LengthOrPercentageOrAuto::Auto" if product == "gecko" else
|
||||
"computed::LengthOrPercentageOrAutoOrContent::Auto",
|
||||
"parse_non_negative_with_context",
|
||||
"parse_non_negative",
|
||||
needs_context=False,
|
||||
spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
|
||||
extra_prefixes="webkit",
|
||||
animatable=True if product == "gecko" else False)}
|
||||
|
|
|
@ -48,16 +48,10 @@
|
|||
|
||||
<%helpers:shorthand name="flex" sub_properties="flex-grow flex-shrink flex-basis" extra_prefixes="webkit"
|
||||
spec="https://drafts.csswg.org/css-flexbox/#flex-property">
|
||||
use parser::Parse;
|
||||
use values::specified::{Number, NoCalcLength};
|
||||
% if product == "gecko":
|
||||
use values::specified::LengthOrPercentageOrAuto;
|
||||
% else:
|
||||
use values::specified::LengthOrPercentageOrAutoOrContent;
|
||||
% endif
|
||||
use values::specified::Number;
|
||||
|
||||
pub fn parse_flexibility(input: &mut Parser)
|
||||
-> Result<(Number, Option<Number>),()> {
|
||||
fn parse_flexibility(input: &mut Parser)
|
||||
-> Result<(Number, Option<Number>),()> {
|
||||
let grow = try!(Number::parse_non_negative(input));
|
||||
let shrink = input.try(Number::parse_non_negative).ok();
|
||||
Ok((grow, shrink))
|
||||
|
@ -72,12 +66,7 @@
|
|||
return Ok(Longhands {
|
||||
flex_grow: Number::new(0.0),
|
||||
flex_shrink: Number::new(0.0),
|
||||
% if product == "gecko":
|
||||
flex_basis: LengthOrPercentageOrAuto::Auto
|
||||
% else:
|
||||
flex_basis: LengthOrPercentageOrAutoOrContent::Auto
|
||||
% endif
|
||||
|
||||
flex_basis: longhands::flex_basis::SpecifiedValue::auto(),
|
||||
})
|
||||
}
|
||||
loop {
|
||||
|
@ -89,11 +78,7 @@
|
|||
}
|
||||
}
|
||||
if basis.is_none() {
|
||||
% if product == "gecko":
|
||||
if let Ok(value) = input.try(|i| LengthOrPercentageOrAuto::parse(context, i)) {
|
||||
% else:
|
||||
if let Ok(value) = input.try(|i| LengthOrPercentageOrAutoOrContent::parse(context, i)) {
|
||||
% endif
|
||||
if let Ok(value) = input.try(|input| longhands::flex_basis::parse(context, input)) {
|
||||
basis = Some(value);
|
||||
continue
|
||||
}
|
||||
|
@ -107,21 +92,17 @@
|
|||
Ok(Longhands {
|
||||
flex_grow: grow.unwrap_or(Number::new(1.0)),
|
||||
flex_shrink: shrink.unwrap_or(Number::new(1.0)),
|
||||
% if product == "gecko":
|
||||
flex_basis: basis.unwrap_or(LengthOrPercentageOrAuto::Length(NoCalcLength::zero()))
|
||||
% else:
|
||||
flex_basis: basis.unwrap_or(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero()))
|
||||
% endif
|
||||
flex_basis: basis.unwrap_or(longhands::flex_basis::SpecifiedValue::zero()),
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
try!(self.flex_grow.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
try!(dest.write_str(" "));
|
||||
|
||||
try!(self.flex_shrink.to_css(dest));
|
||||
try!(write!(dest, " "));
|
||||
try!(dest.write_str(" "));
|
||||
|
||||
self.flex_basis.to_css(dest)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ use gecko_bindings::sugar::refptr::RefPtr;
|
|||
use keyframes::{Keyframe, parse_keyframe_list};
|
||||
use media_queries::{Device, MediaList, parse_media_query_list};
|
||||
use parking_lot::RwLock;
|
||||
use parser::{ParserContext, log_css_error};
|
||||
use parser::{Parse, ParserContext, log_css_error};
|
||||
use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
|
||||
use selector_parser::{SelectorImpl, SelectorParser};
|
||||
use selectors::parser::SelectorList;
|
||||
|
@ -1059,7 +1059,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
|
|||
}
|
||||
AtRulePrelude::Viewport => {
|
||||
Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap(
|
||||
try!(ViewportRule::parse(input, self.context))))))
|
||||
try!(ViewportRule::parse(self.context, input))))))
|
||||
}
|
||||
AtRulePrelude::Keyframes(name) => {
|
||||
Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
use cssparser::{Parser, Token};
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::{CSSFloat, HasViewportPercentage};
|
||||
|
@ -130,23 +131,23 @@ pub enum TrackBreadth<L> {
|
|||
/// Parse a single flexible length.
|
||||
pub fn parse_flex(input: &mut Parser) -> Result<CSSFloat, ()> {
|
||||
match try!(input.next()) {
|
||||
Token::Dimension(ref value, ref unit) if unit.to_lowercase() == "fr" && value.value.is_sign_positive()
|
||||
Token::Dimension(ref value, ref unit) if unit.eq_ignore_ascii_case("fr") && value.value.is_sign_positive()
|
||||
=> Ok(value.value),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for TrackBreadth<LengthOrPercentage> {
|
||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
if let Ok(lop) = input.try(LengthOrPercentage::parse_non_negative) {
|
||||
Ok(TrackBreadth::Breadth(lop))
|
||||
} else {
|
||||
if let Ok(f) = input.try(parse_flex) {
|
||||
Ok(TrackBreadth::Flex(f))
|
||||
} else {
|
||||
TrackKeyword::parse(input).map(TrackBreadth::Keyword)
|
||||
}
|
||||
return Ok(TrackBreadth::Breadth(lop))
|
||||
}
|
||||
|
||||
if let Ok(f) = input.try(parse_flex) {
|
||||
return Ok(TrackBreadth::Flex(f))
|
||||
}
|
||||
|
||||
TrackKeyword::parse(input).map(TrackBreadth::Keyword)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,24 +224,28 @@ impl<L> Default for TrackSize<L> {
|
|||
impl Parse for TrackSize<LengthOrPercentage> {
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
if let Ok(b) = input.try(|i| TrackBreadth::parse(context, i)) {
|
||||
Ok(TrackSize::Breadth(b))
|
||||
} else {
|
||||
if input.try(|i| i.expect_function_matching("minmax")).is_ok() {
|
||||
Ok(try!(input.parse_nested_block(|input| {
|
||||
let inflexible_breadth = if let Ok(lop) = input.try(LengthOrPercentage::parse_non_negative) {
|
||||
Ok(TrackBreadth::Breadth(lop))
|
||||
} else {
|
||||
TrackKeyword::parse(input).map(TrackBreadth::Keyword)
|
||||
return Ok(TrackSize::Breadth(b))
|
||||
}
|
||||
|
||||
if input.try(|i| i.expect_function_matching("minmax")).is_ok() {
|
||||
return input.parse_nested_block(|input| {
|
||||
let inflexible_breadth =
|
||||
match input.try(LengthOrPercentage::parse_non_negative) {
|
||||
Ok(lop) => TrackBreadth::Breadth(lop),
|
||||
Err(..) => {
|
||||
let keyword = try!(TrackKeyword::parse(input));
|
||||
TrackBreadth::Keyword(keyword)
|
||||
}
|
||||
};
|
||||
|
||||
try!(input.expect_comma());
|
||||
Ok(TrackSize::MinMax(try!(inflexible_breadth), try!(TrackBreadth::parse(context, input))))
|
||||
})))
|
||||
} else {
|
||||
try!(input.expect_function_matching("fit-content"));
|
||||
Ok(try!(LengthOrPercentage::parse(context, input).map(TrackSize::FitContent)))
|
||||
}
|
||||
try!(input.expect_comma());
|
||||
Ok(TrackSize::MinMax(inflexible_breadth, try!(TrackBreadth::parse(context, input))))
|
||||
});
|
||||
}
|
||||
|
||||
try!(input.expect_function_matching("fit-content"));
|
||||
// FIXME(emilio): This needs a parse_nested_block, doesn't it?
|
||||
Ok(try!(LengthOrPercentage::parse(context, input).map(TrackSize::FitContent)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -442,7 +442,7 @@ impl Length {
|
|||
/// Parse a non-negative length
|
||||
#[inline]
|
||||
pub fn parse_non_negative(input: &mut Parser) -> Result<Length, ()> {
|
||||
Length::parse_internal(input, AllowedNumericType::NonNegative)
|
||||
Self::parse_internal(input, AllowedNumericType::NonNegative)
|
||||
}
|
||||
|
||||
/// Get an absolute length from a px value.
|
||||
|
@ -462,7 +462,7 @@ impl Length {
|
|||
|
||||
impl Parse for Length {
|
||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
Length::parse_internal(input, AllowedNumericType::All)
|
||||
Self::parse_internal(input, AllowedNumericType::All)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1049,7 +1049,7 @@ impl LengthOrPercentage {
|
|||
/// Parse a non-negative length.
|
||||
#[inline]
|
||||
pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
|
||||
LengthOrPercentage::parse_internal(input, AllowedNumericType::NonNegative)
|
||||
Self::parse_internal(input, AllowedNumericType::NonNegative)
|
||||
}
|
||||
|
||||
/// Parse a length, treating dimensionless numbers as pixels
|
||||
|
@ -1057,11 +1057,13 @@ impl LengthOrPercentage {
|
|||
/// https://www.w3.org/TR/SVG2/types.html#presentation-attribute-css-value
|
||||
pub fn parse_numbers_are_pixels(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
|
||||
if let Ok(lop) = input.try(|i| Self::parse_internal(i, AllowedNumericType::All)) {
|
||||
Ok(lop)
|
||||
} else {
|
||||
let num = input.expect_number()?;
|
||||
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(Au((AU_PER_PX * num) as i32))))
|
||||
return Ok(lop)
|
||||
}
|
||||
|
||||
// TODO(emilio): Probably should use Number::parse_non_negative to
|
||||
// handle calc()?
|
||||
let num = input.expect_number()?;
|
||||
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(Au((AU_PER_PX * num) as i32))))
|
||||
}
|
||||
|
||||
/// Parse a non-negative length, treating dimensionless numbers as pixels
|
||||
|
@ -1069,14 +1071,16 @@ impl LengthOrPercentage {
|
|||
/// This is nonstandard behavior used by Firefox for SVG
|
||||
pub fn parse_numbers_are_pixels_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
|
||||
if let Ok(lop) = input.try(|i| Self::parse_internal(i, AllowedNumericType::NonNegative)) {
|
||||
Ok(lop)
|
||||
return Ok(lop)
|
||||
}
|
||||
|
||||
// TODO(emilio): Probably should use Number::parse_non_negative to
|
||||
// handle calc()?
|
||||
let num = input.expect_number()?;
|
||||
if num >= 0. {
|
||||
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(Au((AU_PER_PX * num) as i32))))
|
||||
} else {
|
||||
let num = input.expect_number()?;
|
||||
if num >= 0. {
|
||||
Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(Au((AU_PER_PX * num) as i32))))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1092,7 +1096,7 @@ impl LengthOrPercentage {
|
|||
impl Parse for LengthOrPercentage {
|
||||
#[inline]
|
||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
LengthOrPercentage::parse_internal(input, AllowedNumericType::All)
|
||||
Self::parse_internal(input, AllowedNumericType::All)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1146,15 +1150,14 @@ impl ToCss for LengthOrPercentageOrAuto {
|
|||
|
||||
impl LengthOrPercentageOrAuto {
|
||||
fn parse_internal(input: &mut Parser, context: AllowedNumericType)
|
||||
-> Result<LengthOrPercentageOrAuto, ()>
|
||||
{
|
||||
-> Result<Self, ()> {
|
||||
match try!(input.next()) {
|
||||
Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
|
||||
NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAuto::Length),
|
||||
Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
|
||||
Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))),
|
||||
Token::Number(ref value) if value.value == 0. =>
|
||||
Ok(LengthOrPercentageOrAuto::Length(NoCalcLength::zero())),
|
||||
Ok(Self::zero()),
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
|
||||
Ok(LengthOrPercentageOrAuto::Auto),
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||
|
@ -1168,22 +1171,24 @@ impl LengthOrPercentageOrAuto {
|
|||
/// Parse a non-negative length, percentage, or auto.
|
||||
#[inline]
|
||||
pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> {
|
||||
LengthOrPercentageOrAuto::parse_internal(input, AllowedNumericType::NonNegative)
|
||||
Self::parse_internal(input, AllowedNumericType::NonNegative)
|
||||
}
|
||||
|
||||
/// Parse a non-negative length, percentage, or auto.
|
||||
#[inline]
|
||||
pub fn parse_non_negative_with_context(_context: &ParserContext,
|
||||
input: &mut Parser)
|
||||
-> Result<LengthOrPercentageOrAuto, ()> {
|
||||
LengthOrPercentageOrAuto::parse_non_negative(input)
|
||||
/// Returns the `auto` value.
|
||||
pub fn auto() -> Self {
|
||||
LengthOrPercentageOrAuto::Auto
|
||||
}
|
||||
|
||||
/// Returns a value representing a `0` length.
|
||||
pub fn zero() -> Self {
|
||||
LengthOrPercentageOrAuto::Length(NoCalcLength::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for LengthOrPercentageOrAuto {
|
||||
#[inline]
|
||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
LengthOrPercentageOrAuto::parse_internal(input, AllowedNumericType::All)
|
||||
Self::parse_internal(input, AllowedNumericType::All)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1241,15 +1246,15 @@ impl LengthOrPercentageOrNone {
|
|||
}
|
||||
/// Parse a non-negative LengthOrPercentageOrNone.
|
||||
#[inline]
|
||||
pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentageOrNone, ()> {
|
||||
LengthOrPercentageOrNone::parse_internal(input, AllowedNumericType::NonNegative)
|
||||
pub fn parse_non_negative(input: &mut Parser) -> Result<Self, ()> {
|
||||
Self::parse_internal(input, AllowedNumericType::NonNegative)
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for LengthOrPercentageOrNone {
|
||||
#[inline]
|
||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
LengthOrPercentageOrNone::parse_internal(input, AllowedNumericType::All)
|
||||
Self::parse_internal(input, AllowedNumericType::All)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1282,12 +1287,36 @@ pub enum LengthOrPercentageOrAutoOrContent {
|
|||
}
|
||||
|
||||
impl LengthOrPercentageOrAutoOrContent {
|
||||
/// Alias to `parse` so that Gecko and Servo can use the same method name for
|
||||
/// both `LengthOrPercentageOrAuto` and `LengthOrPercentageOrAutoOrContent`.
|
||||
///
|
||||
/// NOTE: `parse` already only accepts non-negative values.
|
||||
pub fn parse_non_negative_with_context(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
Self::parse(context, input)
|
||||
/// Parse a non-negative LengthOrPercentageOrAutoOrContent.
|
||||
pub fn parse_non_negative(input: &mut Parser) -> Result<Self, ()> {
|
||||
let context = AllowedNumericType::NonNegative;
|
||||
match try!(input.next()) {
|
||||
Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
|
||||
NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAutoOrContent::Length),
|
||||
Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))),
|
||||
Token::Number(ref value) if value.value == 0. =>
|
||||
Ok(Self::zero()),
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Auto),
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("content") =>
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Content),
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||
let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Calc(Box::new(calc)))
|
||||
},
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `auto` value.
|
||||
pub fn auto() -> Self {
|
||||
LengthOrPercentageOrAutoOrContent::Auto
|
||||
}
|
||||
|
||||
/// Returns a value representing a `0` length.
|
||||
pub fn zero() -> Self {
|
||||
LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1313,43 +1342,20 @@ impl ToCss for LengthOrPercentageOrAutoOrContent {
|
|||
}
|
||||
}
|
||||
|
||||
impl Parse for LengthOrPercentageOrAutoOrContent {
|
||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
let context = AllowedNumericType::NonNegative;
|
||||
match try!(input.next()) {
|
||||
Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
|
||||
NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAutoOrContent::Length),
|
||||
Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))),
|
||||
Token::Number(ref value) if value.value == 0. =>
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero())),
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Auto),
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("content") =>
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Content),
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||
let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
|
||||
Ok(LengthOrPercentageOrAutoOrContent::Calc(Box::new(calc)))
|
||||
},
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Either a `<length>` or a `<number>`.
|
||||
pub type LengthOrNumber = Either<Length, Number>;
|
||||
|
||||
impl LengthOrNumber {
|
||||
/// Parse a non-negative LengthOrNumber.
|
||||
pub fn parse_non_negative(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
// We try to parse as a Number first because, for cases like LengthOrNumber,
|
||||
// we want "0" to be parsed as a plain Number rather than a Length (0px); this
|
||||
// matches the behaviour of all major browsers
|
||||
pub fn parse_non_negative(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
// We try to parse as a Number first because, for cases like
|
||||
// LengthOrNumber, we want "0" to be parsed as a plain Number rather
|
||||
// than a Length (0px); this matches the behaviour of all major browsers
|
||||
if let Ok(v) = input.try(Number::parse_non_negative) {
|
||||
Ok(Either::Second(v))
|
||||
} else {
|
||||
Length::parse_non_negative(input).map(Either::First)
|
||||
return Ok(Either::Second(v))
|
||||
}
|
||||
|
||||
Length::parse_non_negative(input).map(Either::First)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser,
|
|||
use cssparser::ToCss as ParserToCss;
|
||||
use euclid::size::TypedSize2D;
|
||||
use media_queries::Device;
|
||||
use parser::{ParserContext, log_css_error};
|
||||
use parser::{Parse, ParserContext, log_css_error};
|
||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::Cow;
|
||||
|
@ -165,9 +165,9 @@ impl FromMeta for ViewportLength {
|
|||
}
|
||||
|
||||
impl ViewportLength {
|
||||
fn parse(input: &mut Parser) -> Result<ViewportLength, ()> {
|
||||
// we explicitly do not accept 'extend-to-zoom', since it is a UA internal value
|
||||
// for <META> viewport translation
|
||||
fn parse(input: &mut Parser) -> Result<Self, ()> {
|
||||
// we explicitly do not accept 'extend-to-zoom', since it is a UA
|
||||
// internal value for <META> viewport translation
|
||||
LengthOrPercentageOrAuto::parse_non_negative(input).map(ViewportLength::Specified)
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ impl ToCss for ViewportDescriptorDeclaration {
|
|||
|
||||
fn parse_shorthand(input: &mut Parser) -> Result<(ViewportLength, ViewportLength), ()> {
|
||||
let min = try!(ViewportLength::parse(input));
|
||||
match input.try(|input| ViewportLength::parse(input)) {
|
||||
match input.try(ViewportLength::parse) {
|
||||
Err(()) => Ok((min.clone(), min)),
|
||||
Ok(max) => Ok((min, max))
|
||||
}
|
||||
|
@ -287,33 +287,18 @@ impl<'a, 'b> DeclarationParser for ViewportRuleParser<'a, 'b> {
|
|||
}}
|
||||
}
|
||||
|
||||
match name {
|
||||
n if n.eq_ignore_ascii_case("min-width") =>
|
||||
ok!(MinWidth(ViewportLength::parse)),
|
||||
n if n.eq_ignore_ascii_case("max-width") =>
|
||||
ok!(MaxWidth(ViewportLength::parse)),
|
||||
n if n.eq_ignore_ascii_case("width") =>
|
||||
ok!(shorthand -> [MinWidth, MaxWidth]),
|
||||
|
||||
n if n.eq_ignore_ascii_case("min-height") =>
|
||||
ok!(MinHeight(ViewportLength::parse)),
|
||||
n if n.eq_ignore_ascii_case("max-height") =>
|
||||
ok!(MaxHeight(ViewportLength::parse)),
|
||||
n if n.eq_ignore_ascii_case("height") =>
|
||||
ok!(shorthand -> [MinHeight, MaxHeight]),
|
||||
|
||||
n if n.eq_ignore_ascii_case("zoom") =>
|
||||
ok!(Zoom(Zoom::parse)),
|
||||
n if n.eq_ignore_ascii_case("min-zoom") =>
|
||||
ok!(MinZoom(Zoom::parse)),
|
||||
n if n.eq_ignore_ascii_case("max-zoom") =>
|
||||
ok!(MaxZoom(Zoom::parse)),
|
||||
|
||||
n if n.eq_ignore_ascii_case("user-zoom") =>
|
||||
ok!(UserZoom(UserZoom::parse)),
|
||||
n if n.eq_ignore_ascii_case("orientation") =>
|
||||
ok!(Orientation(Orientation::parse)),
|
||||
|
||||
match_ignore_ascii_case! { name,
|
||||
"min-width" => ok!(MinWidth(ViewportLength::parse)),
|
||||
"max-width" => ok!(MaxWidth(ViewportLength::parse)),
|
||||
"width" => ok!(shorthand -> [MinWidth, MaxWidth]),
|
||||
"min-height" => ok!(MinHeight(ViewportLength::parse)),
|
||||
"max-height" => ok!(MaxHeight(ViewportLength::parse)),
|
||||
"height" => ok!(shorthand -> [MinHeight, MaxHeight]),
|
||||
"zoom" => ok!(Zoom(Zoom::parse)),
|
||||
"min-zoom" => ok!(MinZoom(Zoom::parse)),
|
||||
"max-zoom" => ok!(MaxZoom(Zoom::parse)),
|
||||
"user-zoom" => ok!(UserZoom(UserZoom::parse)),
|
||||
"orientation" => ok!(Orientation(Orientation::parse)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
@ -340,11 +325,9 @@ fn is_whitespace_separator_or_equals(c: &char) -> bool {
|
|||
WHITESPACE.contains(c) || SEPARATOR.contains(c) || *c == '='
|
||||
}
|
||||
|
||||
impl ViewportRule {
|
||||
impl Parse for ViewportRule {
|
||||
#[allow(missing_docs)]
|
||||
pub fn parse(input: &mut Parser, context: &ParserContext)
|
||||
-> Result<ViewportRule, ()>
|
||||
{
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
let parser = ViewportRuleParser { context: context };
|
||||
|
||||
let mut cascade = Cascade::new();
|
||||
|
@ -366,7 +349,9 @@ impl ViewportRule {
|
|||
}
|
||||
Ok(ViewportRule { declarations: cascade.finish() })
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewportRule {
|
||||
#[allow(missing_docs)]
|
||||
pub fn from_meta(content: &str) -> Option<ViewportRule> {
|
||||
let mut declarations = vec![None; VIEWPORT_DESCRIPTOR_VARIANTS];
|
||||
|
|
|
@ -8,7 +8,7 @@ use media_queries::CSSErrorReporterTest;
|
|||
use servo_config::prefs::{PREFS, PrefValue};
|
||||
use servo_url::ServoUrl;
|
||||
use style::media_queries::{Device, MediaType};
|
||||
use style::parser::ParserContext;
|
||||
use style::parser::{Parse, ParserContext};
|
||||
use style::shared_lock::SharedRwLock;
|
||||
use style::stylesheets::{Stylesheet, Origin};
|
||||
use style::values::specified::LengthOrPercentageOrAuto::{self, Auto};
|
||||
|
@ -294,7 +294,7 @@ fn constrain_viewport() {
|
|||
|
||||
macro_rules! from_css {
|
||||
($css:expr) => {
|
||||
&ViewportRule::parse(&mut Parser::new($css), &context).unwrap()
|
||||
&ViewportRule::parse(&context, &mut Parser::new($css)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue