зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1846745 - Update cssparser. r=tlouw,supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D185154
This commit is contained in:
Родитель
07889f5cff
Коммит
a12b2fedd1
|
@ -1024,9 +1024,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cssparser"
|
||||
version = "0.31.2"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be"
|
||||
checksum = "2d54fe63cb80af11947c98a880393db44448d0b512f9b6c318398ae355794cb9"
|
||||
dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
|
|
|
@ -31,7 +31,7 @@ accountable-refcell = { version = "0.2.0", optional = true }
|
|||
app_units = "0.7"
|
||||
content-security-policy = { version = "0.4.0", features = ["serde"], optional = true }
|
||||
crossbeam-channel = { version = "0.4", optional = true }
|
||||
cssparser = "0.31"
|
||||
cssparser = "0.32"
|
||||
dom = { path = "../../../dom/base/rust" }
|
||||
euclid = "0.22"
|
||||
hyper = { version = "0.12", optional = true }
|
||||
|
|
|
@ -838,7 +838,7 @@ malloc_size_of_is_0!(Range<f32>, Range<f64>);
|
|||
|
||||
malloc_size_of_is_0!(app_units::Au);
|
||||
|
||||
malloc_size_of_is_0!(cssparser::RGBA, cssparser::TokenSerializationType);
|
||||
malloc_size_of_is_0!(cssparser::TokenSerializationType);
|
||||
|
||||
malloc_size_of_is_0!(dom::ElementState, dom::DocumentState);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ bench = []
|
|||
|
||||
[dependencies]
|
||||
bitflags = "2"
|
||||
cssparser = "0.31"
|
||||
cssparser = "0.32"
|
||||
derive_more = { version = "0.99", default-features = false, features = ["add", "add_assign"] }
|
||||
fxhash = "0.2"
|
||||
log = "0.4"
|
||||
|
|
|
@ -32,7 +32,7 @@ arrayvec = "0.7"
|
|||
atomic_refcell = "0.1"
|
||||
bitflags = "2"
|
||||
byteorder = "1.0"
|
||||
cssparser = "0.31"
|
||||
cssparser = "0.32"
|
||||
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"
|
||||
|
|
|
@ -458,11 +458,9 @@ impl ToCss for AbsoluteColor {
|
|||
ColorSpace::Hwb => self.to_color_space(ColorSpace::Srgb).to_css(dest),
|
||||
|
||||
ColorSpace::Srgb if !self.flags.contains(ColorFlags::AS_COLOR_FUNCTION) => {
|
||||
// Althought we are passing Option<_> in here, the to_css fn
|
||||
// knows that the "none" keyword is not supported in the
|
||||
// rgb/rgba legacy syntax.
|
||||
// The "none" keyword is not supported in the rgb/rgba legacy syntax.
|
||||
cssparser::ToCss::to_css(
|
||||
&cssparser::RGBA::from_floats(maybe_c1, maybe_c2, maybe_c3, maybe_alpha),
|
||||
&cssparser::RgbaLegacy::from_floats(self.components.0, self.components.1, self.components.2, self.alpha),
|
||||
dest,
|
||||
)
|
||||
},
|
||||
|
|
|
@ -44,7 +44,7 @@ pub fn parse_counter_style_name<'i, 't>(
|
|||
|
||||
let location = input.current_source_location();
|
||||
let ident = input.expect_ident()?;
|
||||
if let Some(&lower_cased) = predefined(&ident) {
|
||||
if let Some(&lower_cased) = predefined::get(&ident) {
|
||||
Ok(CustomIdent(Atom::from(lower_cased)))
|
||||
} else {
|
||||
// none is always an invalid <counter-style> value.
|
||||
|
|
|
@ -1924,13 +1924,13 @@ impl CountedUnknownProperty {
|
|||
/// Parse the counted unknown property, for testing purposes only.
|
||||
pub fn parse_for_testing(property_name: &str) -> Option<Self> {
|
||||
ascii_case_insensitive_phf_map! {
|
||||
unknown_id -> CountedUnknownProperty = {
|
||||
unknown_ids -> CountedUnknownProperty = {
|
||||
% for property in data.counted_unknown_properties:
|
||||
"${property.name}" => CountedUnknownProperty::${property.camel_case},
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
unknown_id(property_name).cloned()
|
||||
unknown_ids::get(property_name).cloned()
|
||||
}
|
||||
|
||||
/// Returns the underlying index, used for use counter.
|
||||
|
@ -1977,7 +1977,7 @@ impl PropertyId {
|
|||
CountedUnknown(CountedUnknownProperty),
|
||||
}
|
||||
ascii_case_insensitive_phf_map! {
|
||||
static_id -> StaticId = {
|
||||
static_ids -> StaticId = {
|
||||
% for (kind, properties) in [("Longhand", data.longhands), ("Shorthand", data.shorthands)]:
|
||||
% for property in properties:
|
||||
"${property.name}" => StaticId::${kind}(${kind}Id::${property.camel_case}),
|
||||
|
@ -1999,7 +1999,7 @@ impl PropertyId {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(id) = static_id(property_name) {
|
||||
if let Some(id) = static_ids::get(property_name) {
|
||||
return Ok(match *id {
|
||||
StaticId::Longhand(id) => PropertyId::Longhand(id),
|
||||
StaticId::Shorthand(id) => {
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::parser::{Parse, ParserContext};
|
|||
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use crate::Atom;
|
||||
pub use cssparser::{serialize_identifier, serialize_name, CowRcStr, Parser};
|
||||
pub use cssparser::{SourceLocation, Token, RGBA};
|
||||
pub use cssparser::{SourceLocation, Token};
|
||||
use precomputed_hash::PrecomputedHash;
|
||||
use selectors::parser::SelectorParseErrorKind;
|
||||
use std::fmt::{self, Debug, Write};
|
||||
|
|
|
@ -447,15 +447,9 @@ impl cssparser::FromParsedColor for Color {
|
|||
Color::CurrentColor
|
||||
}
|
||||
|
||||
fn from_rgba(red: Option<u8>, green: Option<u8>, blue: Option<u8>, alpha: Option<f32>) -> Self {
|
||||
fn from_rgba(r: u8, g: u8, b: u8, a: f32) -> Self {
|
||||
Self::Absolute(Box::new(Absolute {
|
||||
color: AbsoluteColor::new(
|
||||
ColorSpace::Srgb,
|
||||
red.unwrap_or(0),
|
||||
green.unwrap_or(0),
|
||||
blue.unwrap_or(0),
|
||||
alpha.unwrap_or(0.0),
|
||||
),
|
||||
color: AbsoluteColor::new(ColorSpace::Srgb, r, g, b, a),
|
||||
authored: None,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ gecko = []
|
|||
[dependencies]
|
||||
app_units = "0.7"
|
||||
bitflags = "2"
|
||||
cssparser = "0.31"
|
||||
cssparser = "0.32"
|
||||
euclid = "0.22"
|
||||
lazy_static = "1"
|
||||
malloc_size_of = { path = "../malloc_size_of" }
|
||||
|
|
|
@ -14,7 +14,7 @@ servo = ["cssparser/serde", "string_cache"]
|
|||
gecko = []
|
||||
|
||||
[dependencies]
|
||||
cssparser = "0.31"
|
||||
cssparser = "0.32"
|
||||
servo_arc = { path = "../servo_arc" }
|
||||
smallbitvec = "2.1.1"
|
||||
smallvec = "1.0"
|
||||
|
|
|
@ -15,7 +15,7 @@ gecko_refcount_logging = ["style/gecko_refcount_logging", "servo_arc/gecko_refco
|
|||
[dependencies]
|
||||
atomic_refcell = "0.1"
|
||||
bincode = "1.0"
|
||||
cssparser = "0.31"
|
||||
cssparser = "0.32"
|
||||
cstr = "0.2"
|
||||
dom = { path = "../../../dom/base/rust" }
|
||||
gecko-profiler = { path = "../../../tools/profiler/rust-api" }
|
||||
|
|
|
@ -12,7 +12,7 @@ doctest = false
|
|||
[dependencies]
|
||||
byteorder = "1.0"
|
||||
app_units = "0.7"
|
||||
cssparser = "0.31"
|
||||
cssparser = "0.32"
|
||||
euclid = "0.22"
|
||||
html5ever = "0.22"
|
||||
parking_lot = "0.10"
|
||||
|
|
|
@ -941,6 +941,12 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
|
|||
criteria = "safe-to-deploy"
|
||||
delta = "0.31.0 -> 0.31.2"
|
||||
|
||||
[[audits.cssparser]]
|
||||
who = "Emilio Cobos Álvarez <emilio@crisal.io>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.31.2 -> 0.32.0"
|
||||
notes = "All changes were either authored or reviewed by Mozilla employees."
|
||||
|
||||
[[audits.cssparser-macros]]
|
||||
who = "Emilio Cobos Álvarez <emilio@crisal.io>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
[color-valid-color-function.html]
|
||||
[e.style['color'\] = "color(srgb 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(srgb 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(srgb calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(srgb calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(srgb-linear 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(srgb-linear 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(srgb-linear calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(srgb-linear calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(a98-rgb 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(a98-rgb 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(a98-rgb calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(a98-rgb calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(rec2020 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(rec2020 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(rec2020 calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(rec2020 calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(prophoto-rgb 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(prophoto-rgb 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(prophoto-rgb calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(prophoto-rgb calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(display-p3 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(display-p3 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(display-p3 calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(display-p3 calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz-d50 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz-d50 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz-d50 calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz-d50 calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz-d65 0 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz-d65 0 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz-d65 calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "color(xyz-d65 calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
|
@ -17,15 +17,9 @@
|
|||
[e.style['color'\] = "oklch(calc(0.5 * 3) calc(0.5 - 1) calc(20deg * 2) / calc(-0.5 + 1))" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "lab(50 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "oklch(calc(infinity) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "oklab(0.5 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "lch(calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -44,21 +38,12 @@
|
|||
[e.style['color'\] = "lab(calc(infinity) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "lch(50 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "lab(calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "oklab(0.5 calc(-infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "oklch(calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "lab(50 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "lch(calc(NaN) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -67,6 +52,3 @@
|
|||
|
||||
[e.style['color'\] = "oklab(calc(0 / 0) 0 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['color'\] = "oklch(0.5 calc(infinity) 0)" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"040cfbd0b6ddccc9ee3703e5386dda1a52e13c1abdacfa207f502af42364607b","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"53a6805edd80f642473514cb93f1f4197e17a911d66a2dfcefc3dc5e82bac206","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"740465ed632940dd9551b92e2ea9140cd9e5e9d3e0f1f548018b98bbff159b6f","src/cow_rc_str.rs":"4d172d3633ef55af815784fbaee03cbcf85796a380765a0af09bbb6ca5b6fbab","src/from_bytes.rs":"b1cf15c4e975523fef46b575598737a39f3c63e5ce0b2bfd6ec627c69c6ea54a","src/lib.rs":"8f1657c507380db0281e5aa7eb06f17d7f559c582b265d6589006042ffad18ad","src/macros.rs":"883df01d4a8dfc661b8ffa17fab694ff6fb271e99e9c6b023e73d49bbaa6e5d6","src/nth.rs":"2fc26915f0a36cb22ac45dd9a7ecbdc64c327b2ec135370258ec3db9f9985460","src/parser.rs":"50fa448b316902d5f4aa18725220633c28bb7d82cbaff125177d79d4cf8dae58","src/rules_and_declarations.rs":"63971fd3dccee82197ecd2e32953bc96fcc2fe43eaa8e1d048d1842d00a5a098","src/serializer.rs":"3a0155521676deea9a6327c2ed00af6d5dabb29a97e2341d0f565f8c2b66d0a3","src/size_of_tests.rs":"da0cbcaa304f7800e9122e2bce0a11d42a70b9012e646a723cb23ee74a6b858c","src/tests.rs":"6c950841e8c454c50ae439543fa8718f935058a6bb1b1bf77033439daeff08a7","src/tokenizer.rs":"9900460d9bad82b7a41829d01537094203fafc7092c954aac969546ea53d5bba","src/unicode_range.rs":"20d96f06fbb73921e308cc340c9fe065e27f19843005689fb259007a6a372bcc"},"package":"5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be"}
|
||||
{"files":{"Cargo.toml":"68e296e817df1ef24bc04823d1eb078b47bda1413c2e37d20155471382a40378","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"53a6805edd80f642473514cb93f1f4197e17a911d66a2dfcefc3dc5e82bac206","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"e37d2907a4ba60768071bcf5a94308bb1efdbdabfbe842ad1cd4bdd8e7795dca","src/cow_rc_str.rs":"4d172d3633ef55af815784fbaee03cbcf85796a380765a0af09bbb6ca5b6fbab","src/from_bytes.rs":"b1cf15c4e975523fef46b575598737a39f3c63e5ce0b2bfd6ec627c69c6ea54a","src/lib.rs":"0d18abef27fa2ca02ae17cf64a184e927b0fd54068758d236241c250b53da279","src/macros.rs":"c6e06fd014ee8c6212c72928e8b474fb1cd13a0b604055e9943ed05179a0e63b","src/nth.rs":"2fc26915f0a36cb22ac45dd9a7ecbdc64c327b2ec135370258ec3db9f9985460","src/parser.rs":"50fa448b316902d5f4aa18725220633c28bb7d82cbaff125177d79d4cf8dae58","src/rules_and_declarations.rs":"63971fd3dccee82197ecd2e32953bc96fcc2fe43eaa8e1d048d1842d00a5a098","src/serializer.rs":"3a0155521676deea9a6327c2ed00af6d5dabb29a97e2341d0f565f8c2b66d0a3","src/size_of_tests.rs":"da0cbcaa304f7800e9122e2bce0a11d42a70b9012e646a723cb23ee74a6b858c","src/tests.rs":"c1b6519beded37e4290d90079e1bb9094564e66d464254bf87e2b0348e095bc3","src/tokenizer.rs":"9900460d9bad82b7a41829d01537094203fafc7092c954aac969546ea53d5bba","src/unicode_range.rs":"20d96f06fbb73921e308cc340c9fe065e27f19843005689fb259007a6a372bcc"},"package":"2d54fe63cb80af11947c98a880393db44448d0b512f9b6c318398ae355794cb9"}
|
|
@ -13,7 +13,7 @@
|
|||
edition = "2018"
|
||||
rust-version = "1.63"
|
||||
name = "cssparser"
|
||||
version = "0.31.2"
|
||||
version = "0.32.0"
|
||||
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
|
||||
exclude = [
|
||||
"src/css-parsing-tests/**",
|
||||
|
@ -62,3 +62,4 @@ version = "1.0"
|
|||
[features]
|
||||
bench = []
|
||||
dummy_match_byte = []
|
||||
skip_long_tests = []
|
||||
|
|
|
@ -16,16 +16,6 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
|||
|
||||
const OPAQUE: f32 = 1.0;
|
||||
|
||||
fn serialize_none_or<T>(dest: &mut impl fmt::Write, value: &Option<T>) -> fmt::Result
|
||||
where
|
||||
T: ToCss,
|
||||
{
|
||||
match value {
|
||||
Some(v) => v.to_css(dest),
|
||||
None => dest.write_str("none"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialize the alpha copmonent of a color according to the specification.
|
||||
/// <https://drafts.csswg.org/css-color-4/#serializing-alpha-values>
|
||||
#[inline]
|
||||
|
@ -55,6 +45,34 @@ pub fn serialize_color_alpha(
|
|||
rounded_alpha.to_css(dest)
|
||||
}
|
||||
|
||||
/// A [`ModernComponent`] can serialize to `none`, `nan`, `infinity` and
|
||||
/// floating point values.
|
||||
struct ModernComponent<'a>(&'a Option<f32>);
|
||||
|
||||
impl<'a> ToCss for ModernComponent<'a> {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
if let Some(value) = self.0 {
|
||||
if value.is_finite() {
|
||||
value.to_css(dest)
|
||||
} else if value.is_nan() {
|
||||
dest.write_str("calc(NaN)")
|
||||
} else {
|
||||
debug_assert!(value.is_infinite());
|
||||
if value.is_sign_negative() {
|
||||
dest.write_str("calc(-infinity)")
|
||||
} else {
|
||||
dest.write_str("calc(infinity)")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dest.write_str("none")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guaratees hue in [0..360)
|
||||
fn normalize_hue(hue: f32) -> f32 {
|
||||
// <https://drafts.csswg.org/css-values/#angles>
|
||||
|
@ -64,44 +82,34 @@ fn normalize_hue(hue: f32) -> f32 {
|
|||
|
||||
/// A color with red, green, blue, and alpha components, in a byte each.
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub struct RGBA {
|
||||
pub struct RgbaLegacy {
|
||||
/// The red component.
|
||||
pub red: Option<u8>,
|
||||
pub red: u8,
|
||||
/// The green component.
|
||||
pub green: Option<u8>,
|
||||
pub green: u8,
|
||||
/// The blue component.
|
||||
pub blue: Option<u8>,
|
||||
pub blue: u8,
|
||||
/// The alpha component.
|
||||
pub alpha: Option<f32>,
|
||||
pub alpha: f32,
|
||||
}
|
||||
|
||||
impl RGBA {
|
||||
impl RgbaLegacy {
|
||||
/// Constructs a new RGBA value from float components. It expects the red,
|
||||
/// green, blue and alpha channels in that order, and all values will be
|
||||
/// clamped to the 0.0 ... 1.0 range.
|
||||
#[inline]
|
||||
pub fn from_floats(
|
||||
red: Option<f32>,
|
||||
green: Option<f32>,
|
||||
blue: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
pub fn from_floats(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
|
||||
Self::new(
|
||||
red.map(clamp_unit_f32),
|
||||
green.map(clamp_unit_f32),
|
||||
blue.map(clamp_unit_f32),
|
||||
alpha.map(|a| a.clamp(0.0, OPAQUE)),
|
||||
clamp_unit_f32(red),
|
||||
clamp_unit_f32(green),
|
||||
clamp_unit_f32(blue),
|
||||
alpha.clamp(0.0, OPAQUE),
|
||||
)
|
||||
}
|
||||
|
||||
/// Same thing, but with `u8` values instead of floats in the 0 to 1 range.
|
||||
#[inline]
|
||||
pub const fn new(
|
||||
red: Option<u8>,
|
||||
green: Option<u8>,
|
||||
blue: Option<u8>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
pub const fn new(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
|
||||
Self {
|
||||
red,
|
||||
green,
|
||||
|
@ -112,7 +120,7 @@ impl RGBA {
|
|||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for RGBA {
|
||||
impl Serialize for RgbaLegacy {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
|
@ -122,32 +130,32 @@ impl Serialize for RGBA {
|
|||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for RGBA {
|
||||
impl<'de> Deserialize<'de> for RgbaLegacy {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let (r, g, b, a) = Deserialize::deserialize(deserializer)?;
|
||||
Ok(RGBA::new(r, g, b, a))
|
||||
Ok(RgbaLegacy::new(r, g, b, a))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for RGBA {
|
||||
impl ToCss for RgbaLegacy {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
let has_alpha = self.alpha.unwrap_or(0.0) != OPAQUE;
|
||||
let has_alpha = self.alpha != OPAQUE;
|
||||
|
||||
dest.write_str(if has_alpha { "rgba(" } else { "rgb(" })?;
|
||||
self.red.unwrap_or(0).to_css(dest)?;
|
||||
self.red.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
self.green.unwrap_or(0).to_css(dest)?;
|
||||
self.green.to_css(dest)?;
|
||||
dest.write_str(", ")?;
|
||||
self.blue.unwrap_or(0).to_css(dest)?;
|
||||
self.blue.to_css(dest)?;
|
||||
|
||||
// Legacy syntax does not allow none components.
|
||||
serialize_color_alpha(dest, Some(self.alpha.unwrap_or(0.0)), true)?;
|
||||
serialize_color_alpha(dest, Some(self.alpha), true)?;
|
||||
|
||||
dest.write_char(')')
|
||||
}
|
||||
|
@ -195,7 +203,7 @@ impl ToCss for Hsl {
|
|||
self.lightness.unwrap_or(0.0),
|
||||
);
|
||||
|
||||
RGBA::from_floats(Some(red), Some(green), Some(blue), self.alpha).to_css(dest)
|
||||
RgbaLegacy::from_floats(red, green, blue, self.alpha.unwrap_or(OPAQUE)).to_css(dest)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +270,7 @@ impl ToCss for Hwb {
|
|||
self.blackness.unwrap_or(0.0),
|
||||
);
|
||||
|
||||
RGBA::from_floats(Some(red), Some(green), Some(blue), self.alpha).to_css(dest)
|
||||
RgbaLegacy::from_floats(red, green, blue, self.alpha.unwrap_or(OPAQUE)).to_css(dest)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,11 +371,11 @@ macro_rules! impl_lab_like {
|
|||
{
|
||||
dest.write_str($fname)?;
|
||||
dest.write_str("(")?;
|
||||
serialize_none_or(dest, &self.lightness)?;
|
||||
ModernComponent(&self.lightness).to_css(dest)?;
|
||||
dest.write_char(' ')?;
|
||||
serialize_none_or(dest, &self.a)?;
|
||||
ModernComponent(&self.a).to_css(dest)?;
|
||||
dest.write_char(' ')?;
|
||||
serialize_none_or(dest, &self.b)?;
|
||||
ModernComponent(&self.b).to_css(dest)?;
|
||||
serialize_color_alpha(dest, self.alpha, false)?;
|
||||
dest.write_char(')')
|
||||
}
|
||||
|
@ -454,11 +462,11 @@ macro_rules! impl_lch_like {
|
|||
{
|
||||
dest.write_str($fname)?;
|
||||
dest.write_str("(")?;
|
||||
serialize_none_or(dest, &self.lightness)?;
|
||||
ModernComponent(&self.lightness).to_css(dest)?;
|
||||
dest.write_char(' ')?;
|
||||
serialize_none_or(dest, &self.chroma)?;
|
||||
ModernComponent(&self.chroma).to_css(dest)?;
|
||||
dest.write_char(' ')?;
|
||||
serialize_none_or(dest, &self.hue)?;
|
||||
ModernComponent(&self.hue).to_css(dest)?;
|
||||
serialize_color_alpha(dest, self.alpha, false)?;
|
||||
dest.write_char(')')
|
||||
}
|
||||
|
@ -579,11 +587,11 @@ impl ToCss for ColorFunction {
|
|||
dest.write_str("color(")?;
|
||||
self.color_space.to_css(dest)?;
|
||||
dest.write_char(' ')?;
|
||||
serialize_none_or(dest, &self.c1)?;
|
||||
ModernComponent(&self.c1).to_css(dest)?;
|
||||
dest.write_char(' ')?;
|
||||
serialize_none_or(dest, &self.c2)?;
|
||||
ModernComponent(&self.c2).to_css(dest)?;
|
||||
dest.write_char(' ')?;
|
||||
serialize_none_or(dest, &self.c3)?;
|
||||
ModernComponent(&self.c3).to_css(dest)?;
|
||||
|
||||
serialize_color_alpha(dest, self.alpha, false)?;
|
||||
|
||||
|
@ -603,7 +611,7 @@ pub enum Color {
|
|||
/// The 'currentcolor' keyword.
|
||||
CurrentColor,
|
||||
/// Specify sRGB colors directly by their red/green/blue/alpha chanels.
|
||||
Rgba(RGBA),
|
||||
Rgba(RgbaLegacy),
|
||||
/// Specifies a color in sRGB using hue, saturation and lightness components.
|
||||
Hsl(Hsl),
|
||||
/// Specifies a color in sRGB using hue, whiteness and blackness components.
|
||||
|
@ -794,7 +802,7 @@ pub trait FromParsedColor {
|
|||
fn from_current_color() -> Self;
|
||||
|
||||
/// Construct a new color from red, green, blue and alpha components.
|
||||
fn from_rgba(red: Option<u8>, green: Option<u8>, blue: Option<u8>, alpha: Option<f32>) -> Self;
|
||||
fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self;
|
||||
|
||||
/// Construct a new color from hue, saturation, lightness and alpha components.
|
||||
fn from_hsl(
|
||||
|
@ -858,28 +866,28 @@ where
|
|||
{
|
||||
Ok(match value.len() {
|
||||
8 => O::from_rgba(
|
||||
Some(from_hex(value[0])? * 16 + from_hex(value[1])?),
|
||||
Some(from_hex(value[2])? * 16 + from_hex(value[3])?),
|
||||
Some(from_hex(value[4])? * 16 + from_hex(value[5])?),
|
||||
Some((from_hex(value[6])? * 16 + from_hex(value[7])?) as f32 / 255.0),
|
||||
from_hex(value[0])? * 16 + from_hex(value[1])?,
|
||||
from_hex(value[2])? * 16 + from_hex(value[3])?,
|
||||
from_hex(value[4])? * 16 + from_hex(value[5])?,
|
||||
(from_hex(value[6])? * 16 + from_hex(value[7])?) as f32 / 255.0,
|
||||
),
|
||||
6 => O::from_rgba(
|
||||
Some(from_hex(value[0])? * 16 + from_hex(value[1])?),
|
||||
Some(from_hex(value[2])? * 16 + from_hex(value[3])?),
|
||||
Some(from_hex(value[4])? * 16 + from_hex(value[5])?),
|
||||
Some(OPAQUE),
|
||||
from_hex(value[0])? * 16 + from_hex(value[1])?,
|
||||
from_hex(value[2])? * 16 + from_hex(value[3])?,
|
||||
from_hex(value[4])? * 16 + from_hex(value[5])?,
|
||||
OPAQUE,
|
||||
),
|
||||
4 => O::from_rgba(
|
||||
Some(from_hex(value[0])? * 17),
|
||||
Some(from_hex(value[1])? * 17),
|
||||
Some(from_hex(value[2])? * 17),
|
||||
Some((from_hex(value[3])? * 17) as f32 / 255.0),
|
||||
from_hex(value[0])? * 17,
|
||||
from_hex(value[1])? * 17,
|
||||
from_hex(value[2])? * 17,
|
||||
(from_hex(value[3])? * 17) as f32 / 255.0,
|
||||
),
|
||||
3 => O::from_rgba(
|
||||
Some(from_hex(value[0])? * 17),
|
||||
Some(from_hex(value[1])? * 17),
|
||||
Some(from_hex(value[2])? * 17),
|
||||
Some(OPAQUE),
|
||||
from_hex(value[0])? * 17,
|
||||
from_hex(value[1])? * 17,
|
||||
from_hex(value[2])? * 17,
|
||||
OPAQUE,
|
||||
),
|
||||
_ => return Err(()),
|
||||
})
|
||||
|
@ -917,8 +925,8 @@ impl FromParsedColor for Color {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn from_rgba(red: Option<u8>, green: Option<u8>, blue: Option<u8>, alpha: Option<f32>) -> Self {
|
||||
Color::Rgba(RGBA::new(red, green, blue, alpha))
|
||||
fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
|
||||
Color::Rgba(RgbaLegacy::new(red, green, blue, alpha))
|
||||
}
|
||||
|
||||
fn from_hsl(
|
||||
|
@ -991,6 +999,178 @@ impl FromParsedColor for Color {
|
|||
}
|
||||
}
|
||||
|
||||
ascii_case_insensitive_phf_map! {
|
||||
named_colors -> (u8, u8, u8) = {
|
||||
"black" => (0, 0, 0),
|
||||
"silver" => (192, 192, 192),
|
||||
"gray" => (128, 128, 128),
|
||||
"white" => (255, 255, 255),
|
||||
"maroon" => (128, 0, 0),
|
||||
"red" => (255, 0, 0),
|
||||
"purple" => (128, 0, 128),
|
||||
"fuchsia" => (255, 0, 255),
|
||||
"green" => (0, 128, 0),
|
||||
"lime" => (0, 255, 0),
|
||||
"olive" => (128, 128, 0),
|
||||
"yellow" => (255, 255, 0),
|
||||
"navy" => (0, 0, 128),
|
||||
"blue" => (0, 0, 255),
|
||||
"teal" => (0, 128, 128),
|
||||
"aqua" => (0, 255, 255),
|
||||
|
||||
"aliceblue" => (240, 248, 255),
|
||||
"antiquewhite" => (250, 235, 215),
|
||||
"aquamarine" => (127, 255, 212),
|
||||
"azure" => (240, 255, 255),
|
||||
"beige" => (245, 245, 220),
|
||||
"bisque" => (255, 228, 196),
|
||||
"blanchedalmond" => (255, 235, 205),
|
||||
"blueviolet" => (138, 43, 226),
|
||||
"brown" => (165, 42, 42),
|
||||
"burlywood" => (222, 184, 135),
|
||||
"cadetblue" => (95, 158, 160),
|
||||
"chartreuse" => (127, 255, 0),
|
||||
"chocolate" => (210, 105, 30),
|
||||
"coral" => (255, 127, 80),
|
||||
"cornflowerblue" => (100, 149, 237),
|
||||
"cornsilk" => (255, 248, 220),
|
||||
"crimson" => (220, 20, 60),
|
||||
"cyan" => (0, 255, 255),
|
||||
"darkblue" => (0, 0, 139),
|
||||
"darkcyan" => (0, 139, 139),
|
||||
"darkgoldenrod" => (184, 134, 11),
|
||||
"darkgray" => (169, 169, 169),
|
||||
"darkgreen" => (0, 100, 0),
|
||||
"darkgrey" => (169, 169, 169),
|
||||
"darkkhaki" => (189, 183, 107),
|
||||
"darkmagenta" => (139, 0, 139),
|
||||
"darkolivegreen" => (85, 107, 47),
|
||||
"darkorange" => (255, 140, 0),
|
||||
"darkorchid" => (153, 50, 204),
|
||||
"darkred" => (139, 0, 0),
|
||||
"darksalmon" => (233, 150, 122),
|
||||
"darkseagreen" => (143, 188, 143),
|
||||
"darkslateblue" => (72, 61, 139),
|
||||
"darkslategray" => (47, 79, 79),
|
||||
"darkslategrey" => (47, 79, 79),
|
||||
"darkturquoise" => (0, 206, 209),
|
||||
"darkviolet" => (148, 0, 211),
|
||||
"deeppink" => (255, 20, 147),
|
||||
"deepskyblue" => (0, 191, 255),
|
||||
"dimgray" => (105, 105, 105),
|
||||
"dimgrey" => (105, 105, 105),
|
||||
"dodgerblue" => (30, 144, 255),
|
||||
"firebrick" => (178, 34, 34),
|
||||
"floralwhite" => (255, 250, 240),
|
||||
"forestgreen" => (34, 139, 34),
|
||||
"gainsboro" => (220, 220, 220),
|
||||
"ghostwhite" => (248, 248, 255),
|
||||
"gold" => (255, 215, 0),
|
||||
"goldenrod" => (218, 165, 32),
|
||||
"greenyellow" => (173, 255, 47),
|
||||
"grey" => (128, 128, 128),
|
||||
"honeydew" => (240, 255, 240),
|
||||
"hotpink" => (255, 105, 180),
|
||||
"indianred" => (205, 92, 92),
|
||||
"indigo" => (75, 0, 130),
|
||||
"ivory" => (255, 255, 240),
|
||||
"khaki" => (240, 230, 140),
|
||||
"lavender" => (230, 230, 250),
|
||||
"lavenderblush" => (255, 240, 245),
|
||||
"lawngreen" => (124, 252, 0),
|
||||
"lemonchiffon" => (255, 250, 205),
|
||||
"lightblue" => (173, 216, 230),
|
||||
"lightcoral" => (240, 128, 128),
|
||||
"lightcyan" => (224, 255, 255),
|
||||
"lightgoldenrodyellow" => (250, 250, 210),
|
||||
"lightgray" => (211, 211, 211),
|
||||
"lightgreen" => (144, 238, 144),
|
||||
"lightgrey" => (211, 211, 211),
|
||||
"lightpink" => (255, 182, 193),
|
||||
"lightsalmon" => (255, 160, 122),
|
||||
"lightseagreen" => (32, 178, 170),
|
||||
"lightskyblue" => (135, 206, 250),
|
||||
"lightslategray" => (119, 136, 153),
|
||||
"lightslategrey" => (119, 136, 153),
|
||||
"lightsteelblue" => (176, 196, 222),
|
||||
"lightyellow" => (255, 255, 224),
|
||||
"limegreen" => (50, 205, 50),
|
||||
"linen" => (250, 240, 230),
|
||||
"magenta" => (255, 0, 255),
|
||||
"mediumaquamarine" => (102, 205, 170),
|
||||
"mediumblue" => (0, 0, 205),
|
||||
"mediumorchid" => (186, 85, 211),
|
||||
"mediumpurple" => (147, 112, 219),
|
||||
"mediumseagreen" => (60, 179, 113),
|
||||
"mediumslateblue" => (123, 104, 238),
|
||||
"mediumspringgreen" => (0, 250, 154),
|
||||
"mediumturquoise" => (72, 209, 204),
|
||||
"mediumvioletred" => (199, 21, 133),
|
||||
"midnightblue" => (25, 25, 112),
|
||||
"mintcream" => (245, 255, 250),
|
||||
"mistyrose" => (255, 228, 225),
|
||||
"moccasin" => (255, 228, 181),
|
||||
"navajowhite" => (255, 222, 173),
|
||||
"oldlace" => (253, 245, 230),
|
||||
"olivedrab" => (107, 142, 35),
|
||||
"orange" => (255, 165, 0),
|
||||
"orangered" => (255, 69, 0),
|
||||
"orchid" => (218, 112, 214),
|
||||
"palegoldenrod" => (238, 232, 170),
|
||||
"palegreen" => (152, 251, 152),
|
||||
"paleturquoise" => (175, 238, 238),
|
||||
"palevioletred" => (219, 112, 147),
|
||||
"papayawhip" => (255, 239, 213),
|
||||
"peachpuff" => (255, 218, 185),
|
||||
"peru" => (205, 133, 63),
|
||||
"pink" => (255, 192, 203),
|
||||
"plum" => (221, 160, 221),
|
||||
"powderblue" => (176, 224, 230),
|
||||
"rebeccapurple" => (102, 51, 153),
|
||||
"rosybrown" => (188, 143, 143),
|
||||
"royalblue" => (65, 105, 225),
|
||||
"saddlebrown" => (139, 69, 19),
|
||||
"salmon" => (250, 128, 114),
|
||||
"sandybrown" => (244, 164, 96),
|
||||
"seagreen" => (46, 139, 87),
|
||||
"seashell" => (255, 245, 238),
|
||||
"sienna" => (160, 82, 45),
|
||||
"skyblue" => (135, 206, 235),
|
||||
"slateblue" => (106, 90, 205),
|
||||
"slategray" => (112, 128, 144),
|
||||
"slategrey" => (112, 128, 144),
|
||||
"snow" => (255, 250, 250),
|
||||
"springgreen" => (0, 255, 127),
|
||||
"steelblue" => (70, 130, 180),
|
||||
"tan" => (210, 180, 140),
|
||||
"thistle" => (216, 191, 216),
|
||||
"tomato" => (255, 99, 71),
|
||||
"turquoise" => (64, 224, 208),
|
||||
"violet" => (238, 130, 238),
|
||||
"wheat" => (245, 222, 179),
|
||||
"whitesmoke" => (245, 245, 245),
|
||||
"yellowgreen" => (154, 205, 50),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the named color with the given name.
|
||||
/// <https://drafts.csswg.org/css-color-4/#typedef-named-color>
|
||||
#[inline]
|
||||
pub fn parse_named_color<Output>(ident: &str) -> Result<Output, ()>
|
||||
where
|
||||
Output: FromParsedColor,
|
||||
{
|
||||
let &(r, g, b) = named_colors::get(ident).ok_or(())?;
|
||||
Ok(Output::from_rgba(r, g, b, 1.0))
|
||||
}
|
||||
|
||||
/// Returns an iterator over all named CSS colors.
|
||||
/// <https://drafts.csswg.org/css-color-4/#typedef-named-color>
|
||||
#[inline]
|
||||
pub fn all_named_colors() -> impl Iterator<Item = (&'static str, (u8, u8, u8))> {
|
||||
named_colors::entries().map(|(k, v)| (*k, *v))
|
||||
}
|
||||
|
||||
/// Return the named color with the given name.
|
||||
///
|
||||
/// Matching is case-insensitive in the ASCII range.
|
||||
|
@ -1001,167 +1181,11 @@ pub fn parse_color_keyword<Output>(ident: &str) -> Result<Output, ()>
|
|||
where
|
||||
Output: FromParsedColor,
|
||||
{
|
||||
ascii_case_insensitive_phf_map! {
|
||||
keyword -> (u8, u8, u8) = {
|
||||
"black" => (0, 0, 0),
|
||||
"silver" => (192, 192, 192),
|
||||
"gray" => (128, 128, 128),
|
||||
"white" => (255, 255, 255),
|
||||
"maroon" => (128, 0, 0),
|
||||
"red" => (255, 0, 0),
|
||||
"purple" => (128, 0, 128),
|
||||
"fuchsia" => (255, 0, 255),
|
||||
"green" => (0, 128, 0),
|
||||
"lime" => (0, 255, 0),
|
||||
"olive" => (128, 128, 0),
|
||||
"yellow" => (255, 255, 0),
|
||||
"navy" => (0, 0, 128),
|
||||
"blue" => (0, 0, 255),
|
||||
"teal" => (0, 128, 128),
|
||||
"aqua" => (0, 255, 255),
|
||||
|
||||
"aliceblue" => (240, 248, 255),
|
||||
"antiquewhite" => (250, 235, 215),
|
||||
"aquamarine" => (127, 255, 212),
|
||||
"azure" => (240, 255, 255),
|
||||
"beige" => (245, 245, 220),
|
||||
"bisque" => (255, 228, 196),
|
||||
"blanchedalmond" => (255, 235, 205),
|
||||
"blueviolet" => (138, 43, 226),
|
||||
"brown" => (165, 42, 42),
|
||||
"burlywood" => (222, 184, 135),
|
||||
"cadetblue" => (95, 158, 160),
|
||||
"chartreuse" => (127, 255, 0),
|
||||
"chocolate" => (210, 105, 30),
|
||||
"coral" => (255, 127, 80),
|
||||
"cornflowerblue" => (100, 149, 237),
|
||||
"cornsilk" => (255, 248, 220),
|
||||
"crimson" => (220, 20, 60),
|
||||
"cyan" => (0, 255, 255),
|
||||
"darkblue" => (0, 0, 139),
|
||||
"darkcyan" => (0, 139, 139),
|
||||
"darkgoldenrod" => (184, 134, 11),
|
||||
"darkgray" => (169, 169, 169),
|
||||
"darkgreen" => (0, 100, 0),
|
||||
"darkgrey" => (169, 169, 169),
|
||||
"darkkhaki" => (189, 183, 107),
|
||||
"darkmagenta" => (139, 0, 139),
|
||||
"darkolivegreen" => (85, 107, 47),
|
||||
"darkorange" => (255, 140, 0),
|
||||
"darkorchid" => (153, 50, 204),
|
||||
"darkred" => (139, 0, 0),
|
||||
"darksalmon" => (233, 150, 122),
|
||||
"darkseagreen" => (143, 188, 143),
|
||||
"darkslateblue" => (72, 61, 139),
|
||||
"darkslategray" => (47, 79, 79),
|
||||
"darkslategrey" => (47, 79, 79),
|
||||
"darkturquoise" => (0, 206, 209),
|
||||
"darkviolet" => (148, 0, 211),
|
||||
"deeppink" => (255, 20, 147),
|
||||
"deepskyblue" => (0, 191, 255),
|
||||
"dimgray" => (105, 105, 105),
|
||||
"dimgrey" => (105, 105, 105),
|
||||
"dodgerblue" => (30, 144, 255),
|
||||
"firebrick" => (178, 34, 34),
|
||||
"floralwhite" => (255, 250, 240),
|
||||
"forestgreen" => (34, 139, 34),
|
||||
"gainsboro" => (220, 220, 220),
|
||||
"ghostwhite" => (248, 248, 255),
|
||||
"gold" => (255, 215, 0),
|
||||
"goldenrod" => (218, 165, 32),
|
||||
"greenyellow" => (173, 255, 47),
|
||||
"grey" => (128, 128, 128),
|
||||
"honeydew" => (240, 255, 240),
|
||||
"hotpink" => (255, 105, 180),
|
||||
"indianred" => (205, 92, 92),
|
||||
"indigo" => (75, 0, 130),
|
||||
"ivory" => (255, 255, 240),
|
||||
"khaki" => (240, 230, 140),
|
||||
"lavender" => (230, 230, 250),
|
||||
"lavenderblush" => (255, 240, 245),
|
||||
"lawngreen" => (124, 252, 0),
|
||||
"lemonchiffon" => (255, 250, 205),
|
||||
"lightblue" => (173, 216, 230),
|
||||
"lightcoral" => (240, 128, 128),
|
||||
"lightcyan" => (224, 255, 255),
|
||||
"lightgoldenrodyellow" => (250, 250, 210),
|
||||
"lightgray" => (211, 211, 211),
|
||||
"lightgreen" => (144, 238, 144),
|
||||
"lightgrey" => (211, 211, 211),
|
||||
"lightpink" => (255, 182, 193),
|
||||
"lightsalmon" => (255, 160, 122),
|
||||
"lightseagreen" => (32, 178, 170),
|
||||
"lightskyblue" => (135, 206, 250),
|
||||
"lightslategray" => (119, 136, 153),
|
||||
"lightslategrey" => (119, 136, 153),
|
||||
"lightsteelblue" => (176, 196, 222),
|
||||
"lightyellow" => (255, 255, 224),
|
||||
"limegreen" => (50, 205, 50),
|
||||
"linen" => (250, 240, 230),
|
||||
"magenta" => (255, 0, 255),
|
||||
"mediumaquamarine" => (102, 205, 170),
|
||||
"mediumblue" => (0, 0, 205),
|
||||
"mediumorchid" => (186, 85, 211),
|
||||
"mediumpurple" => (147, 112, 219),
|
||||
"mediumseagreen" => (60, 179, 113),
|
||||
"mediumslateblue" => (123, 104, 238),
|
||||
"mediumspringgreen" => (0, 250, 154),
|
||||
"mediumturquoise" => (72, 209, 204),
|
||||
"mediumvioletred" => (199, 21, 133),
|
||||
"midnightblue" => (25, 25, 112),
|
||||
"mintcream" => (245, 255, 250),
|
||||
"mistyrose" => (255, 228, 225),
|
||||
"moccasin" => (255, 228, 181),
|
||||
"navajowhite" => (255, 222, 173),
|
||||
"oldlace" => (253, 245, 230),
|
||||
"olivedrab" => (107, 142, 35),
|
||||
"orange" => (255, 165, 0),
|
||||
"orangered" => (255, 69, 0),
|
||||
"orchid" => (218, 112, 214),
|
||||
"palegoldenrod" => (238, 232, 170),
|
||||
"palegreen" => (152, 251, 152),
|
||||
"paleturquoise" => (175, 238, 238),
|
||||
"palevioletred" => (219, 112, 147),
|
||||
"papayawhip" => (255, 239, 213),
|
||||
"peachpuff" => (255, 218, 185),
|
||||
"peru" => (205, 133, 63),
|
||||
"pink" => (255, 192, 203),
|
||||
"plum" => (221, 160, 221),
|
||||
"powderblue" => (176, 224, 230),
|
||||
"rebeccapurple" => (102, 51, 153),
|
||||
"rosybrown" => (188, 143, 143),
|
||||
"royalblue" => (65, 105, 225),
|
||||
"saddlebrown" => (139, 69, 19),
|
||||
"salmon" => (250, 128, 114),
|
||||
"sandybrown" => (244, 164, 96),
|
||||
"seagreen" => (46, 139, 87),
|
||||
"seashell" => (255, 245, 238),
|
||||
"sienna" => (160, 82, 45),
|
||||
"skyblue" => (135, 206, 235),
|
||||
"slateblue" => (106, 90, 205),
|
||||
"slategray" => (112, 128, 144),
|
||||
"slategrey" => (112, 128, 144),
|
||||
"snow" => (255, 250, 250),
|
||||
"springgreen" => (0, 255, 127),
|
||||
"steelblue" => (70, 130, 180),
|
||||
"tan" => (210, 180, 140),
|
||||
"thistle" => (216, 191, 216),
|
||||
"tomato" => (255, 99, 71),
|
||||
"turquoise" => (64, 224, 208),
|
||||
"violet" => (238, 130, 238),
|
||||
"wheat" => (245, 222, 179),
|
||||
"whitesmoke" => (245, 245, 245),
|
||||
"yellowgreen" => (154, 205, 50),
|
||||
}
|
||||
}
|
||||
|
||||
match_ignore_ascii_case! { ident ,
|
||||
"transparent" => Ok(Output::from_rgba(Some(0), Some(0), Some(0), Some(0.0))),
|
||||
"currentcolor" => Ok(Output::from_current_color()),
|
||||
_ => keyword(ident)
|
||||
.map(|(r, g, b)| Output::from_rgba(Some(*r), Some(*g), Some(*b), Some(1.0)))
|
||||
.ok_or(()),
|
||||
}
|
||||
Ok(match_ignore_ascii_case! { ident ,
|
||||
"transparent" => Output::from_rgba(0, 0, 0, 0.0),
|
||||
"currentcolor" => Output::from_current_color(),
|
||||
_ => return parse_named_color(ident),
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1309,47 +1333,50 @@ where
|
|||
// are parsing the legacy syntax.
|
||||
let is_legacy_syntax = maybe_red.is_some() && arguments.try_parse(|p| p.expect_comma()).is_ok();
|
||||
|
||||
let red: Option<u8>;
|
||||
let green: Option<u8>;
|
||||
let blue: Option<u8>;
|
||||
|
||||
let alpha = if is_legacy_syntax {
|
||||
match maybe_red.unwrap() {
|
||||
let (red, green, blue, alpha) = if is_legacy_syntax {
|
||||
let (red, green, blue) = match maybe_red.unwrap() {
|
||||
NumberOrPercentage::Number { value } => {
|
||||
red = Some(clamp_floor_256_f32(value));
|
||||
green = Some(clamp_floor_256_f32(color_parser.parse_number(arguments)?));
|
||||
let red = clamp_floor_256_f32(value);
|
||||
let green = clamp_floor_256_f32(color_parser.parse_number(arguments)?);
|
||||
arguments.expect_comma()?;
|
||||
blue = Some(clamp_floor_256_f32(color_parser.parse_number(arguments)?));
|
||||
let blue = clamp_floor_256_f32(color_parser.parse_number(arguments)?);
|
||||
(red, green, blue)
|
||||
}
|
||||
NumberOrPercentage::Percentage { unit_value } => {
|
||||
red = Some(clamp_unit_f32(unit_value));
|
||||
green = Some(clamp_unit_f32(color_parser.parse_percentage(arguments)?));
|
||||
let red = clamp_unit_f32(unit_value);
|
||||
let green = clamp_unit_f32(color_parser.parse_percentage(arguments)?);
|
||||
arguments.expect_comma()?;
|
||||
blue = Some(clamp_unit_f32(color_parser.parse_percentage(arguments)?));
|
||||
let blue = clamp_unit_f32(color_parser.parse_percentage(arguments)?);
|
||||
(red, green, blue)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Some(parse_legacy_alpha(color_parser, arguments)?)
|
||||
let alpha = parse_legacy_alpha(color_parser, arguments)?;
|
||||
|
||||
(red, green, blue, alpha)
|
||||
} else {
|
||||
#[inline]
|
||||
fn get_component_value(c: Option<NumberOrPercentage>) -> Option<u8> {
|
||||
fn get_component_value(c: Option<NumberOrPercentage>) -> u8 {
|
||||
c.map(|c| match c {
|
||||
NumberOrPercentage::Number { value } => clamp_floor_256_f32(value),
|
||||
NumberOrPercentage::Percentage { unit_value } => clamp_unit_f32(unit_value),
|
||||
})
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
red = get_component_value(maybe_red);
|
||||
let red = get_component_value(maybe_red);
|
||||
|
||||
green = get_component_value(parse_none_or(arguments, |p| {
|
||||
let green = get_component_value(parse_none_or(arguments, |p| {
|
||||
color_parser.parse_number_or_percentage(p)
|
||||
})?);
|
||||
|
||||
blue = get_component_value(parse_none_or(arguments, |p| {
|
||||
let blue = get_component_value(parse_none_or(arguments, |p| {
|
||||
color_parser.parse_number_or_percentage(p)
|
||||
})?);
|
||||
|
||||
parse_modern_alpha(color_parser, arguments)?
|
||||
let alpha = parse_modern_alpha(color_parser, arguments)?.unwrap_or(0.0);
|
||||
|
||||
(red, green, blue, alpha)
|
||||
};
|
||||
|
||||
Ok(P::Output::from_rgba(red, green, blue, alpha))
|
||||
|
@ -1495,7 +1522,7 @@ where
|
|||
P::parse_number_or_percentage,
|
||||
)?;
|
||||
|
||||
let lightness = lightness.map(|l| l.value(lightness_range).max(0.0));
|
||||
let lightness = lightness.map(|l| l.value(lightness_range));
|
||||
let a = a.map(|a| a.value(a_b_range));
|
||||
let b = b.map(|b| b.value(a_b_range));
|
||||
|
||||
|
@ -1521,8 +1548,8 @@ where
|
|||
P::parse_angle_or_number,
|
||||
)?;
|
||||
|
||||
let lightness = lightness.map(|l| l.value(lightness_range).max(0.0));
|
||||
let chroma = chroma.map(|c| c.value(chroma_range).max(0.0));
|
||||
let lightness = lightness.map(|l| l.value(lightness_range));
|
||||
let chroma = chroma.map(|c| c.value(chroma_range));
|
||||
let hue = hue.map(|h| normalize_hue(h.degrees()));
|
||||
|
||||
Ok(into_color(lightness, chroma, hue, alpha))
|
||||
|
@ -1591,3 +1618,45 @@ where
|
|||
|
||||
Ok((r1, r2, r3, alpha))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,9 +68,10 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser)
|
|||
#![recursion_limit = "200"] // For color::parse_color_keyword
|
||||
|
||||
pub use crate::color::{
|
||||
hsl_to_rgb, hwb_to_rgb, parse_color_keyword, parse_color_with, parse_hash_color,
|
||||
serialize_color_alpha, AngleOrNumber, Color, ColorFunction, ColorParser, FromParsedColor, Hsl,
|
||||
Hwb, Lab, Lch, NumberOrPercentage, Oklab, Oklch, PredefinedColorSpace, RGBA,
|
||||
all_named_colors, hsl_to_rgb, hwb_to_rgb, parse_color_keyword, parse_color_with,
|
||||
parse_hash_color, parse_named_color, serialize_color_alpha, AngleOrNumber, Color,
|
||||
ColorFunction, ColorParser, FromParsedColor, Hsl, Hwb, Lab, Lch, NumberOrPercentage, Oklab,
|
||||
Oklch, PredefinedColorSpace, RgbaLegacy,
|
||||
};
|
||||
pub use crate::cow_rc_str::CowRcStr;
|
||||
pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport};
|
||||
|
|
|
@ -76,36 +76,55 @@ macro_rules! match_ignore_ascii_case {
|
|||
///
|
||||
/// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
|
||||
/// cssparser::ascii_case_insensitive_phf_map! {
|
||||
/// keyword -> (u8, u8, u8) = {
|
||||
/// keywords -> (u8, u8, u8) = {
|
||||
/// "red" => (255, 0, 0),
|
||||
/// "green" => (0, 255, 0),
|
||||
/// "blue" => (0, 0, 255),
|
||||
/// }
|
||||
/// }
|
||||
/// keyword(input).cloned()
|
||||
/// keywords::get(input).cloned()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// You can also iterate over the map entries by using `keywords::entries()`.
|
||||
#[macro_export]
|
||||
macro_rules! ascii_case_insensitive_phf_map {
|
||||
($name: ident -> $ValueType: ty = { $( $key: tt => $value: expr ),+ }) => {
|
||||
ascii_case_insensitive_phf_map!($name -> $ValueType = { $( $key => $value, )+ })
|
||||
};
|
||||
($name: ident -> $ValueType: ty = { $( $key: tt => $value: expr, )+ }) => {
|
||||
pub fn $name(input: &str) -> Option<&'static $ValueType> {
|
||||
// This dummy module works around a feature gate,
|
||||
// see comment on the similar module in `match_ignore_ascii_case!` above.
|
||||
mod _cssparser_internal {
|
||||
$crate::_cssparser_internal_max_len! {
|
||||
$( $key )+
|
||||
}
|
||||
use $crate::_cssparser_internal_phf as phf;
|
||||
|
||||
// See macro above for context.
|
||||
mod cssparser_internal {
|
||||
$crate::_cssparser_internal_max_len! {
|
||||
$( $key )+
|
||||
}
|
||||
}
|
||||
|
||||
static MAP: phf::Map<&'static str, $ValueType> = phf::phf_map! {
|
||||
$(
|
||||
$key => $value,
|
||||
)*
|
||||
};
|
||||
|
||||
// While the obvious choice for this would be an inner module, it's not possible to
|
||||
// reference from types from there, see:
|
||||
// <https://github.com/rust-lang/rust/issues/114369>
|
||||
//
|
||||
// So we abuse a struct with static associated functions instead.
|
||||
#[allow(non_camel_case_types)]
|
||||
struct $name;
|
||||
impl $name {
|
||||
#[allow(dead_code)]
|
||||
fn entries() -> impl Iterator<Item = (&'static &'static str, &'static $ValueType)> {
|
||||
MAP.entries()
|
||||
}
|
||||
|
||||
fn get(input: &str) -> Option<&'static $ValueType> {
|
||||
$crate::_cssparser_internal_to_lowercase!(input, cssparser_internal::MAX_LENGTH => lowercase);
|
||||
MAP.get(lowercase?)
|
||||
}
|
||||
use $crate::_cssparser_internal_phf as phf;
|
||||
static MAP: phf::Map<&'static str, $ValueType> = phf::phf_map! {
|
||||
$(
|
||||
$key => $value,
|
||||
)*
|
||||
};
|
||||
$crate::_cssparser_internal_to_lowercase!(input, _cssparser_internal::MAX_LENGTH => lowercase);
|
||||
lowercase.and_then(|s| MAP.get(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ use super::{
|
|||
parse_important, parse_nth, parse_one_declaration, parse_one_rule, stylesheet_encoding,
|
||||
AtRuleParser, BasicParseError, BasicParseErrorKind, Color, CowRcStr, DeclarationParser,
|
||||
Delimiter, EncodingSupport, ParseError, ParseErrorKind, Parser, ParserInput, ParserState,
|
||||
QualifiedRuleParser, RuleBodyItemParser, RuleBodyParser, SourceLocation, StyleSheetParser,
|
||||
ToCss, Token, TokenSerializationType, UnicodeRange, RGBA,
|
||||
QualifiedRuleParser, RgbaLegacy, RuleBodyItemParser, RuleBodyParser, SourceLocation,
|
||||
StyleSheetParser, ToCss, Token, TokenSerializationType, UnicodeRange,
|
||||
};
|
||||
|
||||
macro_rules! JArray {
|
||||
|
@ -373,6 +373,7 @@ fn color3() {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[test]
|
||||
fn color3_hsl() {
|
||||
run_color_tests(include_str!("css-parsing-tests/color3_hsl.json"), |c| {
|
||||
|
@ -395,6 +396,7 @@ fn color3_keywords() {
|
|||
)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[test]
|
||||
fn color4_hwb() {
|
||||
run_color_tests(include_str!("css-parsing-tests/color4_hwb.json"), |c| {
|
||||
|
@ -404,6 +406,7 @@ fn color4_hwb() {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[test]
|
||||
fn color4_lab_lch_oklab_oklch() {
|
||||
run_color_tests(
|
||||
|
@ -592,19 +595,19 @@ fn serialize_current_color() {
|
|||
|
||||
#[test]
|
||||
fn serialize_rgb_full_alpha() {
|
||||
let c = Color::Rgba(RGBA::new(Some(255), Some(230), Some(204), Some(1.0)));
|
||||
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(RGBA::new(Some(26), Some(51), Some(77), Some(0.125)));
|
||||
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(RGBA::from_floats(Some(0.), Some(0.), Some(0.), Some(0.5)));
|
||||
let c = Color::Rgba(RgbaLegacy::from_floats(0., 0., 0., 0.5));
|
||||
assert_eq!(c.to_css_string(), "rgba(0, 0, 0, 0.5)");
|
||||
}
|
||||
|
||||
|
@ -939,6 +942,7 @@ fn unquoted_url(b: &mut Bencher) {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[cfg(feature = "bench")]
|
||||
#[bench]
|
||||
fn numeric(b: &mut Bencher) {
|
||||
|
@ -953,6 +957,7 @@ fn numeric(b: &mut Bencher) {
|
|||
|
||||
struct JsonParser;
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[test]
|
||||
fn no_stack_overflow_multiple_nested_blocks() {
|
||||
let mut input: String = "{{".into();
|
||||
|
@ -1208,8 +1213,8 @@ fn procedural_masquerade_whitespace() {
|
|||
" \t\n" => ()
|
||||
}
|
||||
}
|
||||
assert_eq!(map(" \t\n"), Some(&()));
|
||||
assert_eq!(map(" "), None);
|
||||
assert_eq!(map::get(" \t\n"), Some(&()));
|
||||
assert_eq!(map::get(" "), None);
|
||||
|
||||
match_ignore_ascii_case! { " \t\n",
|
||||
" " => panic!("1"),
|
||||
|
@ -1413,6 +1418,7 @@ fn parse_sourceurl_comments() {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
|
||||
#[test]
|
||||
fn roundtrip_percentage_token() {
|
||||
fn test_roundtrip(value: &str) {
|
||||
|
@ -1526,7 +1532,7 @@ fn generic_parser() {
|
|||
#[derive(Debug, PartialEq)]
|
||||
enum OutputType {
|
||||
CurrentColor,
|
||||
Rgba(Option<u8>, Option<u8>, Option<u8>, Option<f32>),
|
||||
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>),
|
||||
|
@ -1547,12 +1553,7 @@ fn generic_parser() {
|
|||
OutputType::CurrentColor
|
||||
}
|
||||
|
||||
fn from_rgba(
|
||||
red: Option<u8>,
|
||||
green: Option<u8>,
|
||||
blue: Option<u8>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
|
||||
OutputType::Rgba(red, green, blue, alpha)
|
||||
}
|
||||
|
||||
|
@ -1630,10 +1631,10 @@ fn generic_parser() {
|
|||
#[rustfmt::skip]
|
||||
const TESTS: &[(&str, OutputType)] = &[
|
||||
("currentColor", OutputType::CurrentColor),
|
||||
("rgb(1, 2, 3)", OutputType::Rgba(Some(1), Some(2), Some(3), Some(1.0))),
|
||||
("rgba(1, 2, 3, 0.4)", OutputType::Rgba(Some(1), Some(2), Some(3), Some(0.4))),
|
||||
("rgb(none none none / none)", OutputType::Rgba(None, None, None, None)),
|
||||
("rgb(1 none 3 / none)", OutputType::Rgba(Some(1), None, Some(3), None)),
|
||||
("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))),
|
||||
|
|
Загрузка…
Ссылка в новой задаче