Title: [223726] trunk
Revision
223726
Author
n_w...@apple.com
Date
2017-10-19 16:34:16 -0700 (Thu, 19 Oct 2017)

Log Message

AX: Provide a way for Accessibility to cache the selection while retrieving rects for speak selection
https://bugs.webkit.org/show_bug.cgi?id=176247
<rdar://problem/34217143>

Reviewed by Ryosuke Niwa.

Source/WebKit:

When getting the rects for highlighting the spoken text within a selection range on iOS, we can get a
list of totally wrong rects if the user changed the selection to some other text. This is because the
calculation is based on the current selection range. Therefore, we need to provide a way for accessibility
codepath to store the selection during a speaking session.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _accessibilityStoreSelection]):
(-[WKWebView _accessibilityClearSelection]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _accessibilityStoreSelection]):
(-[WKContentView _accessibilityClearSelection]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::storeSelectionForAccessibility):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getRectsForGranularityWithSelectionOffset):
(WebKit::WebPage::storeSelectionForAccessibility):
(WebKit::WebPage::getRectsAtSelectionOffsetWithText):

Tools:

* TestWebKitAPI/Tests/ios/AccessibilityTestsIOS.mm:
(TestWebKitAPI::TEST):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (223725 => 223726)


--- trunk/Source/WebKit/ChangeLog	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/ChangeLog	2017-10-19 23:34:16 UTC (rev 223726)
@@ -1,3 +1,34 @@
+2017-10-19  Nan Wang  <n_w...@apple.com>
+
+        AX: Provide a way for Accessibility to cache the selection while retrieving rects for speak selection
+        https://bugs.webkit.org/show_bug.cgi?id=176247
+        <rdar://problem/34217143>
+
+        Reviewed by Ryosuke Niwa.
+
+        When getting the rects for highlighting the spoken text within a selection range on iOS, we can get a
+        list of totally wrong rects if the user changed the selection to some other text. This is because the
+        calculation is based on the current selection range. Therefore, we need to provide a way for accessibility
+        codepath to store the selection during a speaking session.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _accessibilityStoreSelection]):
+        (-[WKWebView _accessibilityClearSelection]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _accessibilityStoreSelection]):
+        (-[WKContentView _accessibilityClearSelection]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::storeSelectionForAccessibility):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::getRectsForGranularityWithSelectionOffset):
+        (WebKit::WebPage::storeSelectionForAccessibility):
+        (WebKit::WebPage::getRectsAtSelectionOffsetWithText):
+
 2017-10-19  Sam Weinig  <s...@webkit.org>
 
         [Settings] Move global settings into their own file

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (223725 => 223726)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2017-10-19 23:34:16 UTC (rev 223726)
@@ -5531,6 +5531,16 @@
     }];
 }
 
+- (void)_accessibilityStoreSelection
+{
+    [_contentView _accessibilityStoreSelection];
+}
+
+- (void)_accessibilityClearSelection
+{
+    [_contentView _accessibilityClearSelection];
+}
+
 - (CGRect)_contentVisibleRect
 {
     return [self convertRect:[self bounds] toView:self._currentContentView];

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (223725 => 223726)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2017-10-19 23:34:16 UTC (rev 223726)
@@ -392,6 +392,8 @@
 
 - (void)_requestActivatedElementAtPosition:(CGPoint)position completionBlock:(void (^)(_WKActivatedElementInfo *))block WK_API_AVAILABLE(ios(11.0));
 - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text completionHandler:(void (^)(NSArray<NSValue *> *rects))completionHandler WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)_accessibilityStoreSelection WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)_accessibilityClearSelection WK_API_AVAILABLE(ios(WK_IOS_TBA));
 
 #else
 - (void)_dismissContentRelativeChildWindows WK_API_AVAILABLE(macosx(WK_MAC_TBA));

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (223725 => 223726)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2017-10-19 23:34:16 UTC (rev 223726)
@@ -562,6 +562,7 @@
     void requestRectsForGranularityWithSelectionOffset(WebCore::TextGranularity, uint32_t offset, WTF::Function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>&&);
     void requestRectsAtSelectionOffsetWithText(int32_t offset, const String&, WTF::Function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>&&);
     void autofillLoginCredentials(const String& username, const String& password);
+    void storeSelectionForAccessibility(bool);
 #if ENABLE(DATA_INTERACTION)
     void didPerformDataInteractionControllerOperation(bool handled);
     void didHandleStartDataInteractionRequest(bool started);

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (223725 => 223726)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2017-10-19 23:34:16 UTC (rev 223726)
@@ -312,6 +312,8 @@
 - (void)_accessibilityRetrieveRectsEnclosingSelectionOffset:(NSInteger)offset withGranularity:(UITextGranularity)granularity;
 - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text completionHandler:(void (^)(const Vector<WebCore::SelectionRect>& rects))completionHandler;
 - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text;
+- (void)_accessibilityStoreSelection;
+- (void)_accessibilityClearSelection;
 
 @property (nonatomic, readonly) WebKit::InteractionInformationAtPosition currentPositionInformation;
 - (void)doAfterPositionInformationUpdate:(void (^)(WebKit::InteractionInformationAtPosition))action forRequest:(WebKit::InteractionInformationRequest)request;

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (223725 => 223726)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2017-10-19 23:34:16 UTC (rev 223726)
@@ -2307,6 +2307,16 @@
     });
 }
 
+- (void)_accessibilityStoreSelection
+{
+    _page->storeSelectionForAccessibility(true);
+}
+
+- (void)_accessibilityClearSelection
+{
+    _page->storeSelectionForAccessibility(false);
+}
+
 // UIWKInteractionViewProtocol
 
 static inline GestureType toGestureType(UIWKGestureType gestureType)

Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (223725 => 223726)


--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2017-10-19 23:34:16 UTC (rev 223726)
@@ -723,6 +723,11 @@
     m_process->send(Messages::WebPage::GetRectsAtSelectionOffsetWithText(offset, text, callbackID), m_pageID);
 }
 
+void WebPageProxy::storeSelectionForAccessibility(bool shouldStore)
+{
+    m_process->send(Messages::WebPage::StoreSelectionForAccessibility(shouldStore), m_pageID);
+}
+
 void WebPageProxy::moveSelectionByOffset(int32_t offset, WTF::Function<void (CallbackBase::Error)>&& callbackFunction)
 {
     if (!isValid()) {

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (223725 => 223726)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2017-10-19 23:34:16 UTC (rev 223726)
@@ -96,6 +96,7 @@
 #endif
 
 #if PLATFORM(COCOA)
+#include <WebCore/VisibleSelection.h>
 #include <wtf/RetainPtr.h>
 OBJC_CLASS CALayer;
 OBJC_CLASS NSArray;
@@ -137,7 +138,6 @@
 class TextCheckingRequest;
 class URL;
 class VisiblePosition;
-class VisibleSelection;
 enum class TextIndicatorPresentationTransition : uint8_t;
 enum SyntheticClickType : int8_t;
 struct CompositionUnderline;
@@ -586,6 +586,7 @@
     void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
     void getRectsForGranularityWithSelectionOffset(uint32_t, int32_t, CallbackID);
     void getRectsAtSelectionOffsetWithText(int32_t, const String&, CallbackID);
+    void storeSelectionForAccessibility(bool);
 #if ENABLE(IOS_TOUCH_EVENTS)
     void dispatchAsynchronousTouchEvents(const Vector<WebTouchEvent, 1>& queue);
 #endif
@@ -1527,6 +1528,7 @@
     bool m_allowsBlockSelection { false };
 
     RefPtr<WebCore::Range> m_initialSelection;
+    WebCore::VisibleSelection m_storedSelectionForAccessibility { WebCore::VisibleSelection() };
     WebCore::IntSize m_blockSelectionDesiredSize;
     WebCore::FloatSize m_maximumUnobscuredSize;
     int32_t m_deviceOrientation { 0 };

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (223725 => 223726)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2017-10-19 23:34:16 UTC (rev 223726)
@@ -97,8 +97,9 @@
     SetAllowsMediaDocumentInlinePlayback(bool allows)
     HandleTwoFingerTapAtPoint(WebCore::IntPoint point, uint64_t requestID)
     SetForceAlwaysUserScalable(bool userScalable)
-    GetRectsForGranularityWithSelectionOffset(uint32_t granularity, int32_t offset, WebKit::CallbackID callbackID);
-    GetRectsAtSelectionOffsetWithText(int32_t offset, String text, WebKit::CallbackID callbackID);
+    GetRectsForGranularityWithSelectionOffset(uint32_t granularity, int32_t offset, WebKit::CallbackID callbackID)
+    GetRectsAtSelectionOffsetWithText(int32_t offset, String text, WebKit::CallbackID callbackID)
+    StoreSelectionForAccessibility(bool shouldStore)
 #endif
 
     SetControlledByAutomation(bool controlled)

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (223725 => 223726)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2017-10-19 23:34:16 UTC (rev 223726)
@@ -1867,7 +1867,7 @@
 void WebPage::getRectsForGranularityWithSelectionOffset(uint32_t granularity, int32_t offset, CallbackID callbackID)
 {
     Frame& frame = m_page->focusController().focusedOrMainFrame();
-    VisibleSelection selection = frame.selection().selection();
+    VisibleSelection selection = m_storedSelectionForAccessibility.isNone() ? frame.selection().selection() : m_storedSelectionForAccessibility;
     VisiblePosition selectionStart = selection.visibleStart();
 
     if (selectionStart.isNull()) {
@@ -1890,6 +1890,16 @@
     send(Messages::WebPageProxy::SelectionRectsCallback(selectionRects, callbackID));
 }
 
+void WebPage::storeSelectionForAccessibility(bool shouldStore)
+{
+    if (!shouldStore)
+        m_storedSelectionForAccessibility = VisibleSelection();
+    else {
+        Frame& frame = m_page->focusController().focusedOrMainFrame();
+        m_storedSelectionForAccessibility = frame.selection().selection();
+    }
+}
+
 static RefPtr<Range> rangeNearPositionMatchesText(const VisiblePosition& position, RefPtr<Range> originalRange, const String& matchText, RefPtr<Range> selectionRange)
 {
     auto range = Range::create(selectionRange->ownerDocument(), selectionRange->startPosition(), position.deepEquivalent().parentAnchoredEquivalent());
@@ -1901,7 +1911,7 @@
 {
     Frame& frame = m_page->focusController().focusedOrMainFrame();
     uint32_t length = text.length();
-    VisibleSelection selection = frame.selection().selection();
+    VisibleSelection selection = m_storedSelectionForAccessibility.isNone() ? frame.selection().selection() : m_storedSelectionForAccessibility;
     VisiblePosition selectionStart = selection.visibleStart();
     VisiblePosition selectionEnd = selection.visibleEnd();
 

Modified: trunk/Tools/ChangeLog (223725 => 223726)


--- trunk/Tools/ChangeLog	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Tools/ChangeLog	2017-10-19 23:34:16 UTC (rev 223726)
@@ -1,3 +1,14 @@
+2017-10-19  Nan Wang  <n_w...@apple.com>
+
+        AX: Provide a way for Accessibility to cache the selection while retrieving rects for speak selection
+        https://bugs.webkit.org/show_bug.cgi?id=176247
+        <rdar://problem/34217143>
+
+        Reviewed by Ryosuke Niwa.
+
+        * TestWebKitAPI/Tests/ios/AccessibilityTestsIOS.mm:
+        (TestWebKitAPI::TEST):
+
 2017-10-19  Sam Weinig  <s...@webkit.org>
 
         [Settings] Move global settings into their own file

Modified: trunk/Tools/TestWebKitAPI/Tests/ios/AccessibilityTestsIOS.mm (223725 => 223726)


--- trunk/Tools/TestWebKitAPI/Tests/ios/AccessibilityTestsIOS.mm	2017-10-19 23:31:03 UTC (rev 223725)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/AccessibilityTestsIOS.mm	2017-10-19 23:34:16 UTC (rev 223726)
@@ -96,6 +96,24 @@
     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"getSelection().toString()"]);
 }
 
+TEST(AccessibilityTests, StoreSelection)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width,initial-scale=1'><span id='first'>first</span><br><span id='second'>first</span>"];
+    
+    // Select first node and store the selection
+    [webView stringByEvaluatingJavaScript:@"getSelection().setBaseAndExtent(first, 0, first, 1)"];
+    [webView _accessibilityStoreSelection];
+    checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 8, 26, 19), 0);
+    // Now select the second node, we should use the stored selection to retrieve rects
+    [webView stringByEvaluatingJavaScript:@"getSelection().setBaseAndExtent(second, 0, second, 1)"];
+    checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 8, 26, 19), 0);
+    
+    // Clear the stored selection, we should use the current selection to retrieve rects
+    [webView _accessibilityClearSelection];
+    checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 27, 26, 20), 0);
+}
+
 } // namespace TestWebKitAPI
 
 #endif // PLATFORM(IOS) && WK_API_ENABLED
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to