Revert "[a11y] Fixes move by format for CSS spellcheck highlights"
This reverts commit c6bfb8a155
.
Reason for revert: This change broke Narrator's move-by-headings
feature. Heading navigation is a critical feature of screen readers that
facilites navigating web pages, like the google/bing results page. It
impacts all headings throughout the web, whereas the original CL was
fixing a scoped problem: spelling errors unannounced when exposed using
CSS highlights. We will also revert this change from 134.
Original change's description:
> [a11y] Fixes move by format for CSS spellcheck highlights
>
> Uses Spelling/Grammar error CSS highlight markers in the
> Accessibility Tree to break format boundaries around those
> errors to help navigate better around these spelling/grammar
> errors.
>
> This CL achieves following:
> 1) Fixes Move by format to accommodate CSS spellcheck highlights.
> 2) Narrator calls out the spelling issues correctly.
>
> Bug: 364795299
> Change-Id: I4842a49449c666100e31f859447f951e9f9eb09e
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6178990
> Auto-Submit: Vinay Singh <vinaysingh@microsoft.com>
> Reviewed-by: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
> Commit-Queue: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
> Cr-Commit-Position: refs/heads/main@{#1415710}
Bug: 402800783, 364795299
Change-Id: I1ee7bd394f18fba21e97e5cc8998de1a03501931
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6349562
Reviewed-by: Jacques Newman <janewman@microsoft.com>
Auto-Submit: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
Commit-Queue: Benjamin Beaudry <benjamin.beaudry@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1431891}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
03badce254
commit
fa24efebcd
content/browser/accessibility
ui/accessibility
@ -1544,43 +1544,42 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/ L"plain 1\nplain 2\n",
|
||||
/*expected_text*/ L"plain 1\nplain 2",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nplain heading\n",
|
||||
L"plain 1\nplain 2\nplain heading",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nplain heading\nitalic 1\nitalic 2\n",
|
||||
L"plain 1\nplain 2\nplain heading\nitalic 1\nitalic 2",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/ L"plain 1\nplain 2\nplain heading\n",
|
||||
/*expected_text*/ L"plain 1\nplain 2\nplain heading",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nplain heading\nitalic 1\nitalic 2\n",
|
||||
L"plain 1\nplain 2\nplain heading\nitalic 1\nitalic 2",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nplain heading\nitalic 1\nitalic 2\nheading\n",
|
||||
L"plain 1\nplain 2\nplain heading\nitalic 1\nitalic 2\nheading",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nplain heading\nitalic 1\nitalic "
|
||||
L"2\nheading\nheading\n",
|
||||
L"plain 1\nplain 2\nplain heading\nitalic 1\nitalic 2\nheading\nheading",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1597,7 +1596,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/ L"plain 1\nplain 2\n",
|
||||
/*expected_text*/ L"plain 1\nplain 2",
|
||||
/*expected_count*/ 1);
|
||||
}
|
||||
|
||||
@ -1716,59 +1715,59 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/ L"plain 1\nplain 2\n",
|
||||
/*expected_text*/ L"plain 1\nplain 2",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\n",
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/ L"plain 1\nplain 2\n",
|
||||
/*expected_text*/ L"plain 1\nplain 2",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 2,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\n",
|
||||
L"1\ncolor 2",
|
||||
/*expected_count*/ 2);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\n",
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 2,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\n",
|
||||
L"1\ncolor 2\noverline 1\noverline 2",
|
||||
/*expected_count*/ 2);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\n",
|
||||
L"1\ncolor 2",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 2,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through 2\n",
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through 2",
|
||||
/*expected_count*/ 2);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\n",
|
||||
L"1\ncolor 2\noverline 1\noverline 2",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1776,14 +1775,14 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through "
|
||||
L"2\nsup 1\nsup 2\n",
|
||||
L"2\nsup 1\nsup 2",
|
||||
/*expected_count*/ 2);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through 2\n",
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through 2",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1791,7 +1790,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through "
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2\n",
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2",
|
||||
/*expected_count*/ 2);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1799,7 +1798,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through "
|
||||
L"2\nsup 1\nsup 2\n",
|
||||
L"2\nsup 1\nsup 2",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1807,7 +1806,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through "
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2\nfont-family 1\nfont-family 2\n",
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2\nfont-family 1\nfont-family 2",
|
||||
/*expected_count*/ 2);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1815,7 +1814,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through "
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2\n",
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1824,7 +1823,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through "
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2\nfont-family 1\nfont-family "
|
||||
L"2\nspelling 1\nspelling two\n",
|
||||
L"2\nspelling 1\nspelling two",
|
||||
/*expected_count*/ 2);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1832,7 +1831,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
/*expected_text*/
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through "
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2\nfont-family 1\nfont-family 2\n",
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2\nfont-family 1\nfont-family 2",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
@ -1850,7 +1849,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
L"plain 1\nplain 2\nbackground-color 1\nbackground-color 2\ncolor "
|
||||
L"1\ncolor 2\noverline 1\noverline 2\nline-through 1\nline-through "
|
||||
L"2\nsup 1\nsup 2\nbold 1\nbold 2\nfont-family 1\nfont-family "
|
||||
L"2\nspelling 1\nspelling two\n",
|
||||
L"2\nspelling 1\nspelling two",
|
||||
/*expected_count*/ -1);
|
||||
}
|
||||
|
||||
@ -3564,7 +3563,7 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,
|
||||
"<div><h2>Second Heading</h2><span>\nParagraph Two</span></div>";
|
||||
|
||||
const std::vector<const wchar_t*> format_units = {
|
||||
L"First Heading", L"\nParagraph One\n", L"Second Heading",
|
||||
L"First Heading", L"\nParagraph One", L"Second Heading",
|
||||
L"\nParagraph Two"};
|
||||
|
||||
AssertMoveByUnitForMarkup(TextUnit_Format, html_markup, format_units);
|
||||
@ -3584,7 +3583,7 @@ IN_PROC_BROWSER_TEST_F(
|
||||
</html>)HTML";
|
||||
|
||||
const std::vector<const wchar_t*> format_units = {
|
||||
L"First Heading", L"\nParagraph One\n", L"Second Heading",
|
||||
L"First Heading", L"\nParagraph One", L"Second Heading",
|
||||
L"\nParagraph Two"};
|
||||
|
||||
AssertMoveByUnitForMarkup(TextUnit_Format, html_markup, format_units);
|
||||
|
@ -917,9 +917,8 @@ class AXPosition {
|
||||
AXBoundaryType GetFormatStartBoundaryType() const {
|
||||
// Since formats are stored on text anchors, the start of a format boundary
|
||||
// must be at the start of an anchor.
|
||||
if (IsNullPosition() || !AtStartOfAnchor()) {
|
||||
if (IsNullPosition() || !AtStartOfAnchor())
|
||||
return AXBoundaryType::kNone;
|
||||
}
|
||||
|
||||
// Treat the first iterable node as a format boundary.
|
||||
if (CreatePreviousLeafTreePosition(
|
||||
@ -929,9 +928,8 @@ class AXPosition {
|
||||
}
|
||||
|
||||
// Ignored positions cannot be format boundaries.
|
||||
if (IsIgnored()) {
|
||||
if (IsIgnored())
|
||||
return AXBoundaryType::kNone;
|
||||
}
|
||||
|
||||
// Iterate over anchors until a format boundary is found. This will return a
|
||||
// null position upon crossing a boundary. Make sure the previous position
|
||||
@ -949,31 +947,14 @@ class AXPosition {
|
||||
}
|
||||
|
||||
bool AtStartOfFormat() const {
|
||||
AXPositionInstance text_position = AsLeafTextPosition();
|
||||
|
||||
switch (text_position->kind_) {
|
||||
case AXPositionKind::NULL_POSITION:
|
||||
return false;
|
||||
case AXPositionKind::TREE_POSITION:
|
||||
NOTREACHED();
|
||||
case AXPositionKind::TEXT_POSITION: {
|
||||
const std::vector<int32_t>& format_starts =
|
||||
text_position->GetFormatStartOffsets();
|
||||
if (format_starts.size() <= 1) {
|
||||
return GetFormatStartBoundaryType() != AXBoundaryType::kNone;
|
||||
}
|
||||
return base::Contains(format_starts,
|
||||
int32_t{text_position->text_offset_});
|
||||
}
|
||||
}
|
||||
return GetFormatStartBoundaryType() != AXBoundaryType::kNone;
|
||||
}
|
||||
|
||||
AXBoundaryType GetFormatEndBoundaryType() const {
|
||||
// Since formats are stored on text anchors, the end of a format break must
|
||||
// be at the end of an anchor.
|
||||
if (IsNullPosition() || !AtEndOfAnchor()) {
|
||||
if (IsNullPosition() || !AtEndOfAnchor())
|
||||
return AXBoundaryType::kNone;
|
||||
}
|
||||
|
||||
// Treat the last iterable node as a format boundary
|
||||
if (CreateNextLeafTreePosition(
|
||||
@ -982,9 +963,8 @@ class AXPosition {
|
||||
return AXBoundaryType::kContentEnd;
|
||||
|
||||
// Ignored positions cannot be format boundaries.
|
||||
if (IsIgnored()) {
|
||||
if (IsIgnored())
|
||||
return AXBoundaryType::kNone;
|
||||
}
|
||||
|
||||
// Iterate over anchors until a format boundary is found. This will return a
|
||||
// null position upon crossing a boundary. Make sure the next position is
|
||||
@ -1002,23 +982,7 @@ class AXPosition {
|
||||
}
|
||||
|
||||
bool AtEndOfFormat() const {
|
||||
AXPositionInstance text_position = AsLeafTextPosition();
|
||||
|
||||
switch (text_position->kind_) {
|
||||
case AXPositionKind::NULL_POSITION:
|
||||
return false;
|
||||
case AXPositionKind::TREE_POSITION:
|
||||
NOTREACHED();
|
||||
case AXPositionKind::TEXT_POSITION: {
|
||||
const std::vector<int32_t>& format_ends =
|
||||
text_position->GetFormatEndOffsets();
|
||||
if (format_ends.size() <= 1) {
|
||||
return GetFormatEndBoundaryType() != AXBoundaryType::kNone;
|
||||
}
|
||||
return base::Contains(format_ends,
|
||||
int32_t{text_position->text_offset_});
|
||||
}
|
||||
}
|
||||
return GetFormatEndBoundaryType() != AXBoundaryType::kNone;
|
||||
}
|
||||
|
||||
bool AtStartOfSentence() const {
|
||||
@ -3285,8 +3249,7 @@ class AXPosition {
|
||||
return CreateBoundaryStartPosition(
|
||||
options, ax::mojom::MoveDirection::kForward,
|
||||
base::BindRepeating(&AtStartOfFormatPredicate),
|
||||
base::BindRepeating(&AtEndOfFormatPredicate),
|
||||
base::BindRepeating(&GetFormatStartOffsetsFunc));
|
||||
base::BindRepeating(&AtEndOfFormatPredicate));
|
||||
}
|
||||
|
||||
AXPositionInstance CreatePreviousFormatStartPosition(
|
||||
@ -3294,8 +3257,7 @@ class AXPosition {
|
||||
return CreateBoundaryStartPosition(
|
||||
options, ax::mojom::MoveDirection::kBackward,
|
||||
base::BindRepeating(&AtStartOfFormatPredicate),
|
||||
base::BindRepeating(&AtEndOfFormatPredicate),
|
||||
base::BindRepeating(&GetFormatStartOffsetsFunc));
|
||||
base::BindRepeating(&AtEndOfFormatPredicate));
|
||||
}
|
||||
|
||||
AXPositionInstance CreateNextFormatEndPosition(
|
||||
@ -3303,8 +3265,7 @@ class AXPosition {
|
||||
return CreateBoundaryEndPosition(
|
||||
options, ax::mojom::MoveDirection::kForward,
|
||||
base::BindRepeating(&AtStartOfFormatPredicate),
|
||||
base::BindRepeating(&AtEndOfFormatPredicate),
|
||||
base::BindRepeating(&GetFormatEndOffsetsFunc));
|
||||
base::BindRepeating(&AtEndOfFormatPredicate));
|
||||
}
|
||||
|
||||
AXPositionInstance CreatePreviousFormatEndPosition(
|
||||
@ -3312,8 +3273,7 @@ class AXPosition {
|
||||
return CreateBoundaryEndPosition(
|
||||
options, ax::mojom::MoveDirection::kBackward,
|
||||
base::BindRepeating(&AtStartOfFormatPredicate),
|
||||
base::BindRepeating(&AtEndOfFormatPredicate),
|
||||
base::BindRepeating(&GetFormatEndOffsetsFunc));
|
||||
base::BindRepeating(&AtEndOfFormatPredicate));
|
||||
}
|
||||
|
||||
AXPositionInstance CreateNextSentenceStartPosition(
|
||||
@ -4914,143 +4874,6 @@ class AXPosition {
|
||||
ax::mojom::IntListAttribute::kWordEnds);
|
||||
}
|
||||
|
||||
const std::vector<int32_t>& GetFormatStartOffsets() const {
|
||||
if (IsNullPosition()) {
|
||||
static const base::NoDestructor<std::vector<int32_t>> empty_format_starts;
|
||||
return *empty_format_starts;
|
||||
}
|
||||
DCHECK(GetAnchor());
|
||||
|
||||
std::vector<int32_t> format_starts;
|
||||
format_starts.push_back(0);
|
||||
|
||||
// Format is almost always consistent throughout any node -- the only
|
||||
// exception are inline text boxes with CSS highlights. Therefore, unless
|
||||
// the node is an inline text box with CSS highlights, we can assume the
|
||||
// node's format starts only at index 0.
|
||||
if (GetAnchor()->GetRole() != ax::mojom::Role::kInlineTextBox) {
|
||||
static const base::NoDestructor<std::vector<int32_t>> format_starts_copy(
|
||||
std::move(format_starts));
|
||||
return *format_starts_copy;
|
||||
}
|
||||
|
||||
AXNode* parent = GetAnchor()->GetUnignoredParent();
|
||||
|
||||
const std::vector<int32_t>& marker_types =
|
||||
parent->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes);
|
||||
const std::vector<int32_t>& highlight_types = parent->GetIntListAttribute(
|
||||
ax::mojom::IntListAttribute::kHighlightTypes);
|
||||
|
||||
// Since, there are no highlights, there is no possibility of any spelling
|
||||
// or grammar highlights.
|
||||
if (highlight_types.empty()) {
|
||||
static const base::NoDestructor<std::vector<int32_t>> format_starts_copy(
|
||||
std::move(format_starts));
|
||||
return *format_starts_copy;
|
||||
}
|
||||
CHECK_EQ(marker_types.size(), highlight_types.size());
|
||||
|
||||
const std::vector<int>& marker_starts =
|
||||
parent->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts);
|
||||
const std::vector<int>& marker_ends =
|
||||
parent->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds);
|
||||
|
||||
CHECK_EQ(marker_types.size(), marker_starts.size());
|
||||
CHECK_EQ(marker_types.size(), marker_ends.size());
|
||||
|
||||
int text_length = GetAnchor()->GetTextContentLengthUTF16();
|
||||
for (size_t i = 0; i < marker_types.size(); ++i) {
|
||||
if (HasSpellingOrGrammarErrorHighlight(
|
||||
static_cast<ax::mojom::MarkerType>(marker_types[i]),
|
||||
static_cast<ax::mojom::HighlightType>(highlight_types[i]))) {
|
||||
if (marker_starts[i] != 0) { // 0 is already added
|
||||
format_starts.push_back(marker_starts[i]);
|
||||
}
|
||||
if (marker_ends[i] < text_length - 1) {
|
||||
format_starts.push_back(marker_ends[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const base::NoDestructor<std::vector<int32_t>> format_starts_copy(
|
||||
std::move(format_starts));
|
||||
return *format_starts_copy;
|
||||
}
|
||||
|
||||
const std::vector<int32_t>& GetFormatEndOffsets() const {
|
||||
if (IsNullPosition()) {
|
||||
static const base::NoDestructor<std::vector<int32_t>> empty_format_ends;
|
||||
return *empty_format_ends;
|
||||
}
|
||||
DCHECK(GetAnchor());
|
||||
|
||||
int text_length = GetAnchor()->GetTextContentLengthUTF16();
|
||||
std::vector<int32_t> format_ends;
|
||||
format_ends.push_back(text_length);
|
||||
|
||||
// Format is almost always consistent throughout any node -- the only
|
||||
// exception are inline text boxes with CSS highlights. Therefore, unless
|
||||
// the node is an inline text box with CSS highlights, we can assume the
|
||||
// node's format ends only at the text length.
|
||||
if (GetAnchor()->GetRole() != ax::mojom::Role::kInlineTextBox) {
|
||||
static const base::NoDestructor<std::vector<int32_t>> format_ends_copy(
|
||||
std::move(format_ends));
|
||||
return *format_ends_copy;
|
||||
}
|
||||
|
||||
AXNode* parent = GetAnchor()->GetUnignoredParent();
|
||||
|
||||
const std::vector<int32_t>& marker_types =
|
||||
parent->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes);
|
||||
const std::vector<int32_t>& highlight_types = parent->GetIntListAttribute(
|
||||
ax::mojom::IntListAttribute::kHighlightTypes);
|
||||
|
||||
// Since, there are no highlights, there is no possibility of any spelling
|
||||
// or grammar highlights.
|
||||
if (highlight_types.empty()) {
|
||||
static const base::NoDestructor<std::vector<int32_t>> format_ends_copy(
|
||||
std::move(format_ends));
|
||||
return *format_ends_copy;
|
||||
}
|
||||
CHECK_EQ(marker_types.size(), highlight_types.size());
|
||||
|
||||
const std::vector<int>& marker_starts =
|
||||
parent->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts);
|
||||
const std::vector<int>& marker_ends =
|
||||
parent->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds);
|
||||
|
||||
CHECK_EQ(marker_types.size(), marker_starts.size());
|
||||
CHECK_EQ(marker_types.size(), marker_ends.size());
|
||||
|
||||
format_ends.clear();
|
||||
for (size_t i = 0; i < marker_types.size(); ++i) {
|
||||
if (HasSpellingOrGrammarErrorHighlight(
|
||||
static_cast<ax::mojom::MarkerType>(marker_types[i]),
|
||||
static_cast<ax::mojom::HighlightType>(highlight_types[i]))) {
|
||||
if (marker_starts[i] > 0) {
|
||||
format_ends.push_back(marker_starts[i]);
|
||||
}
|
||||
format_ends.push_back(marker_ends[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (format_ends.empty() || format_ends.back() != text_length) {
|
||||
format_ends.push_back(text_length);
|
||||
}
|
||||
|
||||
static const base::NoDestructor<std::vector<int32_t>> format_ends_copy(
|
||||
std::move(format_ends));
|
||||
return *format_ends_copy;
|
||||
}
|
||||
|
||||
static bool HasSpellingOrGrammarErrorHighlight(
|
||||
ax::mojom::MarkerType marker_type,
|
||||
ax::mojom::HighlightType highlight_type) {
|
||||
return marker_type == ax::mojom::MarkerType::kHighlight &&
|
||||
(highlight_type == ax::mojom::HighlightType::kSpellingError ||
|
||||
highlight_type == ax::mojom::HighlightType::kGrammarError);
|
||||
}
|
||||
|
||||
AXNodeID GetNextOnLineID() const {
|
||||
if (IsNullPosition())
|
||||
return kInvalidAXNodeID;
|
||||
@ -5706,16 +5529,6 @@ class AXPosition {
|
||||
return position->GetWordEndOffsets();
|
||||
}
|
||||
|
||||
static const std::vector<int32_t>& GetFormatStartOffsetsFunc(
|
||||
const AXPositionInstance& position) {
|
||||
return position->GetFormatStartOffsets();
|
||||
}
|
||||
|
||||
static const std::vector<int32_t>& GetFormatEndOffsetsFunc(
|
||||
const AXPositionInstance& position) {
|
||||
return position->GetFormatEndOffsets();
|
||||
}
|
||||
|
||||
// Creates an ancestor equivalent position at the root node of this position's
|
||||
// accessibility tree, e.g. at the root of the current iframe (out-of-process
|
||||
// or not), PDF plugin, Views tree, dialog (native, ARIA or HTML), window, or
|
||||
|
@ -884,7 +884,8 @@ HRESULT AXPlatformNodeTextRangeProviderWin::MoveEndpointByUnitImpl(
|
||||
MoveEndpointByCharacter(position_to_move, count, units_moved);
|
||||
break;
|
||||
case TextUnit_Format:
|
||||
new_position = MoveEndpointByFormat(position_to_move, count, units_moved);
|
||||
new_position = MoveEndpointByFormat(position_to_move, is_start_endpoint,
|
||||
count, units_moved);
|
||||
break;
|
||||
case TextUnit_Word:
|
||||
new_position = MoveEndpointByWord(position_to_move, count, units_moved);
|
||||
@ -1362,11 +1363,14 @@ AXPlatformNodeTextRangeProviderWin::MoveEndpointByLine(
|
||||
AXPlatformNodeTextRangeProviderWin::AXPositionInstance
|
||||
AXPlatformNodeTextRangeProviderWin::MoveEndpointByFormat(
|
||||
const AXPositionInstance& endpoint,
|
||||
const bool is_start_endpoint,
|
||||
const int count,
|
||||
int* units_moved) {
|
||||
return MoveEndpointByUnitHelper(std::move(endpoint),
|
||||
ax::mojom::TextBoundary::kFormatStart, count,
|
||||
units_moved);
|
||||
is_start_endpoint
|
||||
? ax::mojom::TextBoundary::kFormatStart
|
||||
: ax::mojom::TextBoundary::kFormatEnd,
|
||||
count, units_moved);
|
||||
}
|
||||
|
||||
AXPlatformNodeTextRangeProviderWin::AXPositionInstance
|
||||
|
@ -163,6 +163,7 @@ class COMPONENT_EXPORT(AX_PLATFORM) __declspec(uuid(
|
||||
const int count,
|
||||
int* units_moved);
|
||||
AXPositionInstance MoveEndpointByFormat(const AXPositionInstance& endpoint,
|
||||
const bool is_start_endpoint,
|
||||
const int count,
|
||||
int* units_moved);
|
||||
AXPositionInstance MoveEndpointByDocument(const AXPositionInstance& endpoint,
|
||||
|
@ -804,19 +804,8 @@ class AXPlatformNodeTextRangeProviderTest : public AXPlatformNodeWinTest {
|
||||
|
||||
AXNodeData paragraph4_text_data;
|
||||
paragraph4_text_data.id = 17;
|
||||
paragraph4_text_data.role = ax::mojom::Role::kInlineTextBox;
|
||||
paragraph4_text_data.SetName("Paraaagraph 4");
|
||||
// Marking `Paraaagraph` as a misspelled word modeled as a CSS highlight.
|
||||
paragraph4_data.AddIntListAttribute(
|
||||
ax::mojom::IntListAttribute::kMarkerTypes,
|
||||
{(int)ax::mojom::MarkerType::kHighlight});
|
||||
paragraph4_data.AddIntListAttribute(
|
||||
ax::mojom::IntListAttribute::kHighlightTypes,
|
||||
{(int)ax::mojom::HighlightType::kSpellingError});
|
||||
paragraph4_data.AddIntListAttribute(
|
||||
ax::mojom::IntListAttribute::kMarkerStarts, {0});
|
||||
paragraph4_data.AddIntListAttribute(
|
||||
ax::mojom::IntListAttribute::kMarkerEnds, {11});
|
||||
paragraph4_text_data.role = ax::mojom::Role::kStaticText;
|
||||
paragraph4_text_data.SetName("Paragraph 4");
|
||||
paragraph4_data.child_ids = {paragraph4_text_data.id};
|
||||
|
||||
AXNodeData root_data;
|
||||
@ -1497,7 +1486,7 @@ TEST_F(AXPlatformNodeTextRangeProviderTest,
|
||||
EXPECT_UIA_TEXTRANGE_EQ(
|
||||
text_range_provider,
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold "
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParaaagraph 4");
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParagraph 4");
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextrange-expandtoenclosingunit
|
||||
// Consider two consecutive text units A and B.
|
||||
@ -2089,7 +2078,7 @@ TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveFormat) {
|
||||
/*count*/ 0,
|
||||
/*expected_text*/
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold "
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParaaagraph 4",
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParagraph 4",
|
||||
/*expected_count*/ 0);
|
||||
|
||||
// Move forward.
|
||||
@ -2099,32 +2088,28 @@ TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveFormat) {
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ 2,
|
||||
/*expected_text*/ L"Paragraph 1\n",
|
||||
/*expected_text*/ L"Paragraph 1",
|
||||
/*expected_count*/ 2);
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/ L"Paragraph 2\nParagraph 3\n",
|
||||
/*expected_text*/ L"Paragraph 2\nParagraph 3",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/ L"Paraaagraph",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/ L" 4",
|
||||
/*expected_text*/ L"Paragraph 4",
|
||||
/*expected_count*/ 1);
|
||||
|
||||
// Trying to move past the last format should have no effect.
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/ L" 4",
|
||||
/*expected_text*/ L"Paragraph 4",
|
||||
/*expected_count*/ 0);
|
||||
|
||||
// Move backward.
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ -4,
|
||||
/*expected_text*/ L"bold text\n",
|
||||
/*expected_count*/ -4);
|
||||
/*count*/ -3,
|
||||
/*expected_text*/ L"bold text",
|
||||
/*expected_count*/ -3);
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/ L"\nStandalone line with no formatting\n",
|
||||
@ -2157,12 +2142,8 @@ TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveFormat) {
|
||||
// Test degenerate range creation at the end of the document.
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ 5,
|
||||
/*expected_text*/ L"Paraaagraph",
|
||||
/*expected_text*/ L"Paragraph 4",
|
||||
/*expected_count*/ 5);
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
/*expected_text*/ L" 4",
|
||||
/*expected_count*/ 1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Format,
|
||||
/*count*/ 1,
|
||||
@ -2171,7 +2152,7 @@ TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveFormat) {
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/ L" 4",
|
||||
/*expected_text*/ L"Paragraph 4",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Format,
|
||||
@ -2181,14 +2162,14 @@ TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveFormat) {
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/ L" 4",
|
||||
/*expected_text*/ L"Paragraph 4",
|
||||
/*expected_count*/ -1);
|
||||
|
||||
// Degenerate range moves.
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ -6,
|
||||
/*count*/ -5,
|
||||
/*expected_text*/ L"Text with formatting",
|
||||
/*expected_count*/ -6);
|
||||
/*expected_count*/ -5);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
@ -2201,7 +2182,7 @@ TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveFormat) {
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
/*count*/ 70,
|
||||
/*expected_text*/ L"",
|
||||
/*expected_count*/ 4);
|
||||
/*expected_count*/ 3);
|
||||
|
||||
// Trying to move past the last format should have no effect.
|
||||
EXPECT_UIA_MOVE(text_range_provider, TextUnit_Format,
|
||||
@ -3251,38 +3232,20 @@ TEST_F(AXPlatformNodeTextRangeProviderTest,
|
||||
EXPECT_UIA_TEXTRANGE_EQ(
|
||||
text_range_provider,
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold "
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParaaagraph 4");
|
||||
|
||||
// `Paraaagraph 4` should be broken into two separate `format` units based on
|
||||
// the spelling error (modeled as CSS highlight) in corresponding AXNode.
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParagraph 4");
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*count*/ -2,
|
||||
/*expected_text*/
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold "
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParaaagraph",
|
||||
/*expected_count*/ -1);
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold "
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\n",
|
||||
/*expected_count*/ -1);
|
||||
L"text\nParagraph 1",
|
||||
/*expected_count*/ -2);
|
||||
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold "
|
||||
L"text\nParagraph 1\n",
|
||||
/*expected_count*/ -1);
|
||||
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -1,
|
||||
/*expected_text*/
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold text\n",
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold text",
|
||||
/*expected_count*/ -1);
|
||||
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
@ -3306,17 +3269,17 @@ TEST_F(AXPlatformNodeTextRangeProviderTest,
|
||||
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ 8,
|
||||
/*count*/ 7,
|
||||
/*expected_text*/
|
||||
L"Text with formatting\nStandalone line with no formatting\nbold "
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParaaagraph 4",
|
||||
/*expected_count*/ 7);
|
||||
L"text\nParagraph 1\nParagraph 2\nParagraph 3\nParagraph 4",
|
||||
/*expected_count*/ 6);
|
||||
|
||||
EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(
|
||||
text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Format,
|
||||
/*count*/ -8,
|
||||
/*expected_text*/ L"",
|
||||
/*expected_count*/ -7);
|
||||
/*expected_count*/ -6);
|
||||
}
|
||||
|
||||
TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderCompare) {
|
||||
|
Reference in New Issue
Block a user