mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Run rustfmt on selectors, servo_arc, and style.
This was generated with: ./mach cargo fmt --package selectors && ./mach cargo fmt --package servo_arc && ./mach cargo fmt --package style Using rustfmt 0.4.1-nightly (a4462d1 2018-03-26)
This commit is contained in:
parent
f7ae1a37e3
commit
c99bcdd4b8
181 changed files with 9981 additions and 7933 deletions
|
@ -85,7 +85,7 @@ impl ToCss for AlignFlags {
|
|||
AlignFlags::LEGACY => dest.write_str("legacy ")?,
|
||||
AlignFlags::SAFE => dest.write_str("safe ")?,
|
||||
// Don't serialize "unsafe", since it's the default.
|
||||
_ => {}
|
||||
_ => {},
|
||||
}
|
||||
|
||||
dest.write_str(match self.value() {
|
||||
|
@ -106,7 +106,7 @@ impl ToCss for AlignFlags {
|
|||
AlignFlags::SPACE_BETWEEN => "space-between",
|
||||
AlignFlags::SPACE_AROUND => "space-around",
|
||||
AlignFlags::SPACE_EVENLY => "space-evenly",
|
||||
_ => unreachable!()
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ impl ContentDistribution {
|
|||
|
||||
fn from_bits(bits: u16) -> Self {
|
||||
Self {
|
||||
primary: AlignFlags::from_bits_truncate(bits as u8)
|
||||
primary: AlignFlags::from_bits_truncate(bits as u8),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,8 +198,8 @@ impl ContentDistribution {
|
|||
}
|
||||
|
||||
// <overflow-position>? <content-position>
|
||||
let overflow_position =
|
||||
input.try(parse_overflow_position)
|
||||
let overflow_position = input
|
||||
.try(parse_overflow_position)
|
||||
.unwrap_or(AlignFlags::empty());
|
||||
|
||||
let content_position = try_match_ident_ignore_ascii_case! { input,
|
||||
|
@ -212,7 +212,9 @@ impl ContentDistribution {
|
|||
"right" if axis == AxisDirection::Inline => AlignFlags::RIGHT,
|
||||
};
|
||||
|
||||
Ok(ContentDistribution::new(content_position | overflow_position))
|
||||
Ok(ContentDistribution::new(
|
||||
content_position | overflow_position,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,8 +297,7 @@ impl SelfAlignment {
|
|||
pub fn is_valid_on_both_axes(&self) -> bool {
|
||||
match self.0.value() {
|
||||
// left | right are only allowed on the inline axis.
|
||||
AlignFlags::LEFT |
|
||||
AlignFlags::RIGHT => false,
|
||||
AlignFlags::LEFT | AlignFlags::RIGHT => false,
|
||||
|
||||
_ => true,
|
||||
}
|
||||
|
@ -317,12 +318,12 @@ impl SelfAlignment {
|
|||
|
||||
// auto | normal | stretch
|
||||
if let Ok(value) = input.try(parse_auto_normal_stretch) {
|
||||
return Ok(SelfAlignment(value))
|
||||
return Ok(SelfAlignment(value));
|
||||
}
|
||||
|
||||
// <overflow-position>? <self-position>
|
||||
let overflow_position =
|
||||
input.try(parse_overflow_position)
|
||||
let overflow_position = input
|
||||
.try(parse_overflow_position)
|
||||
.unwrap_or(AlignFlags::empty());
|
||||
let self_position = parse_self_position(input, axis)?;
|
||||
Ok(SelfAlignment(overflow_position | self_position))
|
||||
|
@ -336,8 +337,14 @@ impl SelfAlignment {
|
|||
pub struct AlignSelf(pub SelfAlignment);
|
||||
|
||||
impl Parse for AlignSelf {
|
||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
Ok(AlignSelf(SelfAlignment::parse(input, AxisDirection::Block)?))
|
||||
fn parse<'i, 't>(
|
||||
_: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Ok(AlignSelf(SelfAlignment::parse(
|
||||
input,
|
||||
AxisDirection::Block,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,8 +367,14 @@ impl From<AlignSelf> for u8 {
|
|||
pub struct JustifySelf(pub SelfAlignment);
|
||||
|
||||
impl Parse for JustifySelf {
|
||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
Ok(JustifySelf(SelfAlignment::parse(input, AxisDirection::Inline)?))
|
||||
fn parse<'i, 't>(
|
||||
_: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Ok(JustifySelf(SelfAlignment::parse(
|
||||
input,
|
||||
AxisDirection::Inline,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,11 +404,13 @@ impl AlignItems {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl Parse for AlignItems {
|
||||
// normal | stretch | <baseline-position> |
|
||||
// <overflow-position>? <self-position>
|
||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
// <baseline-position>
|
||||
if let Ok(baseline) = input.try(parse_baseline) {
|
||||
return Ok(AlignItems(baseline));
|
||||
|
@ -403,10 +418,12 @@ impl Parse for AlignItems {
|
|||
|
||||
// normal | stretch
|
||||
if let Ok(value) = input.try(parse_normal_stretch) {
|
||||
return Ok(AlignItems(value))
|
||||
return Ok(AlignItems(value));
|
||||
}
|
||||
// <overflow-position>? <self-position>
|
||||
let overflow = input.try(parse_overflow_position).unwrap_or(AlignFlags::empty());
|
||||
let overflow = input
|
||||
.try(parse_overflow_position)
|
||||
.unwrap_or(AlignFlags::empty());
|
||||
let self_position = parse_self_position(input, AxisDirection::Block)?;
|
||||
Ok(AlignItems(self_position | overflow))
|
||||
}
|
||||
|
@ -433,7 +450,10 @@ impl JustifyItems {
|
|||
}
|
||||
|
||||
impl Parse for JustifyItems {
|
||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
// <baseline-position>
|
||||
//
|
||||
// It's weird that this accepts <baseline-position>, but not
|
||||
|
@ -456,16 +476,18 @@ impl Parse for JustifyItems {
|
|||
// https://bugs.chromium.org/p/chromium/issues/detail?id=726148
|
||||
//
|
||||
if let Ok(value) = input.try(parse_auto_normal_stretch) {
|
||||
return Ok(JustifyItems(value))
|
||||
return Ok(JustifyItems(value));
|
||||
}
|
||||
|
||||
// [ legacy || [ left | right | center ] ]
|
||||
if let Ok(value) = input.try(parse_legacy) {
|
||||
return Ok(JustifyItems(value))
|
||||
return Ok(JustifyItems(value));
|
||||
}
|
||||
|
||||
// <overflow-position>? <self-position>
|
||||
let overflow = input.try(parse_overflow_position).unwrap_or(AlignFlags::empty());
|
||||
let overflow = input
|
||||
.try(parse_overflow_position)
|
||||
.unwrap_or(AlignFlags::empty());
|
||||
let self_position = parse_self_position(input, AxisDirection::Inline)?;
|
||||
Ok(JustifyItems(overflow | self_position))
|
||||
}
|
||||
|
@ -506,7 +528,9 @@ fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, Pars
|
|||
}
|
||||
|
||||
// <content-distribution>
|
||||
fn parse_content_distribution<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
||||
fn parse_content_distribution<'i, 't>(
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<AlignFlags, ParseError<'i>> {
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"stretch" => Ok(AlignFlags::STRETCH),
|
||||
"space-between" => Ok(AlignFlags::SPACE_BETWEEN),
|
||||
|
@ -516,7 +540,9 @@ fn parse_content_distribution<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Alig
|
|||
}
|
||||
|
||||
// <overflow-position>
|
||||
fn parse_overflow_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> {
|
||||
fn parse_overflow_position<'i, 't>(
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<AlignFlags, ParseError<'i>> {
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"safe" => Ok(AlignFlags::SAFE),
|
||||
"unsafe" => Ok(AlignFlags::UNSAFE),
|
||||
|
@ -553,7 +579,9 @@ fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseE
|
|||
"right" => Ok(AlignFlags::LEGACY | AlignFlags::RIGHT),
|
||||
"center" => Ok(AlignFlags::LEGACY | AlignFlags::CENTER),
|
||||
_ => Err(())
|
||||
}).map_err(|()| b_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(b.clone())))
|
||||
}).map_err(|()| {
|
||||
b_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(b.clone()))
|
||||
})
|
||||
} else if b.eq_ignore_ascii_case("legacy") {
|
||||
(match_ignore_ascii_case! { &a,
|
||||
"left" => Ok(AlignFlags::LEGACY | AlignFlags::LEFT),
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//! Specified angles.
|
||||
|
||||
use cssparser::{Parser, Token};
|
||||
use parser::{ParserContext, Parse};
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, ToCss};
|
||||
use values::CSSFloat;
|
||||
|
@ -59,22 +59,34 @@ impl ToComputedValue for Angle {
|
|||
impl Angle {
|
||||
/// Creates an angle with the given value in degrees.
|
||||
pub fn from_degrees(value: CSSFloat, was_calc: bool) -> Self {
|
||||
Angle { value: ComputedAngle::Deg(value), was_calc }
|
||||
Angle {
|
||||
value: ComputedAngle::Deg(value),
|
||||
was_calc,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an angle with the given value in gradians.
|
||||
pub fn from_gradians(value: CSSFloat, was_calc: bool) -> Self {
|
||||
Angle { value: ComputedAngle::Grad(value), was_calc }
|
||||
Angle {
|
||||
value: ComputedAngle::Grad(value),
|
||||
was_calc,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an angle with the given value in turns.
|
||||
pub fn from_turns(value: CSSFloat, was_calc: bool) -> Self {
|
||||
Angle { value: ComputedAngle::Turn(value), was_calc }
|
||||
Angle {
|
||||
value: ComputedAngle::Turn(value),
|
||||
was_calc,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an angle with the given value in radians.
|
||||
pub fn from_radians(value: CSSFloat, was_calc: bool) -> Self {
|
||||
Angle { value: ComputedAngle::Rad(value), was_calc }
|
||||
Angle {
|
||||
value: ComputedAngle::Rad(value),
|
||||
was_calc,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the amount of radians this angle represents.
|
||||
|
@ -135,11 +147,7 @@ impl Parse for Angle {
|
|||
|
||||
impl Angle {
|
||||
/// Parse an `<angle>` value given a value and an unit.
|
||||
pub fn parse_dimension(
|
||||
value: CSSFloat,
|
||||
unit: &str,
|
||||
from_calc: bool,
|
||||
) -> Result<Angle, ()> {
|
||||
pub fn parse_dimension(value: CSSFloat, unit: &str, from_calc: bool) -> Result<Angle, ()> {
|
||||
let angle = match_ignore_ascii_case! { unit,
|
||||
"deg" => Angle::from_degrees(value, from_calc),
|
||||
"grad" => Angle::from_gradians(value, from_calc),
|
||||
|
@ -168,19 +176,19 @@ impl Angle {
|
|||
// FIXME: remove clone() when lifetimes are non-lexical
|
||||
let token = input.next()?.clone();
|
||||
match token {
|
||||
Token::Dimension { value, ref unit, .. } => {
|
||||
Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} => {
|
||||
Angle::parse_dimension(value, unit, /* from_calc = */ false)
|
||||
}
|
||||
Token::Number { value, .. } if value == 0. => {
|
||||
match allow_unitless_zero {
|
||||
AllowUnitlessZeroAngle::Yes => Ok(Angle::zero()),
|
||||
AllowUnitlessZeroAngle::No => Err(()),
|
||||
}
|
||||
},
|
||||
Token::Number { value, .. } if value == 0. => match allow_unitless_zero {
|
||||
AllowUnitlessZeroAngle::Yes => Ok(Angle::zero()),
|
||||
AllowUnitlessZeroAngle::No => Err(()),
|
||||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
|
||||
}
|
||||
_ => Err(())
|
||||
},
|
||||
_ => Err(()),
|
||||
}.map_err(|()| input.new_unexpected_token_error(token.clone()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,9 @@ impl Parse for BackgroundSize {
|
|||
"cover" => Ok(GenericBackgroundSize::Cover),
|
||||
"contain" => Ok(GenericBackgroundSize::Contain),
|
||||
_ => Err(()),
|
||||
}).map_err(|()| location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
||||
}).map_err(|()| {
|
||||
location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,10 +94,8 @@ impl Parse for BackgroundRepeat {
|
|||
let horizontal = match BackgroundRepeatKeyword::from_ident(&ident) {
|
||||
Ok(h) => h,
|
||||
Err(()) => {
|
||||
return Err(input.new_custom_error(
|
||||
SelectorParseErrorKind::UnexpectedIdent(ident.clone())
|
||||
));
|
||||
}
|
||||
return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())));
|
||||
},
|
||||
};
|
||||
|
||||
let vertical = input.try(BackgroundRepeatKeyword::parse).ok();
|
||||
|
|
|
@ -52,19 +52,25 @@ where
|
|||
ReferenceBox: Parse,
|
||||
ImageOrUrl: Parse,
|
||||
{
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(ShapeSource::None)
|
||||
return Ok(ShapeSource::None);
|
||||
}
|
||||
|
||||
if let Ok(image_or_url) = input.try(|i| ImageOrUrl::parse(context, i)) {
|
||||
return Ok(ShapeSource::ImageOrUrl(image_or_url))
|
||||
return Ok(ShapeSource::ImageOrUrl(image_or_url));
|
||||
}
|
||||
|
||||
fn parse_component<U: Parse>(context: &ParserContext, input: &mut Parser,
|
||||
component: &mut Option<U>) -> bool {
|
||||
fn parse_component<U: Parse>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser,
|
||||
component: &mut Option<U>,
|
||||
) -> bool {
|
||||
if component.is_some() {
|
||||
return false // already parsed this component
|
||||
return false; // already parsed this component
|
||||
}
|
||||
|
||||
*component = input.try(|i| U::parse(context, i)).ok();
|
||||
|
@ -75,22 +81,28 @@ where
|
|||
let mut ref_box = None;
|
||||
|
||||
while parse_component(context, input, &mut shape) ||
|
||||
parse_component(context, input, &mut ref_box) {
|
||||
parse_component(context, input, &mut ref_box)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
if let Some(shp) = shape {
|
||||
return Ok(ShapeSource::Shape(shp, ref_box))
|
||||
return Ok(ShapeSource::Shape(shp, ref_box));
|
||||
}
|
||||
|
||||
ref_box.map(|v| ShapeSource::Box(v)).ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
ref_box
|
||||
.map(|v| ShapeSource::Box(v))
|
||||
.ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for GeometryBox {
|
||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(shape_box) = input.try(|i| ShapeBox::parse(i)) {
|
||||
return Ok(GeometryBox::ShapeBox(shape_box))
|
||||
return Ok(GeometryBox::ShapeBox(shape_box));
|
||||
}
|
||||
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
|
@ -102,7 +114,10 @@ impl Parse for GeometryBox {
|
|||
}
|
||||
|
||||
impl Parse for BasicShape {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
let function = input.expect_function()?.clone();
|
||||
input.parse_nested_block(move |i| {
|
||||
|
@ -112,13 +127,18 @@ impl Parse for BasicShape {
|
|||
"ellipse" => return Ellipse::parse_function_arguments(context, i).map(generic::BasicShape::Ellipse),
|
||||
"polygon" => return Polygon::parse_function_arguments(context, i).map(generic::BasicShape::Polygon),
|
||||
_ => Err(())
|
||||
}).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone())))
|
||||
}).map_err(|()| {
|
||||
location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for InsetRect {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.expect_function_matching("inset")?;
|
||||
input.parse_nested_block(|i| Self::parse_function_arguments(context, i))
|
||||
}
|
||||
|
@ -144,8 +164,10 @@ impl InsetRect {
|
|||
}
|
||||
|
||||
impl Parse for Circle {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.expect_function_matching("circle")?;
|
||||
input.parse_nested_block(|i| Self::parse_function_arguments(context, i))
|
||||
}
|
||||
|
@ -156,7 +178,9 @@ impl Circle {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let radius = input.try(|i| ShapeRadius::parse(context, i)).unwrap_or_default();
|
||||
let radius = input
|
||||
.try(|i| ShapeRadius::parse(context, i))
|
||||
.unwrap_or_default();
|
||||
let position = if input.try(|i| i.expect_ident_matching("at")).is_ok() {
|
||||
Position::parse(context, input)?
|
||||
} else {
|
||||
|
@ -185,7 +209,10 @@ impl ToCss for Circle {
|
|||
}
|
||||
|
||||
impl Parse for Ellipse {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.expect_function_matching("ellipse")?;
|
||||
input.parse_nested_block(|i| Self::parse_function_arguments(context, i))
|
||||
}
|
||||
|
@ -196,9 +223,14 @@ impl Ellipse {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let (a, b) = input.try(|i| -> Result<_, ParseError> {
|
||||
Ok((ShapeRadius::parse(context, i)?, ShapeRadius::parse(context, i)?))
|
||||
}).unwrap_or_default();
|
||||
let (a, b) = input
|
||||
.try(|i| -> Result<_, ParseError> {
|
||||
Ok((
|
||||
ShapeRadius::parse(context, i)?,
|
||||
ShapeRadius::parse(context, i)?,
|
||||
))
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let position = if input.try(|i| i.expect_ident_matching("at")).is_ok() {
|
||||
Position::parse(context, input)?
|
||||
} else {
|
||||
|
@ -233,10 +265,12 @@ impl ToCss for Ellipse {
|
|||
}
|
||||
|
||||
impl Parse for ShapeRadius {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
|
||||
return Ok(generic::ShapeRadius::Length(lop))
|
||||
return Ok(generic::ShapeRadius::Length(lop));
|
||||
}
|
||||
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
|
@ -252,35 +286,39 @@ impl Parse for ShapeRadius {
|
|||
/// are converted to percentages where possible. Only the two or four
|
||||
/// value forms are used. In case of two keyword-percentage pairs,
|
||||
/// the keywords are folded into the percentages
|
||||
fn serialize_basicshape_position<W>(
|
||||
position: &Position,
|
||||
dest: &mut CssWriter<W>,
|
||||
) -> fmt::Result
|
||||
fn serialize_basicshape_position<W>(position: &Position, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
fn to_keyword_and_lop<S>(component: &PositionComponent<S>) -> (S, Cow<LengthOrPercentage>)
|
||||
where S: Copy + Side
|
||||
where
|
||||
S: Copy + Side,
|
||||
{
|
||||
match *component {
|
||||
PositionComponent::Center => {
|
||||
(S::start(), Cow::Owned(LengthOrPercentage::Percentage(Percentage(0.5))))
|
||||
},
|
||||
PositionComponent::Center => (
|
||||
S::start(),
|
||||
Cow::Owned(LengthOrPercentage::Percentage(Percentage(0.5))),
|
||||
),
|
||||
PositionComponent::Side(keyword, None) => {
|
||||
// left | top => 0%
|
||||
// right | bottom => 100%
|
||||
let p = if keyword.is_start() { 0. } else { 1. };
|
||||
(S::start(), Cow::Owned(LengthOrPercentage::Percentage(Percentage(p))))
|
||||
(
|
||||
S::start(),
|
||||
Cow::Owned(LengthOrPercentage::Percentage(Percentage(p))),
|
||||
)
|
||||
},
|
||||
PositionComponent::Side(keyword, Some(ref lop)) if !keyword.is_start() => {
|
||||
if let LengthOrPercentage::Percentage(p) = *to_non_zero_length(lop) {
|
||||
(S::start(), Cow::Owned(LengthOrPercentage::Percentage(Percentage(1. - p.0))))
|
||||
(
|
||||
S::start(),
|
||||
Cow::Owned(LengthOrPercentage::Percentage(Percentage(1. - p.0))),
|
||||
)
|
||||
} else {
|
||||
(keyword, Cow::Borrowed(lop))
|
||||
}
|
||||
},
|
||||
PositionComponent::Length(ref lop) |
|
||||
PositionComponent::Side(_, Some(ref lop)) => {
|
||||
PositionComponent::Length(ref lop) | PositionComponent::Side(_, Some(ref lop)) => {
|
||||
(S::start(), to_non_zero_length(lop))
|
||||
},
|
||||
}
|
||||
|
@ -291,9 +329,7 @@ where
|
|||
LengthOrPercentage::Length(ref l) if l.is_zero() => {
|
||||
Cow::Owned(LengthOrPercentage::Percentage(Percentage(0.)))
|
||||
},
|
||||
_ => {
|
||||
Cow::Borrowed(lop)
|
||||
}
|
||||
_ => Cow::Borrowed(lop),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,7 +357,10 @@ where
|
|||
}
|
||||
|
||||
impl Parse for Polygon {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.expect_function_matching("polygon")?;
|
||||
input.parse_nested_block(|i| Self::parse_function_arguments(context, i))
|
||||
}
|
||||
|
@ -333,14 +372,19 @@ impl Polygon {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let fill = input.try(|i| -> Result<_, ParseError> {
|
||||
let fill = FillRule::parse(i)?;
|
||||
i.expect_comma()?; // only eat the comma if there is something before it
|
||||
Ok(fill)
|
||||
}).unwrap_or_default();
|
||||
let fill = input
|
||||
.try(|i| -> Result<_, ParseError> {
|
||||
let fill = FillRule::parse(i)?;
|
||||
i.expect_comma()?; // only eat the comma if there is something before it
|
||||
Ok(fill)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let buf = input.parse_comma_separated(|i| {
|
||||
Ok((LengthOrPercentage::parse(context, i)?, LengthOrPercentage::parse(context, i)?))
|
||||
Ok((
|
||||
LengthOrPercentage::parse(context, i)?,
|
||||
LengthOrPercentage::parse(context, i)?,
|
||||
))
|
||||
})?;
|
||||
|
||||
Ok(Polygon {
|
||||
|
|
|
@ -57,7 +57,9 @@ impl BorderSideWidth {
|
|||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(length) = input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks)) {
|
||||
if let Ok(length) =
|
||||
input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks))
|
||||
{
|
||||
return Ok(BorderSideWidth::Length(length));
|
||||
}
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
|
@ -69,7 +71,10 @@ impl BorderSideWidth {
|
|||
}
|
||||
|
||||
impl Parse for BorderSideWidth {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +110,10 @@ impl BorderImageSideWidth {
|
|||
}
|
||||
|
||||
impl Parse for BorderImageSideWidth {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||
return Ok(GenericBorderImageSideWidth::Auto);
|
||||
}
|
||||
|
@ -120,7 +128,10 @@ impl Parse for BorderImageSideWidth {
|
|||
}
|
||||
|
||||
impl Parse for BorderImageSlice {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let mut fill = input.try(|i| i.expect_ident_matching("fill")).is_ok();
|
||||
let offsets = Rect::parse_with(context, input, NumberOrPercentage::parse_non_negative)?;
|
||||
if !fill {
|
||||
|
@ -134,7 +145,10 @@ impl Parse for BorderImageSlice {
|
|||
}
|
||||
|
||||
impl Parse for BorderRadius {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let widths = Rect::parse_with(context, input, LengthOrPercentage::parse_non_negative)?;
|
||||
let heights = if input.try(|i| i.expect_delim('/')).is_ok() {
|
||||
Rect::parse_with(context, input, LengthOrPercentage::parse_non_negative)?
|
||||
|
@ -154,7 +168,7 @@ impl Parse for BorderRadius {
|
|||
impl Parse for BorderCornerRadius {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Size::parse_with(context, input, LengthOrPercentage::parse_non_negative)
|
||||
.map(GenericBorderCornerRadius)
|
||||
|
@ -164,7 +178,7 @@ impl Parse for BorderCornerRadius {
|
|||
impl Parse for BorderSpacing {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Size::parse_with(context, input, |context, input| {
|
||||
Length::parse_non_negative_quirky(context, input, AllowQuirks::Yes).map(From::from)
|
||||
|
@ -221,6 +235,9 @@ impl Parse for BorderImageRepeat {
|
|||
) -> Result<Self, ParseError<'i>> {
|
||||
let horizontal = BorderImageRepeatKeyword::parse(input)?;
|
||||
let vertical = input.try(BorderImageRepeatKeyword::parse).ok();
|
||||
Ok(BorderImageRepeat(horizontal, vertical.unwrap_or(horizontal)))
|
||||
Ok(BorderImageRepeat(
|
||||
horizontal,
|
||||
vertical.unwrap_or(horizontal),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,21 @@ use values::specified::length::{LengthOrPercentage, NonNegativeLength};
|
|||
/// the two basic qualities of how an element generates boxes
|
||||
/// <https://drafts.csswg.org/css-display/#propdef-display>
|
||||
pub enum Display {
|
||||
Inline, Block, InlineBlock,
|
||||
Table, InlineTable, TableRowGroup, TableHeaderGroup,
|
||||
TableFooterGroup, TableRow, TableColumnGroup,
|
||||
TableColumn, TableCell, TableCaption, ListItem, None,
|
||||
Inline,
|
||||
Block,
|
||||
InlineBlock,
|
||||
Table,
|
||||
InlineTable,
|
||||
TableRowGroup,
|
||||
TableHeaderGroup,
|
||||
TableFooterGroup,
|
||||
TableRow,
|
||||
TableColumnGroup,
|
||||
TableColumn,
|
||||
TableCell,
|
||||
TableCaption,
|
||||
ListItem,
|
||||
None,
|
||||
#[css(aliases = "-webkit-flex")]
|
||||
Flex,
|
||||
#[css(aliases = "-webkit-inline-flex")]
|
||||
|
@ -106,9 +117,7 @@ impl Display {
|
|||
match *self {
|
||||
Display::Inline => true,
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::Contents |
|
||||
Display::Ruby |
|
||||
Display::RubyBaseContainer => true,
|
||||
Display::Contents | Display::Ruby | Display::RubyBaseContainer => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -122,16 +131,14 @@ impl Display {
|
|||
///
|
||||
/// FIXME(emilio): This is a pretty decent hack, we should try to
|
||||
/// remove it.
|
||||
pub fn should_ignore_parsed_value(
|
||||
_old_display: Self,
|
||||
_new_display: Self,
|
||||
) -> bool {
|
||||
#[cfg(feature = "gecko")] {
|
||||
pub fn should_ignore_parsed_value(_old_display: Self, _new_display: Self) -> bool {
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
match (_old_display, _new_display) {
|
||||
(Display::WebkitBox, Display::MozBox) |
|
||||
(Display::WebkitInlineBox, Display::MozInlineBox) => {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
@ -143,21 +150,19 @@ impl Display {
|
|||
/// ruby.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn is_ruby_type(&self) -> bool {
|
||||
matches!(*self,
|
||||
Display::Ruby |
|
||||
Display::RubyBase |
|
||||
Display::RubyText |
|
||||
Display::RubyBaseContainer |
|
||||
Display::RubyTextContainer
|
||||
matches!(
|
||||
*self,
|
||||
Display::Ruby | Display::RubyBase | Display::RubyText | Display::RubyBaseContainer |
|
||||
Display::RubyTextContainer
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns whether this "display" value is a ruby level container.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn is_ruby_level_container(&self) -> bool {
|
||||
matches!(*self,
|
||||
Display::RubyBaseContainer |
|
||||
Display::RubyTextContainer
|
||||
matches!(
|
||||
*self,
|
||||
Display::RubyBaseContainer | Display::RubyTextContainer
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -178,25 +183,22 @@ impl Display {
|
|||
// Special handling for contents and list-item on the root
|
||||
// element for Gecko.
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::Contents | Display::ListItem if _is_root_element => Display::Block,
|
||||
Display::Contents | Display::ListItem if _is_root_element =>
|
||||
{
|
||||
Display::Block
|
||||
},
|
||||
|
||||
// These are not changed by blockification.
|
||||
Display::None |
|
||||
Display::Block |
|
||||
Display::Flex |
|
||||
Display::ListItem |
|
||||
Display::Table => *self,
|
||||
Display::None | Display::Block | Display::Flex | Display::ListItem | Display::Table => {
|
||||
*self
|
||||
},
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
Display::Contents |
|
||||
Display::FlowRoot |
|
||||
Display::Grid |
|
||||
Display::WebkitBox => *self,
|
||||
Display::Contents | Display::FlowRoot | Display::Grid | Display::WebkitBox => *self,
|
||||
|
||||
// Everything else becomes block.
|
||||
_ => Display::Block,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Convert this display into an inline-outside display.
|
||||
|
@ -206,8 +208,7 @@ impl Display {
|
|||
#[cfg(feature = "gecko")]
|
||||
pub fn inlinify(&self) -> Self {
|
||||
match *self {
|
||||
Display::Block |
|
||||
Display::FlowRoot => Display::InlineBlock,
|
||||
Display::Block | Display::FlowRoot => Display::InlineBlock,
|
||||
Display::Table => Display::InlineTable,
|
||||
Display::Flex => Display::InlineFlex,
|
||||
Display::Grid => Display::InlineGrid,
|
||||
|
@ -243,7 +244,9 @@ impl Parse for VerticalAlign {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_quirky(context, i, AllowQuirks::Yes)) {
|
||||
if let Ok(lop) =
|
||||
input.try(|i| LengthOrPercentage::parse_quirky(context, i, AllowQuirks::Yes))
|
||||
{
|
||||
return Ok(GenericVerticalAlign::Length(lop));
|
||||
}
|
||||
|
||||
|
@ -272,8 +275,11 @@ impl Parse for AnimationIterationCount {
|
|||
context: &ParserContext,
|
||||
input: &mut ::cssparser::Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_ident_matching("infinite")).is_ok() {
|
||||
return Ok(GenericAnimationIterationCount::Infinite)
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("infinite"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(GenericAnimationIterationCount::Infinite);
|
||||
}
|
||||
|
||||
let number = Number::parse_non_negative(context, input)?;
|
||||
|
@ -320,7 +326,7 @@ impl ToCss for AnimationName {
|
|||
impl Parse for AnimationName {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(name) = input.try(|input| KeyframesName::parse(context, input)) {
|
||||
return Ok(AnimationName(Some(name)));
|
||||
|
@ -333,8 +339,7 @@ impl Parse for AnimationName {
|
|||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq)]
|
||||
#[derive(ToComputedValue, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)]
|
||||
pub enum ScrollSnapType {
|
||||
None,
|
||||
Mandatory,
|
||||
|
@ -343,8 +348,7 @@ pub enum ScrollSnapType {
|
|||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq)]
|
||||
#[derive(ToComputedValue, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)]
|
||||
pub enum OverscrollBehavior {
|
||||
Auto,
|
||||
Contain,
|
||||
|
@ -353,8 +357,7 @@ pub enum OverscrollBehavior {
|
|||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq)]
|
||||
#[derive(ToComputedValue, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)]
|
||||
pub enum OverflowClipBox {
|
||||
PaddingBox,
|
||||
ContentBox,
|
||||
|
@ -386,23 +389,27 @@ impl Parse for WillChange {
|
|||
/// auto | <animateable-feature>#
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<WillChange, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("auto"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(WillChange::Auto);
|
||||
}
|
||||
|
||||
let custom_idents = input.parse_comma_separated(|i| {
|
||||
let location = i.current_source_location();
|
||||
CustomIdent::from_ident(location, i.expect_ident()?, &[
|
||||
"will-change",
|
||||
"none",
|
||||
"all",
|
||||
"auto",
|
||||
])
|
||||
CustomIdent::from_ident(
|
||||
location,
|
||||
i.expect_ident()?,
|
||||
&["will-change", "none", "all", "auto"],
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(WillChange::AnimateableFeatures(custom_idents.into_boxed_slice()))
|
||||
Ok(WillChange::AnimateableFeatures(
|
||||
custom_idents.into_boxed_slice(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -441,15 +448,14 @@ impl ToCss for TouchAction {
|
|||
TouchAction::TOUCH_ACTION_NONE => dest.write_str("none"),
|
||||
TouchAction::TOUCH_ACTION_AUTO => dest.write_str("auto"),
|
||||
TouchAction::TOUCH_ACTION_MANIPULATION => dest.write_str("manipulation"),
|
||||
_ if self.contains(TouchAction::TOUCH_ACTION_PAN_X | TouchAction::TOUCH_ACTION_PAN_Y) => {
|
||||
_ if self.contains(
|
||||
TouchAction::TOUCH_ACTION_PAN_X | TouchAction::TOUCH_ACTION_PAN_Y,
|
||||
) =>
|
||||
{
|
||||
dest.write_str("pan-x pan-y")
|
||||
},
|
||||
_ if self.contains(TouchAction::TOUCH_ACTION_PAN_X) => {
|
||||
dest.write_str("pan-x")
|
||||
},
|
||||
_ if self.contains(TouchAction::TOUCH_ACTION_PAN_Y) => {
|
||||
dest.write_str("pan-y")
|
||||
},
|
||||
_ if self.contains(TouchAction::TOUCH_ACTION_PAN_X) => dest.write_str("pan-x"),
|
||||
_ if self.contains(TouchAction::TOUCH_ACTION_PAN_Y) => dest.write_str("pan-y"),
|
||||
_ => panic!("invalid touch-action value"),
|
||||
}
|
||||
}
|
||||
|
@ -458,7 +464,7 @@ impl ToCss for TouchAction {
|
|||
impl Parse for TouchAction {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<TouchAction, ParseError<'i>> {
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"auto" => Ok(TouchAction::TOUCH_ACTION_AUTO),
|
||||
|
@ -531,10 +537,10 @@ impl ToCss for Contain {
|
|||
W: Write,
|
||||
{
|
||||
if self.is_empty() {
|
||||
return dest.write_str("none")
|
||||
return dest.write_str("none");
|
||||
}
|
||||
if self.contains(Contain::STRICT) {
|
||||
return dest.write_str("strict")
|
||||
return dest.write_str("strict");
|
||||
}
|
||||
|
||||
let mut has_any = false;
|
||||
|
@ -547,7 +553,7 @@ impl ToCss for Contain {
|
|||
has_any = true;
|
||||
dest.write_str($str)?;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
maybe_write_value!(Contain::LAYOUT => "layout");
|
||||
maybe_write_value!(Contain::STYLE => "style");
|
||||
|
@ -562,7 +568,7 @@ impl Parse for Contain {
|
|||
/// none | strict | content | [ size || layout || style || paint ]
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Contain, ParseError<'i>> {
|
||||
let mut result = Contain::empty();
|
||||
while let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
|
||||
|
@ -577,7 +583,9 @@ impl Parse for Contain {
|
|||
|
||||
let flag = match flag {
|
||||
Some(flag) if !result.contains(flag) => flag,
|
||||
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name)))
|
||||
_ => {
|
||||
return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name)))
|
||||
},
|
||||
};
|
||||
result.insert(flag);
|
||||
}
|
||||
|
@ -596,11 +604,14 @@ pub type Perspective = GenericPerspective<NonNegativeLength>;
|
|||
impl Parse for Perspective {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(GenericPerspective::None);
|
||||
}
|
||||
Ok(GenericPerspective::Length(NonNegativeLength::parse(context, input)?))
|
||||
Ok(GenericPerspective::Length(NonNegativeLength::parse(
|
||||
context,
|
||||
input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
//!
|
||||
//! [calc]: https://drafts.csswg.org/css-values/#calc-notation
|
||||
|
||||
use cssparser::{Parser, Token, NumberOrPercentage, AngleOrNumber};
|
||||
use cssparser::{AngleOrNumber, NumberOrPercentage, Parser, Token};
|
||||
use parser::ParserContext;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
use values::{CSSInteger, CSSFloat};
|
||||
use values::{CSSFloat, CSSInteger};
|
||||
use values::computed;
|
||||
use values::specified::{Angle, Time};
|
||||
use values::specified::length::{AbsoluteLength, FontRelativeLength, NoCalcLength};
|
||||
|
@ -98,11 +98,7 @@ impl ToCss for CalcLengthOrPercentage {
|
|||
macro_rules! first_value_check {
|
||||
($val:expr) => {
|
||||
if !first_value {
|
||||
dest.write_str(if $val < Zero::zero() {
|
||||
" - "
|
||||
} else {
|
||||
" + "
|
||||
})?;
|
||||
dest.write_str(if $val < Zero::zero() { " - " } else { " + " })?;
|
||||
} else if $val < Zero::zero() {
|
||||
dest.write_str("-")?;
|
||||
}
|
||||
|
@ -164,39 +160,57 @@ impl CalcNode {
|
|||
fn parse_one<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
expected_unit: CalcUnit
|
||||
expected_unit: CalcUnit,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
// FIXME: remove early returns when lifetimes are non-lexical
|
||||
match (input.next()?, expected_unit) {
|
||||
(&Token::Number { value, .. }, _) => return Ok(CalcNode::Number(value)),
|
||||
(&Token::Dimension { value, ref unit, .. }, CalcUnit::Length) |
|
||||
(&Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage) => {
|
||||
(
|
||||
&Token::Dimension {
|
||||
value, ref unit, ..
|
||||
},
|
||||
CalcUnit::Length,
|
||||
) |
|
||||
(
|
||||
&Token::Dimension {
|
||||
value, ref unit, ..
|
||||
},
|
||||
CalcUnit::LengthOrPercentage,
|
||||
) => {
|
||||
return NoCalcLength::parse_dimension(context, value, unit)
|
||||
.map(CalcNode::Length)
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
(&Token::Dimension { value, ref unit, .. }, CalcUnit::Angle) => {
|
||||
},
|
||||
(
|
||||
&Token::Dimension {
|
||||
value, ref unit, ..
|
||||
},
|
||||
CalcUnit::Angle,
|
||||
) => {
|
||||
return Angle::parse_dimension(value, unit, /* from_calc = */ true)
|
||||
.map(CalcNode::Angle)
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
(&Token::Dimension { value, ref unit, .. }, CalcUnit::Time) => {
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
},
|
||||
(
|
||||
&Token::Dimension {
|
||||
value, ref unit, ..
|
||||
},
|
||||
CalcUnit::Time,
|
||||
) => {
|
||||
return Time::parse_dimension(value, unit, /* from_calc = */ true)
|
||||
.map(CalcNode::Time)
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
},
|
||||
(&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) |
|
||||
(&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => {
|
||||
return Ok(CalcNode::Percentage(unit_value))
|
||||
}
|
||||
(&Token::ParenthesisBlock, _) => {}
|
||||
(&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {}
|
||||
(t, _) => return Err(location.new_unexpected_token_error(t.clone()))
|
||||
},
|
||||
(&Token::ParenthesisBlock, _) => {},
|
||||
(&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {},
|
||||
(t, _) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
input.parse_nested_block(|i| {
|
||||
CalcNode::parse(context, i, expected_unit)
|
||||
})
|
||||
input.parse_nested_block(|i| CalcNode::parse(context, i, expected_unit))
|
||||
}
|
||||
|
||||
/// Parse a top-level `calc` expression, with all nested sub-expressions.
|
||||
|
@ -219,26 +233,22 @@ impl CalcNode {
|
|||
// FIXME: remove clone() when lifetimes are non-lexical
|
||||
match input.next()?.clone() {
|
||||
Token::Delim('+') => {
|
||||
let rhs =
|
||||
Self::parse_product(context, input, expected_unit)?;
|
||||
let new_root =
|
||||
CalcNode::Sum(Box::new(root), Box::new(rhs));
|
||||
let rhs = Self::parse_product(context, input, expected_unit)?;
|
||||
let new_root = CalcNode::Sum(Box::new(root), Box::new(rhs));
|
||||
root = new_root;
|
||||
}
|
||||
},
|
||||
Token::Delim('-') => {
|
||||
let rhs =
|
||||
Self::parse_product(context, input, expected_unit)?;
|
||||
let new_root =
|
||||
CalcNode::Sub(Box::new(root), Box::new(rhs));
|
||||
let rhs = Self::parse_product(context, input, expected_unit)?;
|
||||
let new_root = CalcNode::Sub(Box::new(root), Box::new(rhs));
|
||||
root = new_root;
|
||||
}
|
||||
},
|
||||
t => return Err(input.new_unexpected_token_error(t)),
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
input.reset(&start);
|
||||
break
|
||||
}
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,9 +267,8 @@ impl CalcNode {
|
|||
fn parse_product<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
expected_unit: CalcUnit)
|
||||
-> Result<Self, ParseError<'i>>
|
||||
{
|
||||
expected_unit: CalcUnit,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let mut root = Self::parse_one(context, input, expected_unit)?;
|
||||
|
||||
loop {
|
||||
|
@ -269,17 +278,17 @@ impl CalcNode {
|
|||
let rhs = Self::parse_one(context, input, expected_unit)?;
|
||||
let new_root = CalcNode::Mul(Box::new(root), Box::new(rhs));
|
||||
root = new_root;
|
||||
}
|
||||
},
|
||||
// TODO(emilio): Figure out why the `Integer` check.
|
||||
Ok(&Token::Delim('/')) if expected_unit != CalcUnit::Integer => {
|
||||
let rhs = Self::parse_one(context, input, expected_unit)?;
|
||||
let new_root = CalcNode::Div(Box::new(root), Box::new(rhs));
|
||||
root = new_root;
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
input.reset(&start);
|
||||
break
|
||||
}
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,11 +297,13 @@ impl CalcNode {
|
|||
|
||||
/// Tries to simplify this expression into a `<length>` or `<percentage`>
|
||||
/// value.
|
||||
fn to_length_or_percentage(&self, clamping_mode: AllowedNumericType)
|
||||
-> Result<CalcLengthOrPercentage, ()> {
|
||||
fn to_length_or_percentage(
|
||||
&self,
|
||||
clamping_mode: AllowedNumericType,
|
||||
) -> Result<CalcLengthOrPercentage, ()> {
|
||||
let mut ret = CalcLengthOrPercentage {
|
||||
clamping_mode: clamping_mode,
|
||||
.. Default::default()
|
||||
..Default::default()
|
||||
};
|
||||
self.add_length_or_percentage_to(&mut ret, 1.0)?;
|
||||
Ok(ret)
|
||||
|
@ -302,33 +313,27 @@ impl CalcNode {
|
|||
fn to_percentage(&self) -> Result<CSSFloat, ()> {
|
||||
Ok(match *self {
|
||||
CalcNode::Percentage(percentage) => percentage,
|
||||
CalcNode::Sub(ref a, ref b) => {
|
||||
a.to_percentage()? - b.to_percentage()?
|
||||
}
|
||||
CalcNode::Sum(ref a, ref b) => {
|
||||
a.to_percentage()? + b.to_percentage()?
|
||||
}
|
||||
CalcNode::Mul(ref a, ref b) => {
|
||||
match a.to_percentage() {
|
||||
Ok(lhs) => {
|
||||
let rhs = b.to_number()?;
|
||||
lhs * rhs
|
||||
}
|
||||
Err(..) => {
|
||||
let lhs = a.to_number()?;
|
||||
let rhs = b.to_percentage()?;
|
||||
lhs * rhs
|
||||
}
|
||||
}
|
||||
}
|
||||
CalcNode::Sub(ref a, ref b) => a.to_percentage()? - b.to_percentage()?,
|
||||
CalcNode::Sum(ref a, ref b) => a.to_percentage()? + b.to_percentage()?,
|
||||
CalcNode::Mul(ref a, ref b) => match a.to_percentage() {
|
||||
Ok(lhs) => {
|
||||
let rhs = b.to_number()?;
|
||||
lhs * rhs
|
||||
},
|
||||
Err(..) => {
|
||||
let lhs = a.to_number()?;
|
||||
let rhs = b.to_percentage()?;
|
||||
lhs * rhs
|
||||
},
|
||||
},
|
||||
CalcNode::Div(ref a, ref b) => {
|
||||
let lhs = a.to_percentage()?;
|
||||
let rhs = b.to_number()?;
|
||||
if rhs == 0. {
|
||||
return Err(())
|
||||
return Err(());
|
||||
}
|
||||
lhs / rhs
|
||||
}
|
||||
},
|
||||
CalcNode::Number(..) |
|
||||
CalcNode::Length(..) |
|
||||
CalcNode::Angle(..) |
|
||||
|
@ -343,89 +348,76 @@ impl CalcNode {
|
|||
fn add_length_or_percentage_to(
|
||||
&self,
|
||||
ret: &mut CalcLengthOrPercentage,
|
||||
factor: CSSFloat)
|
||||
-> Result<(), ()>
|
||||
{
|
||||
factor: CSSFloat,
|
||||
) -> Result<(), ()> {
|
||||
match *self {
|
||||
CalcNode::Percentage(pct) => {
|
||||
ret.percentage = Some(computed::Percentage(
|
||||
ret.percentage.map_or(0., |p| p.0) + pct * factor,
|
||||
));
|
||||
}
|
||||
CalcNode::Length(ref l) => {
|
||||
match *l {
|
||||
NoCalcLength::Absolute(abs) => {
|
||||
ret.absolute = Some(
|
||||
match ret.absolute {
|
||||
Some(value) => value + abs * factor,
|
||||
None => abs * factor,
|
||||
}
|
||||
);
|
||||
}
|
||||
NoCalcLength::FontRelative(rel) => {
|
||||
match rel {
|
||||
FontRelativeLength::Em(em) => {
|
||||
ret.em = Some(ret.em.unwrap_or(0.) + em * factor);
|
||||
}
|
||||
FontRelativeLength::Ex(ex) => {
|
||||
ret.ex = Some(ret.ex.unwrap_or(0.) + ex * factor);
|
||||
}
|
||||
FontRelativeLength::Ch(ch) => {
|
||||
ret.ch = Some(ret.ch.unwrap_or(0.) + ch * factor);
|
||||
}
|
||||
FontRelativeLength::Rem(rem) => {
|
||||
ret.rem = Some(ret.rem.unwrap_or(0.) + rem * factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
NoCalcLength::ViewportPercentage(rel) => {
|
||||
match rel {
|
||||
ViewportPercentageLength::Vh(vh) => {
|
||||
ret.vh = Some(ret.vh.unwrap_or(0.) + vh * factor)
|
||||
}
|
||||
ViewportPercentageLength::Vw(vw) => {
|
||||
ret.vw = Some(ret.vw.unwrap_or(0.) + vw * factor)
|
||||
}
|
||||
ViewportPercentageLength::Vmax(vmax) => {
|
||||
ret.vmax = Some(ret.vmax.unwrap_or(0.) + vmax * factor)
|
||||
}
|
||||
ViewportPercentageLength::Vmin(vmin) => {
|
||||
ret.vmin = Some(ret.vmin.unwrap_or(0.) + vmin * factor)
|
||||
}
|
||||
}
|
||||
}
|
||||
NoCalcLength::ServoCharacterWidth(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
},
|
||||
CalcNode::Length(ref l) => match *l {
|
||||
NoCalcLength::Absolute(abs) => {
|
||||
ret.absolute = Some(match ret.absolute {
|
||||
Some(value) => value + abs * factor,
|
||||
None => abs * factor,
|
||||
});
|
||||
},
|
||||
NoCalcLength::FontRelative(rel) => match rel {
|
||||
FontRelativeLength::Em(em) => {
|
||||
ret.em = Some(ret.em.unwrap_or(0.) + em * factor);
|
||||
},
|
||||
FontRelativeLength::Ex(ex) => {
|
||||
ret.ex = Some(ret.ex.unwrap_or(0.) + ex * factor);
|
||||
},
|
||||
FontRelativeLength::Ch(ch) => {
|
||||
ret.ch = Some(ret.ch.unwrap_or(0.) + ch * factor);
|
||||
},
|
||||
FontRelativeLength::Rem(rem) => {
|
||||
ret.rem = Some(ret.rem.unwrap_or(0.) + rem * factor);
|
||||
},
|
||||
},
|
||||
NoCalcLength::ViewportPercentage(rel) => match rel {
|
||||
ViewportPercentageLength::Vh(vh) => {
|
||||
ret.vh = Some(ret.vh.unwrap_or(0.) + vh * factor)
|
||||
},
|
||||
ViewportPercentageLength::Vw(vw) => {
|
||||
ret.vw = Some(ret.vw.unwrap_or(0.) + vw * factor)
|
||||
},
|
||||
ViewportPercentageLength::Vmax(vmax) => {
|
||||
ret.vmax = Some(ret.vmax.unwrap_or(0.) + vmax * factor)
|
||||
},
|
||||
ViewportPercentageLength::Vmin(vmin) => {
|
||||
ret.vmin = Some(ret.vmin.unwrap_or(0.) + vmin * factor)
|
||||
},
|
||||
},
|
||||
NoCalcLength::ServoCharacterWidth(..) => unreachable!(),
|
||||
},
|
||||
CalcNode::Sub(ref a, ref b) => {
|
||||
a.add_length_or_percentage_to(ret, factor)?;
|
||||
b.add_length_or_percentage_to(ret, factor * -1.0)?;
|
||||
}
|
||||
},
|
||||
CalcNode::Sum(ref a, ref b) => {
|
||||
a.add_length_or_percentage_to(ret, factor)?;
|
||||
b.add_length_or_percentage_to(ret, factor)?;
|
||||
}
|
||||
CalcNode::Mul(ref a, ref b) => {
|
||||
match b.to_number() {
|
||||
Ok(rhs) => {
|
||||
a.add_length_or_percentage_to(ret, factor * rhs)?;
|
||||
}
|
||||
Err(..) => {
|
||||
let lhs = a.to_number()?;
|
||||
b.add_length_or_percentage_to(ret, factor * lhs)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
CalcNode::Mul(ref a, ref b) => match b.to_number() {
|
||||
Ok(rhs) => {
|
||||
a.add_length_or_percentage_to(ret, factor * rhs)?;
|
||||
},
|
||||
Err(..) => {
|
||||
let lhs = a.to_number()?;
|
||||
b.add_length_or_percentage_to(ret, factor * lhs)?;
|
||||
},
|
||||
},
|
||||
CalcNode::Div(ref a, ref b) => {
|
||||
let new_factor = b.to_number()?;
|
||||
if new_factor == 0. {
|
||||
return Err(());
|
||||
}
|
||||
a.add_length_or_percentage_to(ret, factor / new_factor)?;
|
||||
}
|
||||
CalcNode::Angle(..) |
|
||||
CalcNode::Time(..) |
|
||||
CalcNode::Number(..) => return Err(()),
|
||||
},
|
||||
CalcNode::Angle(..) | CalcNode::Time(..) | CalcNode::Number(..) => return Err(()),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -439,33 +431,31 @@ impl CalcNode {
|
|||
let lhs = a.to_time()?;
|
||||
let rhs = b.to_time()?;
|
||||
Time::from_calc(lhs.seconds() - rhs.seconds())
|
||||
}
|
||||
},
|
||||
CalcNode::Sum(ref a, ref b) => {
|
||||
let lhs = a.to_time()?;
|
||||
let rhs = b.to_time()?;
|
||||
Time::from_calc(lhs.seconds() + rhs.seconds())
|
||||
}
|
||||
CalcNode::Mul(ref a, ref b) => {
|
||||
match b.to_number() {
|
||||
Ok(rhs) => {
|
||||
let lhs = a.to_time()?;
|
||||
Time::from_calc(lhs.seconds() * rhs)
|
||||
}
|
||||
Err(()) => {
|
||||
let lhs = a.to_number()?;
|
||||
let rhs = b.to_time()?;
|
||||
Time::from_calc(lhs * rhs.seconds())
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
CalcNode::Mul(ref a, ref b) => match b.to_number() {
|
||||
Ok(rhs) => {
|
||||
let lhs = a.to_time()?;
|
||||
Time::from_calc(lhs.seconds() * rhs)
|
||||
},
|
||||
Err(()) => {
|
||||
let lhs = a.to_number()?;
|
||||
let rhs = b.to_time()?;
|
||||
Time::from_calc(lhs * rhs.seconds())
|
||||
},
|
||||
},
|
||||
CalcNode::Div(ref a, ref b) => {
|
||||
let lhs = a.to_time()?;
|
||||
let rhs = b.to_number()?;
|
||||
if rhs == 0. {
|
||||
return Err(())
|
||||
return Err(());
|
||||
}
|
||||
Time::from_calc(lhs.seconds() / rhs)
|
||||
}
|
||||
},
|
||||
CalcNode::Number(..) |
|
||||
CalcNode::Length(..) |
|
||||
CalcNode::Percentage(..) |
|
||||
|
@ -481,33 +471,31 @@ impl CalcNode {
|
|||
let lhs = a.to_angle()?;
|
||||
let rhs = b.to_angle()?;
|
||||
Angle::from_calc(lhs.radians() - rhs.radians())
|
||||
}
|
||||
},
|
||||
CalcNode::Sum(ref a, ref b) => {
|
||||
let lhs = a.to_angle()?;
|
||||
let rhs = b.to_angle()?;
|
||||
Angle::from_calc(lhs.radians() + rhs.radians())
|
||||
}
|
||||
CalcNode::Mul(ref a, ref b) => {
|
||||
match a.to_angle() {
|
||||
Ok(lhs) => {
|
||||
let rhs = b.to_number()?;
|
||||
Angle::from_calc(lhs.radians() * rhs)
|
||||
}
|
||||
Err(..) => {
|
||||
let lhs = a.to_number()?;
|
||||
let rhs = b.to_angle()?;
|
||||
Angle::from_calc(lhs * rhs.radians())
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
CalcNode::Mul(ref a, ref b) => match a.to_angle() {
|
||||
Ok(lhs) => {
|
||||
let rhs = b.to_number()?;
|
||||
Angle::from_calc(lhs.radians() * rhs)
|
||||
},
|
||||
Err(..) => {
|
||||
let lhs = a.to_number()?;
|
||||
let rhs = b.to_angle()?;
|
||||
Angle::from_calc(lhs * rhs.radians())
|
||||
},
|
||||
},
|
||||
CalcNode::Div(ref a, ref b) => {
|
||||
let lhs = a.to_angle()?;
|
||||
let rhs = b.to_number()?;
|
||||
if rhs == 0. {
|
||||
return Err(())
|
||||
return Err(());
|
||||
}
|
||||
Angle::from_calc(lhs.radians() / rhs)
|
||||
}
|
||||
},
|
||||
CalcNode::Number(..) |
|
||||
CalcNode::Length(..) |
|
||||
CalcNode::Percentage(..) |
|
||||
|
@ -519,23 +507,17 @@ impl CalcNode {
|
|||
fn to_number(&self) -> Result<CSSFloat, ()> {
|
||||
Ok(match *self {
|
||||
CalcNode::Number(n) => n,
|
||||
CalcNode::Sum(ref a, ref b) => {
|
||||
a.to_number()? + b.to_number()?
|
||||
}
|
||||
CalcNode::Sub(ref a, ref b) => {
|
||||
a.to_number()? - b.to_number()?
|
||||
}
|
||||
CalcNode::Mul(ref a, ref b) => {
|
||||
a.to_number()? * b.to_number()?
|
||||
}
|
||||
CalcNode::Sum(ref a, ref b) => a.to_number()? + b.to_number()?,
|
||||
CalcNode::Sub(ref a, ref b) => a.to_number()? - b.to_number()?,
|
||||
CalcNode::Mul(ref a, ref b) => a.to_number()? * b.to_number()?,
|
||||
CalcNode::Div(ref a, ref b) => {
|
||||
let lhs = a.to_number()?;
|
||||
let rhs = b.to_number()?;
|
||||
if rhs == 0. {
|
||||
return Err(())
|
||||
return Err(());
|
||||
}
|
||||
lhs / rhs
|
||||
}
|
||||
},
|
||||
CalcNode::Length(..) |
|
||||
CalcNode::Percentage(..) |
|
||||
CalcNode::Angle(..) |
|
||||
|
@ -546,7 +528,7 @@ impl CalcNode {
|
|||
/// Convenience parsing function for integers.
|
||||
pub fn parse_integer<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CSSInteger, ParseError<'i>> {
|
||||
Self::parse(context, input, CalcUnit::Integer)?
|
||||
.to_number()
|
||||
|
@ -558,7 +540,7 @@ impl CalcNode {
|
|||
pub fn parse_length_or_percentage<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
clamping_mode: AllowedNumericType
|
||||
clamping_mode: AllowedNumericType,
|
||||
) -> Result<CalcLengthOrPercentage, ParseError<'i>> {
|
||||
Self::parse(context, input, CalcUnit::LengthOrPercentage)?
|
||||
.to_length_or_percentage(clamping_mode)
|
||||
|
@ -568,7 +550,7 @@ impl CalcNode {
|
|||
/// Convenience parsing function for percentages.
|
||||
pub fn parse_percentage<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CSSFloat, ParseError<'i>> {
|
||||
Self::parse(context, input, CalcUnit::Percentage)?
|
||||
.to_percentage()
|
||||
|
@ -579,7 +561,7 @@ impl CalcNode {
|
|||
pub fn parse_length<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
clamping_mode: AllowedNumericType
|
||||
clamping_mode: AllowedNumericType,
|
||||
) -> Result<CalcLengthOrPercentage, ParseError<'i>> {
|
||||
Self::parse(context, input, CalcUnit::Length)?
|
||||
.to_length_or_percentage(clamping_mode)
|
||||
|
@ -589,7 +571,7 @@ impl CalcNode {
|
|||
/// Convenience parsing function for `<number>`.
|
||||
pub fn parse_number<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CSSFloat, ParseError<'i>> {
|
||||
Self::parse(context, input, CalcUnit::Number)?
|
||||
.to_number()
|
||||
|
@ -599,7 +581,7 @@ impl CalcNode {
|
|||
/// Convenience parsing function for `<angle>`.
|
||||
pub fn parse_angle<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Angle, ParseError<'i>> {
|
||||
Self::parse(context, input, CalcUnit::Angle)?
|
||||
.to_angle()
|
||||
|
@ -609,7 +591,7 @@ impl CalcNode {
|
|||
/// Convenience parsing function for `<time>`.
|
||||
pub fn parse_time<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Time, ParseError<'i>> {
|
||||
Self::parse(context, input, CalcUnit::Time)?
|
||||
.to_time()
|
||||
|
@ -619,12 +601,12 @@ impl CalcNode {
|
|||
/// Convenience parsing function for `<number>` or `<percentage>`.
|
||||
pub fn parse_number_or_percentage<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<NumberOrPercentage, ParseError<'i>> {
|
||||
let node = Self::parse(context, input, CalcUnit::Percentage)?;
|
||||
|
||||
if let Ok(value) = node.to_number() {
|
||||
return Ok(NumberOrPercentage::Number { value })
|
||||
return Ok(NumberOrPercentage::Number { value });
|
||||
}
|
||||
|
||||
match node.to_percentage() {
|
||||
|
@ -636,13 +618,13 @@ impl CalcNode {
|
|||
/// Convenience parsing function for `<number>` or `<angle>`.
|
||||
pub fn parse_angle_or_number<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<AngleOrNumber, ParseError<'i>> {
|
||||
let node = Self::parse(context, input, CalcUnit::Angle)?;
|
||||
|
||||
if let Ok(angle) = node.to_angle() {
|
||||
let degrees = angle.degrees();
|
||||
return Ok(AngleOrNumber::Angle { degrees })
|
||||
return Ok(AngleOrNumber::Angle { degrees });
|
||||
}
|
||||
|
||||
match node.to_number() {
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
//! Specified color values.
|
||||
|
||||
use cssparser::{AngleOrNumber, Color as CSSParserColor, Parser, RGBA, Token};
|
||||
use cssparser::{AngleOrNumber, Color as CSSParserColor, Parser, Token, RGBA};
|
||||
use cssparser::{BasicParseErrorKind, NumberOrPercentage, ParseErrorKind};
|
||||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::structs::nscolor;
|
||||
use itoa;
|
||||
use parser::{ParserContext, Parse};
|
||||
use parser::{Parse, ParserContext};
|
||||
#[cfg(feature = "gecko")]
|
||||
use properties::longhands::system_colors::SystemColor;
|
||||
use std::fmt::{self, Write};
|
||||
|
@ -76,12 +76,10 @@ impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponen
|
|||
let location = input.current_source_location();
|
||||
let token = input.next()?.clone();
|
||||
match token {
|
||||
Token::Dimension { value, ref unit, .. } => {
|
||||
let angle = Angle::parse_dimension(
|
||||
value,
|
||||
unit,
|
||||
/* from_calc = */ false,
|
||||
);
|
||||
Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} => {
|
||||
let angle = Angle::parse_dimension(value, unit, /* from_calc = */ false);
|
||||
|
||||
let degrees = match angle {
|
||||
Ok(angle) => angle.degrees(),
|
||||
|
@ -89,30 +87,22 @@ impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponen
|
|||
};
|
||||
|
||||
Ok(AngleOrNumber::Angle { degrees })
|
||||
}
|
||||
Token::Number { value, .. } => {
|
||||
Ok(AngleOrNumber::Number { value })
|
||||
}
|
||||
},
|
||||
Token::Number { value, .. } => Ok(AngleOrNumber::Number { value }),
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||
input.parse_nested_block(|i| CalcNode::parse_angle_or_number(self.0, i))
|
||||
}
|
||||
},
|
||||
t => return Err(location.new_unexpected_token_error(t)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_percentage<'t>(
|
||||
&self,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<f32, ParseError<'i>> {
|
||||
fn parse_percentage<'t>(&self, input: &mut Parser<'i, 't>) -> Result<f32, ParseError<'i>> {
|
||||
use values::specified::Percentage;
|
||||
|
||||
Ok(Percentage::parse(self.0, input)?.get())
|
||||
}
|
||||
|
||||
fn parse_number<'t>(
|
||||
&self,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<f32, ParseError<'i>> {
|
||||
fn parse_number<'t>(&self, input: &mut Parser<'i, 't>) -> Result<f32, ParseError<'i>> {
|
||||
use values::specified::Number;
|
||||
|
||||
Ok(Number::parse(self.0, input)?.get())
|
||||
|
@ -131,14 +121,17 @@ impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponen
|
|||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||
input.parse_nested_block(|i| CalcNode::parse_number_or_percentage(self.0, i))
|
||||
}
|
||||
t => return Err(location.new_unexpected_token_error(t))
|
||||
},
|
||||
t => return Err(location.new_unexpected_token_error(t)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for Color {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
// Currently we only store authored value for color keywords,
|
||||
// because all browsers serialize those values as keywords for
|
||||
// specified value.
|
||||
|
@ -148,15 +141,13 @@ impl Parse for Color {
|
|||
|
||||
let compontent_parser = ColorComponentParser(&*context);
|
||||
match input.try(|i| CSSParserColor::parse_with(&compontent_parser, i)) {
|
||||
Ok(value) => {
|
||||
Ok(match value {
|
||||
CSSParserColor::CurrentColor => Color::CurrentColor,
|
||||
CSSParserColor::RGBA(rgba) => Color::Numeric {
|
||||
parsed: rgba,
|
||||
authored: authored.map(|s| s.to_ascii_lowercase().into_boxed_str()),
|
||||
},
|
||||
})
|
||||
}
|
||||
Ok(value) => Ok(match value {
|
||||
CSSParserColor::CurrentColor => Color::CurrentColor,
|
||||
CSSParserColor::RGBA(rgba) => Color::Numeric {
|
||||
parsed: rgba,
|
||||
authored: authored.map(|s| s.to_ascii_lowercase().into_boxed_str()),
|
||||
},
|
||||
}),
|
||||
Err(e) => {
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
|
@ -173,13 +164,13 @@ impl Parse for Color {
|
|||
|
||||
match e.kind {
|
||||
ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(t)) => {
|
||||
Err(e.location.new_custom_error(
|
||||
StyleParseErrorKind::ValueError(ValueParseErrorKind::InvalidColor(t))
|
||||
))
|
||||
}
|
||||
_ => Err(e)
|
||||
Err(e.location.new_custom_error(StyleParseErrorKind::ValueError(
|
||||
ValueParseErrorKind::InvalidColor(t),
|
||||
)))
|
||||
},
|
||||
_ => Err(e),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -191,8 +182,13 @@ impl ToCss for Color {
|
|||
{
|
||||
match *self {
|
||||
Color::CurrentColor => CSSParserColor::CurrentColor.to_css(dest),
|
||||
Color::Numeric { authored: Some(ref authored), .. } => dest.write_str(authored),
|
||||
Color::Numeric { parsed: ref rgba, .. } => rgba.to_css(dest),
|
||||
Color::Numeric {
|
||||
authored: Some(ref authored),
|
||||
..
|
||||
} => dest.write_str(authored),
|
||||
Color::Numeric {
|
||||
parsed: ref rgba, ..
|
||||
} => rgba.to_css(dest),
|
||||
Color::Complex(_) => Ok(()),
|
||||
#[cfg(feature = "gecko")]
|
||||
Color::System(system) => system.to_css(dest),
|
||||
|
@ -210,12 +206,9 @@ impl ToCss for Color {
|
|||
/// handle a cssparser::Color here. This should really be done in cssparser
|
||||
/// directly rather than here.
|
||||
fn parse_hash_color(value: &[u8]) -> Result<RGBA, ()> {
|
||||
CSSParserColor::parse_hash(value).map(|color| {
|
||||
match color {
|
||||
CSSParserColor::RGBA(rgba) => rgba,
|
||||
CSSParserColor::CurrentColor =>
|
||||
unreachable!("parse_hash should never return currentcolor"),
|
||||
}
|
||||
CSSParserColor::parse_hash(value).map(|color| match color {
|
||||
CSSParserColor::RGBA(rgba) => rgba,
|
||||
CSSParserColor::CurrentColor => unreachable!("parse_hash should never return currentcolor"),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -266,19 +259,22 @@ impl Color {
|
|||
fn parse_quirky_color<'i, 't>(input: &mut Parser<'i, 't>) -> Result<RGBA, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
let (value, unit) = match *input.next()? {
|
||||
Token::Number { int_value: Some(integer), .. } => {
|
||||
(integer, None)
|
||||
},
|
||||
Token::Dimension { int_value: Some(integer), ref unit, .. } => {
|
||||
(integer, Some(unit))
|
||||
},
|
||||
Token::Number {
|
||||
int_value: Some(integer),
|
||||
..
|
||||
} => (integer, None),
|
||||
Token::Dimension {
|
||||
int_value: Some(integer),
|
||||
ref unit,
|
||||
..
|
||||
} => (integer, Some(unit)),
|
||||
Token::Ident(ref ident) => {
|
||||
if ident.len() != 3 && ident.len() != 6 {
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
return parse_hash_color(ident.as_bytes())
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
},
|
||||
ref t => {
|
||||
return Err(location.new_unexpected_token_error(t.clone()));
|
||||
},
|
||||
|
@ -299,7 +295,7 @@ impl Color {
|
|||
} else if value <= 999999 {
|
||||
6
|
||||
} else {
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
};
|
||||
let total = length + unit.as_ref().map_or(0, |d| d.len());
|
||||
if total > 6 {
|
||||
|
@ -310,12 +306,13 @@ impl Color {
|
|||
let mut written = space_padding;
|
||||
written += itoa::write(&mut serialization[written..], value).unwrap();
|
||||
if let Some(unit) = unit {
|
||||
written += (&mut serialization[written..]).write(unit.as_bytes()).unwrap();
|
||||
written += (&mut serialization[written..])
|
||||
.write(unit.as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
debug_assert_eq!(written, 6);
|
||||
parse_hash_color(&serialization).map_err(|()| {
|
||||
location.new_custom_error(StyleParseErrorKind::UnspecifiedError)
|
||||
})
|
||||
parse_hash_color(&serialization)
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
|
||||
/// Returns false if the color is completely transparent, and
|
||||
|
@ -339,28 +336,14 @@ impl Color {
|
|||
///
|
||||
/// If `context` is `None`, and the specified color requires data from
|
||||
/// the context to resolve, then `None` is returned.
|
||||
pub fn to_computed_color(
|
||||
&self,
|
||||
_context: Option<&Context>,
|
||||
) -> Option<ComputedColor> {
|
||||
pub fn to_computed_color(&self, _context: Option<&Context>) -> Option<ComputedColor> {
|
||||
match *self {
|
||||
Color::CurrentColor => {
|
||||
Some(ComputedColor::currentcolor())
|
||||
}
|
||||
Color::Numeric { ref parsed, .. } => {
|
||||
Some(ComputedColor::rgba(*parsed))
|
||||
}
|
||||
Color::Complex(ref complex) => {
|
||||
Some(*complex)
|
||||
}
|
||||
Color::CurrentColor => Some(ComputedColor::currentcolor()),
|
||||
Color::Numeric { ref parsed, .. } => Some(ComputedColor::rgba(*parsed)),
|
||||
Color::Complex(ref complex) => Some(*complex),
|
||||
#[cfg(feature = "gecko")]
|
||||
Color::System(system) => {
|
||||
_context.map(|context| {
|
||||
convert_nscolor_to_computedcolor(
|
||||
system.to_computed_value(context)
|
||||
)
|
||||
})
|
||||
}
|
||||
Color::System(system) => _context
|
||||
.map(|context| convert_nscolor_to_computedcolor(system.to_computed_value(context))),
|
||||
#[cfg(feature = "gecko")]
|
||||
Color::Special(special) => {
|
||||
use self::gecko::SpecialColorKeyword as Keyword;
|
||||
|
@ -374,12 +357,10 @@ impl Color {
|
|||
Keyword::MozVisitedhyperlinktext => pres_context.mVisitedLinkColor,
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "gecko")]
|
||||
Color::InheritFromBodyQuirk => {
|
||||
_context.map(|context| {
|
||||
ComputedColor::rgba(context.device().body_text_color())
|
||||
})
|
||||
_context.map(|context| ComputedColor::rgba(context.device().body_text_color()))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -416,9 +397,11 @@ impl ToComputedValue for Color {
|
|||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
pub struct RGBAColor(pub Color);
|
||||
|
||||
|
||||
impl Parse for RGBAColor {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Color::parse(context, input).map(RGBAColor)
|
||||
}
|
||||
}
|
||||
|
@ -427,7 +410,8 @@ impl ToComputedValue for RGBAColor {
|
|||
type ComputedValue = RGBA;
|
||||
|
||||
fn to_computed_value(&self, context: &Context) -> RGBA {
|
||||
self.0.to_computed_value(context)
|
||||
self.0
|
||||
.to_computed_value(context)
|
||||
.to_rgba(context.style().get_color().clone_color())
|
||||
}
|
||||
|
||||
|
@ -453,7 +437,8 @@ impl ToComputedValue for ColorPropertyValue {
|
|||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> RGBA {
|
||||
self.0.to_computed_value(context)
|
||||
self.0
|
||||
.to_computed_value(context)
|
||||
.to_rgba(context.builder.get_parent_color().clone_color())
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@ impl Parse for ColumnCount {
|
|||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||
return Ok(GenericColumnCount::Auto);
|
||||
}
|
||||
Ok(GenericColumnCount::Integer(PositiveInteger::parse(context, input)?))
|
||||
Ok(GenericColumnCount::Integer(PositiveInteger::parse(
|
||||
context,
|
||||
input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#[cfg(feature = "servo")]
|
||||
use computed_values::list_style_type::T as ListStyleType;
|
||||
use cssparser::{Token, Parser};
|
||||
use cssparser::{Parser, Token};
|
||||
use parser::{Parse, ParserContext};
|
||||
use style_traits::{ParseError, StyleParseErrorKind};
|
||||
use values::CustomIdent;
|
||||
|
@ -26,7 +26,7 @@ pub type CounterIncrement = GenericCounterIncrement<Integer>;
|
|||
impl Parse for CounterIncrement {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Ok(Self::new(parse_counters(context, input, 1)?))
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ pub type CounterReset = GenericCounterReset<Integer>;
|
|||
impl Parse for CounterReset {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Ok(Self::new(parse_counters(context, input, 0)?))
|
||||
}
|
||||
|
@ -49,7 +49,10 @@ fn parse_counters<'i, 't>(
|
|||
input: &mut Parser<'i, 't>,
|
||||
default_value: i32,
|
||||
) -> Result<Vec<(CustomIdent, Integer)>, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("none"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
|
@ -62,8 +65,9 @@ fn parse_counters<'i, 't>(
|
|||
Err(_) => break,
|
||||
};
|
||||
|
||||
let counter_delta = input.try(|input| Integer::parse(context, input))
|
||||
.unwrap_or(Integer::new(default_value));
|
||||
let counter_delta = input
|
||||
.try(|input| Integer::parse(context, input))
|
||||
.unwrap_or(Integer::new(default_value));
|
||||
counters.push((counter_name, counter_delta))
|
||||
}
|
||||
|
||||
|
@ -118,7 +122,11 @@ pub enum ContentItem {
|
|||
Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyleType),
|
||||
/// `counters(name, separator, style)`.
|
||||
#[css(comma, function)]
|
||||
Counters(CustomIdent, Box<str>, #[css(skip_if = "is_decimal")] CounterStyleType),
|
||||
Counters(
|
||||
CustomIdent,
|
||||
Box<str>,
|
||||
#[css(skip_if = "is_decimal")] CounterStyleType,
|
||||
),
|
||||
/// `open-quote`.
|
||||
OpenQuote,
|
||||
/// `close-quote`.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//! Specified types for CSS values related to effects.
|
||||
|
||||
use cssparser::{self, Parser, Token, BasicParseErrorKind};
|
||||
use cssparser::{self, BasicParseErrorKind, Parser, Token};
|
||||
use parser::{Parse, ParserContext};
|
||||
use style_traits::{ParseError, StyleParseErrorKind, ValueParseErrorKind};
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
|
@ -23,8 +23,8 @@ use values::specified::length::{Length, NonNegativeLength};
|
|||
use values::specified::url::SpecifiedUrl;
|
||||
|
||||
/// A specified value for a single shadow of the `box-shadow` property.
|
||||
pub type BoxShadow = GenericBoxShadow<Option<RGBAColor>, Length,
|
||||
Option<NonNegativeLength>, Option<Length>>;
|
||||
pub type BoxShadow =
|
||||
GenericBoxShadow<Option<RGBAColor>, Length, Option<NonNegativeLength>, Option<Length>>;
|
||||
|
||||
/// A specified value for a single `filter`.
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -43,7 +43,7 @@ impl Factor {
|
|||
#[inline]
|
||||
pub fn parse_with_clamping_to_one<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Factor::parse(context, input).map(|v| v.clamp_to_one())
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ impl Factor {
|
|||
},
|
||||
NumberOrPercentage::Number(number) => {
|
||||
Factor(NumberOrPercentage::Number(number.clamp_to_one()))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ impl Parse for Factor {
|
|||
#[inline]
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
NumberOrPercentage::parse_non_negative(context, input).map(Factor)
|
||||
}
|
||||
|
@ -86,7 +86,9 @@ impl ToComputedValue for Factor {
|
|||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
Factor(NumberOrPercentage::Number(ToComputedValue::from_computed_value(&computed.0)))
|
||||
Factor(NumberOrPercentage::Number(
|
||||
ToComputedValue::from_computed_value(&computed.0),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +106,10 @@ impl Parse for BoxShadow {
|
|||
|
||||
loop {
|
||||
if !inset {
|
||||
if input.try(|input| input.expect_ident_matching("inset")).is_ok() {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("inset"))
|
||||
.is_ok()
|
||||
{
|
||||
inset = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -113,7 +118,9 @@ impl Parse for BoxShadow {
|
|||
let value = input.try::<_, _, ParseError>(|i| {
|
||||
let horizontal = Length::parse(context, i)?;
|
||||
let vertical = Length::parse(context, i)?;
|
||||
let (blur, spread) = match i.try::<_, _, ParseError>(|i| Length::parse_non_negative(context, i)) {
|
||||
let (blur, spread) = match i.try::<_, _, ParseError>(|i| {
|
||||
Length::parse_non_negative(context, i)
|
||||
}) {
|
||||
Ok(blur) => {
|
||||
let spread = i.try(|i| Length::parse(context, i)).ok();
|
||||
(Some(blur.into()), spread)
|
||||
|
@ -157,7 +164,10 @@ impl ToComputedValue for BoxShadow {
|
|||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
ComputedBoxShadow {
|
||||
base: self.base.to_computed_value(context),
|
||||
spread: self.spread.as_ref().unwrap_or(&Length::zero()).to_computed_value(context),
|
||||
spread: self.spread
|
||||
.as_ref()
|
||||
.unwrap_or(&Length::zero())
|
||||
.to_computed_value(context),
|
||||
inset: self.inset,
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +186,7 @@ impl Parse for Filter {
|
|||
#[inline]
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
|
@ -190,9 +200,7 @@ impl Parse for Filter {
|
|||
Err(cssparser::BasicParseError {
|
||||
kind: BasicParseErrorKind::UnexpectedToken(t),
|
||||
location,
|
||||
}) => {
|
||||
return Err(location.new_custom_error(ValueParseErrorKind::InvalidFilter(t)))
|
||||
}
|
||||
}) => return Err(location.new_custom_error(ValueParseErrorKind::InvalidFilter(t))),
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
input.parse_nested_block(|i| {
|
||||
|
@ -239,7 +247,7 @@ impl Parse for SimpleShadow {
|
|||
#[inline]
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let color = input.try(|i| RGBAColor::parse(context, i)).ok();
|
||||
let horizontal = Length::parse(context, input)?;
|
||||
|
@ -264,8 +272,10 @@ impl ToComputedValue for SimpleShadow {
|
|||
color: self.color.to_computed_value(context),
|
||||
horizontal: self.horizontal.to_computed_value(context),
|
||||
vertical: self.vertical.to_computed_value(context),
|
||||
blur:
|
||||
self.blur.as_ref().unwrap_or(&NonNegativeLength::zero()).to_computed_value(context),
|
||||
blur: self.blur
|
||||
.as_ref()
|
||||
.unwrap_or(&NonNegativeLength::zero())
|
||||
.to_computed_value(context),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,14 +21,16 @@ use values::specified::length::LengthOrPercentage;
|
|||
pub type ScrollSnapPoint = GenericScrollSnapPoint<LengthOrPercentage>;
|
||||
|
||||
impl Parse for ScrollSnapPoint {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(GenericScrollSnapPoint::None);
|
||||
}
|
||||
input.expect_function_matching("repeat")?;
|
||||
let length = input.parse_nested_block(|i| {
|
||||
LengthOrPercentage::parse_non_negative(context, i)
|
||||
})?;
|
||||
let length =
|
||||
input.parse_nested_block(|i| LengthOrPercentage::parse_non_negative(context, i))?;
|
||||
Ok(GenericScrollSnapPoint::Repeat(length))
|
||||
}
|
||||
}
|
||||
|
@ -45,27 +47,25 @@ pub enum PixelOrPercentage {
|
|||
impl Parse for PixelOrPercentage {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
let token = input.next()?;
|
||||
let value = match *token {
|
||||
Token::Dimension { value, ref unit, .. } => {
|
||||
Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} => {
|
||||
match_ignore_ascii_case! { unit,
|
||||
"px" => Ok(PixelOrPercentage::Pixel(CSSPixelLength::new(value))),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
Token::Percentage { unit_value, .. } => {
|
||||
Ok(PixelOrPercentage::Percentage(
|
||||
computed::Percentage(unit_value)
|
||||
))
|
||||
}
|
||||
},
|
||||
Token::Percentage { unit_value, .. } => Ok(PixelOrPercentage::Percentage(
|
||||
computed::Percentage(unit_value),
|
||||
)),
|
||||
_ => Err(()),
|
||||
};
|
||||
value.map_err(|()| {
|
||||
location.new_custom_error(StyleParseErrorKind::UnspecifiedError)
|
||||
})
|
||||
value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,10 @@ impl Parse for IntersectionObserverRootMargin {
|
|||
//
|
||||
// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-rootmargin>
|
||||
impl ToCss for IntersectionObserverRootMargin {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
// We cannot use the ToCss impl of Rect, because that would
|
||||
// merge items when they are equal. We want to list them all.
|
||||
let mut writer = SequenceWriter::new(dest, " ");
|
||||
|
|
|
@ -5,35 +5,42 @@
|
|||
//! CSS handling for the computed value of
|
||||
//! [grids](https://drafts.csswg.org/css-grid/)
|
||||
|
||||
use cssparser::{Parser, Token, ParseError as CssParseError};
|
||||
use cssparser::{ParseError as CssParseError, Parser, Token};
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::mem;
|
||||
use style_traits::{ParseError, StyleParseErrorKind};
|
||||
use values::{CSSFloat, CustomIdent};
|
||||
use values::computed::{self, Context, ToComputedValue};
|
||||
use values::generics::grid::{GridTemplateComponent, RepeatCount, TrackBreadth};
|
||||
use values::generics::grid::{TrackKeyword, TrackRepeat, LineNameList, TrackSize};
|
||||
use values::generics::grid::{LineNameList, TrackKeyword, TrackRepeat, TrackSize};
|
||||
use values::generics::grid::{TrackList, TrackListType, TrackListValue};
|
||||
use values::specified::{LengthOrPercentage, Integer};
|
||||
use values::specified::{Integer, LengthOrPercentage};
|
||||
|
||||
/// Parse a single flexible length.
|
||||
pub fn parse_flex<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CSSFloat, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
match *input.next()? {
|
||||
Token::Dimension { value, ref unit, .. } if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive()
|
||||
=> Ok(value),
|
||||
Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive() =>
|
||||
{
|
||||
Ok(value)
|
||||
},
|
||||
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for TrackBreadth<LengthOrPercentage> {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
|
||||
return Ok(TrackBreadth::Breadth(lop))
|
||||
return Ok(TrackBreadth::Breadth(lop));
|
||||
}
|
||||
|
||||
if let Ok(f) = input.try(parse_flex) {
|
||||
return Ok(TrackBreadth::Fr(f))
|
||||
return Ok(TrackBreadth::Fr(f));
|
||||
}
|
||||
|
||||
TrackKeyword::parse(input).map(TrackBreadth::Keyword)
|
||||
|
@ -41,9 +48,12 @@ impl Parse for TrackBreadth<LengthOrPercentage> {
|
|||
}
|
||||
|
||||
impl Parse for TrackSize<LengthOrPercentage> {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(b) = input.try(|i| TrackBreadth::parse(context, i)) {
|
||||
return Ok(TrackSize::Breadth(b))
|
||||
return Ok(TrackSize::Breadth(b));
|
||||
}
|
||||
|
||||
if input.try(|i| i.expect_function_matching("minmax")).is_ok() {
|
||||
|
@ -54,11 +64,14 @@ impl Parse for TrackSize<LengthOrPercentage> {
|
|||
Err(..) => {
|
||||
let keyword = TrackKeyword::parse(input)?;
|
||||
TrackBreadth::Keyword(keyword)
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
input.expect_comma()?;
|
||||
Ok(TrackSize::Minmax(inflexible_breadth, TrackBreadth::parse(context, input)?))
|
||||
Ok(TrackSize::Minmax(
|
||||
inflexible_breadth,
|
||||
TrackBreadth::parse(context, input)?,
|
||||
))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -71,12 +84,14 @@ impl Parse for TrackSize<LengthOrPercentage> {
|
|||
/// Parse the grid line names into a vector of owned strings.
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-grid/#typedef-line-names>
|
||||
pub fn parse_line_names<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Box<[CustomIdent]>, ParseError<'i>> {
|
||||
pub fn parse_line_names<'i, 't>(
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Box<[CustomIdent]>, ParseError<'i>> {
|
||||
input.expect_square_bracket_block()?;
|
||||
input.parse_nested_block(|input| {
|
||||
let mut values = vec![];
|
||||
while let Ok((loc, ident)) = input.try(|i| -> Result<_, CssParseError<()>> {
|
||||
Ok((i.current_source_location(), i.expect_ident_cloned()?))
|
||||
Ok((i.current_source_location(), i.expect_ident_cloned()?))
|
||||
}) {
|
||||
let ident = CustomIdent::from_ident(loc, &ident, &["span"])?;
|
||||
values.push(ident);
|
||||
|
@ -105,73 +120,86 @@ impl TrackRepeat<LengthOrPercentage, Integer> {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<(Self, RepeatType), ParseError<'i>> {
|
||||
input.try(|i| i.expect_function_matching("repeat").map_err(|e| e.into())).and_then(|_| {
|
||||
input.parse_nested_block(|input| {
|
||||
let count = RepeatCount::parse(context, input)?;
|
||||
input.expect_comma()?;
|
||||
input
|
||||
.try(|i| i.expect_function_matching("repeat").map_err(|e| e.into()))
|
||||
.and_then(|_| {
|
||||
input.parse_nested_block(|input| {
|
||||
let count = RepeatCount::parse(context, input)?;
|
||||
input.expect_comma()?;
|
||||
|
||||
let is_auto = count == RepeatCount::AutoFit || count == RepeatCount::AutoFill;
|
||||
let mut repeat_type = if is_auto {
|
||||
RepeatType::Auto
|
||||
} else { // <fixed-size> is a subset of <track-size>, so it should work for both
|
||||
RepeatType::Fixed
|
||||
};
|
||||
|
||||
let mut names = vec![];
|
||||
let mut values = vec![];
|
||||
let mut current_names;
|
||||
|
||||
loop {
|
||||
current_names = input.try(parse_line_names).unwrap_or(vec![].into_boxed_slice());
|
||||
if let Ok(track_size) = input.try(|i| TrackSize::parse(context, i)) {
|
||||
if !track_size.is_fixed() {
|
||||
if is_auto {
|
||||
// should be <fixed-size> for <auto-repeat>
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
|
||||
if repeat_type == RepeatType::Fixed {
|
||||
repeat_type = RepeatType::Normal // <track-size> for sure
|
||||
}
|
||||
}
|
||||
|
||||
values.push(track_size);
|
||||
names.push(current_names);
|
||||
if is_auto {
|
||||
// FIXME: In the older version of the spec
|
||||
// (https://www.w3.org/TR/2015/WD-css-grid-1-20150917/#typedef-auto-repeat),
|
||||
// if the repeat type is `<auto-repeat>` we shouldn't try to parse more than
|
||||
// one `TrackSize`. But in current version of the spec, this is deprecated
|
||||
// but we are adding this for gecko parity. We should remove this when
|
||||
// gecko implements new spec.
|
||||
names.push(input.try(parse_line_names).unwrap_or(vec![].into_boxed_slice()));
|
||||
break
|
||||
}
|
||||
let is_auto = count == RepeatCount::AutoFit || count == RepeatCount::AutoFill;
|
||||
let mut repeat_type = if is_auto {
|
||||
RepeatType::Auto
|
||||
} else {
|
||||
if values.is_empty() {
|
||||
// expecting at least one <track-size>
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
// <fixed-size> is a subset of <track-size>, so it should work for both
|
||||
RepeatType::Fixed
|
||||
};
|
||||
|
||||
let mut names = vec![];
|
||||
let mut values = vec![];
|
||||
let mut current_names;
|
||||
|
||||
loop {
|
||||
current_names = input
|
||||
.try(parse_line_names)
|
||||
.unwrap_or(vec![].into_boxed_slice());
|
||||
if let Ok(track_size) = input.try(|i| TrackSize::parse(context, i)) {
|
||||
if !track_size.is_fixed() {
|
||||
if is_auto {
|
||||
// should be <fixed-size> for <auto-repeat>
|
||||
return Err(input
|
||||
.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
if repeat_type == RepeatType::Fixed {
|
||||
repeat_type = RepeatType::Normal // <track-size> for sure
|
||||
}
|
||||
}
|
||||
|
||||
values.push(track_size);
|
||||
names.push(current_names);
|
||||
if is_auto {
|
||||
// FIXME: In the older version of the spec
|
||||
// (https://www.w3.org/TR/2015/WD-css-grid-1-20150917/#typedef-auto-repeat),
|
||||
// if the repeat type is `<auto-repeat>` we shouldn't try to parse more than
|
||||
// one `TrackSize`. But in current version of the spec, this is deprecated
|
||||
// but we are adding this for gecko parity. We should remove this when
|
||||
// gecko implements new spec.
|
||||
names.push(
|
||||
input
|
||||
.try(parse_line_names)
|
||||
.unwrap_or(vec![].into_boxed_slice()),
|
||||
);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if values.is_empty() {
|
||||
// expecting at least one <track-size>
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
names.push(current_names); // final `<line-names>`
|
||||
break; // no more <track-size>, breaking
|
||||
}
|
||||
|
||||
names.push(current_names); // final `<line-names>`
|
||||
break // no more <track-size>, breaking
|
||||
}
|
||||
}
|
||||
|
||||
let repeat = TrackRepeat {
|
||||
count: count,
|
||||
track_sizes: values,
|
||||
line_names: names.into_boxed_slice(),
|
||||
};
|
||||
let repeat = TrackRepeat {
|
||||
count: count,
|
||||
track_sizes: values,
|
||||
line_names: names.into_boxed_slice(),
|
||||
};
|
||||
|
||||
Ok((repeat, repeat_type))
|
||||
Ok((repeat, repeat_type))
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for TrackList<LengthOrPercentage, Integer> {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let mut current_names = vec![];
|
||||
let mut names = vec![];
|
||||
let mut values = vec![];
|
||||
|
@ -189,35 +217,40 @@ impl Parse for TrackList<LengthOrPercentage, Integer> {
|
|||
// assume that everything is <fixed-size>. This flag is useful when we encounter <auto-repeat>
|
||||
let mut atleast_one_not_fixed = false;
|
||||
loop {
|
||||
current_names.extend_from_slice(&mut input.try(parse_line_names).unwrap_or(vec![].into_boxed_slice()));
|
||||
current_names.extend_from_slice(&mut input
|
||||
.try(parse_line_names)
|
||||
.unwrap_or(vec![].into_boxed_slice()));
|
||||
if let Ok(track_size) = input.try(|i| TrackSize::parse(context, i)) {
|
||||
if !track_size.is_fixed() {
|
||||
atleast_one_not_fixed = true;
|
||||
if auto_repeat.is_some() {
|
||||
// <auto-track-list> only accepts <fixed-size> and <fixed-repeat>
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
}
|
||||
|
||||
let vec = mem::replace(&mut current_names, vec![]);
|
||||
names.push(vec.into_boxed_slice());
|
||||
values.push(TrackListValue::TrackSize(track_size));
|
||||
} else if let Ok((repeat, type_)) = input.try(|i| TrackRepeat::parse_with_repeat_type(context, i)) {
|
||||
} else if let Ok((repeat, type_)) =
|
||||
input.try(|i| TrackRepeat::parse_with_repeat_type(context, i))
|
||||
{
|
||||
if list_type == TrackListType::Explicit {
|
||||
list_type = TrackListType::Normal; // <explicit-track-list> doesn't contain repeat()
|
||||
list_type = TrackListType::Normal; // <explicit-track-list> doesn't contain repeat()
|
||||
}
|
||||
|
||||
match type_ {
|
||||
RepeatType::Normal => {
|
||||
atleast_one_not_fixed = true;
|
||||
if auto_repeat.is_some() { // only <fixed-repeat>
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
if auto_repeat.is_some() {
|
||||
// only <fixed-repeat>
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
},
|
||||
RepeatType::Auto => {
|
||||
if auto_repeat.is_some() || atleast_one_not_fixed {
|
||||
// We've either seen <auto-repeat> earlier, or there's at least one non-fixed value
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
list_type = TrackListType::Auto(values.len() as u16 + auto_offset);
|
||||
|
@ -237,11 +270,11 @@ impl Parse for TrackList<LengthOrPercentage, Integer> {
|
|||
values.push(TrackListValue::TrackRepeat(repeat));
|
||||
} else {
|
||||
if values.is_empty() && auto_repeat.is_none() {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
names.push(current_names.into_boxed_slice());
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +322,9 @@ impl ToComputedValue for TrackList<LengthOrPercentage, Integer> {
|
|||
// If the repeat count is numeric, we expand and merge the values.
|
||||
let mut repeat = repeat.expand();
|
||||
let mut repeat_names_iter = repeat.line_names.iter();
|
||||
for (size, repeat_names) in repeat.track_sizes.drain(..).zip(&mut repeat_names_iter) {
|
||||
for (size, repeat_names) in
|
||||
repeat.track_sizes.drain(..).zip(&mut repeat_names_iter)
|
||||
{
|
||||
prev_names.extend_from_slice(&repeat_names);
|
||||
let vec = mem::replace(&mut prev_names, vec![]);
|
||||
line_names.push(vec.into_boxed_slice());
|
||||
|
@ -307,14 +342,20 @@ impl ToComputedValue for TrackList<LengthOrPercentage, Integer> {
|
|||
list_type: self.list_type.to_computed_value(context),
|
||||
values: values,
|
||||
line_names: line_names.into_boxed_slice(),
|
||||
auto_repeat: self.auto_repeat.clone().map(|repeat| repeat.to_computed_value(context)),
|
||||
auto_repeat: self.auto_repeat
|
||||
.clone()
|
||||
.map(|repeat| repeat.to_computed_value(context)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
let mut values = Vec::with_capacity(computed.values.len() + 1);
|
||||
for value in computed.values.iter().map(ToComputedValue::from_computed_value) {
|
||||
for value in computed
|
||||
.values
|
||||
.iter()
|
||||
.map(ToComputedValue::from_computed_value)
|
||||
{
|
||||
values.push(value);
|
||||
}
|
||||
|
||||
|
@ -322,7 +363,10 @@ impl ToComputedValue for TrackList<LengthOrPercentage, Integer> {
|
|||
list_type: computed.list_type,
|
||||
values: values,
|
||||
line_names: computed.line_names.clone(),
|
||||
auto_repeat: computed.auto_repeat.clone().map(|ref repeat| TrackRepeat::from_computed_value(repeat)),
|
||||
auto_repeat: computed
|
||||
.auto_repeat
|
||||
.clone()
|
||||
.map(|ref repeat| TrackRepeat::from_computed_value(repeat)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -342,9 +386,12 @@ fn allow_grid_template_subgrids() -> bool {
|
|||
|
||||
impl Parse for GridTemplateComponent<LengthOrPercentage, Integer> {
|
||||
// FIXME: Derive Parse (probably with None_)
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(GridTemplateComponent::None)
|
||||
return Ok(GridTemplateComponent::None);
|
||||
}
|
||||
|
||||
Self::parse_without_none(context, input)
|
||||
|
@ -359,7 +406,7 @@ impl GridTemplateComponent<LengthOrPercentage, Integer> {
|
|||
) -> Result<Self, ParseError<'i>> {
|
||||
if allow_grid_template_subgrids() {
|
||||
if let Ok(t) = input.try(|i| LineNameList::parse(context, i)) {
|
||||
return Ok(GridTemplateComponent::Subgrid(t))
|
||||
return Ok(GridTemplateComponent::Subgrid(t));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,14 +39,8 @@ pub type Image = generic::Image<Gradient, MozImageRect, SpecifiedImageUrl>;
|
|||
/// Specified values for a CSS gradient.
|
||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type Gradient = generic::Gradient<
|
||||
LineDirection,
|
||||
Length,
|
||||
LengthOrPercentage,
|
||||
Position,
|
||||
RGBAColor,
|
||||
Angle,
|
||||
>;
|
||||
pub type Gradient =
|
||||
generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, RGBAColor, Angle>;
|
||||
|
||||
/// Specified values for a CSS gradient.
|
||||
/// <https://drafts.csswg.org/css-images/#gradients>
|
||||
|
@ -62,23 +56,13 @@ pub type Gradient = generic::Gradient<
|
|||
|
||||
/// A specified gradient kind.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type GradientKind = generic::GradientKind<
|
||||
LineDirection,
|
||||
Length,
|
||||
LengthOrPercentage,
|
||||
Position,
|
||||
Angle,
|
||||
>;
|
||||
pub type GradientKind =
|
||||
generic::GradientKind<LineDirection, Length, LengthOrPercentage, Position, Angle>;
|
||||
|
||||
/// A specified gradient kind.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type GradientKind = generic::GradientKind<
|
||||
LineDirection,
|
||||
Length,
|
||||
LengthOrPercentage,
|
||||
GradientPosition,
|
||||
Angle,
|
||||
>;
|
||||
pub type GradientKind =
|
||||
generic::GradientKind<LineDirection, Length, LengthOrPercentage, GradientPosition, Angle>;
|
||||
|
||||
/// A specified gradient line direction.
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
|
||||
|
@ -123,7 +107,10 @@ pub type ColorStop = generic::ColorStop<RGBAColor, LengthOrPercentage>;
|
|||
pub type MozImageRect = generic::MozImageRect<NumberOrPercentage, SpecifiedImageUrl>;
|
||||
|
||||
impl Parse for Image {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Image, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Image, ParseError<'i>> {
|
||||
if let Ok(url) = input.try(|input| SpecifiedImageUrl::parse(context, input)) {
|
||||
return Ok(generic::Image::Url(url));
|
||||
}
|
||||
|
@ -156,17 +143,18 @@ impl Image {
|
|||
fn parse_element<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Atom, ParseError<'i>> {
|
||||
input.try(|i| i.expect_function_matching("-moz-element"))?;
|
||||
let location = input.current_source_location();
|
||||
input.parse_nested_block(|i| {
|
||||
match *i.next()? {
|
||||
Token::IDHash(ref id) => Ok(Atom::from(id.as_ref())),
|
||||
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
input.parse_nested_block(|i| match *i.next()? {
|
||||
Token::IDHash(ref id) => Ok(Atom::from(id.as_ref())),
|
||||
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for Gradient {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
enum Shape {
|
||||
Linear,
|
||||
Radial,
|
||||
|
@ -225,18 +213,18 @@ impl Parse for Gradient {
|
|||
|
||||
let (shape, repeating, mut compat_mode) = match result {
|
||||
Some(result) => result,
|
||||
None => return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(func))),
|
||||
None => {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(func)))
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
use gecko_bindings::structs;
|
||||
if compat_mode == CompatMode::Moz &&
|
||||
!unsafe { structs::StaticPrefs_sVarCache_layout_css_prefixes_gradients }
|
||||
{
|
||||
return Err(input.new_custom_error(
|
||||
StyleParseErrorKind::UnexpectedFunction(func)
|
||||
));
|
||||
if compat_mode == CompatMode::Moz && !unsafe {
|
||||
structs::StaticPrefs_sVarCache_layout_css_prefixes_gradients
|
||||
} {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(func)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,28 +273,17 @@ impl Gradient {
|
|||
_ => return LineDirection::Vertical(Y::Bottom),
|
||||
};
|
||||
match (h, v) {
|
||||
(Ordering::Less, Ordering::Less) => {
|
||||
LineDirection::Corner(X::Right, Y::Bottom)
|
||||
},
|
||||
(Ordering::Less, Ordering::Equal) => {
|
||||
LineDirection::Horizontal(X::Right)
|
||||
},
|
||||
(Ordering::Less, Ordering::Greater) => {
|
||||
LineDirection::Corner(X::Right, Y::Top)
|
||||
},
|
||||
(Ordering::Equal, Ordering::Greater) => {
|
||||
LineDirection::Vertical(Y::Top)
|
||||
},
|
||||
(Ordering::Equal, Ordering::Equal) |
|
||||
(Ordering::Equal, Ordering::Less) => {
|
||||
(Ordering::Less, Ordering::Less) => LineDirection::Corner(X::Right, Y::Bottom),
|
||||
(Ordering::Less, Ordering::Equal) => LineDirection::Horizontal(X::Right),
|
||||
(Ordering::Less, Ordering::Greater) => LineDirection::Corner(X::Right, Y::Top),
|
||||
(Ordering::Equal, Ordering::Greater) => LineDirection::Vertical(Y::Top),
|
||||
(Ordering::Equal, Ordering::Equal) | (Ordering::Equal, Ordering::Less) => {
|
||||
LineDirection::Vertical(Y::Bottom)
|
||||
},
|
||||
(Ordering::Greater, Ordering::Less) => {
|
||||
LineDirection::Corner(X::Left, Y::Bottom)
|
||||
},
|
||||
(Ordering::Greater, Ordering::Equal) => {
|
||||
LineDirection::Horizontal(X::Left)
|
||||
},
|
||||
(Ordering::Greater, Ordering::Equal) => LineDirection::Horizontal(X::Left),
|
||||
(Ordering::Greater, Ordering::Greater) => {
|
||||
LineDirection::Corner(X::Left, Y::Top)
|
||||
},
|
||||
|
@ -321,8 +298,10 @@ impl Gradient {
|
|||
}
|
||||
|
||||
impl Parse for Point {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.try(|i| {
|
||||
let x = Component::parse(context, i)?;
|
||||
let y = Component::parse(context, i)?;
|
||||
|
@ -338,7 +317,11 @@ impl Gradient {
|
|||
Component::Center => NumberOrPercentage::Percentage(Percentage::new(0.5)),
|
||||
Component::Number(number) => number,
|
||||
Component::Side(side) => {
|
||||
let p = if side.is_start() { Percentage::zero() } else { Percentage::hundred() };
|
||||
let p = if side.is_start() {
|
||||
Percentage::zero()
|
||||
} else {
|
||||
Percentage::hundred()
|
||||
};
|
||||
NumberOrPercentage::Percentage(p)
|
||||
},
|
||||
}
|
||||
|
@ -348,41 +331,40 @@ impl Gradient {
|
|||
impl<S: Side> From<Component<S>> for PositionComponent<S> {
|
||||
fn from(component: Component<S>) -> Self {
|
||||
match component {
|
||||
Component::Center => {
|
||||
PositionComponent::Center
|
||||
},
|
||||
Component::Center => PositionComponent::Center,
|
||||
Component::Number(NumberOrPercentage::Number(number)) => {
|
||||
PositionComponent::Length(Length::from_px(number.value).into())
|
||||
},
|
||||
Component::Number(NumberOrPercentage::Percentage(p)) => {
|
||||
PositionComponent::Length(p.into())
|
||||
},
|
||||
Component::Side(side) => {
|
||||
PositionComponent::Side(side, None)
|
||||
},
|
||||
Component::Side(side) => PositionComponent::Side(side, None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Copy + Side> Component<S> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (NumberOrPercentage::from(*self), NumberOrPercentage::from(*other)) {
|
||||
match (
|
||||
NumberOrPercentage::from(*self),
|
||||
NumberOrPercentage::from(*other),
|
||||
) {
|
||||
(NumberOrPercentage::Percentage(a), NumberOrPercentage::Percentage(b)) => {
|
||||
a.get().partial_cmp(&b.get())
|
||||
},
|
||||
(NumberOrPercentage::Number(a), NumberOrPercentage::Number(b)) => {
|
||||
a.value.partial_cmp(&b.value)
|
||||
},
|
||||
(_, _) => {
|
||||
None
|
||||
}
|
||||
(_, _) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Parse> Parse for Component<S> {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(side) = input.try(|i| S::parse(context, i)) {
|
||||
return Ok(Component::Side(side));
|
||||
}
|
||||
|
@ -446,43 +428,45 @@ impl Gradient {
|
|||
},
|
||||
};
|
||||
|
||||
let mut items = input.try(|i| {
|
||||
i.expect_comma()?;
|
||||
i.parse_comma_separated(|i| {
|
||||
let function = i.expect_function()?.clone();
|
||||
let (color, mut p) = i.parse_nested_block(|i| {
|
||||
let p = match_ignore_ascii_case! { &function,
|
||||
"color-stop" => {
|
||||
let p = match NumberOrPercentage::parse(context, i)? {
|
||||
NumberOrPercentage::Number(number) => Percentage::new(number.value),
|
||||
NumberOrPercentage::Percentage(p) => p,
|
||||
};
|
||||
i.expect_comma()?;
|
||||
p
|
||||
},
|
||||
"from" => Percentage::zero(),
|
||||
"to" => Percentage::hundred(),
|
||||
_ => {
|
||||
return Err(i.new_custom_error(
|
||||
StyleParseErrorKind::UnexpectedFunction(function.clone())
|
||||
))
|
||||
},
|
||||
};
|
||||
let color = Color::parse(context, i)?;
|
||||
if color == Color::CurrentColor {
|
||||
return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
let mut items = input
|
||||
.try(|i| {
|
||||
i.expect_comma()?;
|
||||
i.parse_comma_separated(|i| {
|
||||
let function = i.expect_function()?.clone();
|
||||
let (color, mut p) = i.parse_nested_block(|i| {
|
||||
let p = match_ignore_ascii_case! { &function,
|
||||
"color-stop" => {
|
||||
let p = match NumberOrPercentage::parse(context, i)? {
|
||||
NumberOrPercentage::Number(number) => Percentage::new(number.value),
|
||||
NumberOrPercentage::Percentage(p) => p,
|
||||
};
|
||||
i.expect_comma()?;
|
||||
p
|
||||
},
|
||||
"from" => Percentage::zero(),
|
||||
"to" => Percentage::hundred(),
|
||||
_ => {
|
||||
return Err(i.new_custom_error(
|
||||
StyleParseErrorKind::UnexpectedFunction(function.clone())
|
||||
))
|
||||
},
|
||||
};
|
||||
let color = Color::parse(context, i)?;
|
||||
if color == Color::CurrentColor {
|
||||
return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
Ok((color.into(), p))
|
||||
})?;
|
||||
if reverse_stops {
|
||||
p.reverse();
|
||||
}
|
||||
Ok((color.into(), p))
|
||||
})?;
|
||||
if reverse_stops {
|
||||
p.reverse();
|
||||
}
|
||||
Ok(generic::GradientItem::ColorStop(generic::ColorStop {
|
||||
color: color,
|
||||
position: Some(p.into()),
|
||||
}))
|
||||
Ok(generic::GradientItem::ColorStop(generic::ColorStop {
|
||||
color: color,
|
||||
position: Some(p.into()),
|
||||
}))
|
||||
})
|
||||
})
|
||||
}).unwrap_or(vec![]);
|
||||
.unwrap_or(vec![]);
|
||||
|
||||
if items.is_empty() {
|
||||
items = vec![
|
||||
|
@ -501,13 +485,17 @@ impl Gradient {
|
|||
} else {
|
||||
items.sort_by(|a, b| {
|
||||
match (a, b) {
|
||||
(&generic::GradientItem::ColorStop(ref a), &generic::GradientItem::ColorStop(ref b)) => {
|
||||
match (&a.position, &b.position) {
|
||||
(&Some(LengthOrPercentage::Percentage(a)), &Some(LengthOrPercentage::Percentage(b))) => {
|
||||
return a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
(
|
||||
&generic::GradientItem::ColorStop(ref a),
|
||||
&generic::GradientItem::ColorStop(ref b),
|
||||
) => match (&a.position, &b.position) {
|
||||
(
|
||||
&Some(LengthOrPercentage::Percentage(a)),
|
||||
&Some(LengthOrPercentage::Percentage(b)),
|
||||
) => {
|
||||
return a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal);
|
||||
},
|
||||
_ => {},
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
@ -536,7 +524,8 @@ impl GradientKind {
|
|||
input: &mut Parser<'i, 't>,
|
||||
compat_mode: &mut CompatMode,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let direction = if let Ok(d) = input.try(|i| LineDirection::parse(context, i, compat_mode)) {
|
||||
let direction = if let Ok(d) = input.try(|i| LineDirection::parse(context, i, compat_mode))
|
||||
{
|
||||
input.expect_comma()?;
|
||||
d
|
||||
} else {
|
||||
|
@ -597,7 +586,7 @@ impl GradientKind {
|
|||
});
|
||||
|
||||
(shape, None, angle, position.ok())
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if shape.is_ok() || position.is_some() || angle.is_some() || moz_position.is_some() {
|
||||
|
@ -616,14 +605,22 @@ impl GradientKind {
|
|||
*compat_mode = CompatMode::Modern;
|
||||
}
|
||||
let position = moz_position.unwrap_or(LegacyPosition::center());
|
||||
return Ok(generic::GradientKind::Radial(shape, GradientPosition::Legacy(position), angle));
|
||||
return Ok(generic::GradientKind::Radial(
|
||||
shape,
|
||||
GradientPosition::Legacy(position),
|
||||
angle,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let position = position.unwrap_or(Position::center());
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
return Ok(generic::GradientKind::Radial(shape, GradientPosition::Modern(position), angle));
|
||||
return Ok(generic::GradientKind::Radial(
|
||||
shape,
|
||||
GradientPosition::Modern(position),
|
||||
angle,
|
||||
));
|
||||
}
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
{
|
||||
|
@ -636,15 +633,16 @@ impl generic::LineDirection for LineDirection {
|
|||
fn points_downwards(&self, compat_mode: CompatMode) -> bool {
|
||||
match *self {
|
||||
LineDirection::Angle(ref angle) => angle.radians() == PI,
|
||||
LineDirection::Vertical(Y::Bottom)
|
||||
if compat_mode == CompatMode::Modern => true,
|
||||
LineDirection::Vertical(Y::Top)
|
||||
if compat_mode != CompatMode::Modern => true,
|
||||
LineDirection::Vertical(Y::Bottom) if compat_mode == CompatMode::Modern => true,
|
||||
LineDirection::Vertical(Y::Top) if compat_mode != CompatMode::Modern => true,
|
||||
#[cfg(feature = "gecko")]
|
||||
LineDirection::MozPosition(Some(LegacyPosition {
|
||||
horizontal: ref x,
|
||||
vertical: ref y,
|
||||
}), None) => {
|
||||
LineDirection::MozPosition(
|
||||
Some(LegacyPosition {
|
||||
horizontal: ref x,
|
||||
vertical: ref y,
|
||||
}),
|
||||
None,
|
||||
) => {
|
||||
use values::computed::Percentage as ComputedPercentage;
|
||||
use values::specified::transform::OriginComponent;
|
||||
|
||||
|
@ -652,16 +650,16 @@ impl generic::LineDirection for LineDirection {
|
|||
// These percentage values can also be keywords.
|
||||
let x = match *x {
|
||||
OriginComponent::Center => true,
|
||||
OriginComponent::Length(LengthOrPercentage::Percentage(ComputedPercentage(val))) => {
|
||||
val == 0.5
|
||||
},
|
||||
OriginComponent::Length(LengthOrPercentage::Percentage(
|
||||
ComputedPercentage(val),
|
||||
)) => val == 0.5,
|
||||
_ => false,
|
||||
};
|
||||
let y = match *y {
|
||||
OriginComponent::Side(Y::Top) => true,
|
||||
OriginComponent::Length(LengthOrPercentage::Percentage(ComputedPercentage(val))) => {
|
||||
val == 0.0
|
||||
},
|
||||
OriginComponent::Length(LengthOrPercentage::Percentage(
|
||||
ComputedPercentage(val),
|
||||
)) => val == 0.0,
|
||||
_ => false,
|
||||
};
|
||||
x && y
|
||||
|
@ -670,18 +668,12 @@ impl generic::LineDirection for LineDirection {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_css<W>(
|
||||
&self,
|
||||
dest: &mut CssWriter<W>,
|
||||
compat_mode: CompatMode,
|
||||
) -> fmt::Result
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>, compat_mode: CompatMode) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
match *self {
|
||||
LineDirection::Angle(angle) => {
|
||||
angle.to_css(dest)
|
||||
},
|
||||
LineDirection::Angle(angle) => angle.to_css(dest),
|
||||
LineDirection::Horizontal(x) => {
|
||||
if compat_mode == CompatMode::Modern {
|
||||
dest.write_str("to ")?;
|
||||
|
@ -750,7 +742,9 @@ impl LineDirection {
|
|||
// There is no `to` keyword in webkit prefixed syntax. If it's consumed,
|
||||
// parsing should throw an error.
|
||||
CompatMode::WebKit if to_ident.is_ok() => {
|
||||
return Err(i.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("to".into())))
|
||||
return Err(i.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(
|
||||
"to".into(),
|
||||
)))
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
@ -824,7 +818,9 @@ impl EndingShape {
|
|||
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
||||
}
|
||||
}
|
||||
return Ok(generic::EndingShape::Circle(Circle::Extent(ShapeExtent::FarthestCorner)));
|
||||
return Ok(generic::EndingShape::Circle(Circle::Extent(
|
||||
ShapeExtent::FarthestCorner,
|
||||
)));
|
||||
}
|
||||
if input.try(|i| i.expect_ident_matching("ellipse")).is_ok() {
|
||||
if let Ok(extent) = input.try(|i| ShapeExtent::parse_with_compat_mode(i, compat_mode)) {
|
||||
|
@ -840,7 +836,9 @@ impl EndingShape {
|
|||
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(x, y)));
|
||||
}
|
||||
}
|
||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner)));
|
||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Extent(
|
||||
ShapeExtent::FarthestCorner,
|
||||
)));
|
||||
}
|
||||
// -moz- prefixed radial gradient doesn't allow EndingShape's Length or LengthOrPercentage
|
||||
// to come before shape keyword. Otherwise it conflicts with <position>.
|
||||
|
@ -850,7 +848,10 @@ impl EndingShape {
|
|||
if compat_mode == CompatMode::Modern {
|
||||
let _ = input.try(|i| i.expect_ident_matching("ellipse"));
|
||||
}
|
||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(length.into(), y)));
|
||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
||||
length.into(),
|
||||
y,
|
||||
)));
|
||||
}
|
||||
if compat_mode == CompatMode::Modern {
|
||||
let y = input.try(|i| {
|
||||
|
@ -858,7 +859,10 @@ impl EndingShape {
|
|||
LengthOrPercentage::parse(context, i)
|
||||
});
|
||||
if let Ok(y) = y {
|
||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(length.into(), y)));
|
||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
||||
length.into(),
|
||||
y,
|
||||
)));
|
||||
}
|
||||
let _ = input.try(|i| i.expect_ident_matching("circle"));
|
||||
}
|
||||
|
@ -924,8 +928,10 @@ impl GradientItem {
|
|||
}
|
||||
|
||||
impl Parse for ColorStop {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Ok(ColorStop {
|
||||
color: RGBAColor::parse(context, input)?,
|
||||
position: input.try(|i| LengthOrPercentage::parse(context, i)).ok(),
|
||||
|
@ -941,17 +947,22 @@ impl Parse for PaintWorklet {
|
|||
input.expect_function_matching("paint")?;
|
||||
input.parse_nested_block(|input| {
|
||||
let name = Atom::from(&**input.expect_ident()?);
|
||||
let arguments = input.try(|input| {
|
||||
input.expect_comma()?;
|
||||
input.parse_comma_separated(|input| SpecifiedValue::parse(input))
|
||||
}).unwrap_or(vec![]);
|
||||
let arguments = input
|
||||
.try(|input| {
|
||||
input.expect_comma()?;
|
||||
input.parse_comma_separated(|input| SpecifiedValue::parse(input))
|
||||
})
|
||||
.unwrap_or(vec![]);
|
||||
Ok(PaintWorklet { name, arguments })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for MozImageRect {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.try(|i| i.expect_function_matching("-moz-image-rect"))?;
|
||||
input.parse_nested_block(|i| {
|
||||
let string = i.expect_url_or_string()?;
|
||||
|
@ -964,7 +975,13 @@ impl Parse for MozImageRect {
|
|||
let bottom = NumberOrPercentage::parse_non_negative(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let left = NumberOrPercentage::parse_non_negative(context, i)?;
|
||||
Ok(MozImageRect { url, top, right, bottom, left })
|
||||
Ok(MozImageRect {
|
||||
url,
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
left,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ pub struct ImageOrientation {
|
|||
pub angle: Option<Angle>,
|
||||
|
||||
/// Whether or not "flip" was specified
|
||||
pub flipped: bool
|
||||
pub flipped: bool,
|
||||
}
|
||||
|
||||
impl ToCss for ImageOrientation {
|
||||
|
@ -64,16 +64,16 @@ fn orientation_of_angle(angle: &computed::Angle) -> Orientation {
|
|||
rounded_angle += TWO_PI;
|
||||
}
|
||||
if rounded_angle < 0.25 * PI {
|
||||
return Orientation::Angle0
|
||||
return Orientation::Angle0;
|
||||
}
|
||||
if rounded_angle < 0.75 * PI {
|
||||
return Orientation::Angle90
|
||||
return Orientation::Angle90;
|
||||
}
|
||||
if rounded_angle < 1.25 * PI {
|
||||
return Orientation::Angle180
|
||||
return Orientation::Angle180;
|
||||
}
|
||||
if rounded_angle < 1.75 * PI {
|
||||
return Orientation::Angle270
|
||||
return Orientation::Angle270;
|
||||
}
|
||||
Orientation::Angle0
|
||||
}
|
||||
|
@ -99,11 +99,9 @@ impl ToComputedValue for ImageOrientation {
|
|||
#[inline]
|
||||
fn from_computed_value(computed: &computed::ImageOrientation) -> Self {
|
||||
match *computed {
|
||||
computed::ImageOrientation::FromImage => {
|
||||
ImageOrientation {
|
||||
angle: None,
|
||||
flipped: false
|
||||
}
|
||||
computed::ImageOrientation::FromImage => ImageOrientation {
|
||||
angle: None,
|
||||
flipped: false,
|
||||
},
|
||||
|
||||
computed::ImageOrientation::AngleWithFlipped(ref orientation, flipped) => {
|
||||
|
@ -111,7 +109,7 @@ impl ToComputedValue for ImageOrientation {
|
|||
angle: Some(orientation.angle()),
|
||||
flipped: flipped,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,14 +118,26 @@ impl Parse for ImageOrientation {
|
|||
// from-image | <angle> | [<angle>? flip]
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_ident_matching("from-image")).is_ok() {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("from-image"))
|
||||
.is_ok()
|
||||
{
|
||||
// Handle from-image
|
||||
Ok(ImageOrientation { angle: None, flipped: false })
|
||||
} else if input.try(|input| input.expect_ident_matching("flip")).is_ok() {
|
||||
Ok(ImageOrientation {
|
||||
angle: None,
|
||||
flipped: false,
|
||||
})
|
||||
} else if input
|
||||
.try(|input| input.expect_ident_matching("flip"))
|
||||
.is_ok()
|
||||
{
|
||||
// Handle flip
|
||||
Ok(ImageOrientation { angle: Some(Angle::zero()), flipped: true })
|
||||
Ok(ImageOrientation {
|
||||
angle: Some(Angle::zero()),
|
||||
flipped: true,
|
||||
})
|
||||
} else {
|
||||
// Handle <angle> | <angle> flip
|
||||
let angle = input.try(|input| Angle::parse(context, input)).ok();
|
||||
|
@ -135,8 +145,13 @@ impl Parse for ImageOrientation {
|
|||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok();
|
||||
Ok(ImageOrientation { angle: angle, flipped: flipped })
|
||||
let flipped = input
|
||||
.try(|input| input.expect_ident_matching("flip"))
|
||||
.is_ok();
|
||||
Ok(ImageOrientation {
|
||||
angle: angle,
|
||||
flipped: flipped,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use std::cmp;
|
|||
use std::ops::{Add, Mul};
|
||||
use style_traits::{ParseError, StyleParseErrorKind};
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
use super::{AllowQuirks, Number, ToComputedValue, Percentage};
|
||||
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
|
||||
use values::{Auto, CSSFloat, Either, Normal};
|
||||
use values::computed::{self, CSSPixelLength, Context, ExtremumLength};
|
||||
use values::generics::NonNegative;
|
||||
|
@ -62,7 +62,7 @@ pub enum FontRelativeLength {
|
|||
Ch(CSSFloat),
|
||||
/// A "rem" value: https://drafts.csswg.org/css-values/#rem
|
||||
#[css(dimension)]
|
||||
Rem(CSSFloat)
|
||||
Rem(CSSFloat),
|
||||
}
|
||||
|
||||
/// A source to resolve font-relative units against
|
||||
|
@ -88,8 +88,9 @@ impl FontBaseSize {
|
|||
match *self {
|
||||
FontBaseSize::Custom(size) => size,
|
||||
FontBaseSize::CurrentStyle => context.style().get_font().clone_font_size().size(),
|
||||
FontBaseSize::InheritedStyleButStripEmUnits |
|
||||
FontBaseSize::InheritedStyle => context.style().get_parent_font().clone_font_size().size(),
|
||||
FontBaseSize::InheritedStyleButStripEmUnits | FontBaseSize::InheritedStyle => {
|
||||
context.style().get_parent_font().clone_font_size().size()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +100,9 @@ impl FontRelativeLength {
|
|||
pub fn to_computed_value(&self, context: &Context, base_size: FontBaseSize) -> CSSPixelLength {
|
||||
use std::f32;
|
||||
let (reference_size, length) = self.reference_font_size_and_length(context, base_size);
|
||||
let pixel = (length * reference_size.to_f32_px()).min(f32::MAX).max(f32::MIN);
|
||||
let pixel = (length * reference_size.to_f32_px())
|
||||
.min(f32::MAX)
|
||||
.max(f32::MIN);
|
||||
CSSPixelLength::new(pixel)
|
||||
}
|
||||
|
||||
|
@ -133,10 +136,10 @@ impl FontRelativeLength {
|
|||
FontRelativeLength::Em(length) => {
|
||||
if context.for_non_inherited_property.is_some() {
|
||||
if base_size == FontBaseSize::CurrentStyle {
|
||||
context.rule_cache_conditions.borrow_mut()
|
||||
.set_font_size_dependency(
|
||||
reference_font_size.into()
|
||||
);
|
||||
context
|
||||
.rule_cache_conditions
|
||||
.borrow_mut()
|
||||
.set_font_size_dependency(reference_font_size.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,18 +154,14 @@ impl FontRelativeLength {
|
|||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||
}
|
||||
let reference_size = match query_font_metrics(context, reference_font_size) {
|
||||
FontMetricsQueryResult::Available(metrics) => {
|
||||
metrics.x_height
|
||||
},
|
||||
FontMetricsQueryResult::Available(metrics) => metrics.x_height,
|
||||
// https://drafts.csswg.org/css-values/#ex
|
||||
//
|
||||
// In the cases where it is impossible or impractical to
|
||||
// determine the x-height, a value of 0.5em must be
|
||||
// assumed.
|
||||
//
|
||||
FontMetricsQueryResult::NotAvailable => {
|
||||
reference_font_size.scale_by(0.5)
|
||||
},
|
||||
FontMetricsQueryResult::NotAvailable => reference_font_size.scale_by(0.5),
|
||||
};
|
||||
(reference_size, length)
|
||||
},
|
||||
|
@ -171,9 +170,7 @@ impl FontRelativeLength {
|
|||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||
}
|
||||
let reference_size = match query_font_metrics(context, reference_font_size) {
|
||||
FontMetricsQueryResult::Available(metrics) => {
|
||||
metrics.zero_advance_measure
|
||||
},
|
||||
FontMetricsQueryResult::Available(metrics) => metrics.zero_advance_measure,
|
||||
// https://drafts.csswg.org/css-values/#ch
|
||||
//
|
||||
// In the cases where it is impossible or impractical to
|
||||
|
@ -190,10 +187,10 @@ impl FontRelativeLength {
|
|||
} else {
|
||||
reference_font_size.scale_by(0.5)
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
(reference_size, length)
|
||||
}
|
||||
},
|
||||
FontRelativeLength::Rem(length) => {
|
||||
// https://drafts.csswg.org/css-values/#rem:
|
||||
//
|
||||
|
@ -207,7 +204,7 @@ impl FontRelativeLength {
|
|||
context.device().root_font_size()
|
||||
};
|
||||
(reference_size, length)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,21 +225,21 @@ pub enum ViewportPercentageLength {
|
|||
Vmin(CSSFloat),
|
||||
/// <https://drafts.csswg.org/css-values/#vmax>
|
||||
#[css(dimension)]
|
||||
Vmax(CSSFloat)
|
||||
Vmax(CSSFloat),
|
||||
}
|
||||
|
||||
impl ViewportPercentageLength {
|
||||
/// Computes the given viewport-relative length for the given viewport size.
|
||||
pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> CSSPixelLength {
|
||||
let (factor, length) = match *self {
|
||||
ViewportPercentageLength::Vw(length) =>
|
||||
(length, viewport_size.width),
|
||||
ViewportPercentageLength::Vh(length) =>
|
||||
(length, viewport_size.height),
|
||||
ViewportPercentageLength::Vmin(length) =>
|
||||
(length, cmp::min(viewport_size.width, viewport_size.height)),
|
||||
ViewportPercentageLength::Vmax(length) =>
|
||||
(length, cmp::max(viewport_size.width, viewport_size.height)),
|
||||
ViewportPercentageLength::Vw(length) => (length, viewport_size.width),
|
||||
ViewportPercentageLength::Vh(length) => (length, viewport_size.height),
|
||||
ViewportPercentageLength::Vmin(length) => {
|
||||
(length, cmp::min(viewport_size.width, viewport_size.height))
|
||||
},
|
||||
ViewportPercentageLength::Vmax(length) => {
|
||||
(length, cmp::max(viewport_size.width, viewport_size.height))
|
||||
},
|
||||
};
|
||||
|
||||
// FIXME: Bug 1396535, we need to fix the extremely small viewport length for transform.
|
||||
|
@ -300,13 +297,13 @@ pub enum AbsoluteLength {
|
|||
impl AbsoluteLength {
|
||||
fn is_zero(&self) -> bool {
|
||||
match *self {
|
||||
AbsoluteLength::Px(v)
|
||||
| AbsoluteLength::In(v)
|
||||
| AbsoluteLength::Cm(v)
|
||||
| AbsoluteLength::Mm(v)
|
||||
| AbsoluteLength::Q(v)
|
||||
| AbsoluteLength::Pt(v)
|
||||
| AbsoluteLength::Pc(v) => v == 0.,
|
||||
AbsoluteLength::Px(v) |
|
||||
AbsoluteLength::In(v) |
|
||||
AbsoluteLength::Cm(v) |
|
||||
AbsoluteLength::Mm(v) |
|
||||
AbsoluteLength::Q(v) |
|
||||
AbsoluteLength::Pt(v) |
|
||||
AbsoluteLength::Pc(v) => v == 0.,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,7 +474,7 @@ impl NoCalcLength {
|
|||
pub fn is_zero(&self) -> bool {
|
||||
match *self {
|
||||
NoCalcLength::Absolute(length) => length.is_zero(),
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,25 +574,31 @@ impl Length {
|
|||
let location = input.current_source_location();
|
||||
let token = input.next()?;
|
||||
match *token {
|
||||
Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} if num_context.is_ok(context.parsing_mode, value) =>
|
||||
{
|
||||
return NoCalcLength::parse_dimension(context, value, unit)
|
||||
.map(Length::NoCalc)
|
||||
.map_err(|()| location.new_unexpected_token_error(token.clone()))
|
||||
}
|
||||
Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
if value != 0. &&
|
||||
!context.parsing_mode.allows_unitless_lengths() &&
|
||||
!allow_quirks.allowed(context.quirks_mode) {
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
return Ok(Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(value))))
|
||||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
|
||||
ref token => return Err(location.new_unexpected_token_error(token.clone()))
|
||||
Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
if value != 0. && !context.parsing_mode.allows_unitless_lengths() &&
|
||||
!allow_quirks.allowed(context.quirks_mode)
|
||||
{
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
return Ok(Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(
|
||||
value,
|
||||
))));
|
||||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
|
||||
ref token => return Err(location.new_unexpected_token_error(token.clone())),
|
||||
}
|
||||
}
|
||||
input.parse_nested_block(|input| {
|
||||
CalcNode::parse_length(context, input, num_context).map(|calc| Length::Calc(Box::new(calc)))
|
||||
CalcNode::parse_length(context, input, num_context)
|
||||
.map(|calc| Length::Calc(Box::new(calc)))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -615,7 +618,12 @@ impl Length {
|
|||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_internal(context, input, AllowedNumericType::NonNegative, allow_quirks)
|
||||
Self::parse_internal(
|
||||
context,
|
||||
input,
|
||||
AllowedNumericType::NonNegative,
|
||||
allow_quirks,
|
||||
)
|
||||
}
|
||||
|
||||
/// Get an absolute length from a px value.
|
||||
|
@ -626,7 +634,10 @@ impl Length {
|
|||
}
|
||||
|
||||
impl Parse for Length {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -717,7 +728,7 @@ impl From<Percentage> for LengthOrPercentage {
|
|||
if pc.is_calc() {
|
||||
LengthOrPercentage::Calc(Box::new(CalcLengthOrPercentage {
|
||||
percentage: Some(computed::Percentage(pc.get())),
|
||||
.. Default::default()
|
||||
..Default::default()
|
||||
}))
|
||||
} else {
|
||||
LengthOrPercentage::Percentage(computed::Percentage(pc.get()))
|
||||
|
@ -750,31 +761,37 @@ impl LengthOrPercentage {
|
|||
let location = input.current_source_location();
|
||||
let token = input.next()?;
|
||||
match *token {
|
||||
Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} if num_context.is_ok(context.parsing_mode, value) =>
|
||||
{
|
||||
return NoCalcLength::parse_dimension(context, value, unit)
|
||||
.map(LengthOrPercentage::Length)
|
||||
.map_err(|()| location.new_unexpected_token_error(token.clone()))
|
||||
}
|
||||
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
|
||||
return Ok(LengthOrPercentage::Percentage(computed::Percentage(unit_value)))
|
||||
}
|
||||
},
|
||||
Token::Percentage { unit_value, .. }
|
||||
if num_context.is_ok(context.parsing_mode, unit_value) =>
|
||||
{
|
||||
return Ok(LengthOrPercentage::Percentage(computed::Percentage(
|
||||
unit_value,
|
||||
)))
|
||||
},
|
||||
Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
if value != 0. &&
|
||||
!context.parsing_mode.allows_unitless_lengths() &&
|
||||
!allow_quirks.allowed(context.quirks_mode) {
|
||||
return Err(location.new_unexpected_token_error(token.clone()))
|
||||
if value != 0. && !context.parsing_mode.allows_unitless_lengths() &&
|
||||
!allow_quirks.allowed(context.quirks_mode)
|
||||
{
|
||||
return Err(location.new_unexpected_token_error(token.clone()));
|
||||
} else {
|
||||
return Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value)))
|
||||
return Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value)));
|
||||
}
|
||||
}
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
|
||||
_ => return Err(location.new_unexpected_token_error(token.clone()))
|
||||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
|
||||
_ => return Err(location.new_unexpected_token_error(token.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
let calc = input.parse_nested_block(|i| {
|
||||
CalcNode::parse_length_or_percentage(context, i, num_context)
|
||||
})?;
|
||||
let calc = input
|
||||
.parse_nested_block(|i| CalcNode::parse_length_or_percentage(context, i, num_context))?;
|
||||
Ok(LengthOrPercentage::Calc(Box::new(calc)))
|
||||
}
|
||||
|
||||
|
@ -794,13 +811,21 @@ impl LengthOrPercentage {
|
|||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<LengthOrPercentage, ParseError<'i>> {
|
||||
Self::parse_internal(context, input, AllowedNumericType::NonNegative, allow_quirks)
|
||||
Self::parse_internal(
|
||||
context,
|
||||
input,
|
||||
AllowedNumericType::NonNegative,
|
||||
allow_quirks,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for LengthOrPercentage {
|
||||
#[inline]
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -809,9 +834,11 @@ 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<'i, 't>(context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks) -> Result<Self, ParseError<'i>> {
|
||||
pub fn parse_quirky<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_internal(context, input, AllowedNumericType::All, allow_quirks)
|
||||
}
|
||||
}
|
||||
|
@ -852,35 +879,41 @@ impl LengthOrPercentageOrAuto {
|
|||
let location = input.current_source_location();
|
||||
let token = input.next()?;
|
||||
match *token {
|
||||
Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} if num_context.is_ok(context.parsing_mode, value) =>
|
||||
{
|
||||
return NoCalcLength::parse_dimension(context, value, unit)
|
||||
.map(LengthOrPercentageOrAuto::Length)
|
||||
.map_err(|()| location.new_unexpected_token_error(token.clone()))
|
||||
}
|
||||
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
|
||||
return Ok(LengthOrPercentageOrAuto::Percentage(computed::Percentage(unit_value)))
|
||||
}
|
||||
},
|
||||
Token::Percentage { unit_value, .. }
|
||||
if num_context.is_ok(context.parsing_mode, unit_value) =>
|
||||
{
|
||||
return Ok(LengthOrPercentageOrAuto::Percentage(computed::Percentage(
|
||||
unit_value,
|
||||
)))
|
||||
},
|
||||
Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
if value != 0. &&
|
||||
!context.parsing_mode.allows_unitless_lengths() &&
|
||||
!allow_quirks.allowed(context.quirks_mode) {
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
if value != 0. && !context.parsing_mode.allows_unitless_lengths() &&
|
||||
!allow_quirks.allowed(context.quirks_mode)
|
||||
{
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
return Ok(LengthOrPercentageOrAuto::Length(
|
||||
NoCalcLength::Absolute(AbsoluteLength::Px(value))
|
||||
))
|
||||
}
|
||||
return Ok(LengthOrPercentageOrAuto::Length(NoCalcLength::Absolute(
|
||||
AbsoluteLength::Px(value),
|
||||
)));
|
||||
},
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => {
|
||||
return Ok(LengthOrPercentageOrAuto::Auto)
|
||||
}
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
|
||||
_ => return Err(location.new_unexpected_token_error(token.clone()))
|
||||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
|
||||
_ => return Err(location.new_unexpected_token_error(token.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
let calc = input.parse_nested_block(|i| {
|
||||
CalcNode::parse_length_or_percentage(context, i, num_context)
|
||||
})?;
|
||||
let calc = input
|
||||
.parse_nested_block(|i| CalcNode::parse_length_or_percentage(context, i, num_context))?;
|
||||
Ok(LengthOrPercentageOrAuto::Calc(Box::new(calc)))
|
||||
}
|
||||
|
||||
|
@ -900,7 +933,12 @@ impl LengthOrPercentageOrAuto {
|
|||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_internal(context, input, AllowedNumericType::NonNegative, allow_quirks)
|
||||
Self::parse_internal(
|
||||
context,
|
||||
input,
|
||||
AllowedNumericType::NonNegative,
|
||||
allow_quirks,
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns the `auto` value.
|
||||
|
@ -932,7 +970,10 @@ impl LengthOrPercentageOrAuto {
|
|||
|
||||
impl Parse for LengthOrPercentageOrAuto {
|
||||
#[inline]
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -962,8 +1003,14 @@ impl NonNegativeLengthOrPercentageOrAuto {
|
|||
|
||||
impl Parse for NonNegativeLengthOrPercentageOrAuto {
|
||||
#[inline]
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
Ok(NonNegative(LengthOrPercentageOrAuto::parse_non_negative(context, input)?))
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Ok(NonNegative(LengthOrPercentageOrAuto::parse_non_negative(
|
||||
context,
|
||||
input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -989,34 +1036,41 @@ impl LengthOrPercentageOrNone {
|
|||
let location = input.current_source_location();
|
||||
let token = input.next()?;
|
||||
match *token {
|
||||
Token::Dimension { value, ref unit, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} if num_context.is_ok(context.parsing_mode, value) =>
|
||||
{
|
||||
return NoCalcLength::parse_dimension(context, value, unit)
|
||||
.map(LengthOrPercentageOrNone::Length)
|
||||
.map_err(|()| location.new_unexpected_token_error(token.clone()))
|
||||
}
|
||||
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
|
||||
return Ok(LengthOrPercentageOrNone::Percentage(computed::Percentage(unit_value)))
|
||||
}
|
||||
},
|
||||
Token::Percentage { unit_value, .. }
|
||||
if num_context.is_ok(context.parsing_mode, unit_value) =>
|
||||
{
|
||||
return Ok(LengthOrPercentageOrNone::Percentage(computed::Percentage(
|
||||
unit_value,
|
||||
)))
|
||||
},
|
||||
Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
|
||||
if value != 0. && !context.parsing_mode.allows_unitless_lengths() &&
|
||||
!allow_quirks.allowed(context.quirks_mode) {
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
!allow_quirks.allowed(context.quirks_mode)
|
||||
{
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
return Ok(LengthOrPercentageOrNone::Length(
|
||||
NoCalcLength::Absolute(AbsoluteLength::Px(value))
|
||||
))
|
||||
}
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
|
||||
return Ok(LengthOrPercentageOrNone::Length(NoCalcLength::Absolute(
|
||||
AbsoluteLength::Px(value),
|
||||
)));
|
||||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => {
|
||||
return Ok(LengthOrPercentageOrNone::None)
|
||||
}
|
||||
_ => return Err(location.new_unexpected_token_error(token.clone()))
|
||||
},
|
||||
_ => return Err(location.new_unexpected_token_error(token.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
let calc = input.parse_nested_block(|i| {
|
||||
CalcNode::parse_length_or_percentage(context, i, num_context)
|
||||
})?;
|
||||
let calc = input
|
||||
.parse_nested_block(|i| CalcNode::parse_length_or_percentage(context, i, num_context))?;
|
||||
Ok(LengthOrPercentageOrNone::Calc(Box::new(calc)))
|
||||
}
|
||||
|
||||
|
@ -1036,13 +1090,21 @@ impl LengthOrPercentageOrNone {
|
|||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_internal(context, input, AllowedNumericType::NonNegative, allow_quirks)
|
||||
Self::parse_internal(
|
||||
context,
|
||||
input,
|
||||
AllowedNumericType::NonNegative,
|
||||
allow_quirks,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for LengthOrPercentageOrNone {
|
||||
#[inline]
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_internal(context, input, AllowedNumericType::All, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -1065,8 +1127,12 @@ impl From<NoCalcLength> for NonNegativeLengthOrPercentage {
|
|||
|
||||
impl Parse for NonNegativeLengthOrPercentage {
|
||||
#[inline]
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
LengthOrPercentage::parse_non_negative(context, input).map(NonNegative::<LengthOrPercentage>)
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
LengthOrPercentage::parse_non_negative(context, input)
|
||||
.map(NonNegative::<LengthOrPercentage>)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1109,7 +1175,7 @@ impl LengthOrNumber {
|
|||
// 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(|i| Number::parse_non_negative(context, i)) {
|
||||
return Ok(Either::Second(v))
|
||||
return Ok(Either::Second(v));
|
||||
}
|
||||
|
||||
Length::parse_non_negative(context, input).map(Either::First)
|
||||
|
@ -1136,7 +1202,10 @@ pub enum MozLength {
|
|||
}
|
||||
|
||||
impl Parse for MozLength {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
MozLength::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -1163,11 +1232,8 @@ impl MozLength {
|
|||
return Ok(MozLength::ExtremumLength(l));
|
||||
}
|
||||
|
||||
let length = LengthOrPercentageOrAuto::parse_non_negative_quirky(
|
||||
context,
|
||||
input,
|
||||
allow_quirks,
|
||||
)?;
|
||||
let length =
|
||||
LengthOrPercentageOrAuto::parse_non_negative_quirky(context, input, allow_quirks)?;
|
||||
Ok(MozLength::LengthOrPercentageOrAuto(length))
|
||||
}
|
||||
|
||||
|
@ -1193,7 +1259,10 @@ pub enum MaxLength {
|
|||
}
|
||||
|
||||
impl Parse for MaxLength {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
MaxLength::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -1220,11 +1289,8 @@ impl MaxLength {
|
|||
return Ok(MaxLength::ExtremumLength(l));
|
||||
}
|
||||
|
||||
let length = LengthOrPercentageOrNone::parse_non_negative_quirky(
|
||||
context,
|
||||
input,
|
||||
allow_quirks,
|
||||
)?;
|
||||
let length =
|
||||
LengthOrPercentageOrNone::parse_non_negative_quirky(context, input, allow_quirks)?;
|
||||
Ok(MaxLength::LengthOrPercentageOrNone(length))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,13 +61,15 @@ impl ListStyleType {
|
|||
impl Parse for ListStyleType {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(style) = input.try(|i| CounterStyleOrNone::parse(context, i)) {
|
||||
return Ok(ListStyleType::CounterStyle(style))
|
||||
return Ok(ListStyleType::CounterStyle(style));
|
||||
}
|
||||
|
||||
Ok(ListStyleType::String(input.expect_string()?.as_ref().to_owned()))
|
||||
Ok(ListStyleType::String(
|
||||
input.expect_string()?.as_ref().to_owned(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +92,7 @@ impl ToCss for Quotes {
|
|||
l.to_css(dest)?;
|
||||
dest.write_char(' ')?;
|
||||
r.to_css(dest)?;
|
||||
}
|
||||
},
|
||||
None => return dest.write_str("none"),
|
||||
}
|
||||
|
||||
|
@ -106,24 +108,27 @@ impl ToCss for Quotes {
|
|||
}
|
||||
|
||||
impl Parse for Quotes {
|
||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Quotes, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(Quotes(Vec::new().into_boxed_slice()))
|
||||
fn parse<'i, 't>(
|
||||
_: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Quotes, ParseError<'i>> {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("none"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(Quotes(Vec::new().into_boxed_slice()));
|
||||
}
|
||||
|
||||
let mut quotes = Vec::new();
|
||||
loop {
|
||||
let location = input.current_source_location();
|
||||
let first = match input.next() {
|
||||
Ok(&Token::QuotedString(ref value)) => {
|
||||
value.as_ref().to_owned().into_boxed_str()
|
||||
},
|
||||
Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned().into_boxed_str(),
|
||||
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
Err(_) => break,
|
||||
};
|
||||
|
||||
let second =
|
||||
input.expect_string()?.as_ref().to_owned().into_boxed_str();
|
||||
let second = input.expect_string()?.as_ref().to_owned().into_boxed_str();
|
||||
quotes.push((first, second))
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ use {Atom, Namespace, Prefix};
|
|||
use context::QuirksMode;
|
||||
use cssparser::{Parser, Token};
|
||||
use num_traits::One;
|
||||
use parser::{ParserContext, Parse};
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::f32;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
|
@ -19,7 +19,7 @@ use super::{Auto, CSSFloat, CSSInteger, Either};
|
|||
use super::computed::{Context, ToComputedValue};
|
||||
use super::generics::{GreaterThanOrEqualToOne, NonNegative};
|
||||
use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
|
||||
use super::generics::grid::{TrackSize as GenericTrackSize, TrackList as GenericTrackList};
|
||||
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
||||
use values::serialize_atom_identifier;
|
||||
use values::specified::calc::CalcNode;
|
||||
|
||||
|
@ -28,16 +28,16 @@ pub use self::angle::Angle;
|
|||
#[cfg(feature = "gecko")]
|
||||
pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution};
|
||||
#[cfg(feature = "gecko")]
|
||||
pub use self::align::{SelfAlignment, JustifyContent, JustifyItems, JustifySelf};
|
||||
pub use self::align::{JustifyContent, JustifyItems, JustifySelf, SelfAlignment};
|
||||
pub use self::background::{BackgroundRepeat, BackgroundSize};
|
||||
pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth};
|
||||
pub use self::border::{BorderImageRepeat, BorderImageSideWidth};
|
||||
pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing};
|
||||
pub use self::column::ColumnCount;
|
||||
pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVariantAlternates};
|
||||
pub use self::font::{FontFamily, FontLanguageOverride, FontVariationSettings, FontVariantEastAsian};
|
||||
pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings};
|
||||
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang};
|
||||
pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontVariantAlternates, FontWeight};
|
||||
pub use self::font::{FontFamily, FontLanguageOverride, FontVariantEastAsian, FontVariationSettings};
|
||||
pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric};
|
||||
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
|
||||
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective};
|
||||
pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange};
|
||||
|
@ -72,7 +72,7 @@ pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
|
|||
pub use self::svg::MozContextProperties;
|
||||
pub use self::table::XSpan;
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, MozTabSize, TextAlign};
|
||||
pub use self::text::{TextEmphasisStyle, TextEmphasisPosition};
|
||||
pub use self::text::{TextEmphasisPosition, TextEmphasisStyle};
|
||||
pub use self::text::{TextAlignKeyword, TextDecorationLine, TextOverflow, WordSpacing};
|
||||
pub use self::time::Time;
|
||||
pub use self::transform::{Rotate, Scale, TimingFunction, Transform};
|
||||
|
@ -130,14 +130,12 @@ fn parse_number_with_clamping_mode<'i, 't>(
|
|||
value: value.min(f32::MAX).max(f32::MIN),
|
||||
calc_clamping_mode: None,
|
||||
})
|
||||
}
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
|
||||
ref t => return Err(location.new_unexpected_token_error(t.clone()))
|
||||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
|
||||
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
|
||||
let result = input.parse_nested_block(|i| {
|
||||
CalcNode::parse_number(context, i)
|
||||
})?;
|
||||
let result = input.parse_nested_block(|i| CalcNode::parse_number(context, i))?;
|
||||
|
||||
Ok(Number {
|
||||
value: result.min(f32::MAX).max(f32::MIN),
|
||||
|
@ -151,8 +149,8 @@ fn parse_number_with_clamping_mode<'i, 't>(
|
|||
// FIXME(emilio): Should move to border.rs
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Ord, Parse, PartialEq)]
|
||||
#[derive(PartialOrd, ToComputedValue, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Ord, Parse, PartialEq, PartialOrd,
|
||||
ToComputedValue, ToCss)]
|
||||
pub enum BorderStyle {
|
||||
None = -1,
|
||||
Solid = 6,
|
||||
|
@ -185,9 +183,11 @@ pub struct Number {
|
|||
calc_clamping_mode: Option<AllowedNumericType>,
|
||||
}
|
||||
|
||||
|
||||
impl Parse for Number {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
parse_number_with_clamping_mode(context, input, AllowedNumericType::All)
|
||||
}
|
||||
}
|
||||
|
@ -203,18 +203,23 @@ impl Number {
|
|||
|
||||
/// Returns the numeric value, clamped if needed.
|
||||
pub fn get(&self) -> f32 {
|
||||
self.calc_clamping_mode.map_or(self.value, |mode| mode.clamp(self.value))
|
||||
self.calc_clamping_mode
|
||||
.map_or(self.value, |mode| mode.clamp(self.value))
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Number, ParseError<'i>> {
|
||||
pub fn parse_non_negative<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Number, ParseError<'i>> {
|
||||
parse_number_with_clamping_mode(context, input, AllowedNumericType::NonNegative)
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub fn parse_at_least_one<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Number, ParseError<'i>> {
|
||||
pub fn parse_at_least_one<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Number, ParseError<'i>> {
|
||||
parse_number_with_clamping_mode(context, input, AllowedNumericType::AtLeastOne)
|
||||
}
|
||||
|
||||
|
@ -232,7 +237,9 @@ impl ToComputedValue for Number {
|
|||
type ComputedValue = CSSFloat;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _: &Context) -> CSSFloat { self.get() }
|
||||
fn to_computed_value(&self, _: &Context) -> CSSFloat {
|
||||
self.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &CSSFloat) -> Self {
|
||||
|
@ -277,7 +284,10 @@ impl From<Number> for f64 {
|
|||
pub type NonNegativeNumber = NonNegative<Number>;
|
||||
|
||||
impl Parse for NonNegativeNumber {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
parse_number_with_clamping_mode(context, input, AllowedNumericType::NonNegative)
|
||||
.map(NonNegative::<Number>)
|
||||
}
|
||||
|
@ -294,7 +304,10 @@ impl NonNegativeNumber {
|
|||
pub type GreaterThanOrEqualToOneNumber = GreaterThanOrEqualToOne<Number>;
|
||||
|
||||
impl Parse for GreaterThanOrEqualToOneNumber {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
parse_number_with_clamping_mode(context, input, AllowedNumericType::AtLeastOne)
|
||||
.map(GreaterThanOrEqualToOne::<Number>)
|
||||
}
|
||||
|
@ -312,12 +325,11 @@ pub enum NumberOrPercentage {
|
|||
Number(Number),
|
||||
}
|
||||
|
||||
|
||||
impl NumberOrPercentage {
|
||||
fn parse_with_clamping_mode<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
type_: AllowedNumericType
|
||||
type_: AllowedNumericType,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(per) = input.try(|i| Percentage::parse_with_clamping_mode(context, i, type_)) {
|
||||
return Ok(NumberOrPercentage::Percentage(per));
|
||||
|
@ -327,14 +339,19 @@ impl NumberOrPercentage {
|
|||
}
|
||||
|
||||
/// Parse a non-negative number or percentage.
|
||||
pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
pub fn parse_non_negative<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_with_clamping_mode(context, input, AllowedNumericType::NonNegative)
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for NumberOrPercentage {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_with_clamping_mode(context, input, AllowedNumericType::All)
|
||||
}
|
||||
}
|
||||
|
@ -343,9 +360,11 @@ impl Parse for NumberOrPercentage {
|
|||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToCss)]
|
||||
pub struct Opacity(Number);
|
||||
|
||||
|
||||
impl Parse for Opacity {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Number::parse(context, input).map(Opacity)
|
||||
}
|
||||
}
|
||||
|
@ -420,19 +439,22 @@ impl Integer {
|
|||
}
|
||||
|
||||
impl Parse for Integer {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
|
||||
// FIXME: remove early returns when lifetimes are non-lexical
|
||||
match *input.next()? {
|
||||
Token::Number { int_value: Some(v), .. } => return Ok(Integer::new(v)),
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
|
||||
ref t => return Err(location.new_unexpected_token_error(t.clone()))
|
||||
Token::Number {
|
||||
int_value: Some(v), ..
|
||||
} => return Ok(Integer::new(v)),
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
|
||||
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
|
||||
let result = input.parse_nested_block(|i| {
|
||||
CalcNode::parse_integer(context, i)
|
||||
})?;
|
||||
let result = input.parse_nested_block(|i| CalcNode::parse_integer(context, i))?;
|
||||
|
||||
Ok(Integer::from_calc(result))
|
||||
}
|
||||
|
@ -468,7 +490,7 @@ impl Integer {
|
|||
/// Parse a positive integer (>= 1).
|
||||
pub fn parse_positive<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Integer, ParseError<'i>> {
|
||||
Integer::parse_with_minimum(context, input, 1)
|
||||
}
|
||||
|
@ -478,7 +500,9 @@ impl ToComputedValue for Integer {
|
|||
type ComputedValue = i32;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _: &Context) -> i32 { self.value }
|
||||
fn to_computed_value(&self, _: &Context) -> i32 {
|
||||
self.value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &i32) -> Self {
|
||||
|
@ -507,7 +531,10 @@ pub type PositiveInteger = GreaterThanOrEqualToOne<Integer>;
|
|||
|
||||
impl Parse for PositiveInteger {
|
||||
#[inline]
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Integer::parse_positive(context, input).map(GreaterThanOrEqualToOne::<Integer>)
|
||||
}
|
||||
}
|
||||
|
@ -541,7 +568,6 @@ pub struct ClipRect {
|
|||
pub left: Option<Length>,
|
||||
}
|
||||
|
||||
|
||||
impl ToCss for ClipRect {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
|
@ -588,38 +614,64 @@ impl ToComputedValue for ClipRect {
|
|||
fn to_computed_value(&self, context: &Context) -> super::computed::ClipRect {
|
||||
super::computed::ClipRect {
|
||||
top: self.top.as_ref().map(|top| top.to_computed_value(context)),
|
||||
right: self.right.as_ref().map(|right| right.to_computed_value(context)),
|
||||
bottom: self.bottom.as_ref().map(|bottom| bottom.to_computed_value(context)),
|
||||
left: self.left.as_ref().map(|left| left.to_computed_value(context)),
|
||||
right: self.right
|
||||
.as_ref()
|
||||
.map(|right| right.to_computed_value(context)),
|
||||
bottom: self.bottom
|
||||
.as_ref()
|
||||
.map(|bottom| bottom.to_computed_value(context)),
|
||||
left: self.left
|
||||
.as_ref()
|
||||
.map(|left| left.to_computed_value(context)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &super::computed::ClipRect) -> Self {
|
||||
ClipRect {
|
||||
top: computed.top.map(|top| ToComputedValue::from_computed_value(&top)),
|
||||
right: computed.right.map(|right| ToComputedValue::from_computed_value(&right)),
|
||||
bottom: computed.bottom.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
|
||||
left: computed.left.map(|left| ToComputedValue::from_computed_value(&left)),
|
||||
top: computed
|
||||
.top
|
||||
.map(|top| ToComputedValue::from_computed_value(&top)),
|
||||
right: computed
|
||||
.right
|
||||
.map(|right| ToComputedValue::from_computed_value(&right)),
|
||||
bottom: computed
|
||||
.bottom
|
||||
.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
|
||||
left: computed
|
||||
.left
|
||||
.map(|left| ToComputedValue::from_computed_value(&left)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for ClipRect {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
||||
impl ClipRect {
|
||||
/// Parses a rect(<top>, <left>, <bottom>, <right>), allowing quirks.
|
||||
pub fn parse_quirky<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks) -> Result<Self, ParseError<'i>> {
|
||||
pub fn parse_quirky<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
use values::specified::Length;
|
||||
|
||||
fn parse_argument<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks) -> Result<Option<Length>, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
|
||||
fn parse_argument<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Option<Length>, ParseError<'i>> {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("auto"))
|
||||
.is_ok()
|
||||
{
|
||||
Ok(None)
|
||||
} else {
|
||||
Length::parse_quirky(context, input, allow_quirks).map(Some)
|
||||
|
@ -660,8 +712,11 @@ pub type ClipRectOrAuto = Either<ClipRect, Auto>;
|
|||
|
||||
impl ClipRectOrAuto {
|
||||
/// Parses a ClipRect or Auto, allowing quirks.
|
||||
pub fn parse_quirky<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks) -> Result<Self, ParseError<'i>> {
|
||||
pub fn parse_quirky<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(v) = input.try(|i| ClipRect::parse_quirky(context, i, allow_quirks)) {
|
||||
Ok(Either::First(v))
|
||||
} else {
|
||||
|
@ -698,7 +753,10 @@ pub struct Attr {
|
|||
}
|
||||
|
||||
impl Parse for Attr {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Attr, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Attr, ParseError<'i>> {
|
||||
input.expect_function_matching("attr")?;
|
||||
input.parse_nested_block(|i| Attr::parse_function(context, i))
|
||||
}
|
||||
|
@ -706,7 +764,12 @@ impl Parse for Attr {
|
|||
|
||||
/// Get the Namespace for a given prefix from the namespace map.
|
||||
fn get_namespace_for_prefix(prefix: &Prefix, context: &ParserContext) -> Option<Namespace> {
|
||||
context.namespaces.as_ref()?.prefixes.get(prefix).map(|x| x.clone())
|
||||
context
|
||||
.namespaces
|
||||
.as_ref()?
|
||||
.prefixes
|
||||
.get(prefix)
|
||||
.map(|x| x.clone())
|
||||
}
|
||||
|
||||
impl Attr {
|
||||
|
@ -733,9 +796,7 @@ impl Attr {
|
|||
let prefix = Prefix::from(ns.as_ref());
|
||||
let ns = match get_namespace_for_prefix(&prefix, context) {
|
||||
Some(ns) => ns,
|
||||
None => return Err(location.new_custom_error(
|
||||
StyleParseErrorKind::UnspecifiedError
|
||||
)),
|
||||
None => return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||
};
|
||||
Some((prefix, ns))
|
||||
} else {
|
||||
|
@ -744,8 +805,8 @@ impl Attr {
|
|||
return Ok(Attr {
|
||||
namespace: prefix_and_ns,
|
||||
attribute: Atom::from(second_token.as_ref()),
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
// In the case of attr(foobar ) we don't want to error out
|
||||
// because of the trailing whitespace
|
||||
Token::WhiteSpace(..) => {},
|
||||
|
|
|
@ -10,8 +10,8 @@ use selectors::parser::SelectorParseErrorKind;
|
|||
use style_traits::ParseError;
|
||||
use values::specified::BorderStyle;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Ord)]
|
||||
#[derive(PartialEq, PartialOrd, ToComputedValue, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Ord, PartialEq, PartialOrd, ToComputedValue,
|
||||
ToCss)]
|
||||
/// <https://drafts.csswg.org/css-ui/#propdef-outline-style>
|
||||
pub enum OutlineStyle {
|
||||
/// auto
|
||||
|
@ -32,7 +32,7 @@ impl OutlineStyle {
|
|||
pub fn none_or_hidden(&self) -> bool {
|
||||
match *self {
|
||||
OutlineStyle::Auto => false,
|
||||
OutlineStyle::Other(ref border_style) => border_style.none_or_hidden()
|
||||
OutlineStyle::Other(ref border_style) => border_style.none_or_hidden(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,11 +40,12 @@ impl OutlineStyle {
|
|||
impl Parse for OutlineStyle {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<OutlineStyle, ParseError<'i>> {
|
||||
if let Ok(border_style) = input.try(BorderStyle::parse) {
|
||||
if let BorderStyle::Hidden = border_style {
|
||||
return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into())));
|
||||
return Err(input
|
||||
.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into())));
|
||||
}
|
||||
|
||||
return Ok(OutlineStyle::Other(border_style));
|
||||
|
|
|
@ -9,7 +9,7 @@ use parser::{Parse, ParserContext};
|
|||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, ToCss};
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
use values::{CSSFloat, serialize_percentage};
|
||||
use values::{serialize_percentage, CSSFloat};
|
||||
use values::computed::{Context, ToComputedValue};
|
||||
use values::computed::percentage::Percentage as ComputedPercentage;
|
||||
use values::specified::calc::CalcNode;
|
||||
|
@ -26,7 +26,6 @@ pub struct Percentage {
|
|||
calc_clamping_mode: Option<AllowedNumericType>,
|
||||
}
|
||||
|
||||
|
||||
impl ToCss for Percentage {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
|
@ -73,7 +72,8 @@ impl Percentage {
|
|||
}
|
||||
/// Gets the underlying value for this float.
|
||||
pub fn get(&self) -> CSSFloat {
|
||||
self.calc_clamping_mode.map_or(self.value, |mode| mode.clamp(self.value))
|
||||
self.calc_clamping_mode
|
||||
.map_or(self.value, |mode| mode.clamp(self.value))
|
||||
}
|
||||
|
||||
/// Returns whether this percentage is a `calc()` value.
|
||||
|
@ -98,16 +98,16 @@ impl Percentage {
|
|||
let location = input.current_source_location();
|
||||
// FIXME: remove early returns when lifetimes are non-lexical
|
||||
match *input.next()? {
|
||||
Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => {
|
||||
Token::Percentage { unit_value, .. }
|
||||
if num_context.is_ok(context.parsing_mode, unit_value) =>
|
||||
{
|
||||
return Ok(Percentage::new(unit_value));
|
||||
}
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
|
||||
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
|
||||
let result = input.parse_nested_block(|i| {
|
||||
CalcNode::parse_percentage(context, i)
|
||||
})?;
|
||||
let result = input.parse_nested_block(|i| CalcNode::parse_percentage(context, i))?;
|
||||
|
||||
// TODO(emilio): -moz-image-rect is the only thing that uses
|
||||
// the clamping mode... I guess we could disallow it...
|
||||
|
@ -139,7 +139,7 @@ impl Parse for Percentage {
|
|||
#[inline]
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_with_clamping_mode(context, input, AllowedNumericType::All)
|
||||
}
|
||||
|
|
|
@ -61,7 +61,10 @@ pub enum Y {
|
|||
}
|
||||
|
||||
impl Parse for Position {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +78,9 @@ impl Position {
|
|||
) -> Result<Self, ParseError<'i>> {
|
||||
match input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks)) {
|
||||
Ok(x_pos @ PositionComponent::Center) => {
|
||||
if let Ok(y_pos) = input.try(|i|
|
||||
PositionComponent::parse_quirky(context, i, allow_quirks)) {
|
||||
if let Ok(y_pos) =
|
||||
input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks))
|
||||
{
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
let x_pos = input
|
||||
|
@ -92,7 +96,9 @@ impl Position {
|
|||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
if let Ok(y_keyword) = input.try(Y::parse) {
|
||||
let y_lop = input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)).ok();
|
||||
let y_lop = input
|
||||
.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
|
||||
.ok();
|
||||
let x_pos = PositionComponent::Side(x_keyword, lop);
|
||||
let y_pos = PositionComponent::Side(y_keyword, y_lop);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
|
@ -106,7 +112,9 @@ impl Position {
|
|||
let y_pos = PositionComponent::Side(y_keyword, None);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
if let Ok(y_lop) = input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) {
|
||||
if let Ok(y_lop) =
|
||||
input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
|
||||
{
|
||||
let y_pos = PositionComponent::Length(y_lop);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
|
@ -118,9 +126,11 @@ impl Position {
|
|||
}
|
||||
let y_keyword = Y::parse(input)?;
|
||||
let lop_and_x_pos: Result<_, ParseError> = input.try(|i| {
|
||||
let y_lop = i.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)).ok();
|
||||
let y_lop = i.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
|
||||
.ok();
|
||||
if let Ok(x_keyword) = i.try(X::parse) {
|
||||
let x_lop = i.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)).ok();
|
||||
let x_lop = i.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
|
||||
.ok();
|
||||
let x_pos = PositionComponent::Side(x_keyword, x_lop);
|
||||
return Ok((y_lop, x_pos));
|
||||
};
|
||||
|
@ -150,12 +160,18 @@ impl ToCss for Position {
|
|||
W: Write,
|
||||
{
|
||||
match (&self.horizontal, &self.vertical) {
|
||||
(x_pos @ &PositionComponent::Side(_, Some(_)), &PositionComponent::Length(ref y_lop)) => {
|
||||
(
|
||||
x_pos @ &PositionComponent::Side(_, Some(_)),
|
||||
&PositionComponent::Length(ref y_lop),
|
||||
) => {
|
||||
x_pos.to_css(dest)?;
|
||||
dest.write_str(" top ")?;
|
||||
y_lop.to_css(dest)
|
||||
},
|
||||
(&PositionComponent::Length(ref x_lop), y_pos @ &PositionComponent::Side(_, Some(_))) => {
|
||||
(
|
||||
&PositionComponent::Length(ref x_lop),
|
||||
y_pos @ &PositionComponent::Side(_, Some(_)),
|
||||
) => {
|
||||
dest.write_str("left ")?;
|
||||
x_lop.to_css(dest)?;
|
||||
dest.write_str(" ")?;
|
||||
|
@ -171,17 +187,21 @@ impl ToCss for Position {
|
|||
}
|
||||
|
||||
impl<S: Parse> Parse for PositionComponent<S> {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Parse> PositionComponent<S> {
|
||||
/// Parses a component of a CSS position, with quirks.
|
||||
pub fn parse_quirky<'i, 't>(context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
pub fn parse_quirky<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("center")).is_ok() {
|
||||
return Ok(PositionComponent::Center);
|
||||
}
|
||||
|
@ -189,7 +209,9 @@ impl<S: Parse> PositionComponent<S> {
|
|||
return Ok(PositionComponent::Length(lop));
|
||||
}
|
||||
let keyword = S::parse(context, input)?;
|
||||
let lop = input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)).ok();
|
||||
let lop = input
|
||||
.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
|
||||
.ok();
|
||||
Ok(PositionComponent::Side(keyword, lop))
|
||||
}
|
||||
}
|
||||
|
@ -206,19 +228,16 @@ impl<S: Side> ToComputedValue for PositionComponent<S> {
|
|||
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
PositionComponent::Center => {
|
||||
ComputedLengthOrPercentage::Percentage(Percentage(0.5))
|
||||
},
|
||||
PositionComponent::Center => ComputedLengthOrPercentage::Percentage(Percentage(0.5)),
|
||||
PositionComponent::Side(ref keyword, None) => {
|
||||
let p = Percentage(if keyword.is_start() { 0. } else { 1. });
|
||||
ComputedLengthOrPercentage::Percentage(p)
|
||||
},
|
||||
PositionComponent::Side(ref keyword, Some(ref length)) if !keyword.is_start() => {
|
||||
match length.to_computed_value(context) {
|
||||
ComputedLengthOrPercentage::Length(length) => {
|
||||
ComputedLengthOrPercentage::Calc(
|
||||
CalcLengthOrPercentage::new(-length, Some(Percentage::hundred())))
|
||||
},
|
||||
ComputedLengthOrPercentage::Length(length) => ComputedLengthOrPercentage::Calc(
|
||||
CalcLengthOrPercentage::new(-length, Some(Percentage::hundred())),
|
||||
),
|
||||
ComputedLengthOrPercentage::Percentage(p) => {
|
||||
ComputedLengthOrPercentage::Percentage(Percentage(1.0 - p.0))
|
||||
},
|
||||
|
@ -230,9 +249,7 @@ impl<S: Side> ToComputedValue for PositionComponent<S> {
|
|||
}
|
||||
},
|
||||
PositionComponent::Side(_, Some(ref length)) |
|
||||
PositionComponent::Length(ref length) => {
|
||||
length.to_computed_value(context)
|
||||
},
|
||||
PositionComponent::Length(ref length) => length.to_computed_value(context),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,7 +316,10 @@ pub type LegacyHPosition = OriginComponent<X>;
|
|||
pub type LegacyVPosition = OriginComponent<Y>;
|
||||
|
||||
impl Parse for LegacyPosition {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_quirky(context, input, AllowQuirks::No)
|
||||
}
|
||||
}
|
||||
|
@ -313,8 +333,7 @@ impl LegacyPosition {
|
|||
) -> Result<Self, ParseError<'i>> {
|
||||
match input.try(|i| OriginComponent::parse(context, i)) {
|
||||
Ok(x_pos @ OriginComponent::Center) => {
|
||||
if let Ok(y_pos) = input.try(|i|
|
||||
OriginComponent::parse(context, i)) {
|
||||
if let Ok(y_pos) = input.try(|i| OriginComponent::parse(context, i)) {
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
let x_pos = input
|
||||
|
@ -330,8 +349,10 @@ impl LegacyPosition {
|
|||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
let x_pos = OriginComponent::Side(x_keyword);
|
||||
if let Ok(y_lop) = input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) {
|
||||
return Ok(Self::new(x_pos, OriginComponent::Length(y_lop)))
|
||||
if let Ok(y_lop) =
|
||||
input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
|
||||
{
|
||||
return Ok(Self::new(x_pos, OriginComponent::Length(y_lop)));
|
||||
}
|
||||
let _ = input.try(|i| i.expect_ident_matching("center"));
|
||||
return Ok(Self::new(x_pos, OriginComponent::Center));
|
||||
|
@ -341,7 +362,9 @@ impl LegacyPosition {
|
|||
let y_pos = OriginComponent::Side(y_keyword);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
if let Ok(y_lop) = input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) {
|
||||
if let Ok(y_lop) =
|
||||
input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
|
||||
{
|
||||
let y_pos = OriginComponent::Length(y_lop);
|
||||
return Ok(Self::new(x_pos, y_pos));
|
||||
}
|
||||
|
@ -425,7 +448,9 @@ impl ToCss for GridAutoFlow {
|
|||
{
|
||||
self.autoflow.to_css(dest)?;
|
||||
|
||||
if self.dense { dest.write_str(" dense")?; }
|
||||
if self.dense {
|
||||
dest.write_str(" dense")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +459,7 @@ impl Parse for GridAutoFlow {
|
|||
/// [ row | column ] || dense
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<GridAutoFlow, ParseError<'i>> {
|
||||
let mut value = None;
|
||||
let mut dense = false;
|
||||
|
@ -458,7 +483,8 @@ impl Parse for GridAutoFlow {
|
|||
_ => false
|
||||
};
|
||||
if !success {
|
||||
return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())));
|
||||
return Err(location
|
||||
.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,14 +505,12 @@ impl From<u8> for GridAutoFlow {
|
|||
use gecko_bindings::structs;
|
||||
|
||||
GridAutoFlow {
|
||||
autoflow:
|
||||
if bits & structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8 != 0 {
|
||||
AutoFlow::Row
|
||||
} else {
|
||||
AutoFlow::Column
|
||||
},
|
||||
dense:
|
||||
bits & structs::NS_STYLE_GRID_AUTO_FLOW_DENSE as u8 != 0,
|
||||
autoflow: if bits & structs::NS_STYLE_GRID_AUTO_FLOW_ROW as u8 != 0 {
|
||||
AutoFlow::Row
|
||||
} else {
|
||||
AutoFlow::Column
|
||||
},
|
||||
dense: bits & structs::NS_STYLE_GRID_AUTO_FLOW_DENSE as u8 != 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -669,9 +693,8 @@ impl<'a> Iterator for TemplateAreasTokenizer<'a> {
|
|||
}
|
||||
|
||||
fn is_name_code_point(c: char) -> bool {
|
||||
c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' ||
|
||||
c >= '\u{80}' || c == '_' ||
|
||||
c >= '0' && c <= '9' || c == '-'
|
||||
c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '\u{80}' || c == '_' ||
|
||||
c >= '0' && c <= '9' || c == '-'
|
||||
}
|
||||
|
||||
/// This property specifies named grid areas.
|
||||
|
|
|
@ -16,8 +16,10 @@ pub type LengthOrNumberRect = Rect<LengthOrNumber>;
|
|||
impl LengthOrNumberRect {
|
||||
/// Parses a `LengthOrNumberRect`, rejecting negative values.
|
||||
#[inline]
|
||||
pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
pub fn parse_non_negative<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Rect::parse_with(context, input, LengthOrNumber::parse_non_negative)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,25 +56,19 @@ impl SourceSizeList {
|
|||
|
||||
/// Evaluate this <source-size-list> to get the final viewport length.
|
||||
pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> Au {
|
||||
let matching_source_size = self.source_sizes.iter().find(|source_size| {
|
||||
source_size.condition.matches(device, quirks_mode)
|
||||
});
|
||||
let matching_source_size = self.source_sizes
|
||||
.iter()
|
||||
.find(|source_size| source_size.condition.matches(device, quirks_mode));
|
||||
|
||||
computed::Context::for_media_query_evaluation(device, quirks_mode, |context| {
|
||||
match matching_source_size {
|
||||
Some(source_size) => {
|
||||
source_size.value.to_computed_value(context)
|
||||
}
|
||||
None => {
|
||||
match self.value {
|
||||
Some(ref v) => v.to_computed_value(context),
|
||||
None => {
|
||||
Length::NoCalc(NoCalcLength::ViewportPercentage(
|
||||
ViewportPercentageLength::Vw(100.)
|
||||
)).to_computed_value(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(source_size) => source_size.value.to_computed_value(context),
|
||||
None => match self.value {
|
||||
Some(ref v) => v.to_computed_value(context),
|
||||
None => Length::NoCalc(NoCalcLength::ViewportPercentage(
|
||||
ViewportPercentageLength::Vw(100.),
|
||||
)).to_computed_value(context),
|
||||
},
|
||||
}
|
||||
}).into()
|
||||
}
|
||||
|
@ -103,10 +97,7 @@ impl SourceSizeList {
|
|||
/// NOTE(emilio): This doesn't match the grammar in the spec, see:
|
||||
///
|
||||
/// https://html.spec.whatwg.org/multipage/#parsing-a-sizes-attribute
|
||||
pub fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Self {
|
||||
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Self {
|
||||
let mut source_sizes = vec![];
|
||||
|
||||
loop {
|
||||
|
@ -116,12 +107,15 @@ impl SourceSizeList {
|
|||
|
||||
match result {
|
||||
Ok(SourceSizeOrLength::Length(value)) => {
|
||||
return Self { source_sizes, value: Some(value) }
|
||||
}
|
||||
return Self {
|
||||
source_sizes,
|
||||
value: Some(value),
|
||||
}
|
||||
},
|
||||
Ok(SourceSizeOrLength::SourceSize(source_size)) => {
|
||||
source_sizes.push(source_size);
|
||||
}
|
||||
Err(..) => {}
|
||||
},
|
||||
Err(..) => {},
|
||||
}
|
||||
|
||||
match input.next() {
|
||||
|
@ -131,7 +125,10 @@ impl SourceSizeList {
|
|||
}
|
||||
}
|
||||
|
||||
SourceSizeList { source_sizes, value: None }
|
||||
SourceSizeList {
|
||||
source_sizes,
|
||||
value: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ use values::specified::url::SpecifiedUrl;
|
|||
/// Specified SVG Paint value
|
||||
pub type SVGPaint = generic::SVGPaint<RGBAColor, SpecifiedUrl>;
|
||||
|
||||
|
||||
/// Specified SVG Paint Kind value
|
||||
pub type SVGPaintKind = generic::SVGPaintKind<RGBAColor, SpecifiedUrl>;
|
||||
|
||||
|
@ -61,9 +60,10 @@ impl Parse for SVGLength {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.try(|i| SvgLengthOrPercentageOrNumber::parse(context, i))
|
||||
.map(Into::into)
|
||||
.or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue))
|
||||
input
|
||||
.try(|i| SvgLengthOrPercentageOrNumber::parse(context, i))
|
||||
.map(Into::into)
|
||||
.or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,9 +86,10 @@ impl Parse for SVGWidth {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.try(|i| NonNegativeSvgLengthOrPercentageOrNumber::parse(context, i))
|
||||
.map(Into::into)
|
||||
.or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue))
|
||||
input
|
||||
.try(|i| NonNegativeSvgLengthOrPercentageOrNumber::parse(context, i))
|
||||
.map(Into::into)
|
||||
.or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,9 +107,11 @@ impl Parse for SVGStrokeDashArray {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(values) = input.try(|i| CommaWithSpace::parse(i, |i| {
|
||||
NonNegativeSvgLengthOrPercentageOrNumber::parse(context, i)
|
||||
})) {
|
||||
if let Ok(values) = input.try(|i| {
|
||||
CommaWithSpace::parse(i, |i| {
|
||||
NonNegativeSvgLengthOrPercentageOrNumber::parse(context, i)
|
||||
})
|
||||
}) {
|
||||
Ok(generic::SVGStrokeDashArray::Values(values))
|
||||
} else if let Ok(_) = input.try(|i| i.expect_ident_matching("none")) {
|
||||
Ok(generic::SVGStrokeDashArray::Values(vec![]))
|
||||
|
@ -189,10 +192,10 @@ impl SVGPaintOrder {
|
|||
impl Parse for SVGPaintOrder {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<SVGPaintOrder, ParseError<'i>> {
|
||||
if let Ok(()) = input.try(|i| i.expect_ident_matching("normal")) {
|
||||
return Ok(SVGPaintOrder::normal())
|
||||
return Ok(SVGPaintOrder::normal());
|
||||
}
|
||||
|
||||
let mut value = 0;
|
||||
|
@ -214,20 +217,20 @@ impl Parse for SVGPaintOrder {
|
|||
Ok(val) => {
|
||||
if (seen & (1 << val as u8)) != 0 {
|
||||
// don't parse the same ident twice
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
value |= (val as u8) << (pos * PAINT_ORDER_SHIFT);
|
||||
seen |= 1 << (val as u8);
|
||||
pos += 1;
|
||||
}
|
||||
},
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
|
||||
if value == 0 {
|
||||
// Couldn't find any keyword
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
// fill in rest
|
||||
|
@ -252,7 +255,7 @@ impl ToCss for SVGPaintOrder {
|
|||
W: Write,
|
||||
{
|
||||
if self.0 == 0 {
|
||||
return dest.write_str("normal")
|
||||
return dest.write_str("normal");
|
||||
}
|
||||
|
||||
let mut last_pos_to_serialize = 0;
|
||||
|
@ -283,10 +286,14 @@ pub struct MozContextProperties(pub CustomIdent);
|
|||
impl Parse for MozContextProperties {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<MozContextProperties, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
let i = input.expect_ident()?;
|
||||
Ok(MozContextProperties(CustomIdent::from_ident(location, i, &["all", "none", "auto"])?))
|
||||
Ok(MozContextProperties(CustomIdent::from_ident(
|
||||
location,
|
||||
i,
|
||||
&["all", "none", "auto"],
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use cssparser::Parser;
|
||||
use parser::{Parse, ParserContext};
|
||||
use style_traits::{StyleParseErrorKind, ParseError};
|
||||
use style_traits::{ParseError, StyleParseErrorKind};
|
||||
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
|
||||
/// span. for `<col span>` pres attr
|
||||
|
@ -14,7 +14,10 @@ pub struct XSpan(#[css(skip)] pub i32);
|
|||
|
||||
impl Parse for XSpan {
|
||||
// never parse it, only set via presentation attribute
|
||||
fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result<XSpan, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<XSpan, ParseError<'i>> {
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,10 @@ pub type WordSpacing = Spacing<LengthOrPercentage>;
|
|||
pub type LineHeight = GenericLineHeight<NonNegativeNumber, NonNegativeLengthOrPercentage>;
|
||||
|
||||
impl Parse for InitialLetter {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
|
||||
return Ok(GenericInitialLetter::Normal);
|
||||
}
|
||||
|
@ -48,7 +51,10 @@ impl Parse for InitialLetter {
|
|||
}
|
||||
|
||||
impl Parse for LetterSpacing {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Spacing::parse_with(context, input, |c, i| {
|
||||
Length::parse_quirky(c, i, AllowQuirks::Yes)
|
||||
})
|
||||
|
@ -56,7 +62,10 @@ impl Parse for LetterSpacing {
|
|||
}
|
||||
|
||||
impl Parse for WordSpacing {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Spacing::parse_with(context, input, |c, i| {
|
||||
LengthOrPercentage::parse_quirky(c, i, AllowQuirks::Yes)
|
||||
})
|
||||
|
@ -64,21 +73,23 @@ impl Parse for WordSpacing {
|
|||
}
|
||||
|
||||
impl Parse for LineHeight {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(number) = input.try(|i| NonNegativeNumber::parse(context, i)) {
|
||||
return Ok(GenericLineHeight::Number(number))
|
||||
return Ok(GenericLineHeight::Number(number));
|
||||
}
|
||||
if let Ok(nlop) = input.try(|i| NonNegativeLengthOrPercentage::parse(context, i)) {
|
||||
return Ok(GenericLineHeight::Length(nlop))
|
||||
return Ok(GenericLineHeight::Length(nlop));
|
||||
}
|
||||
let location = input.current_source_location();
|
||||
let ident = input.expect_ident()?;
|
||||
match ident {
|
||||
ref ident if ident.eq_ignore_ascii_case("normal") => {
|
||||
Ok(GenericLineHeight::Normal)
|
||||
},
|
||||
ref ident if ident.eq_ignore_ascii_case("normal") => Ok(GenericLineHeight::Normal),
|
||||
#[cfg(feature = "gecko")]
|
||||
ref ident if ident.eq_ignore_ascii_case("-moz-block-height") => {
|
||||
ref ident if ident.eq_ignore_ascii_case("-moz-block-height") =>
|
||||
{
|
||||
Ok(GenericLineHeight::MozBlockHeight)
|
||||
},
|
||||
ident => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
|
||||
|
@ -94,69 +105,54 @@ impl ToComputedValue for LineHeight {
|
|||
use values::computed::Length as ComputedLength;
|
||||
use values::specified::length::FontBaseSize;
|
||||
match *self {
|
||||
GenericLineHeight::Normal => {
|
||||
GenericLineHeight::Normal
|
||||
},
|
||||
GenericLineHeight::Normal => GenericLineHeight::Normal,
|
||||
#[cfg(feature = "gecko")]
|
||||
GenericLineHeight::MozBlockHeight => {
|
||||
GenericLineHeight::MozBlockHeight
|
||||
},
|
||||
GenericLineHeight::MozBlockHeight => GenericLineHeight::MozBlockHeight,
|
||||
GenericLineHeight::Number(number) => {
|
||||
GenericLineHeight::Number(number.to_computed_value(context))
|
||||
},
|
||||
GenericLineHeight::Length(ref non_negative_lop) => {
|
||||
let result = match non_negative_lop.0 {
|
||||
LengthOrPercentage::Length(NoCalcLength::Absolute(ref abs)) => {
|
||||
context.maybe_zoom_text(abs.to_computed_value(context).into()).0
|
||||
}
|
||||
LengthOrPercentage::Length(ref length) => {
|
||||
length.to_computed_value(context)
|
||||
context
|
||||
.maybe_zoom_text(abs.to_computed_value(context).into())
|
||||
.0
|
||||
},
|
||||
LengthOrPercentage::Percentage(ref p) => {
|
||||
FontRelativeLength::Em(p.0)
|
||||
.to_computed_value(
|
||||
context,
|
||||
FontBaseSize::CurrentStyle,
|
||||
)
|
||||
}
|
||||
LengthOrPercentage::Length(ref length) => length.to_computed_value(context),
|
||||
LengthOrPercentage::Percentage(ref p) => FontRelativeLength::Em(p.0)
|
||||
.to_computed_value(context, FontBaseSize::CurrentStyle),
|
||||
LengthOrPercentage::Calc(ref calc) => {
|
||||
let computed_calc =
|
||||
calc.to_computed_value_zoomed(context, FontBaseSize::CurrentStyle);
|
||||
let font_relative_length =
|
||||
FontRelativeLength::Em(computed_calc.percentage())
|
||||
.to_computed_value(
|
||||
context,
|
||||
FontBaseSize::CurrentStyle,
|
||||
).px();
|
||||
.to_computed_value(context, FontBaseSize::CurrentStyle)
|
||||
.px();
|
||||
|
||||
let absolute_length = computed_calc.unclamped_length().px();
|
||||
let pixel = computed_calc
|
||||
.clamping_mode
|
||||
.clamp(absolute_length + font_relative_length);
|
||||
ComputedLength::new(pixel)
|
||||
}
|
||||
},
|
||||
};
|
||||
GenericLineHeight::Length(result.into())
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
match *computed {
|
||||
GenericLineHeight::Normal => {
|
||||
GenericLineHeight::Normal
|
||||
},
|
||||
GenericLineHeight::Normal => GenericLineHeight::Normal,
|
||||
#[cfg(feature = "gecko")]
|
||||
GenericLineHeight::MozBlockHeight => {
|
||||
GenericLineHeight::MozBlockHeight
|
||||
},
|
||||
GenericLineHeight::MozBlockHeight => GenericLineHeight::MozBlockHeight,
|
||||
GenericLineHeight::Number(ref number) => {
|
||||
GenericLineHeight::Number(NonNegativeNumber::from_computed_value(number))
|
||||
},
|
||||
GenericLineHeight::Length(ref length) => {
|
||||
GenericLineHeight::Length(NoCalcLength::from_computed_value(&length.0).into())
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,8 +169,10 @@ pub enum TextOverflowSide {
|
|||
}
|
||||
|
||||
impl Parse for TextOverflowSide {
|
||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<TextOverflowSide, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<TextOverflowSide, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
match *input.next()? {
|
||||
Token::Ident(ref ident) => {
|
||||
|
@ -185,10 +183,10 @@ impl Parse for TextOverflowSide {
|
|||
SelectorParseErrorKind::UnexpectedIdent(ident.clone())
|
||||
))
|
||||
}
|
||||
}
|
||||
Token::QuotedString(ref v) => {
|
||||
Ok(TextOverflowSide::String(v.as_ref().to_owned().into_boxed_str()))
|
||||
}
|
||||
},
|
||||
Token::QuotedString(ref v) => Ok(TextOverflowSide::String(
|
||||
v.as_ref().to_owned().into_boxed_str(),
|
||||
)),
|
||||
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
}
|
||||
|
@ -204,9 +202,14 @@ pub struct TextOverflow {
|
|||
}
|
||||
|
||||
impl Parse for TextOverflow {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<TextOverflow, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<TextOverflow, ParseError<'i>> {
|
||||
let first = TextOverflowSide::parse(context, input)?;
|
||||
let second = input.try(|input| TextOverflowSide::parse(context, input)).ok();
|
||||
let second = input
|
||||
.try(|input| TextOverflowSide::parse(context, input))
|
||||
.ok();
|
||||
Ok(TextOverflow { first, second })
|
||||
}
|
||||
}
|
||||
|
@ -289,11 +292,14 @@ impl Parse for TextDecorationLine {
|
|||
/// none | [ underline || overline || line-through || blink ]
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<TextDecorationLine, ParseError<'i>> {
|
||||
let mut result = TextDecorationLine::NONE;
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(result)
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("none"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
loop {
|
||||
|
@ -427,7 +433,10 @@ pub enum TextAlign {
|
|||
}
|
||||
|
||||
impl Parse for TextAlign {
|
||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
// MozCenterOrInherit cannot be parsed, only set directly on the elements
|
||||
if let Ok(key) = input.try(TextAlignKeyword::parse) {
|
||||
return Ok(TextAlign::Keyword(key));
|
||||
|
@ -490,25 +499,31 @@ impl ToComputedValue for TextAlign {
|
|||
if _context.is_root_element {
|
||||
return TextAlignKeyword::start();
|
||||
}
|
||||
let parent = _context.builder.get_parent_inheritedtext().clone_text_align();
|
||||
let parent = _context
|
||||
.builder
|
||||
.get_parent_inheritedtext()
|
||||
.clone_text_align();
|
||||
let ltr = _context.builder.inherited_writing_mode().is_bidi_ltr();
|
||||
match (parent, ltr) {
|
||||
(TextAlignKeyword::Start, true) => TextAlignKeyword::Left,
|
||||
(TextAlignKeyword::Start, false) => TextAlignKeyword::Right,
|
||||
(TextAlignKeyword::End, true) => TextAlignKeyword::Right,
|
||||
(TextAlignKeyword::End, false) => TextAlignKeyword::Left,
|
||||
_ => parent
|
||||
_ => parent,
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "gecko")]
|
||||
TextAlign::MozCenterOrInherit => {
|
||||
let parent = _context.builder.get_parent_inheritedtext().clone_text_align();
|
||||
let parent = _context
|
||||
.builder
|
||||
.get_parent_inheritedtext()
|
||||
.clone_text_align();
|
||||
if parent == TextAlignKeyword::Start {
|
||||
TextAlignKeyword::Center
|
||||
} else {
|
||||
parent
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -587,11 +602,31 @@ impl TextEmphasisShapeKeyword {
|
|||
pub fn char(&self, fill: TextEmphasisFillMode) -> &str {
|
||||
let fill = fill == TextEmphasisFillMode::Filled;
|
||||
match *self {
|
||||
TextEmphasisShapeKeyword::Dot => if fill { "\u{2022}" } else { "\u{25e6}" },
|
||||
TextEmphasisShapeKeyword::Circle => if fill { "\u{25cf}" } else { "\u{25cb}" },
|
||||
TextEmphasisShapeKeyword::DoubleCircle => if fill { "\u{25c9}" } else { "\u{25ce}" },
|
||||
TextEmphasisShapeKeyword::Triangle => if fill { "\u{25b2}" } else { "\u{25b3}" },
|
||||
TextEmphasisShapeKeyword::Sesame => if fill { "\u{fe45}" } else { "\u{fe46}" },
|
||||
TextEmphasisShapeKeyword::Dot => if fill {
|
||||
"\u{2022}"
|
||||
} else {
|
||||
"\u{25e6}"
|
||||
},
|
||||
TextEmphasisShapeKeyword::Circle => if fill {
|
||||
"\u{25cf}"
|
||||
} else {
|
||||
"\u{25cb}"
|
||||
},
|
||||
TextEmphasisShapeKeyword::DoubleCircle => if fill {
|
||||
"\u{25c9}"
|
||||
} else {
|
||||
"\u{25ce}"
|
||||
},
|
||||
TextEmphasisShapeKeyword::Triangle => if fill {
|
||||
"\u{25b2}"
|
||||
} else {
|
||||
"\u{25b3}"
|
||||
},
|
||||
TextEmphasisShapeKeyword::Sesame => if fill {
|
||||
"\u{fe45}"
|
||||
} else {
|
||||
"\u{fe46}"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -603,8 +638,9 @@ impl ToComputedValue for TextEmphasisStyle {
|
|||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
TextEmphasisStyle::Keyword(ref keyword) => {
|
||||
let default_shape = if context.style().get_inheritedbox()
|
||||
.clone_writing_mode() == SpecifiedWritingMode::HorizontalTb {
|
||||
let default_shape = if context.style().get_inheritedbox().clone_writing_mode() ==
|
||||
SpecifiedWritingMode::HorizontalTb
|
||||
{
|
||||
TextEmphasisShapeKeyword::Circle
|
||||
} else {
|
||||
TextEmphasisShapeKeyword::Sesame
|
||||
|
@ -620,16 +656,19 @@ impl ToComputedValue for TextEmphasisStyle {
|
|||
// recommendation at http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
|
||||
let string = s.graphemes(true).next().unwrap_or("").to_string();
|
||||
ComputedTextEmphasisStyle::String(string)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
match *computed {
|
||||
ComputedTextEmphasisStyle::Keyword(ref keyword) =>
|
||||
TextEmphasisStyle::Keyword(TextEmphasisKeywordValue::FillAndShape(keyword.fill, keyword.shape)),
|
||||
ComputedTextEmphasisStyle::Keyword(ref keyword) => TextEmphasisStyle::Keyword(
|
||||
TextEmphasisKeywordValue::FillAndShape(keyword.fill, keyword.shape),
|
||||
),
|
||||
ComputedTextEmphasisStyle::None => TextEmphasisStyle::None,
|
||||
ComputedTextEmphasisStyle::String(ref string) => TextEmphasisStyle::String(string.clone())
|
||||
ComputedTextEmphasisStyle::String(ref string) => {
|
||||
TextEmphasisStyle::String(string.clone())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -639,7 +678,10 @@ impl Parse for TextEmphasisStyle {
|
|||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("none"))
|
||||
.is_ok()
|
||||
{
|
||||
return Ok(TextEmphasisStyle::None);
|
||||
}
|
||||
|
||||
|
@ -667,8 +709,7 @@ impl Parse for TextEmphasisStyle {
|
|||
}
|
||||
|
||||
/// The allowed horizontal values for the `text-emphasis-position` property.
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq)]
|
||||
#[derive(ToComputedValue, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)]
|
||||
pub enum TextEmphasisHorizontalWritingModeValue {
|
||||
/// Draw marks over the text in horizontal writing mode.
|
||||
Over,
|
||||
|
@ -677,8 +718,7 @@ pub enum TextEmphasisHorizontalWritingModeValue {
|
|||
}
|
||||
|
||||
/// The allowed vertical values for the `text-emphasis-position` property.
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq)]
|
||||
#[derive(ToComputedValue, ToCss)]
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)]
|
||||
pub enum TextEmphasisVerticalWritingModeValue {
|
||||
/// Draws marks to the right of the text in vertical writing mode.
|
||||
Right,
|
||||
|
@ -690,15 +730,17 @@ pub enum TextEmphasisVerticalWritingModeValue {
|
|||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
|
||||
pub struct TextEmphasisPosition(
|
||||
pub TextEmphasisHorizontalWritingModeValue,
|
||||
pub TextEmphasisVerticalWritingModeValue
|
||||
pub TextEmphasisVerticalWritingModeValue,
|
||||
);
|
||||
|
||||
impl TextEmphasisPosition {
|
||||
#[inline]
|
||||
/// Returns the initial value of `text-emphasis-position`
|
||||
pub fn over_right() -> Self {
|
||||
TextEmphasisPosition(TextEmphasisHorizontalWritingModeValue::Over,
|
||||
TextEmphasisVerticalWritingModeValue::Right)
|
||||
TextEmphasisPosition(
|
||||
TextEmphasisHorizontalWritingModeValue::Over,
|
||||
TextEmphasisVerticalWritingModeValue::Right,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -725,9 +767,11 @@ impl TextEmphasisPosition {
|
|||
impl Parse for TextEmphasisPosition {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(horizontal) = input.try(|input| TextEmphasisHorizontalWritingModeValue::parse(input)) {
|
||||
if let Ok(horizontal) =
|
||||
input.try(|input| TextEmphasisHorizontalWritingModeValue::parse(input))
|
||||
{
|
||||
let vertical = TextEmphasisVerticalWritingModeValue::parse(input)?;
|
||||
Ok(TextEmphasisPosition(horizontal, vertical))
|
||||
} else {
|
||||
|
@ -751,16 +795,20 @@ impl From<TextEmphasisPosition> for u8 {
|
|||
use gecko_bindings::structs;
|
||||
|
||||
let mut result = match v.0 {
|
||||
TextEmphasisHorizontalWritingModeValue::Over => structs::NS_STYLE_TEXT_EMPHASIS_POSITION_OVER,
|
||||
TextEmphasisHorizontalWritingModeValue::Under => structs::NS_STYLE_TEXT_EMPHASIS_POSITION_UNDER,
|
||||
TextEmphasisHorizontalWritingModeValue::Over => {
|
||||
structs::NS_STYLE_TEXT_EMPHASIS_POSITION_OVER
|
||||
},
|
||||
TextEmphasisHorizontalWritingModeValue::Under => {
|
||||
structs::NS_STYLE_TEXT_EMPHASIS_POSITION_UNDER
|
||||
},
|
||||
};
|
||||
match v.1 {
|
||||
TextEmphasisVerticalWritingModeValue::Right => {
|
||||
result |= structs::NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT;
|
||||
}
|
||||
},
|
||||
TextEmphasisVerticalWritingModeValue::Left => {
|
||||
result |= structs::NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT;
|
||||
}
|
||||
},
|
||||
};
|
||||
result as u8
|
||||
}
|
||||
|
@ -779,6 +827,9 @@ impl Parse for MozTabSize {
|
|||
// as the number `0` and not the length `0px`.
|
||||
return Ok(GenericMozTabSize::Number(number));
|
||||
}
|
||||
Ok(GenericMozTabSize::Length(NonNegativeLength::parse(context, input)?))
|
||||
Ok(GenericMozTabSize::Length(NonNegativeLength::parse(
|
||||
context,
|
||||
input,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//! Specified time values.
|
||||
|
||||
use cssparser::{Parser, Token};
|
||||
use parser::{ParserContext, Parse};
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
|
@ -34,7 +34,11 @@ pub enum TimeUnit {
|
|||
impl Time {
|
||||
/// Returns a time value that represents `seconds` seconds.
|
||||
pub fn from_seconds(seconds: CSSFloat) -> Self {
|
||||
Time { seconds, unit: TimeUnit::Second, was_calc: false }
|
||||
Time {
|
||||
seconds,
|
||||
unit: TimeUnit::Second,
|
||||
was_calc: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `0s`.
|
||||
|
@ -48,18 +52,18 @@ impl Time {
|
|||
}
|
||||
|
||||
/// Parses a time according to CSS-VALUES § 6.2.
|
||||
pub fn parse_dimension(
|
||||
value: CSSFloat,
|
||||
unit: &str,
|
||||
was_calc: bool
|
||||
) -> Result<Time, ()> {
|
||||
pub fn parse_dimension(value: CSSFloat, unit: &str, was_calc: bool) -> Result<Time, ()> {
|
||||
let (seconds, unit) = match_ignore_ascii_case! { unit,
|
||||
"s" => (value, TimeUnit::Second),
|
||||
"ms" => (value / 1000.0, TimeUnit::Millisecond),
|
||||
_ => return Err(())
|
||||
};
|
||||
|
||||
Ok(Time { seconds, unit, was_calc })
|
||||
Ok(Time {
|
||||
seconds,
|
||||
unit,
|
||||
was_calc,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a `Time` value from a CSS `calc()` expression.
|
||||
|
@ -74,7 +78,7 @@ impl Time {
|
|||
fn parse_with_clamping_mode<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
clamping_mode: AllowedNumericType
|
||||
clamping_mode: AllowedNumericType,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
use style_traits::ParsingMode;
|
||||
|
||||
|
@ -86,13 +90,16 @@ impl Time {
|
|||
// values for SMIL regardless of clamping_mode, but in this Time
|
||||
// value case, the value does not animate for SMIL at all, so we use
|
||||
// ParsingMode::DEFAULT directly.
|
||||
Ok(&Token::Dimension { value, ref unit, .. }) if clamping_mode.is_ok(ParsingMode::DEFAULT, value) => {
|
||||
Ok(&Token::Dimension {
|
||||
value, ref unit, ..
|
||||
}) if clamping_mode.is_ok(ParsingMode::DEFAULT, value) =>
|
||||
{
|
||||
return Time::parse_dimension(value, unit, /* from_calc = */ false)
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
Ok(&Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {}
|
||||
Ok(&Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {},
|
||||
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
Err(e) => return Err(e.into())
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
match input.parse_nested_block(|i| CalcNode::parse_time(context, i)) {
|
||||
Ok(time) if clamping_mode.is_ok(ParsingMode::DEFAULT, time.seconds) => Ok(time),
|
||||
|
@ -103,7 +110,7 @@ impl Time {
|
|||
/// Parses a non-negative time value.
|
||||
pub fn parse_non_negative<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_with_clamping_mode(context, input, AllowedNumericType::NonNegative)
|
||||
}
|
||||
|
@ -126,7 +133,10 @@ impl ToComputedValue for Time {
|
|||
}
|
||||
|
||||
impl Parse for Time {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Self::parse_with_clamping_mode(context, input, AllowedNumericType::All)
|
||||
}
|
||||
}
|
||||
|
@ -143,11 +153,11 @@ impl ToCss for Time {
|
|||
TimeUnit::Second => {
|
||||
self.seconds.to_css(dest)?;
|
||||
dest.write_str("s")?;
|
||||
}
|
||||
},
|
||||
TimeUnit::Millisecond => {
|
||||
(self.seconds * 1000.).to_css(dest)?;
|
||||
dest.write_str("ms")?;
|
||||
}
|
||||
},
|
||||
}
|
||||
if self.was_calc {
|
||||
dest.write_str(")")?;
|
||||
|
|
|
@ -13,19 +13,14 @@ use values::computed::{Percentage as ComputedPercentage, ToComputedValue};
|
|||
use values::computed::transform::TimingFunction as ComputedTimingFunction;
|
||||
use values::generics::transform as generic;
|
||||
use values::generics::transform::{Matrix, Matrix3D, StepPosition, TimingKeyword};
|
||||
use values::specified::{self, Angle, Number, Length, Integer, LengthOrPercentage};
|
||||
use values::specified::{self, Angle, Integer, Length, LengthOrPercentage, Number};
|
||||
use values::specified::position::{Side, X, Y};
|
||||
|
||||
pub use values::generics::transform::TransformStyle;
|
||||
|
||||
/// A single operation in a specified CSS `transform`
|
||||
pub type TransformOperation = generic::TransformOperation<
|
||||
Angle,
|
||||
Number,
|
||||
Length,
|
||||
Integer,
|
||||
LengthOrPercentage,
|
||||
>;
|
||||
pub type TransformOperation =
|
||||
generic::TransformOperation<Angle, Number, Length, Integer, LengthOrPercentage>;
|
||||
|
||||
/// A specified CSS `transform`
|
||||
pub type Transform = generic::Transform<TransformOperation>;
|
||||
|
@ -55,8 +50,7 @@ impl Transform {
|
|||
let function = input.expect_function()?.clone();
|
||||
input.parse_nested_block(|input| {
|
||||
let location = input.current_source_location();
|
||||
let result =
|
||||
match_ignore_ascii_case! { &function,
|
||||
let result = match_ignore_ascii_case! { &function,
|
||||
"matrix" => {
|
||||
let a = Number::parse(context, input)?;
|
||||
input.expect_comma()?;
|
||||
|
@ -220,8 +214,10 @@ impl Transform {
|
|||
},
|
||||
_ => Err(()),
|
||||
};
|
||||
result
|
||||
.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone())))
|
||||
result.map_err(|()| {
|
||||
location
|
||||
.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))
|
||||
})
|
||||
})
|
||||
})?))
|
||||
}
|
||||
|
@ -230,7 +226,7 @@ impl Transform {
|
|||
impl Parse for Transform {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Transform::parse_internal(context, input)
|
||||
}
|
||||
|
@ -251,11 +247,14 @@ pub enum OriginComponent<S> {
|
|||
pub type TimingFunction = generic::TimingFunction<Integer, Number>;
|
||||
|
||||
impl Parse for TransformOrigin {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let parse_depth = |input: &mut Parser| {
|
||||
input.try(|i| Length::parse(context, i)).unwrap_or(
|
||||
Length::from_px(0.),
|
||||
)
|
||||
input
|
||||
.try(|i| Length::parse(context, i))
|
||||
.unwrap_or(Length::from_px(0.))
|
||||
};
|
||||
match input.try(|i| OriginComponent::parse(context, i)) {
|
||||
Ok(x_origin @ OriginComponent::Center) => {
|
||||
|
@ -305,7 +304,10 @@ impl<S> Parse for OriginComponent<S>
|
|||
where
|
||||
S: Parse,
|
||||
{
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("center")).is_ok() {
|
||||
return Ok(OriginComponent::Center);
|
||||
}
|
||||
|
@ -325,7 +327,9 @@ where
|
|||
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
OriginComponent::Center => ComputedLengthOrPercentage::Percentage(ComputedPercentage(0.5)),
|
||||
OriginComponent::Center => {
|
||||
ComputedLengthOrPercentage::Percentage(ComputedPercentage(0.5))
|
||||
},
|
||||
OriginComponent::Length(ref length) => length.to_computed_value(context),
|
||||
OriginComponent::Side(ref keyword) => {
|
||||
let p = ComputedPercentage(if keyword.is_start() { 0. } else { 1. });
|
||||
|
@ -360,13 +364,15 @@ fn allow_frames_timing() -> bool {
|
|||
}
|
||||
|
||||
impl Parse for TimingFunction {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(keyword) = input.try(TimingKeyword::parse) {
|
||||
return Ok(generic::TimingFunction::Keyword(keyword));
|
||||
}
|
||||
if let Ok(ident) = input.try(|i| i.expect_ident_cloned()) {
|
||||
let position =
|
||||
match_ignore_ascii_case! { &ident,
|
||||
let position = match_ignore_ascii_case! { &ident,
|
||||
"step-start" => StepPosition::Start,
|
||||
"step-end" => StepPosition::End,
|
||||
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
|
||||
|
@ -409,7 +415,9 @@ impl Parse for TimingFunction {
|
|||
}
|
||||
},
|
||||
_ => Err(()),
|
||||
}).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone())))
|
||||
}).map_err(|()| {
|
||||
location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -421,12 +429,7 @@ impl ToComputedValue for TimingFunction {
|
|||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
generic::TimingFunction::Keyword(keyword) => generic::TimingFunction::Keyword(keyword),
|
||||
generic::TimingFunction::CubicBezier {
|
||||
x1,
|
||||
y1,
|
||||
x2,
|
||||
y2,
|
||||
} => {
|
||||
generic::TimingFunction::CubicBezier { x1, y1, x2, y2 } => {
|
||||
generic::TimingFunction::CubicBezier {
|
||||
x1: x1.to_computed_value(context),
|
||||
y1: y1.to_computed_value(context),
|
||||
|
@ -452,17 +455,16 @@ impl ToComputedValue for TimingFunction {
|
|||
ref y1,
|
||||
ref x2,
|
||||
ref y2,
|
||||
} => {
|
||||
generic::TimingFunction::CubicBezier {
|
||||
x1: Number::from_computed_value(x1),
|
||||
y1: Number::from_computed_value(y1),
|
||||
x2: Number::from_computed_value(x2),
|
||||
y2: Number::from_computed_value(y2),
|
||||
}
|
||||
},
|
||||
generic::TimingFunction::Steps(steps, position) => {
|
||||
generic::TimingFunction::Steps(Integer::from_computed_value(&(steps as i32)), position)
|
||||
} => generic::TimingFunction::CubicBezier {
|
||||
x1: Number::from_computed_value(x1),
|
||||
y1: Number::from_computed_value(y1),
|
||||
x2: Number::from_computed_value(x2),
|
||||
y2: Number::from_computed_value(y2),
|
||||
},
|
||||
generic::TimingFunction::Steps(steps, position) => generic::TimingFunction::Steps(
|
||||
Integer::from_computed_value(&(steps as i32)),
|
||||
position,
|
||||
),
|
||||
generic::TimingFunction::Frames(frames) => {
|
||||
generic::TimingFunction::Frames(Integer::from_computed_value(&(frames as i32)))
|
||||
},
|
||||
|
@ -476,7 +478,7 @@ pub type Rotate = generic::Rotate<Number, Angle>;
|
|||
impl Parse for Rotate {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(generic::Rotate::None);
|
||||
|
@ -502,7 +504,7 @@ pub type Translate = generic::Translate<LengthOrPercentage, Length>;
|
|||
impl Parse for Translate {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(generic::Translate::None);
|
||||
|
@ -530,7 +532,7 @@ pub type Scale = generic::Scale<Number>;
|
|||
impl Parse for Scale {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(generic::Scale::None);
|
||||
|
|
|
@ -24,7 +24,7 @@ impl MozForceBrokenImageIcon {
|
|||
impl Parse for MozForceBrokenImageIcon {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<MozForceBrokenImageIcon, ParseError<'i>> {
|
||||
// We intentionally don't support calc values here.
|
||||
match input.expect_integer()? {
|
||||
|
@ -52,6 +52,10 @@ impl From<u8> for MozForceBrokenImageIcon {
|
|||
|
||||
impl From<MozForceBrokenImageIcon> for u8 {
|
||||
fn from(v: MozForceBrokenImageIcon) -> u8 {
|
||||
if v.0 { 1 } else { 0 }
|
||||
if v.0 {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
use values::generics::url::UrlOrNone as GenericUrlOrNone;
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
pub use ::servo::url::{SpecifiedUrl, SpecifiedImageUrl};
|
||||
pub use servo::url::{SpecifiedImageUrl, SpecifiedUrl};
|
||||
#[cfg(feature = "gecko")]
|
||||
pub use ::gecko::url::{SpecifiedUrl, SpecifiedImageUrl};
|
||||
pub use gecko::url::{SpecifiedImageUrl, SpecifiedUrl};
|
||||
|
||||
/// Specified <url> | <none>
|
||||
pub type UrlOrNone = GenericUrlOrNone<SpecifiedUrl>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue