Bug 2048531 - Improve selection contrast in dark mode

On some OSes, the current approach of using `Highlight`/`HighlightText`
colors to draw selected text doesn't work when the OS is set to dark
mode, as we revert the `color-scheme` to `light` to compute them
(because PDFs are normally in light mode) but that does not affect the
`HighlightText` color (which depends not on the `color-scheme` but on
the `currentColor`).

Other than forcing the `color-scheme` to `light`, set the `color` to
`black` and use the `backgroud-color` to compute the `HighlightText`
color instead.

In OSes where `HighlightText` is theme-dependent this will result in the
OS-provided text color, while in OSes where it is `currentColor`-dependent
it will be based on the default color for light themes (i.e. black).
This commit is contained in:
Nicolò Ribaudo 2026-07-09 12:07:39 +02:00
parent 8bc2fe68e5
commit 199d738917
No known key found for this signature in database
GPG Key ID: AAFDA9101C58F338

View File

@ -259,7 +259,7 @@ class DOMFilterFactory extends BaseFilterFactory {
fgColor = Util.makeHexColor(...fgRGB); fgColor = Util.makeHexColor(...fgRGB);
const bgRGB = this.#getRGB(bgColor); const bgRGB = this.#getRGB(bgColor);
bgColor = Util.makeHexColor(...bgRGB); bgColor = Util.makeHexColor(...bgRGB);
this.#defs.style.color = ""; this.#resetDefsColor();
if ( if (
(fgColor === "#000000" && bgColor === "#ffffff") || (fgColor === "#000000" && bgColor === "#ffffff") ||
@ -507,7 +507,7 @@ class DOMFilterFactory extends BaseFilterFactory {
newFgRGB, newFgRGB,
]; ];
} }
this.#defs.style.color = ""; this.#resetDefsColor();
// Now we can create the filters to highlight some canvas parts. // Now we can create the filters to highlight some canvas parts.
// The colors in the pdf will almost be Canvas and CanvasText, hence we // The colors in the pdf will almost be Canvas and CanvasText, hence we
@ -635,13 +635,8 @@ class DOMFilterFactory extends BaseFilterFactory {
this.#appendFeFunc(feComponentTransfer, "feFuncA", aTable); this.#appendFeFunc(feComponentTransfer, "feFuncA", aTable);
} }
#getRGB(color) {
this.#defs.style.color = color;
return getRGB(getComputedStyle(this.#defs).getPropertyValue("color"));
}
/** /**
* Get the RGBA channels of a color. * Get the RGB channels of a color.
* *
* @param {string} color * @param {string} color
* Color in any valid CSS format (such as `x` in `color: x`). * Color in any valid CSS format (such as `x` in `color: x`).
@ -650,9 +645,31 @@ class DOMFilterFactory extends BaseFilterFactory {
* the RGB channels are in the range `[0, 255]`; * the RGB channels are in the range `[0, 255]`;
* the alpha channel is in the range `[0, 1]`. * the alpha channel is in the range `[0, 1]`.
*/ */
#getRGB(color) {
// Some colors on some OSes (e.g. HighlightText in Firefox on macOS)
// are affected by the current text color. Ensure consistent behavior by
// setting it to CanvasText.
this.#defs.style.color = "CanvasText";
this.#defs.style.backgroundColor = color;
return getRGB(
getComputedStyle(this.#defs).getPropertyValue("background-color")
);
}
#getRGBA(color) { #getRGBA(color) {
this.#defs.style.color = color; // Some colors on some OSes (e.g. HighlightText in Firefox on macOS)
return getRGBA(getComputedStyle(this.#defs).getPropertyValue("color")); // are affected by the current text color. Ensure consistent behavior by
// setting it to CanvasText.
this.#defs.style.color = "CanvasText";
this.#defs.style.backgroundColor = color;
return getRGBA(
getComputedStyle(this.#defs).getPropertyValue("background-color")
);
}
#resetDefsColor() {
this.#defs.style.color = "";
this.#defs.style.backgroundColor = "";
} }
/** /**