Page MenuHomePhabricator

Links interrupt text for VoiceOver users, text is therefore hard to understand in the iOS app
Open, MediumPublicBUG REPORT

Description

When VoiceOver is speaking the text of articles, it divides speech on every link to announce that there is a link. This is reasonable when links are sparse and separate. However, in Wikipedia, there is a huge number of links that start directly from words in the sentences in the main text. At the same time it is exactly this text that is the most important content for the user. The presence of links, although technically correct, makes the text very hard to read for a VoiceOver user. Here is an example of what a VoiceOver user hears when reading an article about Wikipedia:

Jimmy Wales. Link. And Larry Sanger. Link. Launched Wikipedia on January 15, 2001. Sanger. Nine. Link. Coined its name. Ten. Link. A portmanteau. Link. Of. Wiki. Link. Notes 3. Link. And. Encyclopedia. Link. Initially only in English, Wikipedia quickly became multilingual. Link. As it developed similar versions in other languages. Link.

The result in speech is very hard to understand, especially as also the prosody and intonation of sentences is completely broken by the links (I tried to mirror this visually by the use of punctuation in the above text.)

Segmentation of text caused by link words also makes it more complicated to navigate the text (i.e. move forward and backward in it) because the links are treated as separate objects.

This is a complex issue. The technically correct solution of course is to fix VoiceOver to handle the reading of densely hyperlinked text in a better way, e.g. to indicate links by a short background sound and to maintain the prosody and intonation of sentences undisturbed. Unfortunately it does not seem likely that Apple would fix this in near future. No other screen readers exist on iOS, so Wikipedia needs to take this issue of the platform into account and still aim to provide some reasonable experience.

I would propose two lines of action:

  1. File and maintain a bug in Apple Bug Report. Contact the appropriate people in Apple and push for this issue to be given priority, because this absolutely must be solved in order for Wikipedia to provide a reasonable experience.
  2. Devise a workaround in the app itself allowing a blind user to temporarily remove links from text. One possible solution might be the following:
    • React to some VoiceOver’s gesture (e.g. the Magic Tap or a long tap) by switching links on/off inside the article (this would likely mean removing interactivity from the a elements through javascript).
    • Add “Do not display links in articles” toggle into the apps Settings Accessibility section. With an additional note under it this could also inform users that it can be easily toggled by the gesture.

I am aware that the setting "Do not display links in articles" sounds rough, but as the situation is now, I know some less skilled users would actually prefer to sacrifice the interlinking capability of Wikipedia in order to be at least able to understand the primary article that they searched for.

However, I think this workaround still needs more thought. In particular, I would have two concerns:

  • The setting in Settings doesn't seem to be enough to let VoiceOver users know that this functionality is there and that it would solve their problem.
  • By blocking a VoiceOver gesture such as Magic Tap for this functionality we sacrifice the possibility to use it in some other way, which could be our concern once we move to trying to make the app really nice and well usable for VoiceOver users. By design, Magic Tap should mean "the most obvious action" in an application. I believe in Wikipedia this would likely be immediate access to Search (from anywhere in the app).

Event Timeline

hhanke raised the priority of this task from to High.
hhanke updated the task description. (Show Details)

@TheDJ Interesting, apparently for some blind people it is even enough reason to look for a third-party reader that would not do links at all.

I was thinking about it some more and I think the Hide/Show links setting and being able to switch it through Magic Tap could actually be quite a good solution for now. When Apple comes with a solution directly in VoiceOver, we will be free to use Magic Tap for something else. But right now I think it would really be the "magic action" :-) that would significantly help VoiceOver users. I also came up with some ideas how to communicate it to the users so I now feel satisfied that this concern can also be resolved.

(I attach a short video which demonstrates the concept. The user first reads normally and he/she is constantly interrupted with the "link" notifications, then the user performs a Magic tap (double tap with two fingers anywhere on screen), the links disappear and the text reads normally. Towards the end of the video, the user becomes interested in the "European Union" term that he has heard, so he performs another Magic Tap to see links again, comes back and clicks the link to open the article about "European Union"). –

I therefore set out to attempt to try the idea and to test it against possible hidden problems.

I implemented the accessibilityPerformMagicTap action in WebViewController and two javascript methods: accessibilityShowLinks and accessibilityHideLinks. The first one sets "display:none" to all relevant <a> elements and appends a <span> element with a "link-placeholder-text" class and containing the same content. The second one does the reverse, it removes the placeholder span and it sets display:inline on the real links.

This seems to work but with a catch. VoiceOver does not seem to update its structure of the accessible elements inside the webView automatically (this is certainly a bug in VoiceOver as the DOM is allowed to change dynamically). This happens even when VoiceOver cursor does not stand on any element directly affected by the change (link or placeholder). The result manifests itself in different ways, sometimes the user cannot move the cursor, sometimes VoiceOver fails to "see" parts of the text etc. This is so severe that the article becomes unusable. I have compared that with the behavior of a WkWebView, but the results are exactly the same (except there is one more issue with WkWebView – it does not even pass MagicTaps to the app as was already discovered by my colleague Boris Dušek).

The obvious workaround for the missing synchronization of VoiceOver would be to force an update manually through posting UIAccessibilityLayoutChangedNotification, but this seems to do nothing in relation to the webView (another bug, I think). I then tested calling UIAccessibilityScreenChangedNotification instead and this does fully resolve the issue of VoiceOver updating its information about the DOM. No more problems with movement of the cursor and no more parts of text being omitted by VoiceOver.

But there is another problem. UIAccessibilityScreenChangedNotification resets the VoiceOver cursor position to the beginning of screen. This is the intended behavior, but does not give us what we want, because if a user decides to switch links on/off in the middle of an article, he will loose its position and he has to start from the beginning. We have encountered that issue already in T125354 in a slightly different form. In the worst-case scenario, users could live with it and this would still be a useful solution, but...

Luckily, I think there might be a solution for that problem too. We can check the cursor position in the webpage via UIAccessibilityFocusedElement after the javascript call but before the screenChanged notification and feed this exact same position back to the screenChanged. The focused object that we receive is not a part of the public API, but I think there is nothing bad in just feeding it back without any manipulation and therefore just asking VoiceOver to stay where it is through the screenChanged notification (I could try to confirm that on Apple's accessibility mailing list).

The rough result is what you can see on the video (above). We would have to polish it of course and resolve some timing issues there (which I think are solvable, but one can never be sure, the webView is a bit of a minefield :-).

@JMinor @BGerstle-WMF Please let me know whether you are OK with the general concept and whether we should take this forward.

@hhanke a few notes:

  • this looks awesome
  • have you tried using ARIA and setting (and removing) role=presentation on the <a> elements? If it worked, then that would not require appending a span with the text. It might also help with the noticeable lag experienced when invoking the switching - adding and removing an attribute (role) should be hopefully roughly twice as fast than adding an attribute (style) and appending element to DOM with already present textual content, effectively roughly doubling the size of the HTML (and DOM); not to speak that just adding role would not require complete visual re-layout of the whole web content by WebKit.
  • the bug you are referring to that I discovered and reported in the mailing list (and rdar) was fixed in iOS 9b2. So if it is present again, it is a regression. I just tried with the sample code attached to the rdar and while the magic tap gets reported to accessibiltiyPerformMagicTap on the view controller, it still starts/stops playing my music nevertheless (i.e. magic tap gets propagated to 2 places, does 2 things), as if I were returning false from the method (which I am not). So it would be worthwile to open a new rdar (or reopen the current one at rdar://problem/20940938 ). If you are however seeing the behavior that the magic tap is indeed not reported to the view controller at all in your code, then ... well let's say WebKit really has a spirit (not only) accessibility-wise :-) (My sample code does not load content from the web but from a static HTML string, maybe that is the reason for the difference...)
  • I guess a general solution directly in VoiceOver could be to allow to play an indicator in the form of a supershort sound when a link is encountered, and not say the usual "link" or pause the speech anyhow. VoiceOver already allows that on OS X (and some screen readers on other platforms allow for such possibility too), though perhaps the user experience could still be improved a little more (no/smaller delay due to the sound, no splitting of text on link/non-link boundaries, more "fluent" feeling to the reading). And the sound could be also turned off completely by the user (to approach the uncompromising efficiency of UX you have in the demo).

@dusek

  • Thanks for the suggestion with role=presentation, that would be an excellent solution! I did not try it before so I tried it now, but unfortunately it turns out VoiceOver ignores it completely on <a>elements. W3C says this role should not be used on visible focusable elements, so I tried to add tabindex=-1 but no joy. I think VoiceOver simply doesn't go that far. But you are right, that would be the simplest solution if it could be used.
  • Regarding accessibilityPerformMagicTap with WkWebView, I confirm the bug remains in 9.2.1 (I didn't test this on the 9.3 beta though). I am also seeing the magic tap propagating to two places on 9.2.1 on a UIWebView if the accessibilityPerformMagicTap method takes long enough to execute (a few seconds). Then it doesn't matter what it returns, Music starts playing anyway. (This is also a concern here, so I now call the javascript asynchronously.)
  • Regarding what we could wish for in VoiceOver itself, I believe it should simply not interrupt reading of text on links at all. Playing a short sound is definitely better than saying "link" but still, the text gets interrupted and that is a bad think. Prosody and tempo of sentences are important for understanding of text. No seeing reader pauses after he seing every link. The sound could even be longer (perhaps for the whole duration of speaking the link) as long as it is soft and in the background. Then we would have something that is far from great, but at least comes closer to the experience of seeing people :-) But yes, if VoiceOver on iOS got at least the same possibility as exists on the Mac, that would be a big improvement and we could handle this issue by concentrating on educating users about this possibility.

@hhanke this seems like a good solution…

as far as getting the web view to update voice over when its structure changes… can we just reload the web view - does that cause voice over to get updated?

@Fjalapeno I would say that reloading the web view would likely result in loosing the VoiceOver focus (so the user would land at the beginning) which is what we can already achieve by sending the screenChanged notification but we would prefer if the cursor remained where it was before the gesture so that the user could continue reading seamlessly. But I will try it, just in case :-)

I am kind of busy now but hopefully I should be able to get back to it over the weekend.

JMinor lowered the priority of this task from High to Medium.May 9 2016, 7:10 PM

We've had some discussions with Apple at WWDC about this issue and potential solutions. Apart from the idea of offering a "no-link" mode, they also suggested we investigate their "reader view" which could be used as the source of reading without link interruptions.

See also T138048, specifically about this solution.

Removing from next version scope. We have many small tangible improvements to accessibility lined up, and there is no obvious and ready-to-implement solution.

We will be working with an accessibility consultant and a small group of disabled testers to discuss and prototype any potential changes here.

JMinor lowered the priority of this task from High to Medium.May 24 2017, 6:07 PM
Aklapper changed the subtype of this task from "Task" to "Bug Report".Feb 17 2023, 8:22 AM