-
Notifications
You must be signed in to change notification settings - Fork 772
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
Reader: screen reader cursor remaining in place after scrolling to another page #4515
Comments
@mrtcode I have been looking into one of the accessibility issues with the reader described in this nice and detailed forums post and wanted to check in on what you think about it. To sum up the issue, if you navigate the content of the PDF or EPUB reader via screen reader, the existing commands for page navigation get somewhat undone by the screen reader's functionality. If you use any of our shortcuts to scroll to the next page B from A, the virtual cursor of the screen reader will have no reason to leave page A. It'll just stay at the previous DOM element, so on the next arrowUp/Down, the screen reader will just read the next line on page A, potentially even scrolling back. That means that, as described in the forums post, if you rely on screen reader for navigating the reader, there is no functional way to traverse PDF and EPUB documents. I looked into a few different ways to address it on an example of a PDF (which is easier), and the easiest but also most functional solution that I could come up with so far is to add a hidden header Does it sound like a viable approach for the PDF overall? It gets a bit trickier with EPUB since it doesn't look like there are clear pages but rather the entire chapter rendered as a series of |
From the PDF view perspective, that sounds right. However, I'm not sure about the EPUB part. Maybe @AbeJellinek has some thoughts on this. |
Gotcha, thanks! |
I'm now realizing that while having such headers is helpful, for PDF it is not strictly needed since NVDA and JAWS do allow you to navigate between But the other thing for me to note is that we just need to have a way to force screen readers to move their virtual cursor to where we need. Otherwise, so many features are way harder to use. Manually changing the page number, selecting a section in the outline, using "Find in document" - all of these scroll to a particular spot in the document without the virtual cursor properly adjusting. So I am now trying out the approach of making an element in the document focusable after navigation, focusing it and them cleaning up after blur, which does seem to help. It's a bit trickier and messier but this could be a more fundamental way to help screen readers. |
We can't add/remove anything within (Some EPUBs do have hidden page number elements, but we can't count on that.) |
Oh, that is good to know! It is what I've been going after... Hm, if we were to place a hidden |
Yes. |
Unfortunately! Is there no way to achieve the same thing by modifying the attributes of an existing element? |
Gotcha ... No DOM manipulation for epub content.
This is what I'll try next! I am trying to make the same interface for epub screen readers navigation as with pdfs (where each page is a "region", so |
I mean, if the screen reader can navigate between |
Or (Note that EPUB documents are just HTML documents - there aren't necessarily top-level |
I think it is not quite correct semantically, since, for example, A question about EPUB locations, just to be sure: is it ok to insert a node if it's going to be shortly deleted? On Tab into the EPUB content after navigating the outline, the virtual cursor has no idea where to go (since it looks at rendered DOM disregarding the scroll position), so I insert and focus an invisible |
It would be safe as long as we add and remove it synchronously; e.g. does something like this work? handleFocus() {
let firstVisibleElement = closestElement(this.flow.startRange.startContainer)!;
let child = this._iframeDocument.createElement('div');
firstVisibleElement.prepend(child);
child.tabIndex = '0'; // or whatever we need
child.focus();
child.remove(); // or setTimeout(() => child.remove()), but that isn't as good
} No way to do this by giving an existing element a |
My current approach is this:
So the element is removed only when the focus moves away from it, otherwise virtual cursor gets confused as well. That would not be good, right? I'll open up a draft PR with all of my changes so far to make it easier to refer to specific parts. |
That code would definitely break EPUB CFIs, so if the If we need different things in PDF and EPUB/snapshot, the delegation approach I mentioned here would be preferable. |
Gotcha, I'll drop all DOM manipulations for EPUB. It seems to be possible with a few tweaks, at least for the outline, which is a decent starting point. I'll do that and open a PR to make sure I'm on the right track. |
https://forums.zotero.org/discussion/comment/469784/#Comment_469784
As described in the forums post, one issue is that screen readers may block keypresses used to switch between pages. This can be worked around by temporarily passing through a keystroke or switching from reading to focus mode for a moment. The bigger issue is that the cursor of screen readers remains unaffected by scrolling another page into view. This is understandable, since as long as the DOM does not change, NVDA has no reason to think that the cursor needs to move. It means that even if the page is scrolled,
arrowDown
will read the \ sentence after the last sentence on the previous page and (sometimes) scroll back to it, essentially undoing previous scroll.As a workaround, I am thinking maybe we could exploit
Control-Home/End
keypresses of NVDA. Their purpose is to move the virtual cursor to the top/bottom of the page. It currently doesn't work right at all in the reader due to pages being dynamically loaded/unloaded, so it moves cursor to the first/last loaded page. What if we mark all pages but the previous and next one asaria-hidden
, in which caseControl-Home/End
theoretically should only move the cursor to the previous/next page (since remaining ones are hidden). I'll try to see if it works.The text was updated successfully, but these errors were encountered: