mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: More cleanups around length parsing and viewport rule parsing.
This commit is contained in:
parent
705ecb4557
commit
846c950b6b
6 changed files with 72 additions and 101 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,
|
||||
|
|
|
@ -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,13 +48,7 @@
|
|||
|
||||
<%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;
|
||||
|
||||
fn parse_flexibility(input: &mut Parser)
|
||||
-> Result<(Number, Option<Number>),()> {
|
||||
|
@ -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 {
|
||||
|
|
|
@ -1150,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") => {
|
||||
|
@ -1175,12 +1174,14 @@ impl LengthOrPercentageOrAuto {
|
|||
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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1286,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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1317,29 +1342,6 @@ 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>;
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
@ -325,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();
|
||||
|
@ -351,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];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue