mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 1771980
- Refactor function parsing branches for specified::easing::TimingFunction
. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D149756
This commit is contained in:
parent
c3f962f2b2
commit
8c02818079
@ -53,74 +53,88 @@ impl Parse for TimingFunction {
|
||||
let location = input.current_source_location();
|
||||
let function = input.expect_function()?.clone();
|
||||
input.parse_nested_block(move |i| {
|
||||
(match_ignore_ascii_case! { &function,
|
||||
"cubic-bezier" => {
|
||||
let x1 = Number::parse(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let y1 = Number::parse(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let x2 = Number::parse(context, i)?;
|
||||
i.expect_comma()?;
|
||||
let y2 = Number::parse(context, i)?;
|
||||
|
||||
if x1.get() < 0.0 || x1.get() > 1.0 || x2.get() < 0.0 || x2.get() > 1.0 {
|
||||
return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
Ok(GenericTimingFunction::CubicBezier { x1, y1, x2, y2 })
|
||||
},
|
||||
"steps" => {
|
||||
let steps = Integer::parse_positive(context, i)?;
|
||||
let position = i.try_parse(|i| {
|
||||
i.expect_comma()?;
|
||||
StepPosition::parse(context, i)
|
||||
}).unwrap_or(StepPosition::End);
|
||||
|
||||
// jump-none accepts a positive integer greater than 1.
|
||||
// FIXME(emilio): The spec asks us to avoid rejecting it at parse
|
||||
// time except until computed value time.
|
||||
//
|
||||
// It's not totally clear it's worth it though, and no other browser
|
||||
// does this.
|
||||
if position == StepPosition::JumpNone && 2 > steps.value() {
|
||||
return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
Ok(GenericTimingFunction::Steps(steps, position))
|
||||
},
|
||||
"linear" => {
|
||||
if !linear_timing_function_enabled() {
|
||||
return Err(i.new_custom_error(StyleParseErrorKind::ExperimentalProperty));
|
||||
}
|
||||
if i.is_exhausted() {
|
||||
return Ok(GenericTimingFunction::LinearFunction(crate::OwnedSlice::default()))
|
||||
}
|
||||
let entries = i.parse_comma_separated(|i| {
|
||||
let mut input_start = i.try_parse(|i| Percentage::parse(context, i)).ok();
|
||||
let mut input_end = i.try_parse(|i| Percentage::parse(context, i)).ok();
|
||||
|
||||
let output = Number::parse(context, i)?;
|
||||
if input_start.is_none() {
|
||||
debug_assert!(input_end.is_none(), "Input end parsed without input start?");
|
||||
input_start = i.try_parse(|i| Percentage::parse(context, i)).ok();
|
||||
input_end = i.try_parse(|i| Percentage::parse(context, i)).ok();
|
||||
}
|
||||
Ok(GenericLinearStop {
|
||||
output,
|
||||
input_start: input_start.into(),
|
||||
input_end: input_end.into()
|
||||
})
|
||||
})?;
|
||||
Ok(GenericTimingFunction::LinearFunction(crate::OwnedSlice::from(entries)))
|
||||
},
|
||||
_ => Err(()),
|
||||
})
|
||||
.map_err(|()| {
|
||||
location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))
|
||||
})
|
||||
match_ignore_ascii_case! { &function,
|
||||
"cubic-bezier" => Self::parse_cubic_bezier(context, i),
|
||||
"steps" => Self::parse_steps(context, i),
|
||||
"linear" => Self::parse_linear_function(context, i),
|
||||
_ => Err(location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TimingFunction {
|
||||
fn parse_cubic_bezier<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let x1 = Number::parse(context, input)?;
|
||||
input.expect_comma()?;
|
||||
let y1 = Number::parse(context, input)?;
|
||||
input.expect_comma()?;
|
||||
let x2 = Number::parse(context, input)?;
|
||||
input.expect_comma()?;
|
||||
let y2 = Number::parse(context, input)?;
|
||||
|
||||
if x1.get() < 0.0 || x1.get() > 1.0 || x2.get() < 0.0 || x2.get() > 1.0 {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
Ok(GenericTimingFunction::CubicBezier { x1, y1, x2, y2 })
|
||||
}
|
||||
|
||||
fn parse_steps<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let steps = Integer::parse_positive(context, input)?;
|
||||
let position = input.try_parse(|i| {
|
||||
i.expect_comma()?;
|
||||
StepPosition::parse(context, i)
|
||||
}).unwrap_or(StepPosition::End);
|
||||
|
||||
// jump-none accepts a positive integer greater than 1.
|
||||
// FIXME(emilio): The spec asks us to avoid rejecting it at parse
|
||||
// time except until computed value time.
|
||||
//
|
||||
// It's not totally clear it's worth it though, and no other browser
|
||||
// does this.
|
||||
if position == StepPosition::JumpNone && steps.value() <= 1 {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
Ok(GenericTimingFunction::Steps(steps, position))
|
||||
}
|
||||
|
||||
fn parse_linear_function<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if !linear_timing_function_enabled() {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::ExperimentalProperty));
|
||||
}
|
||||
if input.is_exhausted() {
|
||||
return Ok(GenericTimingFunction::LinearFunction(crate::OwnedSlice::default()))
|
||||
}
|
||||
let entries = input.parse_comma_separated(|i| {
|
||||
let mut input_start = i.try_parse(|i| Percentage::parse(context, i)).ok();
|
||||
let mut input_end = i.try_parse(|i| Percentage::parse(context, i)).ok();
|
||||
|
||||
let output = Number::parse(context, i)?;
|
||||
if input_start.is_none() {
|
||||
debug_assert!(input_end.is_none(), "Input end parsed without input start?");
|
||||
input_start = i.try_parse(|i| Percentage::parse(context, i)).ok();
|
||||
input_end = i.try_parse(|i| Percentage::parse(context, i)).ok();
|
||||
}
|
||||
Ok(GenericLinearStop {
|
||||
output,
|
||||
input_start: input_start.into(),
|
||||
input_end: input_end.into()
|
||||
})
|
||||
})?;
|
||||
Ok(GenericTimingFunction::LinearFunction(crate::OwnedSlice::from(entries)))
|
||||
}
|
||||
}
|
||||
|
||||
// We need this for converting the specified TimingFunction into computed TimingFunction without
|
||||
// Context (for some FFIs in glue.rs). In fact, we don't really need Context to get the computed
|
||||
// value of TimingFunction.
|
||||
|
Loading…
Reference in New Issue
Block a user