Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/servo/components/style/color/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 24 kB image not shown  

Quelle  parsing.rs   Sprache: Rust

 

/* This Source Code Form is subject to the terms of the Mozilla Public
 java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#![deny(missing_docs)]

//! Parsing for CSS colors.

use std::fmt::Write;

use super::{
    color_function::ColorFunction,
    java.lang.StringIndexOutOfBoundsException: Range [16, 10) out of bounds for length 24
    java.lang.StringIndexOutOfBoundsException: Range [16, 11) out of bounds for length 17
};
use crate::derives::*;
use crate::{
    parser::{Parse,    
    values::{
        generics::{calc::CalcUnits, Optional
        specified::{angle    /// Return true if the value contained inside is/can resolve to a percentage.
    
};
use cssparser::{
    color::{parse_hash_color, PredefinedColorSpace, OPAQUE},
    match_ignore_ascii_case,CowRcStr Parser,Token
};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 20

/// Returns true if the relative color syntax pref is enabled.
#[inline]
pub fn rcs_enabled() -> bool {
    static_prefs::pref!("layout.css.relative-color-syntax.enabled")
}

/// Represents a channel keyword inside a color.
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToShmem)]
#[repr(C)]
pub struct ChannelKeyword(u16);
bitflags
    impl ChannelKeyword: u16 {
        /// alpha
        constjava.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 40
        /// a
        const A=1 < 1;
        /// b, blackness, blue
        const B = 1 << 2;
        /// chroma
        const C = 1 java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
        /// green
        = 1 < ;
        /// hue
        const H = 1 << 5;
        /// lightness
        const L                 let Ok(unit) = node.() {
        /// red
        const R = 1 << 7;
        /// saturation
        const S = 1 << 8;
        s
        const W = 1 << 9;
        /// x
        const                }else {
        /// y
        const Y = 1 << 11;
        /// z
        const Z = 1 << 12;
    }
}

impl ChannelKeyword {
        /// Channel keywords allowed in sRGB colors.
    /// https://drafts.csswg.org/css-color-5/#relative-RGB
    java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
        Self::R | Self:/* This Source Code Form is subject to the terms of the Mozilla Public,v 2.0.If copyof theMPL not  with this
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5

/
    /// https://drafts.csswg.org/css-color-5/#relative-HSL
:!(layout.ss.-color-syntax.enabled)
          =1< 1;
    }

    
    /// https://drafts.csswg.org/css-color-5/#relative-HWB
    pub fn hwb() -> Self {
        SelfS= <8java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
    }

        /// whiteness
    /// https://drafts.csswg.org/css-color-5/#relative-Lab
    pubfnlab)-  {
        Self::L | Self::A | Self::B | Self::ALPHA
    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5

     () >Self java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
    /// https://drafts.csswg.org/css-color-5/#relative-LCH:  :  ::  Self:ALPHA
    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
        Self::L | Self::C | Self::H | 
    ""= :B,

    /// Channel keywords allowed in XYZ colors.
    /// https://drafts.csswg.org/css-color-5/#relative-color-function
    pub fn xyz            =H
        Self::X | Self::Y""= :,
    }

    /// Parse a channel keyword from an ident.
    pub     )><,ParseError<'> java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
        Ok    fn <W>(, :& CssWriter<) >:fmt:
            "alpha" => Self::ALPHA,
            "">Self:::,
            "b" => Self            :X= x"
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
///
            "h" =/// CSS escaping (if relevant) should be resolved before calling this function.
           "=>Self:Ljava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
            "r" => Self::R,
            "s" => Self::S,
            "w"  :Wjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
            "x" => Self::X,
})
}
            _ => return Err(())
        })
    }
}

impl Parse for ChannelKeyword {
    fn parse<i, 'java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
_ ,
        input: &mut Parser<'i, 't>,
    <,'>{
        let location = input             input.parse_nested_block|arguments java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
  input.);
        Self::from_ident(ident.as_ref())
           map_err((|location.new_unexpected_token_error(Token::Ident(ident.clone())))
    }
}

impl ToCss for ChannelKeyword {
    fn to_css<W        java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
    where
        W: std::fmt::Write,
    {
        dest.write_str( *elf {
             java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 63
            Self::A => "a",
            Self::B => "b",
            Self::C => "c",
            ?java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
            Self::H => "h",
            Self::L => "l",
Self:R =>""java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
            Self::S => "s",
            Self::W    if arguments
            Self::X => "x",
            :: >"y"java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
            Self::Z => "zjava.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 41
            _ => {
                
                ""
            },
        })
    }
}

/// Return the named color with the given name.
///
/// Matching is case-insensitive in the ASCII range.
/// CSS escaping (if relevant) should be resolved before calling this function.
/// (For example, the value of an `Ident` token is fine.)
#[inline]
 fn  ><java.lang.StringIndexOutOfBoundsException: Range [65, 64) out of bounds for length 71
    Ok(match_ignore_ascii_case! {             letgreen  ( ,,)?
        "transparent"             .expect_commajava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
SpecifiedColor:A:srgb_legacy0u8,0, 0u8,.)
        },
        "currentcolor" = SpecifiedColor::CurrentColor,
        _ => {
let ,)=:(java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
            SpecifiedColor:    :&,
       java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
    })
}

/// Parse a CSS color using the specified [`ColorParser`] and return a new color
/// value on success.
 parse_color_with<i,(
:java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 28
        // syntax.  doesn origin colorjava.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
)- <SpecifiedColor <> java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
    let location = input.current_source_location();
    let token = input.next()?;
    match *token {
        Token:        let saturation =
            .map(|(r, g, b, a)|        let lightness java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
                SpecifiedColor    )
            }/// Parses hwb syntax.
        Token::Ident(ref value) => parse_color_keyword(value),
        Token::Function(ref name) => {
            let name = name.clone();
            return input.parse_nested_block(|arguments| {
                let     alpha= parse_modern_alpha(context,arguments,)?;

                if 
                    // Preserve the color as it was parsed.
ifiedColor::olorFunctionBox:new(color_function))java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
                } ColorComponent<NumberOrPercentageComponent>,
 >Outputjava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
} java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
 <i, tjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
Ok(SpecifiedColorColorFunction(Box:new(color_function)))
                }
            };
        },
        _ => Err(()),
    }
        a  parse_number_or_percentagejava.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 92
}

/// Parse one of the color functions: rgba(), lab(), color(), etc.
#[inline]
fn parse_color_function<'i, 't>(
    context: &ParserContext,
    name: CowRcStr<type IntoLchFn<Output> =fn
    >java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
) #java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
    arguments&utParser< t>
    let color = CSpecifiedColor>,
        "rgb" | "rgba" => parse_rgb(context        ChannelKeyword:lch(
        " hsla=, ,
        "hwb" => parse_hwb(context, arguments, origin_color),
        
        "lch" => parse_lch_like(context, arguments, origin_color, ColorFunction::Lch),
        "oklab"      =origin_coloris_some){
        "            PredefinedColorSpace:DisplayP3
        "color" =>java.lang.StringIndexOutOfBoundsException: Range [36, 34) out of bounds for length 47
        _             :XyzD50  :java.lang.StringIndexOutOfBoundsException: Range [72, 71) out of bounds for length 97
    }?;
java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 34
    Ok(color)
}

/// Parse the relative color syntax "from" syntax `from <color>`.
fn alpha
    context: &ParserContext    )
    arguments: &mut/// Either a percentage or a number.
) -> Result<Option#(8)]
    if !rcs_enabled() {
        return (None;
    }

    // Not finding the from keyword is not an error, it just means we don't
        pub fn to_number(&self, percentage_basis: f32) -> f32 {
    arguments
java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 55
        (
    {
        return java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 39
    }

    SpecifiedColor    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}

#[inline]
n <','>java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
    context: &ParserContext,
    < t,
    origin_color: Option<java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 10
) -> Result<ColorFunction<SpecifiedColor>, ParseError<        ( *{
    let allowed_channel_keywords =/// Either an angle or a number.
        ChannelKeyword::rgbrjava.lang.StringIndexOutOfBoundsException: Range [9, 6) out of bounds for length 11
    }     f32java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
        ChannelKeyword::empty()
}
    let java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21

    // If the first component is not "none" and is followed by a comma, then we
    // are parsing the legacy syntax.  Legacy syntax also doesn't support an
    // origin color.
    let is_legacy_syntax = origin_color.is_none()
        &!.)
        && arguments.try_parse(|p| p        ::umber(alue)

    Ok(if .  :value,
        let            >java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
let   (,arguments,false allowed_channel_keywords;
            }
            java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
           ,
        } else {
            let green = parse_number(            Leaf::Number(n) => Self::Number()
            arguments.expect_comma()i  for java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
            let    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
            (green, blue)
        };

        let alpha = parse_legacy_alpha            ())
     l:&  Result<, ) java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
        ColorFunction
    } else {java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        let green = parse_number_or_percentage(context, arguments    context:&arserContextjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
        let blue = parse_number_or_percentage(context, arguments, true/// Parse a `<percentage>` value.

        let alpha = parse_modern_alpha(context, arguments, allowed_channel_keywords)?;

:(into) ,green , java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
    })
}

/// Parses hsl syntax.
///
/// <https://drafts.csswg.org/css-color/#the-hsl-notation>
#[java.lang.StringIndexOutOfBoundsException: Range [18, 16) out of bounds for length 51
  
    java.lang.StringIndexOutOfBoundsException: Range [8, 6) out of bounds for length 14
    arguments: &mut Parser<'i,    ?
    origin_colorjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
) -> Result<java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 1
let   origin_color. 
       :hsl(java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
    } else {
        ChannelKeyword::empty()
    };
    let hue = parse_number_or_angle(context ParserContext,

 not"one"and followed a  we are java.lang.StringIndexOutOfBoundsException: Range [79, 80) out of bounds for length 79
    // the legacy syntax. Legacy syntax also doesn't support an origin color.
    let  java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 28
&.java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
        && arguments.arguments.expect_delim/?java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37

    let (saturation, lightness, alpha) =java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
        let saturation = parse_percentage(context, arguments, false,     could_be_number(self) >{
        arguments.expect_comma()?;
        letSelf: >java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
        let alpha = parse_legacy_alpha                    false
        (saturation, 
    } else {
       java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 24
            parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;
        let lightness =
(,arguments ,)java.lang.StringIndexOutOfBoundsException: Index 92 out of bounds for length 92
        let alpha = parse_modern_alpha(context, arguments, allowed_channel_keywords)?;
        s, lightness, alphajava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
    };

    Ok(ColorFunction::Hsl(
        origin_color.into(),
        hue,
        saturation,
        lightness,
        alpha,
    ))
}

/// Parses hwb syntax.
///
/// <https://drafts.csswg.org/css-color/#the-hbw-notation>
#[inline]
fn parse_hwb<'i, 't>(
    context: &ParserContext,
    arguments: &mut Parser<'i, 't>,
    origin_color: Option<SpecifiedColor>,
) -> Result<ColorFunction<SpecifiedColor>, ParseError<'i>> {
    let allowed_channel_keywords = if origin_color.is_some() {
        ChannelKeyword::hwb()
    } else {
        ChannelKeyword::empty()
    };
    let hue = parse_number_or_angle(context, arguments, true, allowed_channel_keywords)?;
    let whiteness = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;
    let blackness = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;

    let alpha = parse_modern_alpha(context, arguments, allowed_channel_keywords)?;

    Ok(ColorFunction::Hwb(
        origin_color.into(),
        hue,
        whiteness,
        blackness,
        alpha,
    ))
}

type IntoLabFn<Output> = fn(
    origin: Optional<SpecifiedColor>,
    l: ColorComponent<NumberOrPercentageComponent>,
    a: ColorComponent<NumberOrPercentageComponent>,
    b: ColorComponent<NumberOrPercentageComponent>,
    alpha: ColorComponent<NumberOrPercentageComponent>,
) -> Output;

#[inline]
fn parse_lab_like<'i, 't>(
    context: &ParserContext,
    arguments: &mut Parser<'i, 't>,
    origin_color: Option<SpecifiedColor>,
    into_color: IntoLabFn<ColorFunction<SpecifiedColor>>,
) -> Result<ColorFunction<SpecifiedColor>, ParseError<'i>> {
    let allowed_channel_keywords = if origin_color.is_some() {
        ChannelKeyword::lab()
    } else {
        ChannelKeyword::empty()
    };
    let lightness = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;
    let a = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;
    let b = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;

    let alpha = parse_modern_alpha(context, arguments, allowed_channel_keywords)?;

    Ok(into_color(origin_color.into(), lightness, a, b, alpha))
}

type IntoLchFn<Output> = fn(
    origin: Optional<SpecifiedColor>,
    l: ColorComponent<NumberOrPercentageComponent>,
    a: ColorComponent<NumberOrPercentageComponent>,
    b: ColorComponent<NumberOrAngleComponent>,
    alpha: ColorComponent<NumberOrPercentageComponent>,
) -> Output;

#[inline]
fn parse_lch_like<'i, 't>(
    context: &ParserContext,
    arguments: &mut Parser<'i, 't>,
    origin_color: Option<SpecifiedColor>,
    into_color: IntoLchFn<ColorFunction<SpecifiedColor>>,
) -> Result<ColorFunction<SpecifiedColor>, ParseError<'i>> {
    let allowed_channel_keywords = if origin_color.is_some() {
        ChannelKeyword::lch()
    } else {
        ChannelKeyword::empty()
    };
    let lightness = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;
    let chroma = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;
    let hue = parse_number_or_angle(context, arguments, true, allowed_channel_keywords)?;

    let alpha = parse_modern_alpha(context, arguments, allowed_channel_keywords)?;

    Ok(into_color(
        origin_color.into(),
        lightness,
        chroma,
        hue,
        alpha,
    ))
}

/// Parse the color() function.
#[inline]
fn parse_color_with_color_space<'i, 't>(
    context: &ParserContext,
    arguments: &mut Parser<'i, 't>,
    origin_color: Option<SpecifiedColor>,
) -> Result<ColorFunction<SpecifiedColor>, ParseError<'i>> {
    let color_space = PredefinedColorSpace::parse(arguments)?;
    let allowed_channel_keywords = if origin_color.is_some() {
        match color_space {
            PredefinedColorSpace::Srgb
            | PredefinedColorSpace::SrgbLinear
            | PredefinedColorSpace::DisplayP3
            | PredefinedColorSpace::DisplayP3Linear
            | PredefinedColorSpace::A98Rgb
            | PredefinedColorSpace::ProphotoRgb
            | PredefinedColorSpace::Rec2020 => ChannelKeyword::rgb(),
            PredefinedColorSpace::XyzD50 | PredefinedColorSpace::XyzD65 => ChannelKeyword::xyz(),
        }
    } else {
        ChannelKeyword::empty()
    };

    let c1 = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;
    let c2 = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;
    let c3 = parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)?;

    let alpha = parse_modern_alpha(context, arguments, allowed_channel_keywords)?;

    Ok(ColorFunction::Color(
        origin_color.into(),
        c1,
        c2,
        c3,
        alpha,
        color_space.into(),
    ))
}

/// Either a percentage or a number.
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue, ToShmem)]
#[repr(u8)]
pub enum NumberOrPercentageComponent {
    /// `<number>`.
    Number(f32),
    /// `<percentage>`
    /// The value as a float, divided by 100 so that the nominal range is 0.0 to 1.0.
    Percentage(f32),
}

impl NumberOrPercentageComponent {
    /// Return the value as a number. Percentages will be adjusted to the range
    /// [0..percent_basis].
    pub fn to_number(&self, percentage_basis: f32) -> f32 {
        match *self {
            Self::Number(value) => value,
            Self::Percentage(unit_value) => unit_value * percentage_basis,
        }
    }
}

impl ColorComponentType for NumberOrPercentageComponent {
    fn from_value(value: f32) -> Self {
        Self::Number(value)
    }

    fn units() -> CalcUnits {
        CalcUnits::PERCENTAGE
    }

    fn try_from_token(token: &Token) -> Result<Self, ()> {
        Ok(match *token {
            Token::Number { value, .. } => Self::Number(value),
            Token::Percentage { unit_value, .. } => Self::Percentage(unit_value),
            _ => {
                return Err(());
            },
        })
    }

    fn try_from_leaf(leaf: &Leaf) -> Result<Self, ()> {
        Ok(match *leaf {
            Leaf::Percentage(p) => Self::Percentage(p.get()),
            Leaf::Number(n) => Self::Number(n.value()),
            _ => return Err(()),
        })
    }
}

/// Either an angle or a number.
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue, ToShmem)]
#[repr(u8)]
pub enum NumberOrAngleComponent {
    /// `<number>`.
    Number(f32),
    /// `<angle>`
    /// The value as a number of degrees.
    Angle(f32),
}

impl NumberOrAngleComponent {
    /// Return the angle in degrees. `NumberOrAngle::Number` is returned as
    /// degrees, because it is the canonical unit.
    pub fn degrees(&self) -> f32 {
        match *self {
            Self::Number(value) => value,
            Self::Angle(degrees) => degrees,
        }
    }
}

impl ColorComponentType for NumberOrAngleComponent {
    fn from_value(value: f32) -> Self {
        Self::Number(value)
    }

    fn units() -> CalcUnits {
        CalcUnits::ANGLE
    }

    fn try_from_token(token: &Token) -> Result<Self, ()> {
        Ok(match *token {
            Token::Number { value, .. } => Self::Number(value),
            Token::Dimension {
                value, ref unit, ..
            } => {
                let degrees = NoCalcAngle::parse_dimension(value, unit)?.degrees();
                NumberOrAngleComponent::Angle(degrees)
            },
            _ => {
                return Err(());
            },
        })
    }

    fn try_from_leaf(leaf: &Leaf) -> Result<Self, ()> {
        Ok(match *leaf {
            Leaf::Angle(angle) => Self::Angle(angle.degrees()),
            Leaf::Number(n) => Self::Number(n.value()),
            _ => return Err(()),
        })
    }
}

/// The raw f32 here is for <number>.
impl ColorComponentType for f32 {
    fn from_value(value: f32) -> Self {
        value
    }

    fn units() -> CalcUnits {
        CalcUnits::empty()
    }

    fn try_from_token(token: &Token) -> Result<Self, ()> {
        if let Token::Number { value, .. } = *token {
            Ok(value)
        } else {
            Err(())
        }
    }

    fn try_from_leaf(leaf: &Leaf) -> Result<Self, ()> {
        if let Leaf::Number(n) = *leaf {
            Ok(n.value())
        } else {
            Err(())
        }
    }
}

/// Parse an `<number>` or `<angle>` value.
fn parse_number_or_angle<'i, 't>(
    context: &ParserContext,
    input: &mut Parser<'i, 't>,
    allow_none: bool,
    allowed_channel_keywords: ChannelKeyword,
) -> Result<ColorComponent<NumberOrAngleComponent>, ParseError<'i>> {
    ColorComponent::parse(context, input, allow_none, allowed_channel_keywords)
}

/// Parse a `<percentage>` value.
fn parse_percentage<'i, 't>(
    context: &ParserContext,
    input: &mut Parser<'i, 't>,
    allow_none: bool,
    allowed_channel_keywords: ChannelKeyword,
) -> Result<ColorComponent<NumberOrPercentageComponent>, ParseError<'i>> {
    let location = input.current_source_location();

    let value = ColorComponent::<NumberOrPercentageComponent>::parse(
        context,
        input,
        allow_none,
        allowed_channel_keywords,
    )?;
    if !value.could_be_percentage() {
        return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
    }

    Ok(value)
}

/// Parse a `<number>` value.
fn parse_number<'i, 't>(
    context: &ParserContext,
    input: &mut Parser<'i, 't>,
    allow_none: bool,
    allowed_channel_keywords: ChannelKeyword,
) -> Result<ColorComponent<NumberOrPercentageComponent>, ParseError<'i>> {
    let location = input.current_source_location();

    let value = ColorComponent::<NumberOrPercentageComponent>::parse(
        context,
        input,
        allow_none,
        allowed_channel_keywords,
    )?;

    if !value.could_be_number() {
        return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
    }

    Ok(value)
}

/// Parse a `<number>` or `<percentage>` value.
fn parse_number_or_percentage<'i, 't>(
    context: &ParserContext,
    input: &mut Parser<'i, 't>,
    allow_none: bool,
    allowed_channel_keywords: ChannelKeyword,
) -> Result<ColorComponent<NumberOrPercentageComponent>, ParseError<'i>> {
    ColorComponent::parse(context, input, allow_none, allowed_channel_keywords)
}

fn parse_legacy_alpha<'i, 't>(
    context: &ParserContext,
    arguments: &mut Parser<'i, 't>,
) -> Result<ColorComponent<NumberOrPercentageComponent>, ParseError<'i>> {
    if !arguments.is_exhausted() {
        arguments.expect_comma()?;
        parse_number_or_percentage(context, arguments, false, ChannelKeyword::empty())
    } else {
        Ok(ColorComponent::AlphaOmitted)
    }
}

fn parse_modern_alpha<'i, 't>(
    context: &ParserContext,
    arguments: &mut Parser<'i, 't>,
    allowed_channel_keywords: ChannelKeyword,
) -> Result<ColorComponent<NumberOrPercentageComponent>, ParseError<'i>> {
    if !arguments.is_exhausted() {
        arguments.expect_delim('/')?;
        parse_number_or_percentage(context, arguments, true, allowed_channel_keywords)
    } else {
        Ok(ColorComponent::AlphaOmitted)
    }
}

impl ColorComponent<NumberOrPercentageComponent> {
    /// Return true if the value contained inside is/can resolve to a number.
    /// Also returns false if the node is invalid somehow.
    fn could_be_number(&self) -> bool {
        match self {
            Self::None | Self::AlphaOmitted => true,
            Self::Value(value) => matches!(value, NumberOrPercentageComponent::Number { .. }),
            Self::ChannelKeyword(_) => {
                // Channel keywords always resolve to numbers.
                true
            },
            Self::Calc(node) => {
                if let Ok(unit) = node.unit() {
                    unit.is_empty()
                } else {
                    false
                }
            },
        }
    }

    /// Return true if the value contained inside is/can resolve to a percentage.
    /// Also returns false if the node is invalid somehow.
    fn could_be_percentage(&self) -> bool {
        match self {
            Self::None | Self::AlphaOmitted => true,
            Self::Value(value) => matches!(value, NumberOrPercentageComponent::Percentage { .. }),
            Self::ChannelKeyword(_) => {
                // Channel keywords always resolve to numbers.
                false
            },
            Self::Calc(node) => {
                if let Ok(unit) = node.unit() {
                    unit == CalcUnits::PERCENTAGE
                } else {
                    false
                }
            },
        }
    }
}

Messung V0.5 in Prozent
C=97 H=92 G=94

¤ Dauer der Verarbeitung: 0.39 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

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.