Browse Source

fix: port CL that fixes ARIA tree impl for macOS (#22367)

loc 5 years ago
parent
commit
fc54db11f3

+ 1 - 0
patches/chromium/.patches

@@ -86,4 +86,5 @@ fix_use_native_window_button_positions_when_macos_locale_is_rtl.patch
 use_electron_resources_in_pdf_util.patch
 hack_plugin_response_interceptor_to_point_to_electron.patch
 fix_route_mouse_event_navigations_through_the_web_contents_delegate.patch
+expose_aria_trees_as_tables_for_macos_accessibility.patch
 feat_add_support_for_overriding_the_base_spellchecker_download_url.patch

+ 118 - 0
patches/chromium/expose_aria_trees_as_tables_for_macos_accessibility.patch

@@ -0,0 +1,118 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Andy Locascio <[email protected]>
+Date: Mon, 24 Feb 2020 13:50:29 -0800
+Subject: Expose ARIA trees as tables for macOS accessibility
+
+ARIA trees were previously un-navigable with VoiceOver on macOS. This
+was because it didn't properly fulfill the NSAccessibilityRowsAttribute
+attribute.
+
+In webkit, this attribute is fulfilled by diving on the row's children
+and surfacing any TreeItem elements. This CL represents a port of their
+implementation.
+
+Additionally, I noticed a confusing spot where the subrole is being
+compared in a long line of role comparisons. I moved this around to be
+less foot-gunny/confusing and added more attributes for the OutlineRow
+subrole that macOS accessibility suggests are necessary (and exist in
+the webkit implementation).
+
+Link to webkit impl:
+https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm#L2836
+https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/accessibility/AccessibilityObject.cpp#L1804
+
+Bug: 868480
+Test: Use VoiceOver to navigate the table at https://cookiecrook.com/test/aria/tree/ariatree2.html. Note that the table is no longer announced as empty.
+Change-Id: Ibb86049efa23e12875aa9aeda541e0145242e3b5
+
+diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h
+index 0216501dda1dc8b8fb4307785a0dab868bc3315a..f9730f71c122965f7ce7815a1b9a7b32f8a224f0 100644
+--- a/content/browser/accessibility/browser_accessibility_cocoa.h
++++ b/content/browser/accessibility/browser_accessibility_cocoa.h
+@@ -6,6 +6,7 @@
+ #define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_COCOA_H_
+ 
+ #import <Cocoa/Cocoa.h>
++#include <vector>
+ 
+ #import "base/mac/scoped_nsobject.h"
+ #include "base/strings/string16.h"
+@@ -75,6 +76,8 @@ struct AXTextEdit {
+ // left).
+ - (NSRect)rectInScreen:(gfx::Rect)rect;
+ 
++- (void)getTreeItemDescendantNodeIds:(std::vector<int32_t>*)tree_item_ids;
++
+ // Return the method name for the given attribute. For testing only.
+ - (NSString*)methodNameForAttribute:(NSString*)attribute;
+ 
+diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
+index 1381a64458dd37d07c72c3265e46166935012cad..5a9ab09b5214f9a8c38756fb627d32b52b028539 100644
+--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
++++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
+@@ -2110,7 +2110,9 @@ - (NSArray*)rows {
+   NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
+ 
+   std::vector<int32_t> node_id_list;
+-  if (ui::IsTableLike(_owner->GetRole()))
++  if (_owner->GetRole() == ax::mojom::Role::kTree)
++    [self getTreeItemDescendantNodeIds:&node_id_list];
++  else if (ui::IsTableLike(_owner->GetRole()))
+     node_id_list = _owner->node()->GetTableRowNodeIds();
+   // Rows attribute for a column is the list of all the elements in that column
+   // at each row.
+@@ -2543,6 +2545,19 @@ - (id)window {
+   return manager->GetWindow();
+ }
+ 
++- (void)getTreeItemDescendantNodeIds:(std::vector<int32_t>*)tree_item_ids {
++  for (auto it = _owner->PlatformChildrenBegin();
++       it != _owner->PlatformChildrenEnd(); ++it) {
++    const BrowserAccessibilityCocoa* child =
++        ToBrowserAccessibilityCocoa(it.get());
++
++    if ([child internalRole] == ax::mojom::Role::kTreeItem) {
++      tree_item_ids->push_back([child hash]);
++    }
++    [child getTreeItemDescendantNodeIds:tree_item_ids];
++  }
++}
++
+ - (NSString*)methodNameForAttribute:(NSString*)attribute {
+   return [attributeToMethodNameMap objectForKey:attribute];
+ }
+@@ -3361,18 +3376,12 @@ - (NSArray*)accessibilityAttributeNames {
+       NSAccessibilityMaxValueAttribute, NSAccessibilityMinValueAttribute,
+       NSAccessibilityValueDescriptionAttribute
+     ]];
+-  } else if ([subrole isEqualToString:NSAccessibilityOutlineRowSubrole]) {
+-    [ret addObjectsFromArray:@[
+-      NSAccessibilityDisclosingAttribute,
+-      NSAccessibilityDisclosedByRowAttribute,
+-      NSAccessibilityDisclosureLevelAttribute,
+-      NSAccessibilityDisclosedRowsAttribute
+-    ]];
+   } else if ([role isEqualToString:NSAccessibilityRowRole]) {
+     BrowserAccessibility* container = _owner->PlatformGetParent();
+     if (container && container->GetRole() == ax::mojom::Role::kRowGroup)
+       container = container->PlatformGetParent();
+-    if (container && container->GetRole() == ax::mojom::Role::kTreeGrid) {
++    if ([subrole isEqualToString:NSAccessibilityOutlineRowSubrole] ||
++        (container && container->GetRole() == ax::mojom::Role::kTreeGrid)) {
+       [ret addObjectsFromArray:@[
+         NSAccessibilityDisclosingAttribute,
+         NSAccessibilityDisclosedByRowAttribute,
+@@ -3387,6 +3396,13 @@ - (NSArray*)accessibilityAttributeNames {
+       NSAccessibilitySelectedChildrenAttribute,
+       NSAccessibilityVisibleChildrenAttribute
+     ]];
++  } else if ([role isEqualToString:NSAccessibilityOutlineRole]) {
++    [ret addObjectsFromArray:@[
++      NSAccessibilitySelectedRowsAttribute,
++      NSAccessibilityRowsAttribute,
++      NSAccessibilityColumnsAttribute,
++      NSAccessibilityOrientationAttribute
++    ]];
+   }
+ 
+   // Caret navigation and text selection attributes.