-
Notifications
You must be signed in to change notification settings - Fork 10.3k
[chrome] Fix text selection with .markedContent
#19785
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[chrome] Fix text selection with .markedContent
#19785
Conversation
fbbbd7d
to
0a1a5b3
Compare
The current text layer approach based on absolutely positioned `<span>` elements by default causes flickering with text selection, and we have browser-specific workarounds to solve that. In Chrome, the workaround involves moving the `.endOfContent` element to right after the last element that contains some selected content. This works well in simple PDFs, but breaks when we have `span.markedContent` elements. Given a text layer structure like the following, rendered as four consecutive lines: ```html <span class="markedContent"> <br> <span>development enter the construction phase (estimated at around</span> </span> <span class="markedContent"> <br> <span>300 MEUR).</span> </span> <span class="markedContent"> <br> <span>Kreate's EBITA increased to 2.8 MEUR (Q4'23: 2.7 MEUR) and the</span> </span> <span class="markedContent"> <br> <span>margin rose to 3.7% (Q4'23: 3.4%). However, profitability was</span> </span> ``` when starting to select from inside the first line and dragging down to the empty space after the second line, Chrome will anchor the selection at the beginning of either the `<br>` or the `<span>` inside the last `.markedContent`, depending on whether the selection is in "per-character mode" (i.e. click and drag) or "per-word mode" (i.e. double click and drag). This causes us to insert the `.endOfContent` element in the wrong place (one element too far), which causes one more line to be selected, which triggers another `"selecctionchange"` event, which causes us to move `.endOfContent` again, and so on, looping until when the whole page is selected. This commit fixes the issue by making sure that when the end of the selection range points to the _begining_ of an element, we walk back the dom finding the first non-empty element, and attatch `.endOfContent` to the end of that.
0a1a5b3
to
da5b681
Compare
/botio integrationtest |
From: Bot.io (Windows)ReceivedCommand cmd_integrationtest from @nicolo-ribaudo received. Current queue size: 0 Live output at: http://54.193.163.58:8877/04bc98056e78896/output.txt |
From: Bot.io (Linux m4)ReceivedCommand cmd_integrationtest from @nicolo-ribaudo received. Current queue size: 0 Live output at: http://54.241.84.105:8877/6fb4259009665dd/output.txt |
From: Bot.io (Linux m4)SuccessFull output at http://54.241.84.105:8877/6fb4259009665dd/output.txt Total script time: 12.39 mins
|
From: Bot.io (Windows)FailedFull output at http://54.193.163.58:8877/04bc98056e78896/output.txt Total script time: 31.09 mins
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=me, thank you.
Commit message:
Note that this PR only touches Chrome-specific code. It's stripped away in MOZCENTRAL builds, and it is behind feature detection in GENERIC builds. Firefox already passes the new tests.
The test PDF is the second page of https://www.inderes.fi/files/42dd9cb4-1021-4f9a-ae29-cfb10ee7529c. This is the video of the current broken behavior:
Screen.Recording.2025-04-07.at.16.37.04.mov