tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 557d0a01bb2823242b71b265fbe2ee4f269817f4
parent a370a87a48baa8be994f40b7eb2e6281765e0ef8
Author: Kiril Panayotov <contact@zakrok.dev>
Date:   Mon,  8 Dec 2025 12:43:42 +0000

Bug 2001615 - Fix carry forward to not override flags from conversion. r=tlouw,emilio,firefox-style-system-reviewers

The bug occurs because any flags about missing components, generated during conversion of the colour (e.g. HSL->OKLCH it can produce a powerless hue) within  are overridden by the source colour's flags.
The change is to make it instead by a disjunction of the source color flag and the flag of the color itself.

Differential Revision: https://phabricator.services.mozilla.com/D275400

Diffstat:
Mservo/components/style/color/mix.rs | 38++++++++++++++++++--------------------
Mtesting/web-platform/tests/css/css-color/parsing/color-computed-color-mix-function.html | 3+++
2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/servo/components/style/color/mix.rs b/servo/components/style/color/mix.rs @@ -252,43 +252,43 @@ impl AbsoluteColor { // Lightness L if matches!(source.color_space, S::Lab | S::Lch | S::Oklab | S::Oklch) { if matches!(self.color_space, S::Lab | S::Lch | S::Oklab | S::Oklch) { - self.flags - .set(F::C0_IS_NONE, source.flags.contains(F::C0_IS_NONE)); + self.flags |= source.flags & F::C0_IS_NONE; } else if matches!(self.color_space, S::Hsl) { - self.flags - .set(F::C2_IS_NONE, source.flags.contains(F::C0_IS_NONE)); + if source.flags.contains(F::C0_IS_NONE) { + self.flags.insert(F::C2_IS_NONE) + } } } else if matches!(source.color_space, S::Hsl) && matches!(self.color_space, S::Lab | S::Lch | S::Oklab | S::Oklch) { - self.flags - .set(F::C0_IS_NONE, source.flags.contains(F::C2_IS_NONE)); + if source.flags.contains(F::C2_IS_NONE) { + self.flags.insert(F::C0_IS_NONE) + } } // Colorfulness C, S if matches!(source.color_space, S::Hsl | S::Lch | S::Oklch) && matches!(self.color_space, S::Hsl | S::Lch | S::Oklch) { - self.flags - .set(F::C1_IS_NONE, source.flags.contains(F::C1_IS_NONE)); + self.flags |= source.flags & F::C1_IS_NONE; } // Hue H if matches!(source.color_space, S::Hsl | S::Hwb) { if matches!(self.color_space, S::Hsl | S::Hwb) { - self.flags - .set(F::C0_IS_NONE, source.flags.contains(F::C0_IS_NONE)); + self.flags |= source.flags & F::C0_IS_NONE; } else if matches!(self.color_space, S::Lch | S::Oklch) { - self.flags - .set(F::C2_IS_NONE, source.flags.contains(F::C0_IS_NONE)); + if source.flags.contains(F::C0_IS_NONE) { + self.flags.insert(F::C2_IS_NONE) + } } } else if matches!(source.color_space, S::Lch | S::Oklch) { if matches!(self.color_space, S::Hsl | S::Hwb) { - self.flags - .set(F::C0_IS_NONE, source.flags.contains(F::C2_IS_NONE)); + if source.flags.contains(F::C2_IS_NONE) { + self.flags.insert(F::C0_IS_NONE) + } } else if matches!(self.color_space, S::Lch | S::Oklch) { - self.flags - .set(F::C2_IS_NONE, source.flags.contains(F::C2_IS_NONE)); + self.flags |= source.flags & F::C2_IS_NONE; } } @@ -297,10 +297,8 @@ impl AbsoluteColor { if matches!(source.color_space, S::Lab | S::Oklab) && matches!(self.color_space, S::Lab | S::Oklab) { - self.flags - .set(F::C1_IS_NONE, source.flags.contains(F::C1_IS_NONE)); - self.flags - .set(F::C2_IS_NONE, source.flags.contains(F::C2_IS_NONE)); + self.flags |= source.flags & F::C1_IS_NONE; + self.flags |= source.flags & F::C2_IS_NONE; } } } diff --git a/testing/web-platform/tests/css/css-color/parsing/color-computed-color-mix-function.html b/testing/web-platform/tests/css/css-color/parsing/color-computed-color-mix-function.html @@ -568,6 +568,9 @@ // Percent with calc that uses font-relative length. fuzzy_test_computed_color(`color-mix(in srgb, red calc(50% + (sign(100em - 1px) * 10%)), blue)`, `color(srgb 0.6 0 0.4)`); + + // Carry forward hue that became powerless due to conversion of colorspace + fuzzy_test_computed_color(`color-mix(in oklch, hsl(0 100% 100%), blue)`, `oklch(0.726007 0.156607 264.052)`); </script> </body> </html>