diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 10:22:43 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 12:36:28 +0000 |
commit | 271a6c3487a14599023a9106329505597638d793 (patch) | |
tree | e040d58ffc86c1480b79ca8528020ca9ec919bf8 /chromium/content/browser/accessibility/browser_accessibility_cocoa.mm | |
parent | 7b2ffa587235a47d4094787d72f38102089f402a (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.mm | 249 |
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]; |