Commit 4ea531e4 authored by Nektarios Paisios's avatar Nektarios Paisios Committed by Commit Bot

Expose an embedded object character only for nodes visible to platform APIs

We don't need to use an object replacement character in IAccessible2, UI Automation and Linux ATK
if the node whose text is replacing is not visible to those APIs,
i.e. if the node lies outside the part of the accessibility tree that could be
accessed by platform APIs.
Object replacement characters are only meaningful when they appear in the accessible text for IAccessible2 and ATK,
and only when they are used as a word or character boundary for UI Automation.
Therefore, any object replacement character that cannot be accessed either via IAccessibleText, UIATextRangeProvider,, ATKText, etc.
is unnecessary. We currently don't expose such characters in IA2 hypertext, for example.
It can also make it impossible to compute the equivalent ancestor AXPosition on a text field for
a text position that is pointing to an inline text box inside that field.

This patch improves and generalizes the fix in
https://chromium-review.googlesource.com/c/chromium/src/+/2473065

AX-Relnotes: n/a.

R=dmazzoni@chromium.org, kschmidt@microsoft.com, vicfei@microsoft.com

Bug: 1141171
Change-Id: Ia6699a841dfca59558ed1188de04a06e5b13e66c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2504504Reviewed-by: default avatarAaron Leventhal <aleventhal@chromium.org>
Reviewed-by: default avatarVictor Fei <vicfei@microsoft.com>
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Auto-Submit: Nektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828959}
parent d3d7f623
...@@ -257,18 +257,24 @@ bool AXNodePosition::IsEmbeddedObjectInParent() const { ...@@ -257,18 +257,24 @@ bool AXNodePosition::IsEmbeddedObjectInParent() const {
case AXEmbeddedObjectBehavior::kSuppressCharacter: case AXEmbeddedObjectBehavior::kSuppressCharacter:
return false; return false;
case AXEmbeddedObjectBehavior::kExposeCharacter: case AXEmbeddedObjectBehavior::kExposeCharacter:
// We don't need to expose an "embedded object character" for textual // We expose an "object replacement character" for all nodes except
// nodes as well as nodes that are invisible to platform APIs, AKA nodes // textual nodes as well as nodes that are invisible to platform APIs, AKA
// that are descendants of platform leaves. In the former case, textual // nodes that are descendants of platform leaves. In the former case,
// nodes are represented by their actual text in the text of their parent // textual nodes are represented by their actual text in the text of their
// nodes, in order to maintain compatibility with how Firefox exposes text // parent nodes, in order to maintain compatibility with how Firefox
// in IAccessibleText. For the latter case, an example of a platform leaf // exposes text in IAccessibleText. For the latter case, an example of a
// is a plain text field. // platform leaf is a plain text field because all of the accessibility
// subtree inside the text field is not visible to platform APIs.
// //
// On the other hand, we do need to expose an "embedded object character" // Please note that for navigational purposes, we need to expose an
// for empty objects, such as an empty text field, for navigational // "object replacement character" in empty controls, such as in an empty
// purposes. This is because such objects need to act as a word and // text field. The presence or the absence of accessible content inside a
// character boundary. // control might alter whether an "object replacement character" would be
// exposed in that control, in contrast to ordinary text such as in the
// case of a non-empty simple text field which should only have textual
// nodes inside it. This is because empty controls need to act as a word
// and character boundary. See
// "AXPosition::IsEmptyObjectReplacedByCharacter()" for more information.
return !IsNullPosition() && !GetAnchor()->IsText() && return !IsNullPosition() && !GetAnchor()->IsText() &&
!GetAnchor()->IsChildOfLeaf(); !GetAnchor()->IsChildOfLeaf();
} }
......
...@@ -3399,10 +3399,18 @@ class AXPosition { ...@@ -3399,10 +3399,18 @@ class AXPosition {
text_offset_ = max_text_offset; text_offset_ = max_text_offset;
} }
// Returns true if this position is on an empty object node that needs to // Returns true if this position is on an empty control that needs to be
// be represented by an empty object replacement character. It does when the // represented by an "object replacement character". This feature is only
// node is a collapsed menu list popup button or has no unignored child and is // enabled on some platforms.
// not a text object. This feature is only enabled on some platforms. //
// This is purely for navigational purposes. We need to expose an "object
// replacement character" in empty controls, such as in an empty text field or
// a collapsed popup menu. The presence or the absence of accessible content
// inside a control might alter whether an "object replacement character"
// would be exposed in that control, in contrast to ordinary text such as in
// the case of a non-empty simple text field which should only have textual
// nodes inside it. This is because empty controls need to act as a word and
// character boundary.
bool IsEmptyObjectReplacedByCharacter() const { bool IsEmptyObjectReplacedByCharacter() const {
if (g_ax_embedded_object_behavior == if (g_ax_embedded_object_behavior ==
AXEmbeddedObjectBehavior::kSuppressCharacter || AXEmbeddedObjectBehavior::kSuppressCharacter ||
......
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