Diff
Modified: trunk/LayoutTests/ChangeLog (231627 => 231628)
--- trunk/LayoutTests/ChangeLog 2018-05-10 01:49:54 UTC (rev 231627)
+++ trunk/LayoutTests/ChangeLog 2018-05-10 02:07:34 UTC (rev 231628)
@@ -1,3 +1,16 @@
+2018-05-09 Nan Wang <n_w...@apple.com>
+
+ AX: VoiceOver iframe scrolling focus jumping bug
+ https://bugs.webkit.org/show_bug.cgi?id=176615
+ <rdar://problem/34333067>
+
+ Reviewed by Chris Fleizach.
+
+ * accessibility/resources/iframe.html: Added.
+ * accessibility/scroll-to-make-visible-iframe-offscreen-expected.txt: Added.
+ * accessibility/scroll-to-make-visible-iframe-offscreen.html: Added.
+ * platform/win/TestExpectations:
+
2018-05-09 Joanmarie Diggs <jdi...@igalia.com>
AX: accessibleNameForNode should simplify whitespace when using innerText
Added: trunk/LayoutTests/accessibility/resources/iframe.html (0 => 231628)
--- trunk/LayoutTests/accessibility/resources/iframe.html (rev 0)
+++ trunk/LayoutTests/accessibility/resources/iframe.html 2018-05-10 02:07:34 UTC (rev 231628)
@@ -0,0 +1,6 @@
+<html>
+<body>
+<div id="box" style='border: 1px solid #000; height: 1000px;'>1000-pixel box</div>
+<iframe id="iframe" src="" style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div><button id='button'>Test Button</button></button></body>"></iframe>
+</body>
+</html>
Added: trunk/LayoutTests/accessibility/scroll-to-make-visible-iframe-offscreen-expected.txt (0 => 231628)
--- trunk/LayoutTests/accessibility/scroll-to-make-visible-iframe-offscreen-expected.txt (rev 0)
+++ trunk/LayoutTests/accessibility/scroll-to-make-visible-iframe-offscreen-expected.txt 2018-05-10 02:07:34 UTC (rev 231628)
@@ -0,0 +1,39 @@
+This tests that scrolling to make an element visible works properly when there's an iframe off screen.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+5000-pixel box
+
+
+Test scrolling an offscreen iframe.
+PASS window.pageYOffset is 0
+
+Scroll lower target to visible.
+The iframe should be scrolled into view
+PASS scrolledYOffset > 0 is true
+Test the lower target should be scrolled into view.
+PASS scrolledIntoView is true
+
+Scroll upper target to visible.
+The main window shouldn't scroll.
+PASS window.pageYOffset == scrolledYOffset is true
+Test the upper target should be scrolled into view.
+PASS scrolledIntoView is true
+
+Reset scrolling. Test scrolling in nested iframes.
+PASS window.pageYOffset is 0
+
+Scroll inner button to visible.
+Test the button inside the inner frame should be scrolled into view
+PASS scrolledIntoView is true
+The inner iframe should be scrolled into view
+PASS outterFrameWindow.pageYOffset > 0 is true
+
+Scroll outter text element to visible.
+The Y offset of the outter iframe should be reset.
+PASS outterFrameWindow.pageYOffset is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/accessibility/scroll-to-make-visible-iframe-offscreen.html (0 => 231628)
--- trunk/LayoutTests/accessibility/scroll-to-make-visible-iframe-offscreen.html (rev 0)
+++ trunk/LayoutTests/accessibility/scroll-to-make-visible-iframe-offscreen.html 2018-05-10 02:07:34 UTC (rev 231628)
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<head>
+<script src=""
+</head>
+<body>
+
+<p id="description"></p>
+
+<div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div>
+
+<iframe id="frame" src="" 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>
+
+<br>
+<iframe id="frame2" src=""
+
+<div id="console"></div>
+
+<script>
+description("This tests that scrolling to make an element visible works properly when there's an iframe off screen.");
+
+window.jsTestIsAsync = true;
+
+function runTest() {
+
+ window.frame = document.getElementById("frame");
+ window.frameWindow = frame.contentWindow;
+
+ var upperTarget = frameWindow.document.getElementById("upper_target");
+ var lowerTarget = frameWindow.document.getElementById("lower_target");
+
+ var lowerTargetAccessibleObject;
+ var upperTargetAccessibleObject;
+ if (frameWindow.accessibilityController) {
+ lowerTargetAccessibleObject = frameWindow.accessibilityController.accessibleElementById("lower_target");
+ upperTargetAccessibleObject = frameWindow.accessibilityController.accessibleElementById("upper_target");
+ }
+
+ // Initial state
+ debug("Test scrolling an offscreen iframe.");
+ window.scrollTo(0, 0);
+ shouldBeZero("window.pageYOffset");
+
+ // Scroll to make lower target visible and check.
+ debug("\nScroll lower target to visible.");
+ if (frameWindow.accessibilityController)
+ lowerTargetAccessibleObject.scrollToMakeVisible();
+ // The iframe should be scrolled into view.
+ debug("The iframe should be scrolled into view");
+ window.scrolledYOffset = window.pageYOffset;
+ shouldBeTrue("scrolledYOffset > 0");
+ // The content inside the iframe should be scrolled into view too
+ testScrolledIntoView(lowerTarget, frameWindow, "Test the lower target should be scrolled into view.")
+
+ // Scroll to make upper target visible and check.
+ debug("\nScroll upper target to visible.");
+ if (frameWindow.accessibilityController)
+ upperTargetAccessibleObject.scrollToMakeVisible();
+ // The iframe should be visible already
+ debug("The main window shouldn't scroll.");
+ shouldBeTrue("window.pageYOffset == scrolledYOffset");
+ // The content inside the iframe should be scrolled into view too
+ testScrolledIntoView(upperTarget, frameWindow, "Test the upper target should be scrolled into view.")
+
+ // Reset and test iframe inside iframe
+ debug("\nReset scrolling. Test scrolling in nested iframes.");
+ window.scrollTo(0, 0);
+ shouldBeZero("window.pageYOffset");
+
+ window.innerFrame = document.getElementById("frame2").contentWindow.document.getElementById("iframe");
+ window.innerFrameWindow = innerFrame.contentWindow;
+ var button = innerFrameWindow.document.getElementById("button");
+ var buttonAccessibleObject;
+ debug("\nScroll inner button to visible.");
+ if (innerFrameWindow.accessibilityController) {
+ buttonAccessibleObject = innerFrameWindow.accessibilityController.accessibleElementById("button");
+ buttonAccessibleObject.scrollToMakeVisible();
+ }
+ // The content inside the inner iframe should be scrolled into view too
+ testScrolledIntoView(button, innerFrameWindow, "Test the button inside the inner frame should be scrolled into view");
+ // Use outter frame to determine the inner frame is scrolled into view.
+ window.outterFrame = document.getElementById("frame2");
+ window.outterFrameWindow = outterFrame.contentWindow;
+ debug("The inner iframe should be scrolled into view");
+ shouldBeTrue("outterFrameWindow.pageYOffset > 0");
+
+ // Now make sure we can scroll back to the outter text above the inner iframe
+ var text = outterFrameWindow.document.getElementById("box").firstChild;
+ var textAccessibleObject;
+ debug("\nScroll outter text element to visible.");
+ if (outterFrameWindow.accessibilityController) {
+ textAccessibleObject = outterFrameWindow.accessibilityController.accessibleElementById("box").childAtIndex(0);
+ textAccessibleObject.scrollToMakeVisible();
+ }
+ debug("The Y offset of the outter iframe should be reset.")
+ shouldBeZero("outterFrameWindow.pageYOffset");
+
+ finishJSTest();
+}
+
+function testScrolledIntoView(object, testWindow, description) {
+ debug(description);
+ window.frameMinYOffset = object.offsetTop + object.offsetHeight - testWindow.innerHeight;
+ window.frameMaxYOffset = object.offsetTop;
+ window.scrolledIntoView = testWindow.pageYOffset >= frameMinYOffset && testWindow.pageYOffset <= frameMaxYOffset;
+ shouldBeTrue("scrolledIntoView");
+}
+
+window.addEventListener("load", function() {
+ setTimeout(runTest, 0);
+}, false);
+
+</script>
+
+</body>
+</html>
Modified: trunk/LayoutTests/platform/win/TestExpectations (231627 => 231628)
--- trunk/LayoutTests/platform/win/TestExpectations 2018-05-10 01:49:54 UTC (rev 231627)
+++ trunk/LayoutTests/platform/win/TestExpectations 2018-05-10 02:07:34 UTC (rev 231628)
@@ -1574,6 +1574,7 @@
accessibility/scroll-to-make-visible-nested-2.html [ Skip ]
accessibility/scroll-to-make-visible-nested.html [ Skip ]
accessibility/scroll-to-make-visible-with-subfocus.html [ Skip ]
+accessibility/scroll-to-make-visible-iframe-offscreen.html [ Skip ]
# Apparently missing support for roleDescription on Windows.
accessibility/aria-roledescription.html [ Failure ]
Modified: trunk/Source/WebCore/ChangeLog (231627 => 231628)
--- trunk/Source/WebCore/ChangeLog 2018-05-10 01:49:54 UTC (rev 231627)
+++ trunk/Source/WebCore/ChangeLog 2018-05-10 02:07:34 UTC (rev 231628)
@@ -1,3 +1,20 @@
+2018-05-09 Nan Wang <n_w...@apple.com>
+
+ AX: VoiceOver iframe scrolling focus jumping bug
+ https://bugs.webkit.org/show_bug.cgi?id=176615
+ <rdar://problem/34333067>
+
+ Reviewed by Chris Fleizach.
+
+ Scrolling to make elements visible is not working correctly for elements inside an
+ offscreen iframe. Fixed it by using RenderLayer::scrollRectToVisible() to handle
+ scrolling more properly.
+
+ Test: accessibility/scroll-to-make-visible-iframe-offscreen.html
+
+ * accessibility/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::scrollToMakeVisible const):
+
2018-05-09 Joanmarie Diggs <jdi...@igalia.com>
AX: accessibleNameForNode should simplify whitespace when using innerText
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (231627 => 231628)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2018-05-10 01:49:54 UTC (rev 231627)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2018-05-10 02:07:34 UTC (rev 231628)
@@ -2981,9 +2981,12 @@
{
if (dispatchAccessibilityEventWithType(AccessibilityEventType::ScrollIntoView))
return;
- IntRect objectRect = snappedIntRect(boundingBoxRect());
- objectRect.setLocation(IntPoint());
- scrollToMakeVisibleWithSubFocus(objectRect);
+
+ if (isScrollView() && parentObject())
+ parentObject()->scrollToMakeVisible();
+
+ if (auto* renderer = this->renderer())
+ renderer->scrollRectToVisible(SelectionRevealMode::Reveal, boundingBoxRect(), false, ScrollAlignment::alignCenterIfNotVisible, ScrollAlignment::alignCenterIfNotVisible);
}
void AccessibilityObject::scrollToMakeVisibleWithSubFocus(const IntRect& subfocus) const