Skip to content

Commit 643a008

Browse files
committed
Revert "Revert "Support number or percentage in lab, lch, oklab, and oklch colors""
This reverts commit 81cd955.
1 parent 8a61b16 commit 643a008

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13534,6 +13534,14 @@ mod tests {
1353413534
".foo { color: lab(29.2345% 39.3825 20.0664); }",
1353513535
".foo{color:lab(29.2345% 39.3825 20.0664)}",
1353613536
);
13537+
minify_test(
13538+
".foo { color: lab(29.2345 39.3825 20.0664); }",
13539+
".foo{color:lab(29.2345% 39.3825 20.0664)}",
13540+
);
13541+
minify_test(
13542+
".foo { color: lab(29.2345% 39.3825% 20.0664%); }",
13543+
".foo{color:lab(29.2345% 49.2281 25.083)}",
13544+
);
1353713545
minify_test(
1353813546
".foo { color: lab(29.2345% 39.3825 20.0664 / 100%); }",
1353913547
".foo{color:lab(29.2345% 39.3825 20.0664)}",
@@ -13546,6 +13554,14 @@ mod tests {
1354613554
".foo { color: lch(29.2345% 44.2 27); }",
1354713555
".foo{color:lch(29.2345% 44.2 27)}",
1354813556
);
13557+
minify_test(
13558+
".foo { color: lch(29.2345 44.2 27); }",
13559+
".foo{color:lch(29.2345% 44.2 27)}",
13560+
);
13561+
minify_test(
13562+
".foo { color: lch(29.2345% 44.2% 27deg); }",
13563+
".foo{color:lch(29.2345% 66.3 27)}",
13564+
);
1354913565
minify_test(
1355013566
".foo { color: lch(29.2345% 44.2 45deg); }",
1355113567
".foo{color:lch(29.2345% 44.2 45)}",
@@ -13566,10 +13582,26 @@ mod tests {
1356613582
".foo { color: oklab(40.101% 0.1147 0.0453); }",
1356713583
".foo{color:oklab(40.101% .1147 .0453)}",
1356813584
);
13585+
minify_test(
13586+
".foo { color: oklab(.40101 0.1147 0.0453); }",
13587+
".foo{color:oklab(40.101% .1147 .0453)}",
13588+
);
13589+
minify_test(
13590+
".foo { color: oklab(40.101% 0.1147% 0.0453%); }",
13591+
".foo{color:oklab(40.101% .0004588 .0001812)}",
13592+
);
1356913593
minify_test(
1357013594
".foo { color: oklch(40.101% 0.12332 21.555); }",
1357113595
".foo{color:oklch(40.101% .12332 21.555)}",
1357213596
);
13597+
minify_test(
13598+
".foo { color: oklch(.40101 0.12332 21.555); }",
13599+
".foo{color:oklch(40.101% .12332 21.555)}",
13600+
);
13601+
minify_test(
13602+
".foo { color: oklch(40.101% 0.12332% 21.555); }",
13603+
".foo{color:oklch(40.101% .00049328 21.555)}",
13604+
);
1357313605
minify_test(
1357413606
".foo { color: oklch(40.101% 0.12332 .5turn); }",
1357513607
".foo{color:oklch(40.101% .12332 180)}",

src/values/color.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@ impl ToCss for CssColor {
487487
Ok(())
488488
}
489489
CssColor::LAB(lab) => match &**lab {
490-
LABColor::LAB(lab) => write_components("lab", lab.l, lab.a, lab.b, lab.alpha, dest),
491-
LABColor::LCH(lch) => write_components("lch", lch.l, lch.c, lch.h, lch.alpha, dest),
490+
LABColor::LAB(lab) => write_components("lab", lab.l / 100.0, lab.a, lab.b, lab.alpha, dest),
491+
LABColor::LCH(lch) => write_components("lch", lch.l / 100.0, lch.c, lch.h, lch.alpha, dest),
492492
LABColor::OKLAB(lab) => write_components("oklab", lab.l, lab.a, lab.b, lab.alpha, dest),
493493
LABColor::OKLCH(lch) => write_components("oklch", lch.l, lch.c, lch.h, lch.alpha, dest),
494494
},
@@ -828,22 +828,22 @@ fn parse_color_function<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor,
828828

829829
match_ignore_ascii_case! {&*function,
830830
"lab" => {
831-
let (l, a, b, alpha) = parse_lab::<LAB>(input, &mut parser)?;
831+
let (l, a, b, alpha) = parse_lab::<LAB>(input, &mut parser, 100.0, 125.0)?;
832832
let lab = LABColor::LAB(LAB { l, a, b, alpha });
833833
Ok(CssColor::LAB(Box::new(lab)))
834834
},
835835
"oklab" => {
836-
let (l, a, b, alpha) = parse_lab::<OKLAB>(input, &mut parser)?;
836+
let (l, a, b, alpha) = parse_lab::<OKLAB>(input, &mut parser, 1.0, 0.4)?;
837837
let lab = LABColor::OKLAB(OKLAB { l, a, b, alpha });
838838
Ok(CssColor::LAB(Box::new(lab)))
839839
},
840840
"lch" => {
841-
let (l, c, h, alpha) = parse_lch::<LCH>(input, &mut parser)?;
841+
let (l, c, h, alpha) = parse_lch::<LCH>(input, &mut parser, 100.0, 150.0)?;
842842
let lab = LABColor::LCH(LCH { l, c, h, alpha });
843843
Ok(CssColor::LAB(Box::new(lab)))
844844
},
845845
"oklch" => {
846-
let (l, c, h, alpha) = parse_lch::<OKLCH>(input, &mut parser)?;
846+
let (l, c, h, alpha) = parse_lch::<OKLCH>(input, &mut parser, 1.0, 0.4)?;
847847
let lab = LABColor::OKLCH(OKLCH { l, c, h, alpha });
848848
Ok(CssColor::LAB(Box::new(lab)))
849849
},
@@ -877,15 +877,17 @@ fn parse_color_function<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CssColor,
877877
fn parse_lab<'i, 't, T: From<CssColor> + ColorSpace>(
878878
input: &mut Parser<'i, 't>,
879879
parser: &mut ComponentParser,
880+
l_basis: f32,
881+
ab_basis: f32,
880882
) -> Result<(f32, f32, f32, f32), ParseError<'i, ParserError<'i>>> {
881883
// https://www.w3.org/TR/css-color-4/#funcdef-lab
882884
let res = input.parse_nested_block(|input| {
883885
parser.parse_relative::<T>(input)?;
884886

885887
// f32::max() does not propagate NaN, so use clamp for now until f32::maximum() is stable.
886-
let l = parser.parse_percentage(input)?.clamp(0.0, f32::MAX);
887-
let a = parser.parse_number(input)?;
888-
let b = parser.parse_number(input)?;
888+
let l = parse_number_or_percentage(input, parser, l_basis)?.clamp(0.0, f32::MAX);
889+
let a = parse_number_or_percentage(input, parser, ab_basis)?;
890+
let b = parse_number_or_percentage(input, parser, ab_basis)?;
889891
let alpha = parse_alpha(input, parser)?;
890892

891893
Ok((l, a, b, alpha))
@@ -899,6 +901,8 @@ fn parse_lab<'i, 't, T: From<CssColor> + ColorSpace>(
899901
fn parse_lch<'i, 't, T: From<CssColor> + ColorSpace>(
900902
input: &mut Parser<'i, 't>,
901903
parser: &mut ComponentParser,
904+
l_basis: f32,
905+
c_basis: f32,
902906
) -> Result<(f32, f32, f32, f32), ParseError<'i, ParserError<'i>>> {
903907
// https://www.w3.org/TR/css-color-4/#funcdef-lch
904908
let res = input.parse_nested_block(|input| {
@@ -912,8 +916,8 @@ fn parse_lch<'i, 't, T: From<CssColor> + ColorSpace>(
912916
}
913917
}
914918

915-
let l = parser.parse_percentage(input)?.clamp(0.0, f32::MAX);
916-
let c = parser.parse_number(input)?.clamp(0.0, f32::MAX);
919+
let l = parse_number_or_percentage(input, parser, l_basis)?.clamp(0.0, f32::MAX);
920+
let c = parse_number_or_percentage(input, parser, c_basis)?.clamp(0.0, f32::MAX);
917921
let h = parse_angle_or_number(input, parser)?;
918922
let alpha = parse_alpha(input, parser)?;
919923

@@ -958,13 +962,13 @@ fn parse_predefined<'i, 't>(
958962
// Out of gamut values should not be clamped, i.e. values < 0 or > 1 should be preserved.
959963
// The browser will gamut-map the color for the target device that it is rendered on.
960964
let a = input
961-
.try_parse(|input| parse_number_or_percentage(input, parser))
965+
.try_parse(|input| parse_number_or_percentage(input, parser, 1.0))
962966
.unwrap_or(0.0);
963967
let b = input
964-
.try_parse(|input| parse_number_or_percentage(input, parser))
968+
.try_parse(|input| parse_number_or_percentage(input, parser, 1.0))
965969
.unwrap_or(0.0);
966970
let c = input
967-
.try_parse(|input| parse_number_or_percentage(input, parser))
971+
.try_parse(|input| parse_number_or_percentage(input, parser, 1.0))
968972
.unwrap_or(0.0);
969973
let alpha = parse_alpha(input, parser)?;
970974

@@ -1090,10 +1094,11 @@ fn parse_angle_or_number<'i, 't>(
10901094
fn parse_number_or_percentage<'i, 't>(
10911095
input: &mut Parser<'i, 't>,
10921096
parser: &ComponentParser,
1097+
percent_basis: f32,
10931098
) -> Result<f32, ParseError<'i, ParserError<'i>>> {
10941099
Ok(match parser.parse_number_or_percentage(input)? {
10951100
NumberOrPercentage::Number { value } => value,
1096-
NumberOrPercentage::Percentage { unit_value } => unit_value,
1101+
NumberOrPercentage::Percentage { unit_value } => unit_value * percent_basis,
10971102
})
10981103
}
10991104

@@ -1103,7 +1108,7 @@ fn parse_alpha<'i, 't>(
11031108
parser: &ComponentParser,
11041109
) -> Result<f32, ParseError<'i, ParserError<'i>>> {
11051110
let res = if input.try_parse(|input| input.expect_delim('/')).is_ok() {
1106-
parse_number_or_percentage(input, parser)?.clamp(0.0, 1.0)
1111+
parse_number_or_percentage(input, parser, 1.0)?.clamp(0.0, 1.0)
11071112
} else {
11081113
1.0
11091114
};
@@ -1127,6 +1132,7 @@ where
11271132
if a.is_nan() {
11281133
dest.write_str("none")?;
11291134
} else {
1135+
// Safari 15 only supports percentages.
11301136
Percentage(a).to_css(dest)?;
11311137
}
11321138
dest.write_char(' ')?;
@@ -1567,7 +1573,7 @@ impl From<LAB> for XYZd50 {
15671573
const E: f32 = 216.0 / 24389.0; // 6^3/29^3
15681574

15691575
let lab = lab.resolve_missing();
1570-
let l = lab.l * 100.0;
1576+
let l = lab.l;
15711577
let a = lab.a;
15721578
let b = lab.b;
15731579

@@ -1826,7 +1832,7 @@ impl From<XYZd50> for LAB {
18261832

18271833
let f2 = if z > E { z.cbrt() } else { (K * z + 16.0) / 116.0 };
18281834

1829-
let l = ((116.0 * f1) - 16.0) / 100.0;
1835+
let l = (116.0 * f1) - 16.0;
18301836
let a = 500.0 * (f0 - f1);
18311837
let b = 200.0 * (f1 - f2);
18321838
LAB {

0 commit comments

Comments
 (0)