-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
Fix flickering on text selection #17923
Fix flickering on text selection #17923
Conversation
cd50835
to
92b5cf6
Compare
/botio-linux preview |
I'm not sure if it's possible to add an integration test for this kind of change because even though we can probably do the selection with Puppeteer I don't really see what we could assert in the test. In any case, let's first check if all existing tests still pass with this change applied: /botio test |
It looks like the integration tests did notice the change, so we fortunately at least have some coverage on this (although we don't specifically test this selection issue, but it's most likely noticed as a side-effect of other selection/scrolling tests). However, sadly they seem to fail on both Linux and Windows. Tip: what usually helps for quick debugging is enabling one of failing tests from the logs by changing |
@timvandermeij Thanks for the tip! The flickering behavior is very consistent/predictable, so if with puppeteer I could simulate "long-tap at (x1,y2) to select, then hold the selection bubble and drag to (x2,y2), and check what is selected" I would be able to add a test. The problem is the "drag the selection bubble" part, since it's not dragging on the page (the selection bubble is browser UI and doesn't trigger touch events) |
I pushed two commits:
I still need to investigate testing. |
7d096ec
to
0ada3c1
Compare
I have looked that the Puppeteer API documentation, but I can't really find anything related to this. However, if the flickering effects are also consistently visible in Firefox or Chrome on desktop then we might be able to write a test that starts a selection, moves the mouse to certain coordinates and gets the selected text. We'd have to try it out to see if it actually works, but it sounds like it might be doable. (By the way, thank you for providing such detailed issue/PR descriptions, visuals and inline comments! That really helps to understand the change, especially for these kinds of bugs that are usually a bit tricky and difficult to fully test in an automated way, and therefore require additional manual testing.) |
@timvandermeij I managed to add a test when using a mouse (which before this PR fails in Chrome), but unfortunately puppeteer's API doesn't seem to allow selecting text emulating a touchscreen input. In Chrome this test will trigger the |
0f74102
to
a4e6ad9
Compare
In Firefox (desktop), it's possible to reproduce the flickering in setting the pref |
Oh thank you :) Can I somehow set it in Puppeteer? |
Yes, Firefox-specific preferences are configured here: https://github.com/mozilla/pdf.js/blob/master/test/test.mjs#L907-L942. If it helps, I also found some more documentation about this preference at https://firefox-source-docs.mozilla.org/layout/AccessibleCaret.html. |
I pushed
I am working on a test for this multi-page flickering on Firefox desktop, then I'll try if |
a519c40
to
de1e73b
Compare
All tests are passing locally, except for Chrome reftests because one of them kept timing out while I was trying to generate the reference images from I had to add one more commit to fix a regression:
This is ready for re-review -- I will squash once it's ready :) |
751cb91
to
75d9741
Compare
Rebased! |
/botio-windows integrationtest |
From: Bot.io (Windows)ReceivedCommand cmd_integrationtest from @timvandermeij received. Current queue size: 0 Live output at: http://54.193.163.58:8877/edfbf086f943cfc/output.txt |
From: Bot.io (Windows)FailedFull output at http://54.193.163.58:8877/edfbf086f943cfc/output.txt Total script time: 1.73 mins |
/botio-windows integrationtest |
From: Bot.io (Windows)ReceivedCommand cmd_integrationtest from @timvandermeij received. Current queue size: 0 Live output at: http://54.193.163.58:8877/3ad9ebab6ed3957/output.txt |
/botio-windows integrationtest |
From: Bot.io (Windows)ReceivedCommand cmd_integrationtest from @timvandermeij received. Current queue size: 1 Live output at: http://54.193.163.58:8877/60e691075d73896/output.txt |
From: Bot.io (Windows)FailedFull output at http://54.193.163.58:8877/60e691075d73896/output.txt Total script time: 21.60 mins
|
@nicolo-ribaudo We're down to just one failure on Windows now, so we have improved since the last fixup. Looking at the logs above, could this be a problem with the "roughly equals" function given that the assertions look very close at least on a quick glance? Fortunately you've logged the actual/expected values in the message, so hopefully this can be checked in isolation more easily now. |
When seleciting on a touch screen device, whenever the finger moves to a blank area (so over `div.textLayer` directly rather than on a `<span>`), the selection jumps to include all the text between the beginning of the .textLayer and the selection side that is not being moved. The existing selection flickering fix when using the mouse cannot be trivially re-used on mobile, because when modifying a selection on a touchscreen device Firefox will not emit any pointer event (and Chrome will emit them inconsistently). Instead, we have to listen to the 'selectionchange' event. The fix is different in Firefox and Chrome: - on Firefox, we have to make sure that, when modifying the selection, hovering on blank areas will hover on the .endOfContent element rather than on the .textLayer element. This is done by adjusting the z-indexes so that .endOfContent is above .textLayer. - on Chrome, hovering on blank areas needs to trigger hovering on an element that is either immediately after (or immediately before, depending on which side of the selection the user is moving) the currently selected text. This is done by moving the .endOfContent element around between the correct `<span>`s in the text layer. The new anti-flickering code is also used when selecting using a mouse: the improvement in Firefox is only observable on multi-page selection, while in Chrome it also affects selection within a single page. After this commit, the `z-index`es inside .textLayer are as follows: - .endOfContent has `z-index: 0` - everything else has `z-index: 1` - except for .markedContent, which have `z-index: 0` and their contents have `z-index: 1`. `.textLayer` has an explicit `z-index: 0` to introduce a new stacking context, so that its contents are not drawn on top of `.annotationLayer`.
75d9741
to
6f2e4d0
Compare
@timvandermeij I relaxed the assertion a bit, hopefully it will pass now. The "roughly equals" function checks that the expected value is an almost-complete substring of the actual value. It cannot get a substring of the expected value because it also supports regexp, and slicing a regexp is... complex. |
/botio integrationtest |
From: Bot.io (Linux m4)ReceivedCommand cmd_integrationtest from @timvandermeij received. Current queue size: 1 Live output at: http://54.241.84.105:8877/078a82ccad8684f/output.txt |
From: Bot.io (Windows)ReceivedCommand cmd_integrationtest from @timvandermeij received. Current queue size: 2 Live output at: http://54.193.163.58:8877/0002a3c99d2cf86/output.txt |
From: Bot.io (Linux m4)SuccessFull output at http://54.241.84.105:8877/078a82ccad8684f/output.txt Total script time: 7.32 mins
|
Windows is still running, but so far the selection tests passed :)
|
From: Bot.io (Windows)SuccessFull output at http://54.193.163.58:8877/0002a3c99d2cf86/output.txt Total script time: 20.79 mins
|
Nice work; thank you for the effort you put into this! |
When seleciting on a touch screen device, whenever the finger moves to a blank area (so over
div.textLayer
directly rather than on a<span>
), the selection jumps to include all the text between the beginning of the.textLayer
and the selection side that is not being moved.The existing selection flickering fix when using the mouse cannot be trivially re-used on mobile, because when modifying a selection on a touchscreen device Firefox will not emit any pointer event (and Chrome will emit them inconsistently). Instead, we have to listen to the 'selectionchange' event.
The fix is different in Firefox and Chrome:
.endOfContent
element rather than on the.textLayer
element. This is done by adjusting the z-indexes so that.endOfContent
is above.textLayer
..endOfContent
element around between the correct<span>
s in the text layer.In Safari mobile it is still broken in random and fun ways, the fix for Safari would be completely different, and out-of-scope for this PR.
Before/after videos (mobile)
pdf1_firefox_before.mp4
pdf1_firefox_after.mp4
pdf1_chrome_before.mp4
pdf1_chrome_after.mp4
Before/after videos (desktop)
pdfjs-recording-before.mp4
pdfjs-recording-after.mp4
2024-04-17.14-08-35.mp4
2024-04-17.13-42-39.mp4
Fixes #17912
I'm not sure about how to add a test for this, if it's even possible.