Commit 7cf6d186 authored by Mohamed Mansour's avatar Mohamed Mansour Committed by Commit Bot

Views a11y: Announce Table Columns for TableView

Implements the ITableProvider and ITableItemProvider for UIA.
Currently just supports TableView's column headers. Row headers
are not supported in TableView's control.

AX-Relnotes: Column Headers in TableView are announceable.
Bug: 1078623
Change-Id: I7c8ba49cd8de9fffe471e91c4d6d4e759c9ddc29
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2348541
Commit-Queue: Mohamed Mansour <mmansour@microsoft.com>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799200}
parent 1569b82f
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "ui/base/ui_base_types.h" #include "ui/base/ui_base_types.h"
#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/rect_conversions.h"
#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/accessibility/view_ax_platform_node_delegate.h"
#include "ui/views/view.h" #include "ui/views/view.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
...@@ -386,7 +387,10 @@ gfx::NativeViewAccessible AXVirtualView::GetFocus() { ...@@ -386,7 +387,10 @@ gfx::NativeViewAccessible AXVirtualView::GetFocus() {
} }
ui::AXPlatformNode* AXVirtualView::GetFromNodeID(int32_t id) { ui::AXPlatformNode* AXVirtualView::GetFromNodeID(int32_t id) {
// TODO(nektar): Implement. AXVirtualView* virtual_view = GetFromId(id);
if (virtual_view) {
return virtual_view->ax_platform_node();
}
return nullptr; return nullptr;
} }
...@@ -423,6 +427,18 @@ gfx::AcceleratedWidget AXVirtualView::GetTargetForNativeAccessibilityEvent() { ...@@ -423,6 +427,18 @@ gfx::AcceleratedWidget AXVirtualView::GetTargetForNativeAccessibilityEvent() {
return gfx::kNullAcceleratedWidget; return gfx::kNullAcceleratedWidget;
} }
base::Optional<bool> AXVirtualView::GetTableHasColumnOrRowHeaderNode() const {
return GetDelegate()->GetTableHasColumnOrRowHeaderNode();
}
std::vector<int32_t> AXVirtualView::GetColHeaderNodeIds() const {
return GetDelegate()->GetColHeaderNodeIds();
}
std::vector<int32_t> AXVirtualView::GetColHeaderNodeIds(int col_index) const {
return GetDelegate()->GetColHeaderNodeIds(col_index);
}
bool AXVirtualView::IsIgnored() const { bool AXVirtualView::IsIgnored() const {
return GetData().IsIgnored(); return GetData().IsIgnored();
} }
...@@ -473,6 +489,12 @@ View* AXVirtualView::GetOwnerView() const { ...@@ -473,6 +489,12 @@ View* AXVirtualView::GetOwnerView() const {
return nullptr; return nullptr;
} }
ViewAXPlatformNodeDelegate* AXVirtualView::GetDelegate() const {
DCHECK(GetOwnerView());
return static_cast<ViewAXPlatformNodeDelegate*>(
&GetOwnerView()->GetViewAccessibility());
}
AXVirtualViewWrapper* AXVirtualView::GetOrCreateWrapper( AXVirtualViewWrapper* AXVirtualView::GetOrCreateWrapper(
views::AXAuraObjCache* cache) { views::AXAuraObjCache* cache) {
#if defined(USE_AURA) #if defined(USE_AURA)
......
...@@ -40,6 +40,7 @@ namespace views { ...@@ -40,6 +40,7 @@ namespace views {
class AXAuraObjCache; class AXAuraObjCache;
class View; class View;
class ViewAccessibility; class ViewAccessibility;
class ViewAXPlatformNodeDelegate;
// Implements a virtual view that is used only for accessibility. // Implements a virtual view that is used only for accessibility.
// //
...@@ -99,6 +100,8 @@ class VIEWS_EXPORT AXVirtualView : public ui::AXPlatformNodeDelegateBase { ...@@ -99,6 +100,8 @@ class VIEWS_EXPORT AXVirtualView : public ui::AXPlatformNodeDelegateBase {
} }
AXVirtualView* virtual_parent_view() { return virtual_parent_view_; } AXVirtualView* virtual_parent_view() { return virtual_parent_view_; }
ui::AXPlatformNode* ax_platform_node() { return ax_platform_node_; }
// Returns true if |view| is contained within the hierarchy of this // Returns true if |view| is contained within the hierarchy of this
// AXVirtualView, even as an indirect descendant. Will return true if |view| // AXVirtualView, even as an indirect descendant. Will return true if |view|
// is also this AXVirtualView. // is also this AXVirtualView.
...@@ -153,10 +156,16 @@ class VIEWS_EXPORT AXVirtualView : public ui::AXPlatformNodeDelegateBase { ...@@ -153,10 +156,16 @@ class VIEWS_EXPORT AXVirtualView : public ui::AXPlatformNodeDelegateBase {
bool IsOffscreen() const override; bool IsOffscreen() const override;
const ui::AXUniqueId& GetUniqueId() const override; const ui::AXUniqueId& GetUniqueId() const override;
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override; gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
base::Optional<bool> GetTableHasColumnOrRowHeaderNode() const override;
std::vector<int32_t> GetColHeaderNodeIds() const override;
std::vector<int32_t> GetColHeaderNodeIds(int col_index) const override;
// Gets the real View that owns our shallowest virtual ancestor,, if any. // Gets the real View that owns our shallowest virtual ancestor,, if any.
View* GetOwnerView() const; View* GetOwnerView() const;
// Gets the view platform delegate if exists, otherwise nullptr.
ViewAXPlatformNodeDelegate* GetDelegate() const;
// Gets or creates a wrapper suitable for use with tree sources. // Gets or creates a wrapper suitable for use with tree sources.
AXVirtualViewWrapper* GetOrCreateWrapper(views::AXAuraObjCache* cache); AXVirtualViewWrapper* GetOrCreateWrapper(views::AXAuraObjCache* cache);
......
...@@ -540,6 +540,46 @@ const ui::AXUniqueId& ViewAXPlatformNodeDelegate::GetUniqueId() const { ...@@ -540,6 +540,46 @@ const ui::AXUniqueId& ViewAXPlatformNodeDelegate::GetUniqueId() const {
return ViewAccessibility::GetUniqueId(); return ViewAccessibility::GetUniqueId();
} }
base::Optional<bool>
ViewAXPlatformNodeDelegate::GetTableHasColumnOrRowHeaderNode() const {
if (!GetAncestorTableView())
return false;
return !GetAncestorTableView()->visible_columns().empty();
}
std::vector<int32_t> ViewAXPlatformNodeDelegate::GetColHeaderNodeIds() const {
std::vector<int32_t> col_header_ids;
if (!virtual_children().empty()) {
for (const std::unique_ptr<AXVirtualView>& header_cell :
virtual_children().front()->children()) {
const ui::AXNodeData& header_data = header_cell->GetData();
if (header_data.role == ax::mojom::Role::kColumnHeader) {
col_header_ids.push_back(header_data.id);
}
}
}
return col_header_ids;
}
std::vector<int32_t> ViewAXPlatformNodeDelegate::GetColHeaderNodeIds(
int col_index) const {
std::vector<int32_t> columns = GetColHeaderNodeIds();
if (columns.size() <= size_t{col_index}) {
return {};
}
return {columns[col_index]};
}
TableView* ViewAXPlatformNodeDelegate::GetAncestorTableView() const {
ui::AXNodeData data;
view()->GetViewAccessibility().GetAccessibleNodeData(&data);
if (!ui::IsTableLike(data.role))
return nullptr;
return static_cast<TableView*>(view());
}
bool ViewAXPlatformNodeDelegate::IsOrderedSetItem() const { bool ViewAXPlatformNodeDelegate::IsOrderedSetItem() const {
const ui::AXNodeData& data = GetData(); const ui::AXNodeData& data = GetData();
return (view()->GetGroup() >= 0) || return (view()->GetGroup() >= 0) ||
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/table/table_view.h"
#include "ui/views/widget/widget_observer.h" #include "ui/views/widget/widget_observer.h"
namespace ui { namespace ui {
...@@ -83,6 +84,9 @@ class ViewAXPlatformNodeDelegate : public ViewAccessibility, ...@@ -83,6 +84,9 @@ class ViewAXPlatformNodeDelegate : public ViewAccessibility,
bool IsMinimized() const override; bool IsMinimized() const override;
// Also in |ViewAccessibility|. // Also in |ViewAccessibility|.
const ui::AXUniqueId& GetUniqueId() const override; const ui::AXUniqueId& GetUniqueId() const override;
base::Optional<bool> GetTableHasColumnOrRowHeaderNode() const override;
std::vector<int32_t> GetColHeaderNodeIds() const override;
std::vector<int32_t> GetColHeaderNodeIds(int col_index) const override;
// Ordered-set-like and item-like nodes. // Ordered-set-like and item-like nodes.
bool IsOrderedSetItem() const override; bool IsOrderedSetItem() const override;
...@@ -108,6 +112,9 @@ class ViewAXPlatformNodeDelegate : public ViewAccessibility, ...@@ -108,6 +112,9 @@ class ViewAXPlatformNodeDelegate : public ViewAccessibility,
ChildWidgetsResult GetChildWidgets() const; ChildWidgetsResult GetChildWidgets() const;
// Gets the real TableView, otherwise nullptr.
TableView* GetAncestorTableView() const;
// We own this, but it is reference-counted on some platforms so we can't use // We own this, but it is reference-counted on some platforms so we can't use
// a unique_ptr. It is destroyed in the destructor. // a unique_ptr. It is destroyed in the destructor.
ui::AXPlatformNode* ax_platform_node_; ui::AXPlatformNode* ax_platform_node_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment