summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 10:22:43 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 12:36:28 +0000
commit271a6c3487a14599023a9106329505597638d793 (patch)
treee040d58ffc86c1480b79ca8528020ca9ec919bf8 /chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
parent7b2ffa587235a47d4094787d72f38102089f402a (diff)
BASELINE: Update Chromium to 77.0.3865.59
Change-Id: I1e89a5f3b009a9519a6705102ad65c92fe736f21 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/content/browser/accessibility/browser_accessibility_cocoa.mm')
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_cocoa.mm249
1 files changed, 125 insertions, 124 deletions
diff --git a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
index 444bb384d84..a2927a31d6b 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -231,10 +231,27 @@ AXPlatformRange CreateRangeFromTextMarkerRange(
return AXPlatformRange(std::move(anchor), std::move(focus));
}
+BrowserAccessibilityPositionInstance CreateTreePosition(
+ const BrowserAccessibility& object,
+ int offset) {
+ // A tree position is one for which the |offset| argument refers to a child
+ // index instead of a character offset inside a text object.
+ if (!object.instance_active())
+ return BrowserAccessibilityPosition::CreateNullPosition();
+
+ const BrowserAccessibilityManager* manager = object.manager();
+ DCHECK(manager);
+ return BrowserAccessibilityPosition::CreateTreePosition(
+ manager->ax_tree_id(), object.GetId(), offset);
+}
+
BrowserAccessibilityPositionInstance CreateTextPosition(
const BrowserAccessibility& object,
int offset,
ax::mojom::TextAffinity affinity) {
+ // A text position is one for which the |offset| argument refers to a
+ // character offset inside a text object. As such, text positions are only
+ // valid on platform leaf objects, e.g. static text nodes and text fields.
if (!object.instance_active())
return BrowserAccessibilityPosition::CreateNullPosition();
@@ -244,46 +261,59 @@ BrowserAccessibilityPositionInstance CreateTextPosition(
manager->ax_tree_id(), object.GetId(), offset, affinity);
}
-AXPlatformRange CreateTextRange(const BrowserAccessibility& start_object,
- int start_offset,
- ax::mojom::TextAffinity start_affinity,
- const BrowserAccessibility& end_object,
- int end_offset,
- ax::mojom::TextAffinity end_affinity) {
+AXPlatformRange CreateAXPlatformRange(const BrowserAccessibility& start_object,
+ int start_offset,
+ ax::mojom::TextAffinity start_affinity,
+ const BrowserAccessibility& end_object,
+ int end_offset,
+ ax::mojom::TextAffinity end_affinity) {
BrowserAccessibilityPositionInstance anchor =
- CreateTextPosition(start_object, start_offset, start_affinity);
+ start_object.IsTextOnlyObject()
+ ? CreateTextPosition(start_object, start_offset, start_affinity)
+ : CreateTreePosition(start_object, start_offset);
BrowserAccessibilityPositionInstance focus =
- CreateTextPosition(end_object, end_offset, end_affinity);
+ end_object.IsTextOnlyObject()
+ ? CreateTextPosition(end_object, end_offset, end_affinity)
+ : CreateTreePosition(end_object, end_offset);
// |AXPlatformRange| takes ownership of its anchor and focus.
return AXPlatformRange(std::move(anchor), std::move(focus));
}
-void AddMisspelledTextAttributes(
- const std::vector<const BrowserAccessibility*>& text_only_objects,
- NSMutableAttributedString* attributed_string) {
+void AddMisspelledTextAttributes(const AXPlatformRange& ax_range,
+ NSMutableAttributedString* attributed_string) {
+ int anchor_start_offset = 0;
[attributed_string beginEditing];
- for (const BrowserAccessibility* text_object : text_only_objects) {
- const std::vector<int32_t>& marker_types = text_object->GetIntListAttribute(
- ax::mojom::IntListAttribute::kMarkerTypes);
- const std::vector<int>& marker_starts = text_object->GetIntListAttribute(
- ax::mojom::IntListAttribute::kMarkerStarts);
- const std::vector<int>& marker_ends = text_object->GetIntListAttribute(
- ax::mojom::IntListAttribute::kMarkerEnds);
+ for (const AXPlatformRange& leaf_text_range : ax_range) {
+ DCHECK(!leaf_text_range.IsNull());
+ DCHECK_EQ(leaf_text_range.anchor()->GetAnchor(),
+ leaf_text_range.focus()->GetAnchor())
+ << "An anchor range should only span a single object.";
+ const BrowserAccessibility* anchor = leaf_text_range.focus()->GetAnchor();
+ const std::vector<int32_t>& marker_types =
+ anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes);
+ const std::vector<int>& marker_starts =
+ anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts);
+ const std::vector<int>& marker_ends =
+ anchor->GetIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds);
for (size_t i = 0; i < marker_types.size(); ++i) {
if (!(marker_types[i] &
static_cast<int32_t>(ax::mojom::MarkerType::kSpelling))) {
continue;
}
- int misspelling_start = marker_starts[i];
- int misspelling_end = marker_ends[i];
+ int misspelling_start = anchor_start_offset + marker_starts[i];
+ int misspelling_end = anchor_start_offset + marker_ends[i];
int misspelling_length = misspelling_end - misspelling_start;
+ DCHECK_LE(static_cast<unsigned long>(misspelling_end),
+ [attributed_string length]);
DCHECK_GT(misspelling_length, 0);
[attributed_string
addAttribute:NSAccessibilityMarkedMisspelledTextAttribute
value:@YES
range:NSMakeRange(misspelling_start, misspelling_length)];
}
+
+ anchor_start_offset += leaf_text_range.GetText().length();
}
[attributed_string endEditing];
}
@@ -297,54 +327,20 @@ NSString* GetTextForTextMarkerRange(AXTextMarkerRangeRef marker_range) {
NSAttributedString* GetAttributedTextForTextMarkerRange(
AXTextMarkerRangeRef marker_range) {
- BrowserAccessibility* start_object;
- BrowserAccessibility* end_object;
- int start_offset, end_offset;
- ax::mojom::TextAffinity start_affinity, end_affinity;
AXPlatformRange ax_range = CreateRangeFromTextMarkerRange(marker_range);
if (ax_range.IsNull())
return nil;
- start_object = ax_range.anchor()->GetAnchor();
- end_object = ax_range.focus()->GetAnchor();
- start_offset = ax_range.anchor()->text_offset();
- end_offset = ax_range.focus()->text_offset();
- start_affinity = ax_range.anchor()->affinity();
- end_affinity = ax_range.focus()->affinity();
- NSString* text = base::SysUTF16ToNSString(
- BrowserAccessibilityManager::GetTextForRange(*start_object, *end_object));
+ NSString* text = base::SysUTF16ToNSString(ax_range.GetText());
if ([text length] == 0)
return nil;
- // Be permissive with the start and end offsets.
- if (start_object == end_object && end_offset < start_offset)
- std::swap(start_offset, end_offset);
-
- int trim_length = 0;
- if ((end_object->IsPlainTextField() || end_object->IsTextOnlyObject()) &&
- end_offset < static_cast<int>(end_object->GetInnerText().length())) {
- trim_length =
- static_cast<int>(end_object->GetInnerText().length()) - end_offset;
- }
- int range_length = [text length] - start_offset - trim_length;
-
- // http://crbug.com/651145
- // This shouldn't happen, so this is a temporary workaround to prevent
- // hard crashes.
- if (range_length < 0)
- return nil;
-
- DCHECK_GE(range_length, 0);
- NSRange range = NSMakeRange(start_offset, range_length);
- DCHECK_LE(NSMaxRange(range), [text length]);
-
NSMutableAttributedString* attributed_text =
[[[NSMutableAttributedString alloc] initWithString:text] autorelease];
- std::vector<const BrowserAccessibility*> text_only_objects =
- BrowserAccessibilityManager::FindTextOnlyObjectsInRange(*start_object,
- *end_object);
- AddMisspelledTextAttributes(text_only_objects, attributed_text);
- return [attributed_text attributedSubstringFromRange:range];
+ // Currently, we only decorate the attributed string with misspelling
+ // information.
+ AddMisspelledTextAttributes(ax_range, attributed_text);
+ return attributed_text;
}
// Returns an autoreleased copy of the AXNodeData's attribute.
@@ -729,21 +725,22 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
- (NSNumber*)ariaColumnCount {
- if (!ui::IsTableLike(owner_->GetRole()))
+ if (![self instanceActive])
return nil;
- DCHECK(owner_->node());
- base::Optional<int32_t> aria_col_count =
- owner_->node()->GetTableAriaColCount();
+ base::Optional<int> aria_col_count = owner_->node()->GetTableAriaColCount();
if (!aria_col_count)
return nil;
- return [NSNumber numberWithInt:aria_col_count.value()];
+ return [NSNumber numberWithInt:*aria_col_count];
}
- (NSNumber*)ariaColumnIndex {
- if (!ui::IsCellOrTableHeader(owner_->GetRole()))
+ if (![self instanceActive])
+ return nil;
+ base::Optional<int> aria_col_index =
+ owner_->node()->GetTableCellAriaColIndex();
+ if (!aria_col_index)
return nil;
- DCHECK(owner_->node());
- return [NSNumber numberWithInt:owner_->node()->GetTableCellAriaColIndex()];
+ return [NSNumber numberWithInt:*aria_col_index];
}
- (NSString*)ariaLive {
@@ -756,7 +753,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)ariaPosInSet {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithInt:owner_->node()->GetPosInSet()];
+ base::Optional<int> pos_in_set = owner_->node()->GetPosInSet();
+ if (!pos_in_set)
+ return nil;
+ return [NSNumber numberWithInt:*pos_in_set];
}
- (NSString*)ariaRelevant {
@@ -767,27 +767,31 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
- (NSNumber*)ariaRowCount {
- if (!ui::IsTableLike(owner_->GetRole()))
+ if (![self instanceActive])
return nil;
- DCHECK(owner_->node());
- base::Optional<int32_t> aria_row_count =
- owner_->node()->GetTableAriaRowCount();
+ base::Optional<int> aria_row_count = owner_->node()->GetTableAriaRowCount();
if (!aria_row_count)
return nil;
- return [NSNumber numberWithInt:aria_row_count.value()];
+ return [NSNumber numberWithInt:*aria_row_count];
}
- (NSNumber*)ariaRowIndex {
- if (!ui::IsCellOrTableHeader(owner_->GetRole()))
+ if (![self instanceActive])
return nil;
- DCHECK(owner_->node());
- return [NSNumber numberWithInt:owner_->node()->GetTableCellAriaRowIndex()];
+ base::Optional<int> aria_row_index =
+ owner_->node()->GetTableCellAriaRowIndex();
+ if (!aria_row_index)
+ return nil;
+ return [NSNumber numberWithInt:*aria_row_index];
}
- (NSNumber*)ariaSetSize {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithInt:owner_->node()->GetSetSize()];
+ base::Optional<int> set_size = owner_->node()->GetSetSize();
+ if (!set_size)
+ return nil;
+ return [NSNumber numberWithInt:*set_size];
}
- (NSString*)autocompleteValue {
@@ -823,9 +827,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (!children_) {
uint32_t childCount = owner_->PlatformChildCount();
children_.reset([[NSMutableArray alloc] initWithCapacity:childCount]);
- for (uint32_t index = 0; index < childCount; ++index) {
- BrowserAccessibilityCocoa* child =
- ToBrowserAccessibilityCocoa(owner_->PlatformGetChild(index));
+ for (auto it = owner_->PlatformChildrenBegin();
+ it != owner_->PlatformChildrenEnd(); ++it) {
+ BrowserAccessibilityCocoa* child = ToBrowserAccessibilityCocoa(it.get());
if ([child isIgnored])
[children_ addObjectsFromArray:[child children]];
else
@@ -876,11 +880,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
-
if (is_table_like) {
// If this is a table, return all column headers.
std::set<int32_t> headerIds;
- for (int i = 0; i < table->GetTableColCount(); i++) {
+ for (int i = 0; i < *owner_->GetTableColCount(); i++) {
std::vector<int32_t> colHeaderIds = table->GetColHeaderNodeIds(i);
std::copy(colHeaderIds.begin(), colHeaderIds.end(),
std::inserter(headerIds, headerIds.end()));
@@ -892,9 +895,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
} else {
// Otherwise this is a cell, return the column headers for this cell.
- int column = owner_->node()->GetTableCellColIndex();
+ base::Optional<int> column = owner_->GetTableCellColIndex();
+ if (!column)
+ return nil;
- std::vector<int32_t> colHeaderIds = table->GetColHeaderNodeIds(column);
+ std::vector<int32_t> colHeaderIds = table->GetColHeaderNodeIds(*column);
for (int32_t id : colHeaderIds) {
BrowserAccessibility* cell = owner_->manager()->GetFromID(id);
if (cell)
@@ -908,13 +913,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSValue*)columnIndexRange {
if (![self instanceActive])
return nil;
- if (!ui::IsCellOrTableHeader(owner_->GetRole()))
- return nil;
- int column = owner_->node()->GetTableCellColIndex();
- int colspan = owner_->node()->GetTableCellColSpan();
- if (column >= 0 && colspan >= 1)
- return [NSValue valueWithRange:NSMakeRange(column, colspan)];
+ base::Optional<int> column = owner_->node()->GetTableCellColIndex();
+ base::Optional<int> colspan = owner_->node()->GetTableCellColSpan();
+ if (column && colspan)
+ return [NSValue valueWithRange:NSMakeRange(*column, *colspan)];
return nil;
}
@@ -1238,8 +1241,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// AXTableInfo and indirect_child_ids.
uint32_t childCount = owner_->PlatformChildCount();
if (childCount > 0) {
- BrowserAccessibility* tableHeader =
- owner_->PlatformGetChild(childCount - 1);
+ BrowserAccessibility* tableHeader = owner_->PlatformGetLastChild();
if (tableHeader->GetRole() == ax::mojom::Role::kTableHeaderContainer)
return ToBrowserAccessibilityCocoa(tableHeader);
}
@@ -1292,10 +1294,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
if ([self internalRole] == ax::mojom::Role::kColumn) {
DCHECK(owner_->node());
- return @(owner_->node()->GetTableColColIndex());
+ return @(*owner_->node()->GetTableColColIndex());
} else if ([self internalRole] == ax::mojom::Role::kRow) {
DCHECK(owner_->node());
- return @(owner_->node()->GetTableRowRowIndex());
+ return @(*owner_->node()->GetTableRowRowIndex());
}
return nil;
@@ -1347,10 +1349,6 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return @"false";
case ax::mojom::InvalidState::kTrue:
return @"true";
- case ax::mojom::InvalidState::kSpelling:
- return @"spelling";
- case ax::mojom::InvalidState::kGrammar:
- return @"grammar";
case ax::mojom::InvalidState::kOther: {
std::string ariaInvalidValue;
if (owner_->GetStringAttribute(
@@ -1874,7 +1872,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (is_table_like) {
// If this is a table, return all row headers.
std::set<int32_t> headerIds;
- for (int i = 0; i < table->GetTableRowCount(); i++) {
+ for (int i = 0; i < *table->GetTableRowCount(); i++) {
std::vector<int32_t> rowHeaderIds = table->GetRowHeaderNodeIds(i);
for (int32_t id : rowHeaderIds)
headerIds.insert(id);
@@ -1901,13 +1899,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSValue*)rowIndexRange {
if (![self instanceActive])
return nil;
- if (!ui::IsCellOrTableHeader(owner_->GetRole()))
- return nil;
- int row = owner_->node()->GetTableCellRowIndex();
- int rowspan = owner_->node()->GetTableCellRowSpan();
- if (row >= 0 && rowspan >= 1)
- return [NSValue valueWithRange:NSMakeRange(row, rowspan)];
+ base::Optional<int> row = owner_->node()->GetTableCellRowIndex();
+ base::Optional<int> rowspan = owner_->node()->GetTableCellRowSpan();
+ if (row && rowspan)
+ return [NSValue valueWithRange:NSMakeRange(*row, *rowspan)];
return nil;
}
@@ -1976,9 +1972,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// If it's multiselectable or if the previous attempts failed,
// return any children with the "selected" state, which may
// come from aria-selected.
- uint32_t childCount = owner_->PlatformChildCount();
- for (uint32_t index = 0; index < childCount; ++index) {
- BrowserAccessibility* child = owner_->PlatformGetChild(index);
+ for (auto it = owner_->PlatformChildrenBegin();
+ it != owner_->PlatformChildrenEnd(); ++it) {
+ BrowserAccessibility* child = it.get();
if (child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
[ret addObject:ToBrowserAccessibilityCocoa(child)];
}
@@ -2041,29 +2037,32 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (!manager)
return nil;
- int32_t anchorId = manager->GetTreeData().sel_anchor_object_id;
+ ui::AXTree::Selection unignored_selection =
+ manager->ax_tree()->GetUnignoredSelection();
+ int32_t anchorId = unignored_selection.anchor_object_id;
const BrowserAccessibility* anchorObject = manager->GetFromID(anchorId);
if (!anchorObject)
return nil;
- int32_t focusId = manager->GetTreeData().sel_focus_object_id;
+ int32_t focusId = unignored_selection.focus_object_id;
const BrowserAccessibility* focusObject = manager->GetFromID(focusId);
if (!focusObject)
return nil;
- int anchorOffset = manager->GetTreeData().sel_anchor_offset;
- int focusOffset = manager->GetTreeData().sel_focus_offset;
+ // |anchorOffset| and / or |focusOffset| refer to a character offset if
+ // |anchorObject| / |focusObject| are text-only objects. Otherwise, they
+ // should be treated as child indices.
+ int anchorOffset = unignored_selection.anchor_offset;
+ int focusOffset = unignored_selection.focus_offset;
if (anchorOffset < 0 || focusOffset < 0)
return nil;
- ax::mojom::TextAffinity anchorAffinity =
- manager->GetTreeData().sel_anchor_affinity;
- ax::mojom::TextAffinity focusAffinity =
- manager->GetTreeData().sel_focus_affinity;
+ ax::mojom::TextAffinity anchorAffinity = unignored_selection.anchor_affinity;
+ ax::mojom::TextAffinity focusAffinity = unignored_selection.focus_affinity;
- return CreateTextMarkerRange(CreateTextRange(*anchorObject, anchorOffset,
- anchorAffinity, *focusObject,
- focusOffset, focusAffinity));
+ return CreateTextMarkerRange(
+ CreateAXPlatformRange(*anchorObject, anchorOffset, anchorAffinity,
+ *focusObject, focusOffset, focusAffinity));
}
- (NSValue*)size {
@@ -2393,13 +2392,16 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return base::SysUTF16ToNSString(value.substr(range.location, range.length));
}
+// Retrieves the text inside this object and decorates it with attributes
+// indicating specific ranges of interest within the text, e.g. the location of
+// misspellings.
- (NSAttributedString*)attributedValueForRange:(NSRange)range {
if (![self instanceActive])
return nil;
base::string16 text = owner_->GetValue();
if (owner_->IsTextOnlyObject() && text.empty())
- text = owner_->GetInnerText();
+ text = owner_->GetText();
// We need to get the whole text because a spelling mistake might start or end
// outside our range.
@@ -2408,10 +2410,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
[[[NSMutableAttributedString alloc] initWithString:value] autorelease];
if (!owner_->IsTextOnlyObject()) {
- std::vector<const BrowserAccessibility*> textOnlyObjects =
- BrowserAccessibilityManager::FindTextOnlyObjectsInRange(*owner_,
- *owner_);
- AddMisspelledTextAttributes(textOnlyObjects, attributedValue);
+ AXPlatformRange ax_range(owner_->CreatePositionAt(0),
+ owner_->CreatePositionAt(int{text.length()}));
+ AddMisspelledTextAttributes(ax_range, attributedValue);
}
return [attributedValue attributedSubstringFromRange:range];