зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1851370 - Vendor cssparser-color into Gecko r=emilio
To increase the integration between color and calc it is nescessary to vendor the current cssparser-color library into Gecko where all the calc functionality lives. Differential Revision: https://phabricator.services.mozilla.com/D188216
This commit is contained in:
Родитель
d16a6ad83e
Коммит
b52ec06463
|
@ -1036,15 +1036,6 @@ dependencies = [
|
|||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cssparser-color"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556c099a61d85989d7af52b692e35a8d68a57e7df8c6d07563dc0778b3960c9f"
|
||||
dependencies = [
|
||||
"cssparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cssparser-macros"
|
||||
version = "0.6.1"
|
||||
|
@ -5191,7 +5182,6 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"byteorder",
|
||||
"cssparser",
|
||||
"cssparser-color",
|
||||
"derive_more 0.99.999",
|
||||
"dom",
|
||||
"euclid",
|
||||
|
|
|
@ -33,7 +33,6 @@ atomic_refcell = "0.1"
|
|||
bitflags = "1.0"
|
||||
byteorder = "1.0"
|
||||
cssparser = "0.33"
|
||||
cssparser-color = "0.1"
|
||||
derive_more = { version = "0.99", default-features = false, features = ["add", "add_assign", "deref", "deref_mut", "from"] }
|
||||
dom = { path = "../../../dom/base/rust" }
|
||||
new_debug_unreachable = "1.0"
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
/// cbindgen:ignore
|
||||
pub mod convert;
|
||||
pub mod mix;
|
||||
pub mod parsing;
|
||||
|
||||
use cssparser::color::PredefinedColorSpace;
|
||||
use std::fmt::{self, Write};
|
||||
|
@ -512,7 +513,7 @@ impl ToCss for AbsoluteColor {
|
|||
ColorSpace::Srgb if self.flags.contains(ColorFlags::IS_LEGACY_SRGB) => {
|
||||
// The "none" keyword is not supported in the rgb/rgba legacy syntax.
|
||||
cssparser::ToCss::to_css(
|
||||
&cssparser_color::RgbaLegacy::from_floats(
|
||||
&parsing::RgbaLegacy::from_floats(
|
||||
self.components.0,
|
||||
self.components.1,
|
||||
self.components.2,
|
||||
|
@ -523,19 +524,19 @@ impl ToCss for AbsoluteColor {
|
|||
},
|
||||
ColorSpace::Hsl | ColorSpace::Hwb => self.into_srgb_legacy().to_css(dest),
|
||||
ColorSpace::Lab => cssparser::ToCss::to_css(
|
||||
&cssparser_color::Lab::new(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
&parsing::Lab::new(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
dest,
|
||||
),
|
||||
ColorSpace::Lch => cssparser::ToCss::to_css(
|
||||
&cssparser_color::Lch::new(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
&parsing::Lch::new(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
dest,
|
||||
),
|
||||
ColorSpace::Oklab => cssparser::ToCss::to_css(
|
||||
&cssparser_color::Oklab::new(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
&parsing::Oklab::new(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
dest,
|
||||
),
|
||||
ColorSpace::Oklch => cssparser::ToCss::to_css(
|
||||
&cssparser_color::Oklch::new(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
&parsing::Oklch::new(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
dest,
|
||||
),
|
||||
_ => {
|
||||
|
@ -560,14 +561,14 @@ impl ToCss for AbsoluteColor {
|
|||
},
|
||||
};
|
||||
|
||||
let color_function = cssparser_color::ColorFunction {
|
||||
let color_function = parsing::ColorFunction {
|
||||
color_space,
|
||||
c1: maybe_c1,
|
||||
c2: maybe_c2,
|
||||
c3: maybe_c3,
|
||||
alpha: maybe_alpha,
|
||||
};
|
||||
let color = cssparser_color::Color::ColorFunction(color_function);
|
||||
let color = parsing::Color::ColorFunction(color_function);
|
||||
cssparser::ToCss::to_css(&color, dest)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
//! Relative colors, color-mix, system colors, and other such things require better calc() support
|
||||
//! and integration.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use cssparser::color::{
|
||||
clamp_floor_256_f32, clamp_unit_f32, parse_hash_color, serialize_color_alpha,
|
||||
PredefinedColorSpace, OPAQUE,
|
|
@ -10,7 +10,7 @@ use crate::values::computed::percentage::Percentage;
|
|||
use crate::values::generics::color::{
|
||||
GenericCaretColor, GenericColor, GenericColorMix, GenericColorOrAuto,
|
||||
};
|
||||
use cssparser_color::Color as CSSParserColor;
|
||||
use crate::color::parsing::Color as CSSParserColor;
|
||||
use std::fmt;
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::values::specified::length::{ContainerRelativeLength, ViewportPercenta
|
|||
use crate::values::specified::{self, Angle, Resolution, Time};
|
||||
use crate::values::{serialize_number, serialize_percentage, CSSFloat, CSSInteger};
|
||||
use cssparser::{CowRcStr, Parser, Token};
|
||||
use cssparser_color::{AngleOrNumber, NumberOrPercentage};
|
||||
use crate::color::parsing::{AngleOrNumber, NumberOrPercentage};
|
||||
use smallvec::SmallVec;
|
||||
use std::cmp;
|
||||
use std::fmt::{self, Write};
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::values::generics::color::{
|
|||
use crate::values::specified::calc::CalcNode;
|
||||
use crate::values::specified::Percentage;
|
||||
use crate::values::{normalize, CustomIdent};
|
||||
use cssparser_color::{AngleOrNumber, Color as CSSParserColor, NumberOrPercentage, FromParsedColor};
|
||||
use crate::color::parsing::{AngleOrNumber, Color as CSSParserColor, NumberOrPercentage, FromParsedColor, self};
|
||||
use cssparser::{Parser, Token, BasicParseErrorKind, ParseErrorKind, color::PredefinedColorSpace};
|
||||
use itoa;
|
||||
use std::fmt::{self, Write};
|
||||
|
@ -500,7 +500,7 @@ impl FromParsedColor for Color {
|
|||
}
|
||||
|
||||
struct ColorParser<'a, 'b: 'a>(&'a ParserContext<'b>);
|
||||
impl<'a, 'b: 'a, 'i: 'a> cssparser_color::ColorParser<'i> for ColorParser<'a, 'b> {
|
||||
impl<'a, 'b: 'a, 'i: 'a> parsing::ColorParser<'i> for ColorParser<'a, 'b> {
|
||||
type Output = Color;
|
||||
type Error = StyleParseErrorKind<'i>;
|
||||
|
||||
|
@ -601,7 +601,7 @@ impl Color {
|
|||
};
|
||||
|
||||
let color_parser = ColorParser(&*context);
|
||||
match input.try_parse(|i| cssparser_color::parse_color_with(&color_parser, i)) {
|
||||
match input.try_parse(|i| parsing::parse_color_with(&color_parser, i)) {
|
||||
Ok(mut color) => {
|
||||
if let Color::Absolute(ref mut absolute) = color {
|
||||
let enabled = {
|
||||
|
|
|
@ -38,7 +38,7 @@ includes = ["mozilla/ServoStyleConstsForwards.h", "mozilla/ServoStyleSet.h"]
|
|||
[parse]
|
||||
parse_deps = true
|
||||
extra_bindings = ["style"]
|
||||
include = ["style", "app_units", "cssparser", "cssparser_color", "style_traits", "servo_arc"]
|
||||
include = ["style", "app_units", "cssparser", "style_traits", "servo_arc"]
|
||||
|
||||
[struct]
|
||||
associated_constants_in_body = true
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
{"files":{"Cargo.toml":"4d81f7fec4a83149e1b7365eaac98a7b6e910db62c5e82f0e69f80f2718d81f1","lib.rs":"3756b36c919d2150007a933ee7e01dab68620656ce4f8a14463de00f4ced98ba","tests.rs":"685edeec1ee7f3df2bdf6bd8ae01766bbeaad6c1feb52de55791d89f8dcc7989"},"package":"556c099a61d85989d7af52b692e35a8d68a57e7df8c6d07563dc0778b3960c9f"}
|
|
@ -1,36 +0,0 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "cssparser-color"
|
||||
version = "0.1.0"
|
||||
authors = ["Emilio Cobos Álvarez <emilio@crisal.io>"]
|
||||
description = "Color implementation based on cssparser"
|
||||
documentation = "https://docs.rs/cssparser-color/"
|
||||
license = "MPL-2.0"
|
||||
repository = "https://github.com/servo/rust-cssparser"
|
||||
resolver = "1"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.cssparser]
|
||||
version = "0.33"
|
||||
|
||||
[dev-dependencies.difference]
|
||||
version = "2.0"
|
||||
|
||||
[dev-dependencies.encoding_rs]
|
||||
version = "0.8"
|
||||
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0"
|
|
@ -1,401 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use super::*;
|
||||
use crate::{ColorParser, PredefinedColorSpace, Color, RgbaLegacy};
|
||||
use cssparser::{Parser, ParserInput};
|
||||
use serde_json::{self, json, Value};
|
||||
|
||||
fn almost_equals(a: &Value, b: &Value) -> bool {
|
||||
match (a, b) {
|
||||
(&Value::Number(ref a), &Value::Number(ref b)) => {
|
||||
let a = a.as_f64().unwrap();
|
||||
let b = b.as_f64().unwrap();
|
||||
(a - b).abs() <= a.abs() * 1e-6
|
||||
}
|
||||
|
||||
(&Value::Bool(a), &Value::Bool(b)) => a == b,
|
||||
(&Value::String(ref a), &Value::String(ref b)) => a == b,
|
||||
(&Value::Array(ref a), &Value::Array(ref b)) => {
|
||||
a.len() == b.len()
|
||||
&& a.iter()
|
||||
.zip(b.iter())
|
||||
.all(|(ref a, ref b)| almost_equals(*a, *b))
|
||||
}
|
||||
(&Value::Object(_), &Value::Object(_)) => panic!("Not implemented"),
|
||||
(&Value::Null, &Value::Null) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_json_eq(results: Value, expected: Value, message: &str) {
|
||||
if !almost_equals(&results, &expected) {
|
||||
println!(
|
||||
"{}",
|
||||
::difference::Changeset::new(
|
||||
&serde_json::to_string_pretty(&results).unwrap(),
|
||||
&serde_json::to_string_pretty(&expected).unwrap(),
|
||||
"\n",
|
||||
)
|
||||
);
|
||||
panic!("{}", message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn run_raw_json_tests<F: Fn(Value, Value) -> ()>(json_data: &str, run: F) {
|
||||
let items = match serde_json::from_str(json_data) {
|
||||
Ok(Value::Array(items)) => items,
|
||||
other => panic!("Invalid JSON: {:?}", other),
|
||||
};
|
||||
assert!(items.len() % 2 == 0);
|
||||
let mut input = None;
|
||||
for item in items.into_iter() {
|
||||
match (&input, item) {
|
||||
(&None, json_obj) => input = Some(json_obj),
|
||||
(&Some(_), expected) => {
|
||||
let input = input.take().unwrap();
|
||||
run(input, expected)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn run_json_tests<F: Fn(&mut Parser) -> Value>(json_data: &str, parse: F) {
|
||||
run_raw_json_tests(json_data, |input, expected| match input {
|
||||
Value::String(input) => {
|
||||
let mut parse_input = ParserInput::new(&input);
|
||||
let result = parse(&mut Parser::new(&mut parse_input));
|
||||
assert_json_eq(result, expected, &input);
|
||||
}
|
||||
_ => panic!("Unexpected JSON"),
|
||||
});
|
||||
}
|
||||
fn run_color_tests<F: Fn(Result<Color, ()>) -> Value>(json_data: &str, to_json: F) {
|
||||
run_json_tests(json_data, |input| {
|
||||
let result: Result<_, ParseError<()>> =
|
||||
input.parse_entirely(|i| Color::parse(i).map_err(Into::into));
|
||||
to_json(result.map_err(|_| ()))
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn color3() {
|
||||
run_color_tests(include_str!("../src/css-parsing-tests/color3.json"), |c| {
|
||||
c.ok()
|
||||
.map(|v| v.to_css_string().to_json())
|
||||
.unwrap_or(Value::Null)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[test]
|
||||
fn color3_hsl() {
|
||||
run_color_tests(include_str!("../src/css-parsing-tests/color3_hsl.json"), |c| {
|
||||
c.ok()
|
||||
.map(|v| v.to_css_string().to_json())
|
||||
.unwrap_or(Value::Null)
|
||||
})
|
||||
}
|
||||
|
||||
/// color3_keywords.json is different: R, G and B are in 0..255 rather than 0..1
|
||||
#[test]
|
||||
fn color3_keywords() {
|
||||
run_color_tests(
|
||||
include_str!("../src/css-parsing-tests/color3_keywords.json"),
|
||||
|c| {
|
||||
c.ok()
|
||||
.map(|v| v.to_css_string().to_json())
|
||||
.unwrap_or(Value::Null)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[test]
|
||||
fn color4_hwb() {
|
||||
run_color_tests(include_str!("../src/css-parsing-tests/color4_hwb.json"), |c| {
|
||||
c.ok()
|
||||
.map(|v| v.to_css_string().to_json())
|
||||
.unwrap_or(Value::Null)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[test]
|
||||
fn color4_lab_lch_oklab_oklch() {
|
||||
run_color_tests(
|
||||
include_str!("../src/css-parsing-tests/color4_lab_lch_oklab_oklch.json"),
|
||||
|c| {
|
||||
c.ok()
|
||||
.map(|v| v.to_css_string().to_json())
|
||||
.unwrap_or(Value::Null)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn color4_color_function() {
|
||||
run_color_tests(
|
||||
include_str!("../src/css-parsing-tests/color4_color_function.json"),
|
||||
|c| {
|
||||
c.ok()
|
||||
.map(|v| v.to_css_string().to_json())
|
||||
.unwrap_or(Value::Null)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! parse_single_color {
|
||||
($i:expr) => {{
|
||||
let input = $i;
|
||||
let mut input = ParserInput::new(input);
|
||||
let mut input = Parser::new(&mut input);
|
||||
Color::parse(&mut input).map_err(Into::<ParseError<()>>::into)
|
||||
}};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn color4_invalid_color_space() {
|
||||
let result = parse_single_color!("color(invalid 1 1 1)");
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_current_color() {
|
||||
let c = Color::CurrentColor;
|
||||
assert!(c.to_css_string() == "currentcolor");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_rgb_full_alpha() {
|
||||
let c = Color::Rgba(RgbaLegacy::new(255, 230, 204, 1.0));
|
||||
assert_eq!(c.to_css_string(), "rgb(255, 230, 204)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_rgba() {
|
||||
let c = Color::Rgba(RgbaLegacy::new(26, 51, 77, 0.125));
|
||||
assert_eq!(c.to_css_string(), "rgba(26, 51, 77, 0.125)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_rgba_two_digit_float_if_roundtrips() {
|
||||
let c = Color::Rgba(RgbaLegacy::from_floats(0., 0., 0., 0.5));
|
||||
assert_eq!(c.to_css_string(), "rgba(0, 0, 0, 0.5)");
|
||||
}
|
||||
|
||||
trait ToJson {
|
||||
fn to_json(&self) -> Value;
|
||||
}
|
||||
|
||||
impl<T> ToJson for T
|
||||
where
|
||||
T: Clone,
|
||||
Value: From<T>,
|
||||
{
|
||||
fn to_json(&self) -> Value {
|
||||
Value::from(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for Color {
|
||||
fn to_json(&self) -> Value {
|
||||
match *self {
|
||||
Color::CurrentColor => "currentcolor".to_json(),
|
||||
Color::Rgba(ref rgba) => {
|
||||
json!([rgba.red, rgba.green, rgba.blue, rgba.alpha])
|
||||
}
|
||||
Color::Hsl(ref c) => json!([c.hue, c.saturation, c.lightness, c.alpha]),
|
||||
Color::Hwb(ref c) => json!([c.hue, c.whiteness, c.blackness, c.alpha]),
|
||||
Color::Lab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
|
||||
Color::Lch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
|
||||
Color::Oklab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
|
||||
Color::Oklch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
|
||||
Color::ColorFunction(ref c) => {
|
||||
json!([c.color_space.as_str(), c.c1, c.c2, c.c3, c.alpha])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_parser() {
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum OutputType {
|
||||
CurrentColor,
|
||||
Rgba(u8, u8, u8, f32),
|
||||
Hsl(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
|
||||
Hwb(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
|
||||
Lab(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
|
||||
Lch(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
|
||||
Oklab(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
|
||||
Oklch(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
|
||||
ColorFunction(
|
||||
PredefinedColorSpace,
|
||||
Option<f32>,
|
||||
Option<f32>,
|
||||
Option<f32>,
|
||||
Option<f32>,
|
||||
),
|
||||
}
|
||||
|
||||
impl FromParsedColor for OutputType {
|
||||
fn from_current_color() -> Self {
|
||||
OutputType::CurrentColor
|
||||
}
|
||||
|
||||
fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
|
||||
OutputType::Rgba(red, green, blue, alpha)
|
||||
}
|
||||
|
||||
fn from_hsl(
|
||||
hue: Option<f32>,
|
||||
saturation: Option<f32>,
|
||||
lightness: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
OutputType::Hsl(hue, saturation, lightness, alpha)
|
||||
}
|
||||
|
||||
fn from_hwb(
|
||||
hue: Option<f32>,
|
||||
blackness: Option<f32>,
|
||||
whiteness: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
OutputType::Hwb(hue, blackness, whiteness, alpha)
|
||||
}
|
||||
|
||||
fn from_lab(
|
||||
lightness: Option<f32>,
|
||||
a: Option<f32>,
|
||||
b: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
OutputType::Lab(lightness, a, b, alpha)
|
||||
}
|
||||
|
||||
fn from_lch(
|
||||
lightness: Option<f32>,
|
||||
chroma: Option<f32>,
|
||||
hue: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
OutputType::Lch(lightness, chroma, hue, alpha)
|
||||
}
|
||||
|
||||
fn from_oklab(
|
||||
lightness: Option<f32>,
|
||||
a: Option<f32>,
|
||||
b: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
OutputType::Oklab(lightness, a, b, alpha)
|
||||
}
|
||||
|
||||
fn from_oklch(
|
||||
lightness: Option<f32>,
|
||||
chroma: Option<f32>,
|
||||
hue: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
OutputType::Oklch(lightness, chroma, hue, alpha)
|
||||
}
|
||||
|
||||
fn from_color_function(
|
||||
color_space: PredefinedColorSpace,
|
||||
c1: Option<f32>,
|
||||
c2: Option<f32>,
|
||||
c3: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
OutputType::ColorFunction(color_space, c1, c2, c3, alpha)
|
||||
}
|
||||
}
|
||||
|
||||
struct TestColorParser;
|
||||
impl<'i> ColorParser<'i> for TestColorParser {
|
||||
type Output = OutputType;
|
||||
type Error = ();
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TESTS: &[(&str, OutputType)] = &[
|
||||
("currentColor", OutputType::CurrentColor),
|
||||
("rgb(1, 2, 3)", OutputType::Rgba(1, 2, 3, 1.0)),
|
||||
("rgba(1, 2, 3, 0.4)", OutputType::Rgba(1, 2, 3, 0.4)),
|
||||
("rgb(none none none / none)", OutputType::Rgba(0, 0, 0, 0.0)),
|
||||
("rgb(1 none 3 / none)", OutputType::Rgba(1, 0, 3, 0.0)),
|
||||
|
||||
("hsla(45deg, 20%, 30%, 0.4)", OutputType::Hsl(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
|
||||
("hsl(45deg none none)", OutputType::Hsl(Some(45.0), None, None, Some(1.0))),
|
||||
("hsl(none 10% none / none)", OutputType::Hsl(None, Some(0.1), None, None)),
|
||||
("hsl(120 100.0% 50.0%)", OutputType::Hsl(Some(120.0), Some(1.0), Some(0.5), Some(1.0))),
|
||||
|
||||
("hwb(45deg 20% 30% / 0.4)", OutputType::Hwb(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
|
||||
|
||||
("lab(100 20 30 / 0.4)", OutputType::Lab(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
|
||||
("lch(100 20 30 / 0.4)", OutputType::Lch(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
|
||||
|
||||
("oklab(100 20 30 / 0.4)", OutputType::Oklab(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
|
||||
("oklch(100 20 30 / 0.4)", OutputType::Oklch(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
|
||||
|
||||
("color(srgb 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::Srgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
|
||||
("color(srgb none none none)", OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, Some(1.0))),
|
||||
("color(srgb none none none / none)", OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, None)),
|
||||
("color(srgb-linear 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::SrgbLinear, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
|
||||
("color(display-p3 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::DisplayP3, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
|
||||
("color(a98-rgb 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::A98Rgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
|
||||
("color(prophoto-rgb 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::ProphotoRgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
|
||||
("color(rec2020 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::Rec2020, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
|
||||
("color(xyz-d50 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::XyzD50, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
|
||||
("color(xyz-d65 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::XyzD65, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
|
||||
];
|
||||
|
||||
for (input, expected) in TESTS {
|
||||
let mut input = ParserInput::new(*input);
|
||||
let mut input = Parser::new(&mut input);
|
||||
|
||||
let actual: OutputType = parse_color_with(&TestColorParser, &mut input).unwrap();
|
||||
assert_eq!(actual, *expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_modern_components() {
|
||||
// None.
|
||||
assert_eq!(ModernComponent(&None).to_css_string(), "none".to_string());
|
||||
|
||||
// Finite values.
|
||||
assert_eq!(
|
||||
ModernComponent(&Some(10.0)).to_css_string(),
|
||||
"10".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
ModernComponent(&Some(-10.0)).to_css_string(),
|
||||
"-10".to_string()
|
||||
);
|
||||
assert_eq!(ModernComponent(&Some(0.0)).to_css_string(), "0".to_string());
|
||||
assert_eq!(
|
||||
ModernComponent(&Some(-0.0)).to_css_string(),
|
||||
"0".to_string()
|
||||
);
|
||||
|
||||
// Infinite values.
|
||||
assert_eq!(
|
||||
ModernComponent(&Some(f32::INFINITY)).to_css_string(),
|
||||
"calc(infinity)".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
ModernComponent(&Some(f32::NEG_INFINITY)).to_css_string(),
|
||||
"calc(-infinity)".to_string()
|
||||
);
|
||||
|
||||
// NaN.
|
||||
assert_eq!(
|
||||
ModernComponent(&Some(f32::NAN)).to_css_string(),
|
||||
"calc(NaN)".to_string()
|
||||
);
|
||||
}
|
Загрузка…
Ссылка в новой задаче