Commit 6fe94c07 authored by Tiaan Louw's avatar Tiaan Louw
Browse files

Bug 1813481 - Use abstract color parser r=emilio,supply-chain-reviewers

In stead of having the css parser construct a color in it's own format
and then converting it to what Gecko needs to perform operations, we now
construct a Gecko friendly color type directly.

Differential Revision: https://phabricator.services.mozilla.com/D170187
parent f7fe2aaf
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -122,7 +122,7 @@ replace-with = "vendored-sources"


[source."https://github.com/servo/rust-cssparser"]
[source."https://github.com/servo/rust-cssparser"]
git = "https://github.com/servo/rust-cssparser"
git = "https://github.com/servo/rust-cssparser"
rev = "d3670a89bae26ba3a8db4758eb7976616113987d"
rev = "b196a164dcbb317016d4aa6c58c13147e6045ebb"
replace-with = "vendored-sources"
replace-with = "vendored-sources"




+2 −2
Original line number Original line Diff line number Diff line
@@ -1104,7 +1104,7 @@ dependencies = [
[[package]]
[[package]]
name = "cssparser"
name = "cssparser"
version = "0.30.0"
version = "0.30.0"
source = "git+https://github.com/servo/rust-cssparser?rev=d3670a89bae26ba3a8db4758eb7976616113987d#d3670a89bae26ba3a8db4758eb7976616113987d"
source = "git+https://github.com/servo/rust-cssparser?rev=b196a164dcbb317016d4aa6c58c13147e6045ebb#b196a164dcbb317016d4aa6c58c13147e6045ebb"
dependencies = [
dependencies = [
 "cssparser-macros",
 "cssparser-macros",
 "dtoa-short",
 "dtoa-short",
@@ -1119,7 +1119,7 @@ dependencies = [
[[package]]
[[package]]
name = "cssparser-macros"
name = "cssparser-macros"
version = "0.6.0"
version = "0.6.0"
source = "git+https://github.com/servo/rust-cssparser?rev=d3670a89bae26ba3a8db4758eb7976616113987d#d3670a89bae26ba3a8db4758eb7976616113987d"
source = "git+https://github.com/servo/rust-cssparser?rev=b196a164dcbb317016d4aa6c58c13147e6045ebb#b196a164dcbb317016d4aa6c58c13147e6045ebb"
dependencies = [
dependencies = [
 "quote",
 "quote",
 "syn",
 "syn",
+1 −1
Original line number Original line Diff line number Diff line
@@ -167,7 +167,7 @@ minidump-writer = { git = "https://github.com/rust-minidump/minidump-writer.git"
# warp 0.3.3 + https://github.com/seanmonstar/warp/pull/1007
# warp 0.3.3 + https://github.com/seanmonstar/warp/pull/1007
warp = { git = "https://github.com/glandium/warp", rev = "4af45fae95bc98b0eba1ef0db17e1dac471bb23d" }
warp = { git = "https://github.com/glandium/warp", rev = "4af45fae95bc98b0eba1ef0db17e1dac471bb23d" }


cssparser = { git = "https://github.com/servo/rust-cssparser", rev = "d3670a89bae26ba3a8db4758eb7976616113987d" }
cssparser = { git = "https://github.com/servo/rust-cssparser", rev = "b196a164dcbb317016d4aa6c58c13147e6045ebb" }


# application-services overrides to make updating them all simpler.
# application-services overrides to make updating them all simpler.
interrupt-support = { git = "https://github.com/bendk/application-services", rev = "ecb35df5fc40357c49922f90e86bf4147fa52953" }
interrupt-support = { git = "https://github.com/bendk/application-services", rev = "ecb35df5fc40357c49922f90e86bf4147fa52953" }
+1 −47
Original line number Original line Diff line number Diff line
@@ -274,52 +274,6 @@ impl From<cssparser::PredefinedColorSpace> for ColorSpace {
    }
    }
}
}


impl From<cssparser::AbsoluteColor> for AbsoluteColor {
    fn from(f: cssparser::AbsoluteColor) -> Self {
        match f {
            cssparser::AbsoluteColor::Rgba(rgba) => Self::from_rgba(rgba),

            cssparser::AbsoluteColor::Lab(lab) => Self::new(
                ColorSpace::Lab,
                ColorComponents(lab.lightness, lab.a, lab.b),
                lab.alpha,
            ),

            cssparser::AbsoluteColor::Lch(lch) => Self::new(
                ColorSpace::Lch,
                ColorComponents(lch.lightness, lch.chroma, lch.hue),
                lch.alpha,
            ),

            cssparser::AbsoluteColor::Oklab(oklab) => Self::new(
                ColorSpace::Oklab,
                ColorComponents(oklab.lightness, oklab.a, oklab.b),
                oklab.alpha,
            ),

            cssparser::AbsoluteColor::Oklch(oklch) => Self::new(
                ColorSpace::Oklch,
                ColorComponents(oklch.lightness, oklch.chroma, oklch.hue),
                oklch.alpha,
            ),

            cssparser::AbsoluteColor::ColorFunction(c) => {
                let mut result = AbsoluteColor::new(
                    c.color_space.into(),
                    ColorComponents(c.c1, c.c2, c.c3),
                    c.alpha,
                );

                if matches!(c.color_space, cssparser::PredefinedColorSpace::Srgb) {
                    result.flags |= SerializationFlags::AS_COLOR_FUNCTION;
                }

                result
            },
        }
    }
}

impl ToCss for AbsoluteColor {
impl ToCss for AbsoluteColor {
    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
    where
    where
@@ -394,7 +348,7 @@ impl ToCss for AbsoluteColor {
                    c3: self.components.2,
                    c3: self.components.2,
                    alpha: self.alpha,
                    alpha: self.alpha,
                };
                };
                let color = cssparser::AbsoluteColor::ColorFunction(color_function);
                let color = cssparser::Color::ColorFunction(color_function);
                cssparser::ToCss::to_css(&color, dest)
                cssparser::ToCss::to_css(&color, dest)
            },
            },
        }
        }
+80 −16
Original line number Original line Diff line number Diff line
@@ -6,7 +6,7 @@


use super::AllowQuirks;
use super::AllowQuirks;
use crate::color::mix::ColorInterpolationMethod;
use crate::color::mix::ColorInterpolationMethod;
use crate::color::{AbsoluteColor, ColorComponents, ColorSpace};
use crate::color::{AbsoluteColor, ColorComponents, ColorSpace, SerializationFlags};
use crate::media_queries::Device;
use crate::media_queries::Device;
use crate::parser::{Parse, ParserContext};
use crate::parser::{Parse, ParserContext};
use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue};
use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue};
@@ -417,8 +417,65 @@ impl From<RGBA> for Color {
    }
    }
}
}


struct ColorComponentParser<'a, 'b: 'a>(&'a ParserContext<'b>);
#[inline]
impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponentParser<'a, 'b> {
fn new_absolute(color_space: ColorSpace, c1: f32, c2: f32, c3: f32, alpha: f32) -> Color {
    Color::Absolute(Box::new(Absolute {
        color: AbsoluteColor::new(color_space, ColorComponents(c1, c2, c3), alpha),
        authored: None,
    }))
}

impl cssparser::FromParsedColor for Color {
    fn from_current_color() -> Self {
        Color::CurrentColor
    }

    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
        new_absolute(
            ColorSpace::Srgb,
            red as f32 / 255.0,
            green as f32 / 255.0,
            blue as f32 / 255.0,
            alpha,
        )
    }

    fn from_lab(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
        new_absolute(ColorSpace::Lab, lightness, a, b, alpha)
    }

    fn from_lch(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
        new_absolute(ColorSpace::Lch, lightness, chroma, hue, alpha)
    }

    fn from_oklab(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
        new_absolute(ColorSpace::Oklab, lightness, a, b, alpha)
    }

    fn from_oklch(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
        new_absolute(ColorSpace::Oklch, lightness, chroma, hue, alpha)
    }

    fn from_color_function(
        color_space: cssparser::PredefinedColorSpace,
        c1: f32,
        c2: f32,
        c3: f32,
        alpha: f32,
    ) -> Self {
        let mut result = new_absolute(color_space.into(), c1, c2, c3, alpha);
        if let Color::Absolute(ref mut absolute) = result {
            if matches!(absolute.color.color_space, ColorSpace::Srgb) {
                absolute.color.flags |= SerializationFlags::AS_COLOR_FUNCTION;
            }
        }
        result
    }
}

struct ColorParser<'a, 'b: 'a>(&'a ParserContext<'b>);
impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorParser<'i> for ColorParser<'a, 'b> {
    type Output = Color;
    type Error = StyleParseErrorKind<'i>;
    type Error = StyleParseErrorKind<'i>;


    fn parse_angle_or_number<'t>(
    fn parse_angle_or_number<'t>(
@@ -516,23 +573,30 @@ impl Color {
            },
            },
        };
        };


        let compontent_parser = ColorComponentParser(&*context);
        let color_parser = ColorParser(&*context);
        match input.try_parse(|i| CSSParserColor::parse_with(&compontent_parser, i)) {
        match input.try_parse(|i| cssparser::parse_color_with(&color_parser, i)) {
            Ok(value) => Ok(match value {
            Ok(mut color) => {
                CSSParserColor::CurrentColor => Color::CurrentColor,
                if let Color::Absolute(ref mut absolute) = color {
                CSSParserColor::Absolute(absolute) => {
                    let enabled = {
                    let enabled = matches!(absolute, cssparser::AbsoluteColor::Rgba(_)) ||
                        let is_srgb = matches!(absolute.color.color_space, ColorSpace::Srgb);
                        static_prefs::pref!("layout.css.more_color_4.enabled");
                        let is_color_function = absolute
                            .color
                            .flags
                            .contains(SerializationFlags::AS_COLOR_FUNCTION);
                        let pref_enabled = static_prefs::pref!("layout.css.more_color_4.enabled");

                        (is_srgb && !is_color_function) || pref_enabled
                    };
                    if !enabled {
                    if !enabled {
                        return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
                        return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
                    }
                    }


                    Color::Absolute(Box::new(Absolute {
                    // Because we can't set the `authored` value at construction time, we have to set it
                        color: absolute.into(),
                    // here.
                        authored: authored.map(|s| s.to_ascii_lowercase().into_boxed_str()),
                    absolute.authored = authored.map(|s| s.to_ascii_lowercase().into_boxed_str());
                    }))
                }
                Ok(color)
            },
            },
            }),
            Err(e) => {
            Err(e) => {
                #[cfg(feature = "gecko")]
                #[cfg(feature = "gecko")]
                {
                {
Loading