/* 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/. */
/// Parse a `<number>` value, with a given clamping mode. fn parse_number_with_clamping_mode<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
clamping_mode: AllowedNumericType,
) -> Result<Number, ParseError<'i>> { let location = input.current_source_location(); match *input.next()? {
Token::Number { value, .. } if clamping_mode.is_ok(context.parsing_mode, value) => {
Ok(Number {
value,
calc_clamping_mode: None,
})
},
Token::Function(ref name) => { let function = CalcNode::math_function(context, name, location)?; let value = CalcNode::parse_number(context, input, function)?;
Ok(Number {
value,
calc_clamping_mode: Some(clamping_mode),
})
}, ref t => Err(location.new_unexpected_token_error(t.clone())),
}
}
/// A CSS `<number>` specified value. /// /// https://drafts.csswg.org/css-values-3/#number-value #[derive(Clone, Copy, Debug, MallocSizeOf, PartialOrd, ToShmem)] pubstruct Number { /// The numeric value itself.
value: CSSFloat, /// If this number came from a calc() expression, this tells how clamping /// should be done on the value.
calc_clamping_mode: Option<AllowedNumericType>,
}
impl Number { /// Returns a new number with the value `val`. #[inline] fn new_with_clamping_mode(
value: CSSFloat,
calc_clamping_mode: Option<AllowedNumericType>,
) -> Self { Self {
value,
calc_clamping_mode,
}
}
/// Returns this percentage as a number. pubfn to_percentage(&self) -> Percentage {
Percentage::new_with_clamping_mode(self.value, self.calc_clamping_mode)
}
/// Returns a new number with the value `val`. #[inline] pubfn new(val: CSSFloat) -> Self { Self::new_with_clamping_mode(val, None)
}
/// Returns whether this number came from a `calc()` expression. #[inline] pubfn was_calc(&self) -> bool { self.calc_clamping_mode.is_some()
}
/// Clamp to 1.0 if the value is over 1.0. #[inline] pubfn clamp_to_one(self) -> Self {
Number {
value: self.value.min(1.),
calc_clamping_mode: self.calc_clamping_mode,
}
}
}
impl ToComputedValue for Number { type ComputedValue = CSSFloat;
impl ToCss for Number { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where
W: Write,
{
serialize_number(self.value, self.calc_clamping_mode.is_some(), dest)
}
}
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 NonNegativeNumber { /// Returns a new non-negative number with the value `val`. pubfn new(val: CSSFloat) -> Self {
NonNegative::<Number>(Number::new(val.max(0.)))
}
/// Parse a non-negative number or percentage. pubfn 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)
}
/// Convert the number or the percentage to a number. pubfn to_percentage(self) -> Percentage { matchself { Self::Percentage(p) => p, Self::Number(n) => n.to_percentage(),
}
}
/// Convert the number or the percentage to a number. pubfn to_number(self) -> Number { matchself { Self::Percentage(p) => p.to_number(), Self::Number(n) => n,
}
}
}
/// The value of Opacity is <alpha-value>, which is "<number> | <percentage>". /// However, we serialize the specified value as number, so it's ok to store /// the Opacity as Number. #[derive(
Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, ToCss, ToShmem,
)] pubstruct Opacity(Number);
impl Parse for Opacity { /// Opacity accepts <number> | <percentage>, so we parse it as NumberOrPercentage, /// and then convert into an Number if it's a Percentage. /// https://drafts.csswg.org/cssom/#serializing-css-values fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { let number = NumberOrPercentage::parse(context, input)?.to_number();
Ok(Opacity(number))
}
}
impl ToComputedValue for Opacity { type ComputedValue = CSSFloat;
#[inline] fn to_computed_value(&self, context: &Context) -> CSSFloat { let value = self.0.to_computed_value(context); if context.for_smil_animation { // SMIL expects to be able to interpolate between out-of-range // opacity values.
value
} else {
value.min(1.0).max(0.0)
}
}
/// Returns the integer value associated with this value. pubfn value(&self) -> CSSInteger { self.value
}
/// Trivially constructs a new integer value from a `calc()` expression. fn from_calc(val: CSSInteger) -> Self {
Integer {
value: val,
was_calc: true,
}
}
}
impl Parse for Integer { fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { let location = input.current_source_location(); match *input.next()? {
Token::Number {
int_value: Some(v), ..
} => Ok(Integer::new(v)),
Token::Function(ref name) => { let function = CalcNode::math_function(context, name, location)?; let result = CalcNode::parse_integer(context, input, function)?;
Ok(Integer::from_calc(result))
}, ref t => Err(location.new_unexpected_token_error(t.clone())),
}
}
}
impl Integer { /// Parse an integer value which is at least `min`. pubfn parse_with_minimum<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
min: i32,
) -> Result<Integer, ParseError<'i>> { let value = Integer::parse(context, input)?; // 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 value.value() < min { return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
}
Ok(value)
}
/// The specified value of a grid `<track-breadth>` pubtype TrackBreadth = GenericTrackBreadth<LengthPercentage>;
/// The specified value of a grid `<track-size>` pubtype TrackSize = GenericTrackSize<LengthPercentage>;
/// The specified value of a grid `<track-size>+` pubtype ImplicitGridTracks = GenericImplicitGridTracks<TrackSize>;
/// The specified value of a grid `<track-list>` /// (could also be `<auto-track-list>` or `<explicit-track-list>`) pubtype TrackList = GenericTrackList<LengthPercentage, Integer>;
/// The specified value of a `<grid-line>`. pubtype GridLine = GenericGridLine<Integer>;
/// Whether quirks are allowed in this context. #[derive(Clone, Copy, PartialEq)] pubenum AllowQuirks { /// Quirks are not allowed.
No, /// Quirks are allowed, in quirks mode.
Yes, /// Quirks are always allowed, used for SVG lengths.
Always,
}
impl AllowQuirks { /// Returns `true` if quirks are allowed in this context. pubfn allowed(self, quirks_mode: QuirksMode) -> bool { matchself {
AllowQuirks::Always => true,
AllowQuirks::No => false,
AllowQuirks::Yes => quirks_mode == QuirksMode::Quirks,
}
}
}
/// Get the Namespace for a given prefix from the namespace map. fn get_namespace_for_prefix(prefix: &Prefix, context: &ParserContext) -> Option<Namespace> {
context.namespaces.prefixes.get(prefix).cloned()
}
/// Try to parse a namespace and return it if parsed, or none if there was not one present fn parse_namespace<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<(Prefix, Namespace), ParseError<'i>> { let ns_prefix = match input.next()? {
Token::Ident(ref prefix) => Some(Prefix::from(prefix.as_ref())),
Token::Delim('|') => None,
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
};
if ns_prefix.is_some() && !matches!(*input.next_including_whitespace()?, Token::Delim('|')) { return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
}
impl Attr { /// Parse contents of attr() assuming we have already parsed `attr` and are /// within a parse_nested_block() pubfn parse_function<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Attr, ParseError<'i>> { // Syntax is `[namespace? '|']? ident [',' fallback]?` let namespace = input
.try_parse(|input| parse_namespace(context, input))
.ok(); let namespace_is_some = namespace.is_some(); let (namespace_prefix, namespace_url) = namespace.unwrap_or_default();
// If there is a namespace, ensure no whitespace following '|' let attribute = Atom::from(if namespace_is_some { let location = input.current_source_location(); match *input.next_including_whitespace()? {
Token::Ident(ref ident) => ident.as_ref(), ref t => return Err(location.new_unexpected_token_error(t.clone())),
}
} else {
input.expect_ident()?.as_ref()
});
// Fallback will always be a string value for now as we do not support // attr() types yet. let fallback = input
.try_parse(|input| -> Result<AtomString, ParseError<'i>> {
input.expect_comma()?;
Ok(input.expect_string()?.as_ref().into())
})
.unwrap_or_default();
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.