Skip to content

Commit

Permalink
Fix flickering on Chrome desktop, and when there is .markedContent
Browse files Browse the repository at this point in the history
This commit removes the existing anti-flickering implementation
for Chrome desktop, and replaces it with the same one used for
mobile. This prevents much more flickering also on desktop.

This commit also ensures that also nested `<span>` elements inside
.textLayer get a `z-index: 1`, while leaving .markedContent elements
at `z-index: 0` (and the `<span>`s they contain will have `z-index: 1`).
In Chrome, .endOfContent can now be moved right after the selected
`<span>` even if it's inside a .markedContent element, removing
flickering over the .markedContent section.
  • Loading branch information
nicolo-ribaudo committed Apr 16, 2024
1 parent 67da5fd commit 0ada3c1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 39 deletions.
8 changes: 4 additions & 4 deletions web/text_layer_builder.css
Expand Up @@ -37,6 +37,10 @@
transform-origin: 0% 0%;
}

span:not(.markedContent) {
z-index: 1;
}

/* Only necessary in Google Chrome, see issue 14205, and most unfortunately
* the problem doesn't show up in "text" reference tests. */
/*#if !MOZCENTRAL*/
Expand Down Expand Up @@ -116,8 +120,4 @@
top: 0;
}
}

> * {
z-index: 1;
}
}
67 changes: 32 additions & 35 deletions web/text_layer_builder.js
Expand Up @@ -193,27 +193,14 @@ class TextLayerBuilder {

div.addEventListener("mousedown", evt => {
selectingThroughMouse = true;

if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
isFirefox ??=
(typeof PDFJSDev === "undefined" || !PDFJSDev.test("CHROME")) &&
getComputedStyle(end).getPropertyValue("-moz-user-select") === "none";
// On non-Firefox browsers, the selection will feel better if the height
// of the `endOfContent` div is adjusted to start at mouse click
// location. This avoids flickering when the selection moves up.
// However it does not work when selection is started on empty space.
if (!isFirefox && evt.target !== div) {
const divBounds = div.getBoundingClientRect();
const r = Math.max(0, (evt.pageY - divBounds.top) / divBounds.height);
end.style.top = (r * 100).toFixed(2) + "%";
}
}
end.classList.add("active");
});

const reset = () => {
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
end.style.top = "";
div.append(end);
end.style.width = "";
end.style.height = "";
}
end.classList.remove("active");
selectingThroughMouse = false;
Expand Down Expand Up @@ -242,7 +229,16 @@ class TextLayerBuilder {
document.addEventListener(
"selectionchange",
() => {
if (selectingThroughMouse) {
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
isFirefox ??=
(typeof PDFJSDev === "undefined" || !PDFJSDev.test("CHROME")) &&
getComputedStyle(end).getPropertyValue("-moz-user-select") ===
"none";

if (isFirefox && selectingThroughMouse) {
return;
}
} else if (selectingThroughMouse) {
return;
}

Expand All @@ -259,17 +255,13 @@ class TextLayerBuilder {
}

if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
isFirefox ??=
(typeof PDFJSDev === "undefined" || !PDFJSDev.test("CHROME")) &&
getComputedStyle(end).getPropertyValue("-moz-user-select") ===
"none";
// In non-Firefox browsers, when hovering over an empty space (thus, on
// .endOfContent), the selection will expand to cover all the text
// In non-Firefox browsers, when hovering over an empty space (thus,
// on .endOfContent), the selection will expand to cover all the text
// between the current selection and .endOfContent. By moving
// .endOfContent to right after (or before, depending on which side of
// the selection the user is moving), we limit the selection jump to at
// most cover the enteirety of the <span> where the selection is being
// modified.
// .endOfContent to right after (or before, depending on which side
// of the selection the user is moving), we limit the selection jump
// to at most cover the enteirety of the <span> where the selection
// is being modified.
if (!isFirefox) {
const modifyStart =
prevRange &&
Expand All @@ -282,20 +274,25 @@ class TextLayerBuilder {
if (anchor.nodeType === Node.TEXT_NODE) {
anchor = anchor.parentNode;
}
// Make sure that we are always only moving .endOfContent to somewhere
// directly in .textLayer, and not inside nested spans.
anchor = anchor.closest(".textLayer > span");
anchor.parentElement.insertBefore(
end,
modifyStart ? anchor : anchor.nextSibling
);
// Make sure that we are only moving .endOfContent to somewhere
// inside this .textLayer, in case of multi-page selections.
const parentTextLayer = anchor.parentElement.closest(".textLayer");
if (parentTextLayer === div) {
end.style.width = div.style.width;
end.style.height = div.style.height;
anchor.parentElement.insertBefore(
end,
modifyStart ? anchor : anchor.nextSibling
);
}

prevRange = range.cloneRange();
}
}

end.classList.add("active");
},
this.#selectionChangeAbortController
{ signal: this.#selectionChangeAbortController.signal }
);

div.addEventListener("copy", event => {
Expand Down

0 comments on commit 0ada3c1

Please sign in to comment.