/* 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/. */
usesuper::computed::{Context, ToComputedValue}; usesuper::generics::grid::ImplicitGridTracks as GenericImplicitGridTracks; usesuper::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth}; usesuper::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize}; usesuper::generics::{self, NonNegative}; usesuper::CSSFloat; usecrate::context::QuirksMode; usecrate::derives::*; usecrate::parser::{Parse, ParserContext}; usecrate::values::specified::number::parse_number_with_clamping_mode; usecrate::values::{computed, serialize_atom_identifier, AtomString}; usecrate::{Atom, Namespace, Prefix}; use cssparser::{Parser, Token}; use rustc_hash::FxHashMap; use std::fmt::{self, Write}; use style_traits::values::specified::AllowedNumericType; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
/// <number> | <percentage> /// /// Accepts only non-negative numbers. /// /// TODO(Bug 2040559) - Convert this into a NumericUnion, instead of an enum over /// Number and Percentage. Both types are also NumericUnions of unitless floats. #[allow(missing_docs)] #[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem, ToTyped)] pubenum NumberOrPercentage {
Percentage(Percentage),
Number(Number),
}
/// 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) -> Option<Percentage> { matchself { Self::Percentage(p) => Some(p), Self::Number(n) => n.to_percentage(),
}
}
/// Convert the number or the percentage to a number. pubfn to_number(&self) -> Option<Number> { matchself { Self::Percentage(p) => p.to_number(), Self::Number(n) => Some(n.clone()),
}
}
/// Gets a reference to the underlying percentage, or None if this is a number pubfn as_percentage(&self) -> Option<&Percentage> { matchself {
NumberOrPercentage::Percentage(percentage) => Some(percentage),
_ => None,
}
}
/// If this is a non-calc percentage, replaces it with the equivalent /// number; otherwise, returns the original value. pubfn into_simplified_number(self) -> NumberOrPercentage { matchself.as_percentage().and_then(|p| p.get()) {
Some(p) => NumberOrPercentage::Number(Number::new(p)),
None => self,
}
}
/// Attempts to resolve this number or percentage to a computed value. pubfn to_computed_value_without_context(&self) -> Result<computed::NumberOrPercentage, ()> {
Ok(matchself {
NumberOrPercentage::Percentage(percentage) => computed::NumberOrPercentage::Percentage(
computed::Percentage(percentage.resolve().ok_or(())?),
),
NumberOrPercentage::Number(number) => {
computed::NumberOrPercentage::Number(number.resolve().ok_or(())?)
},
})
}
}
impl Parse for Opacity { /// Opacity accepts <number> | <percentage>, so we parse it as NumberOrPercentage, /// and then convert into an Number if it's a non-calc Percentage. /// https://drafts.csswg.org/css-color-4/#serializing-opacity-values fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Ok(Opacity(
NumberOrPercentage::parse(context, input)?.into_simplified_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).value(); if context.for_animation { // Type <number> and <percentage> should be able to interpolate // out-of-range opacity values which benefits additive animation
value
} else {
value.min(1.0).max(0.0)
}
}
/// 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,
}
}
}
#[derive(Clone, Debug, PartialEq, MallocSizeOf, ToShmem)] /// A namespace wrapper to distinguish between valid variants pubenum ParsedNamespace { /// Unregistered namespace
Unknown, /// Registered namespace
Known(Namespace),
}
impl ParsedNamespace { /// Parse a namespace prefix and resolve it to the correct /// namespace URI. pubfn parse<'i, 't>(
namespaces: &FxHashMap<Prefix, Namespace>,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { // We don't need to keep the prefix because different // prefixes can resolve to the same id. Additionally, // we also don't need it for serialization as substitution // functions serialize from the direct css declaration.
parse_namespace(namespaces, input, /*allow_non_registered*/ true)
.map(|(_prefix, namespace)| namespace)
}
}
/// Try to parse a namespace and return it if parsed, or none if there was not one present pubfn parse_namespace<'i, 't>(
namespaces: &FxHashMap<Prefix, Namespace>,
input: &mut Parser<'i, 't>, // TODO: Once general attr is enabled, we should remove this flag
allow_non_registered: bool,
) -> Result<(Prefix, ParsedNamespace), 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.namespaces.prefixes,
input, /*allow_non_registered*/ false,
)
})
.ok(); let namespace_is_some = namespace.is_some(); let (namespace_prefix, namespace_url) = namespace.unwrap_or_default(); let ParsedNamespace::Known(namespace_url) = namespace_url else {
unreachable!("Non-registered url not allowed (see parse namespace flag).")
};
// 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.