Commit 993145d4 authored by Nektarios Paisios's avatar Nektarios Paisios Committed by Commit Bot

Translates selection offsets from ignored to unignored and vice versa

Anchor and focus offsets in accessibility selection may refer to children that are
ignored but are included in the accessibility tree.
We need to translate between ignored and unignored offsets at the platform boundary
both when setting as well as when retrieving the selection.

AX-Relnotes: Reading the current selection as well as setting the selection using Jaws and NVDA no longer reads
the wrong selection or fails to set the selection.

R=dmazzoni@chromium.org, aleventhal@chromium.org

Bug: 1082814
Change-Id: I4530f3079eaa282d6db9778f7d6af221345841f9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2205400
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#773159}
parent aa40934a
......@@ -449,7 +449,7 @@ BrowserAccessibility::InternalChildrenEnd() const {
}
int32_t BrowserAccessibility::GetId() const {
return node_ ? node_->id() : -1;
return node()->id();
}
gfx::RectF BrowserAccessibility::GetLocation() const {
......@@ -1487,10 +1487,43 @@ const ui::AXTreeData& BrowserAccessibility::GetTreeData() const {
const ui::AXTree::Selection BrowserAccessibility::GetUnignoredSelection()
const {
if (manager())
return manager()->ax_tree()->GetUnignoredSelection();
return ui::AXTree::Selection{-1, -1, -1,
ax::mojom::TextAffinity::kDownstream};
DCHECK(manager());
ui::AXTree::Selection selection =
manager()->ax_tree()->GetUnignoredSelection();
// "selection.anchor_offset" and "selection.focus_ofset" might need to be
// adjusted if the anchor or the focus nodes include ignored children.
const BrowserAccessibility* anchor_object =
manager()->GetFromID(selection.anchor_object_id);
if (anchor_object && !anchor_object->PlatformIsLeaf()) {
DCHECK_GE(selection.anchor_offset, 0);
if (size_t{selection.anchor_offset} <
anchor_object->node()->children().size()) {
const ui::AXNode* anchor_child =
anchor_object->node()->children()[selection.anchor_offset];
DCHECK(anchor_child);
selection.anchor_offset = int{anchor_child->GetUnignoredIndexInParent()};
} else {
selection.anchor_offset = anchor_object->GetChildCount();
}
}
const BrowserAccessibility* focus_object =
manager()->GetFromID(selection.focus_object_id);
if (focus_object && !focus_object->PlatformIsLeaf()) {
DCHECK_GE(selection.focus_offset, 0);
if (size_t{selection.focus_offset} <
focus_object->node()->children().size()) {
const ui::AXNode* focus_child =
focus_object->node()->children()[selection.focus_offset];
DCHECK(focus_child);
selection.focus_offset = int{focus_child->GetUnignoredIndexInParent()};
} else {
selection.focus_offset = focus_object->GetChildCount();
}
}
return selection;
}
ui::AXNodePosition::AXPositionInstance
......@@ -1520,7 +1553,7 @@ gfx::NativeViewAccessible BrowserAccessibility::GetParent() {
}
int BrowserAccessibility::GetChildCount() const {
return PlatformChildCount();
return int{PlatformChildCount()};
}
gfx::NativeViewAccessible BrowserAccessibility::ChildAtIndex(int index) {
......@@ -1709,7 +1742,7 @@ int BrowserAccessibility::GetIndexInParent() {
// index at AXPlatformNodeBase.
return -1;
}
return node_ ? node_->GetUnignoredIndexInParent() : -1;
return node()->GetUnignoredIndexInParent();
}
gfx::AcceleratedWidget
......@@ -1869,9 +1902,34 @@ bool BrowserAccessibility::AccessibilityPerformAction(
case ax::mojom::Action::kSetScrollOffset:
manager_->SetScrollOffset(*this, data.target_point);
return true;
case ax::mojom::Action::kSetSelection:
manager_->SetSelection(data);
case ax::mojom::Action::kSetSelection: {
// "data.anchor_offset" and "data.focus_ofset" might need to be adjusted
// if the anchor or the focus nodes include ignored children.
ui::AXActionData selection = data;
const BrowserAccessibility* anchor_object =
manager()->GetFromID(selection.anchor_node_id);
DCHECK(anchor_object);
if (!anchor_object->PlatformIsLeaf()) {
const BrowserAccessibility* anchor_child =
anchor_object->InternalGetChild(uint32_t{selection.anchor_offset});
if (anchor_child)
selection.anchor_offset =
int{anchor_child->node()->index_in_parent()};
}
const BrowserAccessibility* focus_object =
manager()->GetFromID(selection.focus_node_id);
DCHECK(focus_object);
if (!focus_object->PlatformIsLeaf()) {
const BrowserAccessibility* focus_child =
focus_object->InternalGetChild(uint32_t{selection.focus_offset});
if (focus_child)
selection.focus_offset = int{focus_child->node()->index_in_parent()};
}
manager_->SetSelection(selection);
return true;
}
case ax::mojom::Action::kSetValue:
manager_->SetValue(*this, data.value);
return true;
......
......@@ -29,9 +29,10 @@ AXNodePosition::AXPositionInstance AXNodePosition::CreatePosition(
return CreateNullPosition();
AXTreeID tree_id = node.tree()->GetAXTreeID();
if (node.IsText())
if (node.IsText()) {
return CreateTextPosition(tree_id, node.id(), child_index_or_text_offset,
affinity);
}
return CreateTreePosition(tree_id, node.id(), child_index_or_text_offset);
}
......
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