/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Specified types for CSS values that are related to transformations.
usecrate::derives::*; usecrate::parser::{Parse, ParserContext}; usecrate::values::computed::{Context, LengthPercentage as ComputedLengthPercentage}; usecrate::values::computed::{Percentage as ComputedPercentage, ToComputedValue}; usecrate::values::generics::transform as generic; usecrate::values::generics::transform::{Matrix, Matrix3D, ToFloat}; usecrate::values::specified::percentage::NoCalcPercentage; usecrate::values::specified::position::{
HorizontalPositionKeyword, Side, VerticalPositionKeyword,
}; usecrate::values::specified::{ self, AllowQuirks, Angle, Integer, Length, LengthPercentage, Number, NumberOrPercentage,
}; usecrate::Zero; use cssparser::{match_ignore_ascii_case, Parser}; use style_traits::{ParseError, StyleParseErrorKind};
/// A single operation in a specified CSS `transform` pubtype TransformOperation =
generic::TransformOperation<Angle, Number, Length, Integer, LengthPercentage>;
/// A specified CSS `transform` pubtype Transform = generic::Transform<TransformOperation>;
/// The specified value of a CSS `<transform-origin>` pubtype TransformOrigin = generic::TransformOrigin<
OriginComponent<HorizontalPositionKeyword>,
OriginComponent<VerticalPositionKeyword>,
Length,
>;
/// The specified value of `transform-box`. /// https://drafts.csswg.org/css-transforms-1/#transform-box // Note: Once we ship everything, we can drop this and just use single_keyword for tranform-box. #[allow(missing_docs)] #[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
Deserialize,
MallocSizeOf,
Parse,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
ToTyped,
)] #[repr(u8)] pubenum TransformBox { #[parse(condition = "all_transform_boxes_are_enabled")]
ContentBox,
BorderBox,
FillBox, #[parse(condition = "all_transform_boxes_are_enabled")]
StrokeBox,
ViewBox,
}
impl TransformOrigin { /// Returns the initial specified value for `transform-origin`. #[inline] pubfn initial_value() -> Self { Self::new(
OriginComponent::Length(LengthPercentage::Percentage(NoCalcPercentage::new(0.5))),
OriginComponent::Length(LengthPercentage::Percentage(NoCalcPercentage::new(0.5))),
Length::zero(),
)
}
/// The specified value of a component of a CSS `<transform-origin>`. #[derive(Clone, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)] pubenum OriginComponent<S> { /// `center`
Center, /// `<length-percentage>`
Length(LengthPercentage), /// `<side>`
Side(S),
}
impl Parse for TransformOrigin { fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { let parse_depth = |input: &mut Parser| {
input
.try_parse(|i| Length::parse(context, i))
.unwrap_or(Length::zero())
}; match input.try_parse(|i| OriginComponent::parse(context, i)) {
Ok(x_origin @ OriginComponent::Center) => { iflet Ok(y_origin) = input.try_parse(|i| OriginComponent::parse(context, i)) { let depth = parse_depth(input); return Ok(Self::new(x_origin, y_origin, depth));
} let y_origin = OriginComponent::Center; iflet Ok(x_keyword) = input.try_parse(HorizontalPositionKeyword::parse) { let x_origin = OriginComponent::Side(x_keyword); let depth = parse_depth(input); return Ok(Self::new(x_origin, y_origin, depth));
} let depth = Length::from_px(0.); return Ok(Self::new(x_origin, y_origin, depth));
},
Ok(x_origin) => { iflet Ok(y_origin) = input.try_parse(|i| OriginComponent::parse(context, i)) { let depth = parse_depth(input); return Ok(Self::new(x_origin, y_origin, depth));
} let y_origin = OriginComponent::Center; let depth = Length::from_px(0.); return Ok(Self::new(x_origin, y_origin, depth));
},
Err(_) => {},
} let y_keyword = VerticalPositionKeyword::parse(input)?; let y_origin = OriginComponent::Side(y_keyword); iflet Ok(x_keyword) = input.try_parse(HorizontalPositionKeyword::parse) { let x_origin = OriginComponent::Side(x_keyword); let depth = parse_depth(input); return Ok(Self::new(x_origin, y_origin, depth));
} if input
.try_parse(|i| i.expect_ident_matching("center"))
.is_ok()
{ let x_origin = OriginComponent::Center; let depth = parse_depth(input); return Ok(Self::new(x_origin, y_origin, depth));
} let x_origin = OriginComponent::Center; let depth = Length::from_px(0.);
Ok(Self::new(x_origin, y_origin, depth))
}
}
impl<S> ToComputedValue for OriginComponent<S> where
S: Side,
{ type ComputedValue = ComputedLengthPercentage;
// Parse <angle> or [ x | y | z | <number>{3} ] && <angle>. // // 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_parse(|i| specified::Angle::parse(context, i))
.ok(); let axis = input
.try_parse(|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_parse(|i| {
Ok((
Number::parse(context, i)?,
Number::parse(context, i)?,
Number::parse(context, i)?,
))
})
})
.ok(); let angle = match angle {
Some(a) => a,
None => specified::Angle::parse(context, input)?,
};
Ok(match axis {
Some((x, y, z)) => generic::Rotate::Rotate3D(x, y, z, angle),
None => generic::Rotate::Rotate(angle),
})
}
}
/// A specified CSS `translate` pubtype Translate = generic::Translate<LengthPercentage, Length>;
/// An individual value that can appear in a CSS `scale`. #[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem, ToTyped)] pubstruct ScaleFactor(NumberOrPercentage);
impl Parse for ScaleFactor { /// Scale accepts <number> | <percentage>, so we parse it as NumberOrPercentage, /// and then convert into an Number if it's a non-calc Percentage. /// https://github.com/w3c/csswg-drafts/pull/4396 fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Ok(ScaleFactor(
NumberOrPercentage::parse(context, input)?.into_simplified_number(),
))
}
}
impl ToComputedValue for ScaleFactor { type ComputedValue = <Number as ToComputedValue>::ComputedValue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.