Commit 806b1c0c authored by Victor Fei's avatar Victor Fei Committed by Commit Bot

UIA: SelectionItem::get_IsSelected default to return false

Fix for AXPlatformNodeWin::get_IsSelected (ISelectionItemProvider::
get_IsSelected) to return false by default if the node supports
ISelectionItemProvider. Previously, we threw UIA_E_INVALIDOPERATION
for node that supports ISelectionItemProvider but not explicitly
marked as selected.

The motivation behind this change is due to Windows Narrator announcing
"No Item in View" for list items because their ISelectionItemProvider::
get_IsSelected by default returns UIA_E_INVALIDOPERATION and confuses
Narrator.

Bug: 844149
Change-Id: Iafc1c083dd0feb98b8d1a2d3b18c38284105e2e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1810060
Commit-Queue: Victor Fei <vicfei@microsoft.com>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#698537}
parent d2c99f0c
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<ul> <ul>
<li> First item properly groups itself despite <b>bolded</b> text. <li> First item properly groups itself despite <b>bolded</b> text.
<li>This should also be <i>seen</i> as a group. <li>This should also be <i>seen</i> as a group.
<li> Some <strong>more</strong> text. <li> Some <strong>more</strong> text.
<!-- Omission of closing ul as seen in live site --> <!-- Omission of closing ul as seen in live site -->
</body> </body>
</html> </html>
...@@ -2,21 +2,21 @@ ...@@ -2,21 +2,21 @@
@MAC-ALLOW:AXSubrole* @MAC-ALLOW:AXSubrole*
--> -->
<html> <html>
<style type="text/css"> <style type="text/css">
.inlineList li { .inlineList li {
display: inline; display: inline;
} }
</style> </style>
<body> <body>
<ul> <ul>
<li>tic</li> <li>tic</li>
<li>tac</li> <li>tac</li>
<li>toe</li> <li>toe</li>
</ul> </ul>
<ul class="inlineList"> <ul class="inlineList">
<li>tic</li> <li>tic</li>
<li>tac</li> <li>tac</li>
<li>toe</li> <li>toe</li>
</ul> </ul>
</body> </body>
</html> </html>
...@@ -459,14 +459,24 @@ bool AXPlatformNodeBase::IsSelectionItemSupported() const { ...@@ -459,14 +459,24 @@ bool AXPlatformNodeBase::IsSelectionItemSupported() const {
return table->GetData().role == ax::mojom::Role::kGrid || return table->GetData().role == ax::mojom::Role::kGrid ||
table->GetData().role == ax::mojom::Role::kTreeGrid; table->GetData().role == ax::mojom::Role::kTreeGrid;
} }
// https://www.w3.org/TR/core-aam-1.1/#mapping_state-property_table
// SelectionItem.IsSelected is exposed when aria-checked is True or False,
// for 'radio' and 'menuitemradio' roles.
case ax::mojom::Role::kRadioButton:
case ax::mojom::Role::kMenuItemRadio: {
if (GetData().GetCheckedState() == ax::mojom::CheckedState::kTrue ||
GetData().GetCheckedState() == ax::mojom::CheckedState::kFalse)
return true;
return false;
}
// https://www.w3.org/TR/wai-aria-1.1/#aria-selected
// SelectionItem.IsSelected is exposed when aria-select is True or False.
case ax::mojom::Role::kListBoxOption: case ax::mojom::Role::kListBoxOption:
case ax::mojom::Role::kListItem: case ax::mojom::Role::kListItem:
case ax::mojom::Role::kMenuItemRadio:
case ax::mojom::Role::kMenuListOption: case ax::mojom::Role::kMenuListOption:
case ax::mojom::Role::kRadioButton:
case ax::mojom::Role::kTab: case ax::mojom::Role::kTab:
case ax::mojom::Role::kTreeItem: case ax::mojom::Role::kTreeItem:
return true; return HasBoolAttribute(ax::mojom::BoolAttribute::kSelected);
default: default:
return false; return false;
} }
......
...@@ -2024,9 +2024,6 @@ IFACEMETHODIMP AXPlatformNodeWin::get_VerticalViewSize(double* result) { ...@@ -2024,9 +2024,6 @@ IFACEMETHODIMP AXPlatformNodeWin::get_VerticalViewSize(double* result) {
HRESULT AXPlatformNodeWin::ISelectionItemProviderSetSelected(bool selected) { HRESULT AXPlatformNodeWin::ISelectionItemProviderSetSelected(bool selected) {
UIA_VALIDATE_CALL(); UIA_VALIDATE_CALL();
if (!IsSelectionItemSupported())
return UIA_E_INVALIDOPERATION;
int restriction; int restriction;
if (GetIntAttribute(ax::mojom::IntAttribute::kRestriction, &restriction)) { if (GetIntAttribute(ax::mojom::IntAttribute::kRestriction, &restriction)) {
if (restriction == static_cast<int>(ax::mojom::Restriction::kDisabled)) if (restriction == static_cast<int>(ax::mojom::Restriction::kDisabled))
...@@ -2064,38 +2061,23 @@ IFACEMETHODIMP AXPlatformNodeWin::Select() { ...@@ -2064,38 +2061,23 @@ IFACEMETHODIMP AXPlatformNodeWin::Select() {
IFACEMETHODIMP AXPlatformNodeWin::get_IsSelected(BOOL* result) { IFACEMETHODIMP AXPlatformNodeWin::get_IsSelected(BOOL* result) {
WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTIONITEM_GET_ISSELECTED); WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTIONITEM_GET_ISSELECTED);
UIA_VALIDATE_CALL_1_ARG(result); UIA_VALIDATE_CALL_1_ARG(result);
if (!IsSelectionItemSupported())
return UIA_E_INVALIDOPERATION;
// https://www.w3.org/TR/core-aam-1.1/#mapping_state-property_table // https://www.w3.org/TR/core-aam-1.1/#mapping_state-property_table
// SelectionItem.IsSelected is exposed when aria-checked is True or False, // SelectionItem.IsSelected is set according to the True or False value of
// for 'radio' and 'menuitemradio' roles // aria-checked for 'radio' and 'menuitemradio' roles.
if (GetData().role == ax::mojom::Role::kRadioButton || if (GetData().role == ax::mojom::Role::kRadioButton ||
GetData().role == ax::mojom::Role::kMenuItemRadio) { GetData().role == ax::mojom::Role::kMenuItemRadio) {
const auto checked_state = GetData().GetCheckedState(); *result = (GetData().GetCheckedState() == ax::mojom::CheckedState::kTrue);
switch (checked_state) { return S_OK;
case ax::mojom::CheckedState::kTrue:
case ax::mojom::CheckedState::kFalse: {
*result = (checked_state == ax::mojom::CheckedState::kTrue);
return S_OK;
}
case ax::mojom::CheckedState::kMixed:
case ax::mojom::CheckedState::kNone: {
return UIA_E_INVALIDOPERATION;
}
}
} }
// https://www.w3.org/TR/wai-aria-1.1/#aria-selected // https://www.w3.org/TR/wai-aria-1.1/#aria-selected
// Elements are not selectable when aria-selected is undefined // SelectionItem.IsSelected is set according to the True or False value of
// aria-selected.
bool is_selected; bool is_selected;
if (GetBoolAttribute(ax::mojom::BoolAttribute::kSelected, &is_selected)) { if (GetBoolAttribute(ax::mojom::BoolAttribute::kSelected, &is_selected))
*result = is_selected; *result = is_selected;
return S_OK;
}
return UIA_E_INVALIDOPERATION; return S_OK;
} }
IFACEMETHODIMP AXPlatformNodeWin::get_SelectionContainer( IFACEMETHODIMP AXPlatformNodeWin::get_SelectionContainer(
......
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