From e9753328dd5ee63117a95b54f0015656b77965ab Mon Sep 17 00:00:00 2001 From: Chun-Heng Tai Date: Mon, 15 May 2023 10:11:45 -0700 Subject: [PATCH] Overrides accessibilityScrollToVisible --- .../ios/framework/Source/SemanticsObject.mm | 16 ++++++++ .../framework/Source/SemanticsObjectTest.mm | 39 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm b/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm index 68f1beb7c31bc..a12f60c538540 100644 --- a/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm +++ b/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm @@ -569,6 +569,22 @@ - (id)_accessibilityHitTest:(CGPoint)point withEvent:(UIEvent*)event { return [self search:point]; } +// A private API iOS called when an item is swipe-to-focusd in VoiceOver. +- (BOOL)accessibilityScrollToVisible { + [self bridge]->DispatchSemanticsAction([self uid], flutter::SemanticsAction::kShowOnScreen); + // There is no documentation on the return value. It doesn't appear + // to make a difference whether it returns YES or NO. Use Yes for now. + return YES; +} + +// A private API iOS called when an item is swipe-to-focusd VoiceOver. +// +// There isn't a documentation on the input child, and the `child` appears always +// the same object of `self`. +- (BOOL)accessibilityScrollToVisibleWithChild:(id)child { + return [child accessibilityScrollToVisible]; +} + - (NSAttributedString*)accessibilityAttributedLabel { NSString* label = [self accessibilityLabel]; if (label.length == 0) { diff --git a/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm b/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm index cc2e29a126a92..48ebd0063563a 100644 --- a/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm +++ b/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm @@ -93,7 +93,8 @@ @interface SemanticsObjectTest : XCTestCase @end @interface SemanticsObject (Tests) - +- (BOOL)accessibilityScrollToVisible; +- (BOOL)accessibilityScrollToVisibleWithChild:(id)child; - (id)_accessibilityHitTest:(CGPoint)point withEvent:(UIEvent*)event; @end @@ -202,6 +203,42 @@ - (void)testAccessibilityHitTestNoFocusableItem { XCTAssertNil(hitTestResult); } +- (void)testAccessibilityScrollToVisible { + fml::WeakPtrFactory factory( + new flutter::MockAccessibilityBridge()); + fml::WeakPtr bridge = factory.GetWeakPtr(); + SemanticsObject* object3 = [[SemanticsObject alloc] initWithBridge:bridge uid:3]; + + flutter::SemanticsNode node3; + node3.id = 3; + node3.rect = SkRect::MakeXYWH(0, 0, 200, 200); + [object3 setSemanticsNode:&node3]; + + [object3 accessibilityScrollToVisible]; + + XCTAssertTrue(bridge->observations.size() == 1); + XCTAssertTrue(bridge->observations[0].id == 3); + XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen); +} + +- (void)testAccessibilityScrollToVisibleWithChild { + fml::WeakPtrFactory factory( + new flutter::MockAccessibilityBridge()); + fml::WeakPtr bridge = factory.GetWeakPtr(); + SemanticsObject* object3 = [[SemanticsObject alloc] initWithBridge:bridge uid:3]; + + flutter::SemanticsNode node3; + node3.id = 3; + node3.rect = SkRect::MakeXYWH(0, 0, 200, 200); + [object3 setSemanticsNode:&node3]; + + [object3 accessibilityScrollToVisibleWithChild:object3]; + + XCTAssertTrue(bridge->observations.size() == 1); + XCTAssertTrue(bridge->observations[0].id == 3); + XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen); +} + - (void)testAccessibilityHitTestOutOfRect { fml::WeakPtrFactory factory( new flutter::MockAccessibilityBridge());