style: Support keywords [x|y|z] on rotate.

Update the parser and the serialization to support the keywords, [x|y|z].

Differential Revision: https://phabricator.services.mozilla.com/D11531
This commit is contained in:
Boris Chiou 2018-11-13 18:37:14 +00:00 committed by Emilio Cobos Álvarez
parent f486ef7e47
commit 41d2f7f3a2
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
4 changed files with 85 additions and 8 deletions

View file

@ -6,9 +6,11 @@
//!
//! TODO(emilio): Enhance docs.
use super::computed::transform::DirectionVector;
use super::computed::{Context, ToComputedValue};
use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
use super::generics::transform::IsParallelTo;
use super::generics::{GreaterThanOrEqualToOne, NonNegative};
use super::{Auto, CSSFloat, CSSInteger, Either};
use crate::context::QuirksMode;
@ -292,6 +294,16 @@ impl ToCss for Number {
}
}
impl IsParallelTo for (Number, Number, Number) {
fn is_parallel_to(&self, vector: &DirectionVector) -> bool {
use euclid::approxeq::ApproxEq;
// If a and b is parallel, the angle between them is 0deg, so
// a x b = |a|*|b|*sin(0)*n = 0 * n, |a x b| == 0.
let self_vector = DirectionVector::new(self.0.get(), self.1.get(), self.2.get());
self_vector.cross(*vector).square_length().approx_eq(&0.0f32)
}
}
impl SpecifiedValueInfo for Number {}
impl From<Number> for f32 {

View file

@ -358,17 +358,24 @@ impl Parse for Rotate {
}
// Parse <angle> or [ x | y | z | <number>{3} ] && <angle>.
// TODO: Bug 1504327: Parse [x|y|z] keywords.
//
// The rotate axis and angle could be in any order, so we parse angle twice to cover
// two cases. i.e. `<number>{3} <angle>` or `<angle> <number>{3}`
let angle = input.try(|i| specified::Angle::parse(context, i)).ok();
let axis = input.try(|i| -> Result<_, ParseError> {
Ok((
Number::parse(context, i)?,
Number::parse(context, i)?,
Number::parse(context, i)?,
))
let axis = input.try(|i| {
Ok(try_match_ident_ignore_ascii_case! { i,
"x" => (Number::new(1.), Number::new(0.), Number::new(0.)),
"y" => (Number::new(0.), Number::new(1.), Number::new(0.)),
"z" => (Number::new(0.), Number::new(0.), Number::new(1.)),
})
}).or_else(|_: ParseError| -> Result<_, ParseError> {
input.try(|i| {
Ok((
Number::parse(context, i)?,
Number::parse(context, i)?,
Number::parse(context, i)?,
))
})
}).ok();
let angle = match angle {
Some(a) => a,