mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-19 06:38:07 +02:00
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.
134 KiB
134 KiB