Bug 176615

Summary: AX: VoiceOver iframe scrolling focus jumping bug
Product: WebKit Reporter: Paul J. Adam <paul>
Component: AccessibilityAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Blocker CC: aboxhall, apinheiro, cfleizach, commit-queue, dhbollinger, dmazzoni, ews-watchlist, jcraig, jdiggs, n_wang, rniwa, samuel_white, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 10   
Hardware: All   
OS: All   
See Also: https://bugs.webkit.org/show_bug.cgi?id=186956
Attachments:
Description Flags
showing iframe has focus but page is visually scrolled to the very top and you can't see the iframe
none
patch
ews-watchlist: commit-queue-
Archive of layout-test-results from ews200 for win-future
none
patch
ews-watchlist: commit-queue-
Archive of layout-test-results from ews107 for mac-sierra-wk2
none
patch none

Description Paul J. Adam 2017-09-08 10:11:31 PDT
Created attachment 320276 [details]
showing iframe has focus but page is visually scrolled to the very top and you can't see the iframe

It's not possible to tab or swipe to iframe content using VoiceOver and Safari because once you tab or swipe into the content the page scrolls up to the top and you can't see your focus. 

Steps to reproduce bug:

1. Turn VoiceOver On.
2. Visit demo page at http://pauljadam.com/demos/iframe-voiceover-scrolling-bug.html
3. Tab through page and iframe content at bottom of the page in Safari macOS or swipe through page in Safari iOS.

Expected results:

Page scrolls normally as you tab or swipe through the page without any browser scroll jumping up and down the page. Focused item always remains visible.

Actual results:

Once you focus on the iframe content the page abruptly jumps up and down from the top to bottom of the page as you tab and swipe through the iframe elements. It's impossible to see the focused element because the window always scrolls to the very top of the page.
Comment 1 Radar WebKit Bug Importer 2017-09-08 10:11:51 PDT
<rdar://problem/34333067>
Comment 2 Nan Wang 2018-05-08 16:22:29 PDT
Created attachment 339895 [details]
patch
Comment 3 chris fleizach 2018-05-08 16:27:31 PDT
Comment on attachment 339895 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=339895&action=review

> Source/WebCore/accessibility/AccessibilityObject.cpp:3000
> +    LayoutRect objectRect = isScrollView() ? elementRect() : boundingBoxRect();

Should we implement bounding box rect for scroll view?
Comment 4 Nan Wang 2018-05-08 16:43:41 PDT
(In reply to chris fleizach from comment #3)
> Comment on attachment 339895 [details]
> patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=339895&action=review
> 
> > Source/WebCore/accessibility/AccessibilityObject.cpp:3000
> > +    LayoutRect objectRect = isScrollView() ? elementRect() : boundingBoxRect();
> 
> Should we implement bounding box rect for scroll view?

I think boundingBoxRect() should only be available when there's a renderer
Comment 5 chris fleizach 2018-05-08 17:06:33 PDT
Comment on attachment 339895 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=339895&action=review

> LayoutTests/accessibility/scroll-to-make-visible-iframe-offscreen.html:11
> +<iframe id="frame" src="data:text/html,<body><button id='upper_target'>Upper Target</button><div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div><button id='lower_target'>Lower Target</button></body>"></iframe>

can we also test a iframe inside an iframe
Comment 6 Simon Fraser (smfr) 2018-05-08 17:16:52 PDT
Comment on attachment 339895 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=339895&action=review

> Source/WebCore/accessibility/AccessibilityObject.cpp:3027
>      IntRect newSubfocus = subfocus;
>      IntRect newElementRect = snappedIntRect(elementRect());
> -    IntRect scrollParentRect = snappedIntRect(scrollParent->elementRect());
>      newSubfocus.move(newElementRect.x(), newElementRect.y());
> -    newSubfocus.move(-scrollParentRect.x(), -scrollParentRect.y());
>      

We have a family of helper functions for this kind of thing: Widget::convertToContainingView, convertToRootView etc. Please always use those rather than trying to hand-roll coordinate conversion code, since they know about things like scroll view insets and headers/footers.

> Source/WebCore/accessibility/AccessibilityObject.cpp:3028
>      // Recursively make sure the scroll parent itself is visible.

Why isn't this just using RenderLayer::scrollRectToVisible() which knows how to do all this scrolling?
Comment 7 EWS Watchlist 2018-05-08 18:44:15 PDT
Comment on attachment 339895 [details]
patch

Attachment 339895 [details] did not pass win-ews (win):
Output: http://webkit-queues.webkit.org/results/7618051

New failing tests:
accessibility/scroll-to-make-visible-iframe-offscreen.html
http/tests/preload/onload_event.html
http/tests/security/canvas-remote-read-remote-video-localhost.html
Comment 8 EWS Watchlist 2018-05-08 18:44:26 PDT
Created attachment 339911 [details]
Archive of layout-test-results from ews200 for win-future

The attached test failures were seen while running run-webkit-tests on the win-ews.
Bot: ews200  Port: win-future  Platform: CYGWIN_NT-6.1-2.9.0-0.318-5-3-x86_64-64bit
Comment 9 Nan Wang 2018-05-08 19:25:04 PDT
Created attachment 339916 [details]
patch

- Use RenderLayer::scrollRectToVisible()
- Added more test case
Comment 10 EWS Watchlist 2018-05-08 20:26:23 PDT
Comment on attachment 339916 [details]
patch

Attachment 339916 [details] did not pass mac-wk2-ews (mac-wk2):
Output: http://webkit-queues.webkit.org/results/7619265

New failing tests:
http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html
Comment 11 EWS Watchlist 2018-05-08 20:26:24 PDT
Created attachment 339925 [details]
Archive of layout-test-results from ews107 for mac-sierra-wk2

The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews.
Bot: ews107  Port: mac-sierra-wk2  Platform: Mac OS X 10.12.6
Comment 12 chris fleizach 2018-05-08 20:57:05 PDT
Comment on attachment 339916 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=339916&action=review

> Source/WebCore/accessibility/AccessibilityObject.cpp:2992
> +        renderer->scrollRectToVisible(SelectionRevealMode::Reveal, absoluteBounds, insideFixed, ScrollAlignment::alignCenterIfNotVisible, ScrollAlignment::alignCenterIfNotVisible);

should we go with align center or align top?
Comment 13 Nan Wang 2018-05-08 21:17:10 PDT
(In reply to chris fleizach from comment #12)
> Comment on attachment 339916 [details]
> patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=339916&action=review
> 
> > Source/WebCore/accessibility/AccessibilityObject.cpp:2992
> > +        renderer->scrollRectToVisible(SelectionRevealMode::Reveal, absoluteBounds, insideFixed, ScrollAlignment::alignCenterIfNotVisible, ScrollAlignment::alignCenterIfNotVisible);
> 
> should we go with align center or align top?

I think previously we explicitly center the rect.
Comment 14 Nan Wang 2018-05-09 12:48:33 PDT
Created attachment 340008 [details]
patch

Found an issue where renderTextElement is not being scrolled. Added a test case for that.
Comment 15 WebKit Commit Bot 2018-05-09 19:07:39 PDT
Comment on attachment 340008 [details]
patch

Clearing flags on attachment: 340008

Committed r231628: <https://trac.webkit.org/changeset/231628>
Comment 16 WebKit Commit Bot 2018-05-09 19:07:41 PDT
All reviewed patches have been landed.  Closing bug.