| Index: content/browser/accessibility/browser_accessibility_cocoa.mm | 
| diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm | 
| index 2698d30c785d5b46b8259a9346cfe8147a84e49c..5e96f632217c176e2aba374dc7943076f7452ac5 100644 | 
| --- a/content/browser/accessibility/browser_accessibility_cocoa.mm | 
| +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm | 
| @@ -15,6 +15,7 @@ | 
|  | 
| #include "base/mac/foundation_util.h" | 
| #include "base/mac/scoped_cftyperef.h" | 
| +#include "base/memory/ptr_util.h" | 
| #include "base/strings/string16.h" | 
| #include "base/strings/sys_string_conversions.h" | 
| #include "base/strings/utf_string_conversions.h" | 
| @@ -28,12 +29,11 @@ | 
| #include "third_party/skia/include/core/SkColor.h" | 
| #include "ui/accessibility/ax_range.h" | 
| #import "ui/accessibility/platform/ax_platform_node_mac.h" | 
| +#import "ui/accessibility/platform/text_marker_helper_mac.h" | 
|  | 
| using AXPlatformPositionInstance = | 
| content::AXPlatformPosition::AXPositionInstance; | 
| using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>; | 
| -using AXTextMarkerRangeRef = CFTypeRef; | 
| -using AXTextMarkerRef = CFTypeRef; | 
| using StringAttribute = ui::AXStringAttribute; | 
| using content::AXPlatformPosition; | 
| using content::AccessibilityMatchPredicate; | 
| @@ -111,93 +111,38 @@ NSDictionary* attributeToMethodNameMap = nil; | 
| // VoiceOver uses -1 to mean "no limit" for AXResultsLimit. | 
| const int kAXResultsLimitNoLimit = -1; | 
|  | 
| -extern "C" { | 
| - | 
| -// The following are private accessibility APIs required for cursor navigation | 
| -// and text selection. VoiceOver started relying on them in Mac OS X 10.11. | 
| -#if !defined(MAC_OS_X_VERSION_10_11) || \ | 
| -    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11 | 
| - | 
| -AXTextMarkerRef AXTextMarkerCreate(CFAllocatorRef allocator, | 
| -                                   const UInt8* bytes, | 
| -                                   CFIndex length); | 
| - | 
| -const UInt8* AXTextMarkerGetBytePtr(AXTextMarkerRef text_marker); | 
| - | 
| -size_t AXTextMarkerGetLength(AXTextMarkerRef text_marker); | 
| - | 
| -AXTextMarkerRangeRef AXTextMarkerRangeCreate(CFAllocatorRef allocator, | 
| -                                             AXTextMarkerRef start_marker, | 
| -                                             AXTextMarkerRef end_marker); | 
| - | 
| -AXTextMarkerRef AXTextMarkerRangeCopyStartMarker( | 
| -    AXTextMarkerRangeRef text_marker_range); | 
| - | 
| -AXTextMarkerRef AXTextMarkerRangeCopyEndMarker( | 
| -    AXTextMarkerRangeRef text_marker_range); | 
| - | 
| -#endif  // MAC_OS_X_VERSION_10_11 | 
| +class BrowserPositionFactory : public ui::PositionFactory { | 
| + public: | 
| +  explicit BrowserPositionFactory( | 
| +      content::BrowserAccessibility* browser_accessibility) | 
| +      : browser_accessibility_(browser_accessibility) {} | 
|  | 
| -}  // extern "C" | 
| +  ui::AXPositionPointer GetRoot() const override; | 
| +  ui::AXRangePointer GetSelection() const override; | 
| +  ui::AXPositionPointer GetFromData( | 
| +      const ui::AXPositionData& data) const override; | 
| +  id GetAccessibilityObject(const ui::AXPositionData& data) const override; | 
|  | 
| -// AXTextMarkerCreate copies from data buffer given to it. | 
| -id CreateTextMarker(AXPlatformPositionInstance position) { | 
| -  AXTextMarkerRef text_marker = AXTextMarkerCreate( | 
| -      kCFAllocatorDefault, reinterpret_cast<const UInt8*>(position.get()), | 
| -      sizeof(AXPlatformPosition)); | 
| -  return static_cast<id>( | 
| -      base::mac::CFTypeRefToNSObjectAutorelease(text_marker)); | 
| -} | 
| + private: | 
| +  bool IsActive() const { | 
| +    return browser_accessibility_ && browser_accessibility_->instance_active(); | 
| +  } | 
|  | 
| -// |range| is destructed at the end of this method. |anchor| and |focus| are | 
| -// copied into the individual text markers. | 
| -id CreateTextMarkerRange(const AXPlatformRange range) { | 
| -  base::ScopedCFTypeRef<AXTextMarkerRef> start_marker(AXTextMarkerCreate( | 
| -      kCFAllocatorDefault, reinterpret_cast<const UInt8*>(range.anchor()), | 
| -      sizeof(AXPlatformPosition))); | 
| -  base::ScopedCFTypeRef<AXTextMarkerRef> end_marker(AXTextMarkerCreate( | 
| -      kCFAllocatorDefault, reinterpret_cast<const UInt8*>(range.focus()), | 
| -      sizeof(AXPlatformPosition))); | 
| -  AXTextMarkerRangeRef marker_range = | 
| -      AXTextMarkerRangeCreate(kCFAllocatorDefault, start_marker, end_marker); | 
| -  return static_cast<id>( | 
| -      base::mac::CFTypeRefToNSObjectAutorelease(marker_range)); | 
| -} | 
| +  content::BrowserAccessibility* browser_accessibility_; | 
|  | 
| -AXPlatformPositionInstance CreatePositionFromTextMarker( | 
| -    AXTextMarkerRef text_marker) { | 
| -  DCHECK(text_marker); | 
| -  if (AXTextMarkerGetLength(text_marker) != sizeof(AXPlatformPosition)) | 
| -    return AXPlatformPosition::CreateNullPosition(); | 
| -  const UInt8* source_buffer = AXTextMarkerGetBytePtr(text_marker); | 
| -  if (!source_buffer) | 
| -    return AXPlatformPosition::CreateNullPosition(); | 
| -  UInt8* destination_buffer = new UInt8[sizeof(AXPlatformPosition)]; | 
| -  std::memcpy(destination_buffer, source_buffer, sizeof(AXPlatformPosition)); | 
| -  AXPlatformPosition::AXPositionInstance position( | 
| -      reinterpret_cast<AXPlatformPosition::AXPositionInstance::pointer>( | 
| -          destination_buffer)); | 
| -  if (!position) | 
| -    return AXPlatformPosition::CreateNullPosition(); | 
| -  return position; | 
| -} | 
| +  DISALLOW_COPY_AND_ASSIGN(BrowserPositionFactory); | 
| +}; | 
|  | 
| -AXPlatformRange CreateRangeFromTextMarkerRange( | 
| -    AXTextMarkerRangeRef marker_range) { | 
| -  DCHECK(marker_range); | 
| -  base::ScopedCFTypeRef<AXTextMarkerRef> start_marker( | 
| -      AXTextMarkerRangeCopyStartMarker(marker_range)); | 
| -  base::ScopedCFTypeRef<AXTextMarkerRef> end_marker( | 
| -      AXTextMarkerRangeCopyEndMarker(marker_range)); | 
| -  if (!start_marker.get() || !end_marker.get()) | 
| +AXPlatformRange CreateRangeFromTextMarkerRange(id marker_range) { | 
| +  ui::AXPositionData start, end; | 
| +  if (![TextMarkerHelperMac getRangeDataFromMarkerRange:marker_range | 
| +                                                  start:&start | 
| +                                                    end:&end]) { | 
| return AXPlatformRange(); | 
| +  } | 
|  | 
| -  AXPlatformPositionInstance anchor = | 
| -      CreatePositionFromTextMarker(start_marker.get()); | 
| -  AXPlatformPositionInstance focus = | 
| -      CreatePositionFromTextMarker(end_marker.get()); | 
| -  // |AXPlatformRange| takes ownership of its anchor and focus. | 
| -  return AXPlatformRange(std::move(anchor), std::move(focus)); | 
| +  return AXPlatformRange(AXPlatformPosition::CreateFromData(start), | 
| +                         AXPlatformPosition::CreateFromData(end)); | 
| } | 
|  | 
| AXPlatformPositionInstance CreateTextPosition( | 
| @@ -213,18 +158,18 @@ AXPlatformPositionInstance CreateTextPosition( | 
| manager->ax_tree_id(), object.GetId(), offset, affinity); | 
| } | 
|  | 
| -AXPlatformRange CreateTextRange(const BrowserAccessibility& start_object, | 
| -                                int start_offset, | 
| -                                ui::AXTextAffinity start_affinity, | 
| -                                const BrowserAccessibility& end_object, | 
| -                                int end_offset, | 
| -                                ui::AXTextAffinity end_affinity) { | 
| +ui::AXRangePointer CreateTextRange(const BrowserAccessibility& start_object, | 
| +                                   int start_offset, | 
| +                                   ui::AXTextAffinity start_affinity, | 
| +                                   const BrowserAccessibility& end_object, | 
| +                                   int end_offset, | 
| +                                   ui::AXTextAffinity end_affinity) { | 
| AXPlatformPositionInstance anchor = | 
| CreateTextPosition(start_object, start_offset, start_affinity); | 
| AXPlatformPositionInstance focus = | 
| CreateTextPosition(end_object, end_offset, end_affinity); | 
| -  // |AXPlatformRange| takes ownership of its anchor and focus. | 
| -  return AXPlatformRange(std::move(anchor), std::move(focus)); | 
| +  // |AXRangePointer| takes ownership of its anchor and focus. | 
| +  return ui::AXRangePointer(std::move(anchor), std::move(focus)); | 
| } | 
|  | 
| void AddMisspelledTextAttributes( | 
| @@ -257,15 +202,14 @@ void AddMisspelledTextAttributes( | 
| [attributed_string endEditing]; | 
| } | 
|  | 
| -NSString* GetTextForTextMarkerRange(AXTextMarkerRangeRef marker_range) { | 
| +NSString* GetTextForTextMarkerRange(id marker_range) { | 
| AXPlatformRange range = CreateRangeFromTextMarkerRange(marker_range); | 
| if (range.IsNull()) | 
| return nil; | 
| return base::SysUTF16ToNSString(range.GetText()); | 
| } | 
|  | 
| -NSAttributedString* GetAttributedTextForTextMarkerRange( | 
| -    AXTextMarkerRangeRef marker_range) { | 
| +NSAttributedString* GetAttributedTextForTextMarkerRange(id marker_range) { | 
| BrowserAccessibility* start_object; | 
| BrowserAccessibility* end_object; | 
| int start_offset, end_offset; | 
| @@ -523,7 +467,16 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| } | 
| #endif  // MAC_OS_X_VERSION_10_12 | 
|  | 
| -@implementation BrowserAccessibilityCocoa | 
| +@interface BrowserAccessibilityCocoa () | 
| + | 
| +// Lazily creates a TextMarkerHelper and returns it. | 
| +- (TextMarkerHelperMac*)textMarkerHelper; | 
| + | 
| +@end | 
| + | 
| +@implementation BrowserAccessibilityCocoa { | 
| +  base::scoped_nsobject<TextMarkerHelperMac> textMarkerHelper_; | 
| +} | 
|  | 
| + (void)initialize { | 
| const struct { | 
| @@ -966,16 +919,12 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| !GetState(browserAccessibility_, ui::AX_STATE_DISABLED)]; | 
| } | 
|  | 
| -// Returns a text marker that points to the last character in the document that | 
| -// can be selected with VoiceOver. | 
| -- (id)endTextMarker { | 
| -  const BrowserAccessibility* root = | 
| -      browserAccessibility_->manager()->GetRoot(); | 
| -  if (!root) | 
| -    return nil; | 
| +- (id)startTextMarker { | 
| +  return [[self textMarkerHelper] startTextMarker]; | 
| +} | 
|  | 
| -  AXPlatformPositionInstance position = root->CreatePositionAt(0); | 
| -  return CreateTextMarker(position->CreatePositionAtEndOfAnchor()); | 
| +- (id)endTextMarker { | 
| +  return [[self textMarkerHelper] endTextMarker]; | 
| } | 
|  | 
| - (NSNumber*)expanded { | 
| @@ -1669,35 +1618,7 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| } | 
|  | 
| - (id)selectedTextMarkerRange { | 
| -  if (![self instanceActive]) | 
| -    return nil; | 
| - | 
| -  BrowserAccessibilityManager* manager = browserAccessibility_->manager(); | 
| -  if (!manager) | 
| -    return nil; | 
| - | 
| -  int32_t anchorId = manager->GetTreeData().sel_anchor_object_id; | 
| -  const BrowserAccessibility* anchorObject = manager->GetFromID(anchorId); | 
| -  if (!anchorObject) | 
| -    return nil; | 
| - | 
| -  int32_t focusId = manager->GetTreeData().sel_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; | 
| -  if (anchorOffset < 0 || focusOffset < 0) | 
| -    return nil; | 
| - | 
| -  ui::AXTextAffinity anchorAffinity = | 
| -        manager->GetTreeData().sel_anchor_affinity; | 
| -  ui::AXTextAffinity focusAffinity = manager->GetTreeData().sel_focus_affinity; | 
| - | 
| -  return CreateTextMarkerRange(CreateTextRange(*anchorObject, anchorOffset, | 
| -                                               anchorAffinity, *focusObject, | 
| -                                               focusOffset, focusAffinity)); | 
| +  return [[self textMarkerHelper] selectedTextMarkerRange]; | 
| } | 
|  | 
| - (NSValue*)size { | 
| @@ -1731,18 +1652,6 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| return nil; | 
| } | 
|  | 
| -// Returns a text marker that points to the first character in the document that | 
| -// can be selected with VoiceOver. | 
| -- (id)startTextMarker { | 
| -  const BrowserAccessibility* root = | 
| -      browserAccessibility_->manager()->GetRoot(); | 
| -  if (!root) | 
| -    return nil; | 
| - | 
| -  AXPlatformPositionInstance position = root->CreatePositionAt(0); | 
| -  return CreateTextMarker(position->CreatePositionAtStartOfAnchor()); | 
| -} | 
| - | 
| // Returns a subrole based upon the role. | 
| - (NSString*) subrole { | 
| if (![self instanceActive]) | 
| @@ -2013,6 +1922,15 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| return [attributedValue attributedSubstringFromRange:range]; | 
| } | 
|  | 
| +- (TextMarkerHelperMac*)textMarkerHelper { | 
| +  if (!textMarkerHelper_) { | 
| +    textMarkerHelper_.reset([[TextMarkerHelperMac alloc] | 
| +        initWithFactory:base::MakeUnique<BrowserPositionFactory>( | 
| +                            browserAccessibility_)]); | 
| +  } | 
| +  return textMarkerHelper_; | 
| +} | 
| + | 
| // Returns the accessibility value for the given attribute.  If the value isn't | 
| // supported this will return nil. | 
| - (id)accessibilityAttributeValue:(NSString*)attribute { | 
| @@ -2129,163 +2047,20 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| return nil; | 
| } | 
|  | 
| -  if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (!position->IsNullPosition()) | 
| -      return ToBrowserAccessibilityCocoa(position->GetAnchor()); | 
| - | 
| -    return nil; | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) { | 
| -    AXPlatformPositionInstance startPosition = | 
| -        browserAccessibility_->CreatePositionAt(0); | 
| -    AXPlatformPositionInstance endPosition = | 
| -        startPosition->CreatePositionAtEndOfAnchor(); | 
| -    AXPlatformRange range = | 
| -        AXPlatformRange(std::move(startPosition), std::move(endPosition)); | 
| -    return CreateTextMarkerRange(std::move(range)); | 
| +  SEL selector = NSSelectorFromString([attribute stringByAppendingString:@":"]); | 
| +  DCHECK(selector); | 
| +  if ([TextMarkerHelperMac instancesRespondToSelector:selector]) { | 
| +    return | 
| +        [[self textMarkerHelper] performSelector:selector withObject:parameter]; | 
| } | 
|  | 
| +  // TODO(tapted): Move the next three to TextMarkerHelper. | 
| if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) | 
| return GetTextForTextMarkerRange(parameter); | 
|  | 
| if ([attribute isEqualToString:@"AXAttributedStringForTextMarkerRange"]) | 
| return GetAttributedTextForTextMarkerRange(parameter); | 
|  | 
| -  if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (position->IsNullPosition()) | 
| -      return nil; | 
| -    return CreateTextMarker(position->CreateNextCharacterPosition()); | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (position->IsNullPosition()) | 
| -      return nil; | 
| -    return CreateTextMarker(position->CreatePreviousCharacterPosition()); | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) { | 
| -    AXPlatformPositionInstance endPosition = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (endPosition->IsNullPosition()) | 
| -      return nil; | 
| - | 
| -    AXPlatformPositionInstance startWordPosition = | 
| -        endPosition->CreatePreviousWordStartPosition(); | 
| -    AXPlatformPositionInstance endWordPosition = | 
| -        endPosition->CreatePreviousWordEndPosition(); | 
| -    AXPlatformPositionInstance startPosition = | 
| -        *startWordPosition <= *endWordPosition ? std::move(endWordPosition) | 
| -                                               : std::move(startWordPosition); | 
| -    AXPlatformRange range(std::move(startPosition), std::move(endPosition)); | 
| -    return CreateTextMarkerRange(std::move(range)); | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) { | 
| -    AXPlatformPositionInstance startPosition = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (startPosition->IsNullPosition()) | 
| -      return nil; | 
| - | 
| -    AXPlatformPositionInstance endWordPosition = | 
| -        startPosition->CreateNextWordEndPosition(); | 
| -    AXPlatformPositionInstance startWordPosition = | 
| -        startPosition->CreateNextWordStartPosition(); | 
| -    AXPlatformPositionInstance endPosition = | 
| -        *startWordPosition <= *endWordPosition ? std::move(startWordPosition) | 
| -                                               : std::move(endWordPosition); | 
| -    AXPlatformRange range(std::move(startPosition), std::move(endPosition)); | 
| -    return CreateTextMarkerRange(std::move(range)); | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (position->IsNullPosition()) | 
| -      return nil; | 
| -    return CreateTextMarker(position->CreateNextWordEndPosition()); | 
| -  } | 
| - | 
| -  if ([attribute | 
| -          isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (position->IsNullPosition()) | 
| -      return nil; | 
| -    return CreateTextMarker(position->CreatePreviousWordStartPosition()); | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (position->IsNullPosition()) | 
| -      return nil; | 
| - | 
| -    AXPlatformPositionInstance startPosition = | 
| -        position->CreatePreviousLineStartPosition(); | 
| -    AXPlatformPositionInstance endPosition = | 
| -        position->CreateNextLineEndPosition(); | 
| -    AXPlatformRange range(std::move(startPosition), std::move(endPosition)); | 
| -    return CreateTextMarkerRange(std::move(range)); | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) { | 
| -    AXPlatformPositionInstance endPosition = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (endPosition->IsNullPosition()) | 
| -      return nil; | 
| - | 
| -    AXPlatformPositionInstance startLinePosition = | 
| -        endPosition->CreatePreviousLineStartPosition(); | 
| -    AXPlatformPositionInstance endLinePosition = | 
| -        endPosition->CreatePreviousLineEndPosition(); | 
| -    AXPlatformPositionInstance startPosition = | 
| -        *startLinePosition <= *endLinePosition ? std::move(endLinePosition) | 
| -                                               : std::move(startLinePosition); | 
| -    AXPlatformRange range(std::move(startPosition), std::move(endPosition)); | 
| -    return CreateTextMarkerRange(std::move(range)); | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) { | 
| -    AXPlatformPositionInstance startPosition = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (startPosition->IsNullPosition()) | 
| -      return nil; | 
| - | 
| -    AXPlatformPositionInstance startLinePosition = | 
| -        startPosition->CreateNextLineStartPosition(); | 
| -    AXPlatformPositionInstance endLinePosition = | 
| -        startPosition->CreateNextLineEndPosition(); | 
| -    AXPlatformPositionInstance endPosition = | 
| -        *startLinePosition <= *endLinePosition ? std::move(startLinePosition) | 
| -                                               : std::move(endLinePosition); | 
| -    AXPlatformRange range(std::move(startPosition), std::move(endPosition)); | 
| -    return CreateTextMarkerRange(std::move(range)); | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (position->IsNullPosition()) | 
| -      return nil; | 
| -    return CreateTextMarker(position->CreateNextLineEndPosition()); | 
| -  } | 
| - | 
| -  if ([attribute | 
| -          isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (position->IsNullPosition()) | 
| -      return nil; | 
| -    return CreateTextMarker(position->CreatePreviousLineStartPosition()); | 
| -  } | 
| - | 
| if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) { | 
| NSString* text = GetTextForTextMarkerRange(parameter); | 
| return [NSNumber numberWithInt:[text length]]; | 
| @@ -2327,18 +2102,7 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| return nil; | 
| } | 
|  | 
| -  if ([attribute isEqualToString: | 
| -           NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) { | 
| -    AXPlatformPositionInstance position = | 
| -        CreatePositionFromTextMarker(parameter); | 
| -    if (position->IsNullPosition()) | 
| -      return nil; | 
| - | 
| -    AXPlatformRange range(position->CreatePreviousLineStartPosition(), | 
| -                          position->CreateNextLineEndPosition()); | 
| -    return CreateTextMarkerRange(std::move(range)); | 
| -  } | 
| - | 
| +  // TODO(tapted): Move this to TextMarkerHelper. | 
| if ([attribute isEqualToString: | 
| NSAccessibilityBoundsForTextMarkerRangeParameterizedAttribute]) { | 
| BrowserAccessibility* startObject; | 
| @@ -2367,28 +2131,6 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| } | 
|  | 
| if ([attribute isEqualToString: | 
| -           NSAccessibilityTextMarkerRangeForUnorderedTextMarkersParameterizedAttribute]) { | 
| -    if (![parameter isKindOfClass:[NSArray class]]) | 
| -      return nil; | 
| - | 
| -    NSArray* text_marker_array = parameter; | 
| -    if ([text_marker_array count] != 2) | 
| -      return nil; | 
| - | 
| -    AXPlatformPositionInstance startPosition = | 
| -        CreatePositionFromTextMarker([text_marker_array objectAtIndex:0]); | 
| -    AXPlatformPositionInstance endPosition = | 
| -        CreatePositionFromTextMarker([text_marker_array objectAtIndex:1]); | 
| -    if (*startPosition <= *endPosition) { | 
| -      return CreateTextMarkerRange( | 
| -          AXPlatformRange(std::move(startPosition), std::move(endPosition))); | 
| -    } else { | 
| -      return CreateTextMarkerRange( | 
| -          AXPlatformRange(std::move(endPosition), std::move(startPosition))); | 
| -    } | 
| -  } | 
| - | 
| -  if ([attribute isEqualToString: | 
| NSAccessibilityIndexForChildUIElementParameterizedAttribute]) { | 
| if (![parameter isKindOfClass:[BrowserAccessibilityCocoa class]]) | 
| return nil; | 
| @@ -2885,3 +2627,58 @@ NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 
| } | 
|  | 
| @end | 
| + | 
| +ui::AXPositionPointer BrowserPositionFactory::GetRoot() const { | 
| +  const BrowserAccessibility* root = | 
| +      browser_accessibility_->manager()->GetRoot(); | 
| +  if (!root) | 
| +    return nullptr; | 
| + | 
| +  return root->CreatePositionAt(0); | 
| +} | 
| + | 
| +ui::AXRangePointer BrowserPositionFactory::GetSelection() const { | 
| +  if (!IsActive()) | 
| +    return ui::AXRangePointer(nullptr, nullptr); | 
| + | 
| +  BrowserAccessibilityManager* manager = browser_accessibility_->manager(); | 
| +  if (!manager) | 
| +    return ui::AXRangePointer(nullptr, nullptr); | 
| + | 
| +  int32_t anchor_id = manager->GetTreeData().sel_anchor_object_id; | 
| +  const BrowserAccessibility* anchor_object = manager->GetFromID(anchor_id); | 
| +  if (!anchor_object) | 
| +    return ui::AXRangePointer(nullptr, nullptr); | 
| + | 
| +  int32_t focus_id = manager->GetTreeData().sel_focus_object_id; | 
| +  const BrowserAccessibility* focusObject = manager->GetFromID(focus_id); | 
| +  if (!focusObject) | 
| +    return ui::AXRangePointer(nullptr, nullptr); | 
| + | 
| +  int anchor_offset = manager->GetTreeData().sel_anchor_offset; | 
| +  int focus_offset = manager->GetTreeData().sel_focus_offset; | 
| +  if (anchor_offset < 0 || focus_offset < 0) | 
| +    return ui::AXRangePointer(nullptr, nullptr); | 
| + | 
| +  ui::AXTextAffinity anchorAffinity = | 
| +      manager->GetTreeData().sel_anchor_affinity; | 
| +  ui::AXTextAffinity focusAffinity = manager->GetTreeData().sel_focus_affinity; | 
| + | 
| +  return CreateTextRange(*anchor_object, anchor_offset, anchorAffinity, | 
| +                         *focusObject, focus_offset, focusAffinity); | 
| +} | 
| + | 
| +ui::AXPositionPointer BrowserPositionFactory::GetFromData( | 
| +    const ui::AXPositionData& data) const { | 
| +  return AXPlatformPosition::CreateFromData(data); | 
| +} | 
| + | 
| +id BrowserPositionFactory::GetAccessibilityObject( | 
| +    const ui::AXPositionData& data) const { | 
| +  AXPlatformPositionInstance position = | 
| +      AXPlatformPosition::CreateFromData(data); | 
| +  if (!position->IsNullPosition()) | 
| +    return ToBrowserAccessibilityCocoa(position->GetAnchor()); | 
| + | 
| +  return nil; | 
| +} | 
|  |