Skip to content

Commit 62c25ea

Browse files
committed
Make the caret visible in the text layer in caret browsing mode
In order to do that we must change the text layer opacity to 1 but it has several implications: - the selection color must have an alpha component, - the background color of the span used for highlighted words must have an alpha component either, but now the opacity is 1 we can use some backdrop-filters in HCM making the highlighted words more visible. - fix a regression caused by mozilla#17196: the css variable --hcm-highlight-filter has to live under the #viewer element because in HCM it's overwritten by js at this level, hence links annotations for example didn't have the right colors when hovered.
1 parent 1cdbcfe commit 62c25ea

7 files changed

+97
-42
lines changed

src/display/base_factory.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class BaseFilterFactory {
3030
return "none";
3131
}
3232

33-
addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) {
33+
addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgColor) {
3434
return "none";
3535
}
3636

src/display/display_utils.js

+50-33
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,7 @@ class DOMFilterFactory extends BaseFilterFactory {
5757

5858
#document;
5959

60-
#hcmFilter;
61-
62-
#hcmKey;
63-
64-
#hcmUrl;
65-
66-
#hcmHighlightFilter;
67-
68-
#hcmHighlightKey;
69-
70-
#hcmHighlightUrl;
60+
#_hcmCache;
7161

7262
#id = 0;
7363

@@ -81,6 +71,10 @@ class DOMFilterFactory extends BaseFilterFactory {
8171
return (this.#_cache ||= new Map());
8272
}
8373

74+
get #hcmCache() {
75+
return (this.#_hcmCache ||= new Map());
76+
}
77+
8478
get #defs() {
8579
if (!this.#_defs) {
8680
const div = this.#document.createElement("div");
@@ -161,16 +155,28 @@ class DOMFilterFactory extends BaseFilterFactory {
161155

162156
addHCMFilter(fgColor, bgColor) {
163157
const key = `${fgColor}-${bgColor}`;
164-
if (this.#hcmKey === key) {
165-
return this.#hcmUrl;
158+
const filterName = "base";
159+
let info = this.#hcmCache.get(filterName);
160+
if (info?.key === key) {
161+
return info.url;
166162
}
167163

168-
this.#hcmKey = key;
169-
this.#hcmUrl = "none";
170-
this.#hcmFilter?.remove();
164+
if (info) {
165+
info.filter?.remove();
166+
info.key = key;
167+
info.url = "none";
168+
info.filter = null;
169+
} else {
170+
info = {
171+
key,
172+
url: "none",
173+
filter: null,
174+
};
175+
this.#hcmCache.set(filterName, info);
176+
}
171177

172178
if (!fgColor || !bgColor) {
173-
return this.#hcmUrl;
179+
return info.url;
174180
}
175181

176182
const fgRGB = this.#getRGB(fgColor);
@@ -183,7 +189,7 @@ class DOMFilterFactory extends BaseFilterFactory {
183189
(fgColor === "#000000" && bgColor === "#ffffff") ||
184190
fgColor === bgColor
185191
) {
186-
return this.#hcmUrl;
192+
return info.url;
187193
}
188194

189195
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_Colors_and_Luminance
@@ -203,7 +209,7 @@ class DOMFilterFactory extends BaseFilterFactory {
203209
const table = map.join(",");
204210

205211
const id = `g_${this.#docId}_hcm_filter`;
206-
const filter = (this.#hcmHighlightFilter = this.#createFilter(id));
212+
const filter = (info.filter = this.#createFilter(id));
207213
this.#addTransferMapConversion(table, table, table, filter);
208214
this.#addGrayConversion(filter);
209215

@@ -223,22 +229,33 @@ class DOMFilterFactory extends BaseFilterFactory {
223229
filter
224230
);
225231

226-
this.#hcmUrl = `url(#${id})`;
227-
return this.#hcmUrl;
232+
info.url = `url(#${id})`;
233+
return info.url;
228234
}
229235

230-
addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) {
236+
addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgColor) {
231237
const key = `${fgColor}-${bgColor}-${newFgColor}-${newBgColor}`;
232-
if (this.#hcmHighlightKey === key) {
233-
return this.#hcmHighlightUrl;
238+
let info = this.#hcmCache.get(filterName);
239+
if (info?.key === key) {
240+
return info.url;
234241
}
235242

236-
this.#hcmHighlightKey = key;
237-
this.#hcmHighlightUrl = "none";
238-
this.#hcmHighlightFilter?.remove();
243+
if (info) {
244+
info.filter?.remove();
245+
info.key = key;
246+
info.url = "none";
247+
info.filter = null;
248+
} else {
249+
info = {
250+
key,
251+
url: "none",
252+
filter: null,
253+
};
254+
this.#hcmCache.set(filterName, info);
255+
}
239256

240257
if (!fgColor || !bgColor) {
241-
return this.#hcmHighlightUrl;
258+
return info.url;
242259
}
243260

244261
const [fgRGB, bgRGB] = [fgColor, bgColor].map(this.#getRGB.bind(this));
@@ -294,8 +311,8 @@ class DOMFilterFactory extends BaseFilterFactory {
294311
return arr.join(",");
295312
};
296313

297-
const id = `g_${this.#docId}_hcm_highlight_filter`;
298-
const filter = (this.#hcmHighlightFilter = this.#createFilter(id));
314+
const id = `g_${this.#docId}_hcm_${filterName}_filter`;
315+
const filter = (info.filter = this.#createFilter(id));
299316

300317
this.#addGrayConversion(filter);
301318
this.#addTransferMapConversion(
@@ -305,12 +322,12 @@ class DOMFilterFactory extends BaseFilterFactory {
305322
filter
306323
);
307324

308-
this.#hcmHighlightUrl = `url(#${id})`;
309-
return this.#hcmHighlightUrl;
325+
info.url = `url(#${id})`;
326+
return info.url;
310327
}
311328

312329
destroy(keepHCM = false) {
313-
if (keepHCM && (this.#hcmUrl || this.#hcmHighlightUrl)) {
330+
if (keepHCM && this.#hcmCache.size !== 0) {
314331
return;
315332
}
316333
if (this.#_defs) {

web/annotation_layer_builder.css

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
--input-disabled-border-color: GrayText;
2929
--input-hover-border-color: Highlight;
3030
--link-outline: 1.5px solid LinkText;
31-
--hcm-highlight-filter: invert(100%);
3231

3332
.textWidgetAnnotation :is(input, textarea):required,
3433
.choiceWidgetAnnotation select:required,

web/pdf_page_view.js

+11
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,17 @@ class PDFPageView {
284284
this._container?.style.setProperty(
285285
"--hcm-highlight-filter",
286286
pdfPage.filterFactory.addHighlightHCMFilter(
287+
"highlight",
288+
"CanvasText",
289+
"Canvas",
290+
"HighlightText",
291+
"Highlight"
292+
)
293+
);
294+
this._container?.style.setProperty(
295+
"--hcm-highlight-selected-filter",
296+
pdfPage.filterFactory.addHighlightHCMFilter(
297+
"highlight_selected",
287298
"CanvasText",
288299
"Canvas",
289300
"HighlightText",

web/pdf_viewer.css

+7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@
3636
}
3737
}
3838

39+
#viewer {
40+
--hcm-highlight-filter: none;
41+
@media screen and (forced-colors: active) {
42+
--hcm-highlight-filter: invert(100%);
43+
}
44+
}
45+
3946
[data-main-rotation="90"] {
4047
transform: rotate(90deg) translateY(-100%);
4148
}

web/pdf_viewer.js

+11
Original file line numberDiff line numberDiff line change
@@ -884,12 +884,23 @@ class PDFViewer {
884884
this.viewer.style.setProperty(
885885
"--hcm-highlight-filter",
886886
pdfDocument.filterFactory.addHighlightHCMFilter(
887+
"highlight",
887888
"CanvasText",
888889
"Canvas",
889890
"HighlightText",
890891
"Highlight"
891892
)
892893
);
894+
this.viewer.style.setProperty(
895+
"--hcm-highlight-selected-filter",
896+
pdfDocument.filterFactory.addHighlightHCMFilter(
897+
"highlight_selected",
898+
"CanvasText",
899+
"Canvas",
900+
"HighlightText",
901+
"ButtonText"
902+
)
903+
);
893904
}
894905

895906
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {

web/text_layer_builder.css

+17-7
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@
1818
text-align: initial;
1919
inset: 0;
2020
overflow: hidden;
21-
opacity: 0.25;
21+
opacity: 1;
2222
line-height: 1;
2323
text-size-adjust: none;
2424
forced-color-adjust: none;
2525
transform-origin: 0 0;
2626
z-index: 2;
27+
caret-color: CanvasText;
2728

2829
&.drawing {
2930
touch-action: none;
@@ -47,17 +48,24 @@
4748
/*#endif*/
4849

4950
.highlight {
50-
--highlight-bg-color: rgb(180 0 170);
51-
--highlight-selected-bg-color: rgb(0 100 0);
51+
--highlight-bg-color: rgb(180 0 170 / 0.25);
52+
--highlight-selected-bg-color: rgb(0 100 0 / 0.25);
53+
--highlight-backdrop-filter: none;
54+
--highlight-selected-backdrop-filter: none;
5255

5356
@media screen and (forced-colors: active) {
54-
--highlight-bg-color: Highlight;
55-
--highlight-selected-bg-color: ButtonText;
57+
--highlight-bg-color: transparent;
58+
--highlight-selected-bg-color: transparent;
59+
--highlight-backdrop-filter: var(--hcm-highlight-filter);
60+
--highlight-selected-backdrop-filter: var(
61+
--hcm-highlight-selected-filter
62+
);
5663
}
5764

5865
margin: -1px;
5966
padding: 1px;
6067
background-color: var(--highlight-bg-color);
68+
backdrop-filter: var(--highlight-backdrop-filter);
6169
border-radius: 4px;
6270

6371
&.appended {
@@ -78,14 +86,16 @@
7886

7987
&.selected {
8088
background-color: var(--highlight-selected-bg-color);
89+
backdrop-filter: var(--highlight-selected-backdrop-filter);
8190
}
8291
}
8392

8493
::selection {
8594
/*#if !MOZCENTRAL*/
86-
background: blue;
95+
background: rgba(0 0 255 / 0.25);
8796
/*#endif*/
88-
background: AccentColor; /* stylelint-disable-line declaration-block-no-duplicate-properties */
97+
/* stylelint-disable-next-line declaration-block-no-duplicate-properties */
98+
background: color-mix(in srgb, AccentColor, transparent 75%);
8999
}
90100

91101
/* Avoids https://github.com/mozilla/pdf.js/issues/13840 in Chrome */

0 commit comments

Comments
 (0)