OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 5 #import "content/browser/accessibility/browser_accessibility_cocoa.h" |
6 | 6 |
7 #include <execinfo.h> | 7 #include <execinfo.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 10 matching lines...) Expand all Loading... | |
21 #include "content/app/strings/grit/content_strings.h" | 21 #include "content/app/strings/grit/content_strings.h" |
22 #include "content/browser/accessibility/ax_platform_position.h" | 22 #include "content/browser/accessibility/ax_platform_position.h" |
23 #include "content/browser/accessibility/browser_accessibility_mac.h" | 23 #include "content/browser/accessibility/browser_accessibility_mac.h" |
24 #include "content/browser/accessibility/browser_accessibility_manager.h" | 24 #include "content/browser/accessibility/browser_accessibility_manager.h" |
25 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" | 25 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" |
26 #include "content/browser/accessibility/one_shot_accessibility_tree_search.h" | 26 #include "content/browser/accessibility/one_shot_accessibility_tree_search.h" |
27 #include "content/public/common/content_client.h" | 27 #include "content/public/common/content_client.h" |
28 #include "third_party/skia/include/core/SkColor.h" | 28 #include "third_party/skia/include/core/SkColor.h" |
29 #include "ui/accessibility/ax_range.h" | 29 #include "ui/accessibility/ax_range.h" |
30 #import "ui/accessibility/platform/ax_platform_node_mac.h" | 30 #import "ui/accessibility/platform/ax_platform_node_mac.h" |
31 #import "ui/accessibility/platform/text_marker_helper_mac.h" | |
31 | 32 |
32 using AXAbstractPositionInstance = | |
33 content::AXPlatformPosition::AXPositionInstance; | |
34 using AXPlatformPositionInstance = | 33 using AXPlatformPositionInstance = |
35 content::AXPlatformPosition::ConcreteInstance; | 34 content::AXPlatformPosition::ConcreteInstance; |
36 using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>; | 35 using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>; |
37 using AXTextMarkerRangeRef = CFTypeRef; | |
38 using AXTextMarkerRef = CFTypeRef; | |
39 using StringAttribute = ui::AXStringAttribute; | 36 using StringAttribute = ui::AXStringAttribute; |
40 using content::AXPlatformPosition; | 37 using content::AXPlatformPosition; |
41 using content::AccessibilityMatchPredicate; | 38 using content::AccessibilityMatchPredicate; |
42 using content::BrowserAccessibility; | 39 using content::BrowserAccessibility; |
43 using content::BrowserAccessibilityDelegate; | 40 using content::BrowserAccessibilityDelegate; |
44 using content::BrowserAccessibilityManager; | 41 using content::BrowserAccessibilityManager; |
45 using content::BrowserAccessibilityManagerMac; | 42 using content::BrowserAccessibilityManagerMac; |
46 using content::ContentClient; | 43 using content::ContentClient; |
47 using content::OneShotAccessibilityTreeSearch; | 44 using content::OneShotAccessibilityTreeSearch; |
48 using ui::AXNodeData; | 45 using ui::AXNodeData; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 | 103 |
107 // Actions. | 104 // Actions. |
108 NSString* const NSAccessibilityScrollToVisibleAction = @"AXScrollToVisible"; | 105 NSString* const NSAccessibilityScrollToVisibleAction = @"AXScrollToVisible"; |
109 | 106 |
110 // A mapping from an accessibility attribute to its method name. | 107 // A mapping from an accessibility attribute to its method name. |
111 NSDictionary* attributeToMethodNameMap = nil; | 108 NSDictionary* attributeToMethodNameMap = nil; |
112 | 109 |
113 // VoiceOver uses -1 to mean "no limit" for AXResultsLimit. | 110 // VoiceOver uses -1 to mean "no limit" for AXResultsLimit. |
114 const int kAXResultsLimitNoLimit = -1; | 111 const int kAXResultsLimitNoLimit = -1; |
115 | 112 |
116 extern "C" { | |
117 | |
118 // The following are private accessibility APIs required for cursor navigation | |
119 // and text selection. VoiceOver started relying on them in Mac OS X 10.11. | |
120 #if !defined(MAC_OS_X_VERSION_10_11) || \ | |
121 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11 | |
122 | |
123 AXTextMarkerRef AXTextMarkerCreate(CFAllocatorRef allocator, | |
124 const UInt8* bytes, | |
125 CFIndex length); | |
126 | |
127 const UInt8* AXTextMarkerGetBytePtr(AXTextMarkerRef text_marker); | |
128 | |
129 size_t AXTextMarkerGetLength(AXTextMarkerRef text_marker); | |
130 | |
131 AXTextMarkerRangeRef AXTextMarkerRangeCreate(CFAllocatorRef allocator, | |
132 AXTextMarkerRef start_marker, | |
133 AXTextMarkerRef end_marker); | |
134 | |
135 AXTextMarkerRef AXTextMarkerRangeCopyStartMarker( | |
136 AXTextMarkerRangeRef text_marker_range); | |
137 | |
138 AXTextMarkerRef AXTextMarkerRangeCopyEndMarker( | |
139 AXTextMarkerRangeRef text_marker_range); | |
140 | |
141 #endif // MAC_OS_X_VERSION_10_11 | |
142 | |
143 } // extern "C" | |
144 | |
145 static_assert(sizeof(AXPlatformPosition) == sizeof(ui::AXPositionBase), | 113 static_assert(sizeof(AXPlatformPosition) == sizeof(ui::AXPositionBase), |
146 "AXPosition size mismatch"); | 114 "AXPosition size mismatch"); |
147 constexpr size_t kAXPositionSize = sizeof(ui::AXPositionBase); | 115 constexpr size_t kAXPositionSize = sizeof(ui::AXPositionBase); |
148 | 116 |
149 // to call |release| on it to transfer ownership of the position to the text | 117 class BrowserPositionFactory : public ui::PositionFactory { |
150 // marker object. | 118 public: |
151 id CreateTextMarker(AXAbstractPositionInstance position) { | 119 explicit BrowserPositionFactory( |
152 AXTextMarkerRef text_marker = AXTextMarkerCreate( | 120 content::BrowserAccessibility* browser_accessibility) |
153 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(position.release()), | 121 : browser_accessibility_(browser_accessibility) {} |
154 kAXPositionSize); | |
155 return static_cast<id>( | |
156 base::mac::CFTypeRefToNSObjectAutorelease(text_marker)); | |
157 } | |
158 | 122 |
159 // |range| is destructed at the end of this method and ownership of its |anchor| | 123 std::unique_ptr<ui::AXPositionBase> GetRoot() const override; |
160 // and |focus| are transfered to the marker range object. | 124 std::unique_ptr<ui::AXAbstractRange> GetSelection() const override; |
161 id CreateTextMarkerRange(const ui::AXAbstractRange range) { | 125 std::unique_ptr<ui::AXPositionBase> ExtractFromMarker( |
162 AXTextMarkerRef start_marker = AXTextMarkerCreate( | 126 AXTextMarkerRef marker) const override; |
163 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(range.anchor()), | 127 |
164 kAXPositionSize); | 128 private: |
165 AXTextMarkerRef end_marker = AXTextMarkerCreate( | 129 bool IsActive() const { |
166 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(range.focus()), | 130 return browser_accessibility_ && browser_accessibility_->instance_active(); |
167 kAXPositionSize); | 131 } |
168 AXTextMarkerRangeRef marker_range = | 132 |
169 AXTextMarkerRangeCreate(kCFAllocatorDefault, start_marker, end_marker); | 133 content::BrowserAccessibility* browser_accessibility_; |
170 return static_cast<id>( | 134 |
171 base::mac::CFTypeRefToNSObjectAutorelease(marker_range)); | 135 DISALLOW_COPY_AND_ASSIGN(BrowserPositionFactory); |
172 } | 136 }; |
173 | 137 |
174 AXPlatformPositionInstance CreateConcretePositionFromTextMarker( | 138 AXPlatformPositionInstance CreateConcretePositionFromTextMarker( |
175 AXTextMarkerRef text_marker) { | 139 AXTextMarkerRef text_marker) { |
176 DCHECK(text_marker); | 140 DCHECK(text_marker); |
177 if (AXTextMarkerGetLength(text_marker) != kAXPositionSize) | 141 if (AXTextMarkerGetLength(text_marker) != kAXPositionSize) |
178 return AXPlatformPosition::CreateConcreteNullPosition(); | 142 return AXPlatformPosition::CreateConcreteNullPosition(); |
179 const UInt8* source_buffer = AXTextMarkerGetBytePtr(text_marker); | 143 const UInt8* source_buffer = AXTextMarkerGetBytePtr(text_marker); |
180 if (!source_buffer) | 144 if (!source_buffer) |
181 return AXPlatformPosition::CreateConcreteNullPosition(); | 145 return AXPlatformPosition::CreateConcreteNullPosition(); |
182 UInt8* destination_buffer = new UInt8[kAXPositionSize]; | 146 UInt8* destination_buffer = new UInt8[kAXPositionSize]; |
183 std::memcpy(destination_buffer, source_buffer, kAXPositionSize); | 147 std::memcpy(destination_buffer, source_buffer, kAXPositionSize); |
184 AXPlatformPositionInstance position( | 148 AXPlatformPositionInstance position( |
185 reinterpret_cast<AXPlatformPositionInstance::pointer>( | 149 reinterpret_cast<AXPlatformPositionInstance::pointer>( |
186 destination_buffer)); | 150 destination_buffer)); |
187 if (!position) | 151 if (!position) |
188 return AXPlatformPosition::CreateConcreteNullPosition(); | 152 return AXPlatformPosition::CreateConcreteNullPosition(); |
189 return position; | 153 return position; |
190 } | 154 } |
191 | 155 |
192 AXAbstractPositionInstance CreatePositionFromTextMarker( | |
193 AXTextMarkerRef text_marker) { | |
194 return base::WrapUnique( | |
195 CreateConcretePositionFromTextMarker(text_marker).release()); | |
196 } | |
197 | |
198 AXPlatformRange CreateRangeFromTextMarkerRange( | 156 AXPlatformRange CreateRangeFromTextMarkerRange( |
199 AXTextMarkerRangeRef marker_range) { | 157 AXTextMarkerRangeRef marker_range) { |
200 DCHECK(marker_range); | 158 DCHECK(marker_range); |
201 base::ScopedCFTypeRef<AXTextMarkerRef> start_marker( | 159 base::ScopedCFTypeRef<AXTextMarkerRef> start_marker( |
202 AXTextMarkerRangeCopyStartMarker(marker_range)); | 160 AXTextMarkerRangeCopyStartMarker(marker_range)); |
203 base::ScopedCFTypeRef<AXTextMarkerRef> end_marker( | 161 base::ScopedCFTypeRef<AXTextMarkerRef> end_marker( |
204 AXTextMarkerRangeCopyEndMarker(marker_range)); | 162 AXTextMarkerRangeCopyEndMarker(marker_range)); |
205 if (!start_marker.get() || !end_marker.get()) | 163 if (!start_marker.get() || !end_marker.get()) |
206 return AXPlatformRange(); | 164 return AXPlatformRange(); |
207 | 165 |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 } // namespace | 487 } // namespace |
530 | 488 |
531 // The following private WebKit accessibility attribute became public in 10.12. | 489 // The following private WebKit accessibility attribute became public in 10.12. |
532 #if !defined(MAC_OS_X_VERSION_10_12) || \ | 490 #if !defined(MAC_OS_X_VERSION_10_12) || \ |
533 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 | 491 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 |
534 extern "C" { | 492 extern "C" { |
535 NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; | 493 NSString* const NSAccessibilityRequiredAttribute = @"AXRequired"; |
536 } | 494 } |
537 #endif // MAC_OS_X_VERSION_10_12 | 495 #endif // MAC_OS_X_VERSION_10_12 |
538 | 496 |
539 @implementation BrowserAccessibilityCocoa | 497 @interface BrowserAccessibilityCocoa () |
498 | |
499 // Lazily creates a TextMarkerHelper and returns it. | |
500 - (TextMarkerHelperMac*)textMarkerHelper; | |
501 | |
502 @end | |
503 | |
504 @implementation BrowserAccessibilityCocoa { | |
505 base::scoped_nsobject<TextMarkerHelperMac> textMarkerHelper_; | |
506 } | |
540 | 507 |
541 + (void)initialize { | 508 + (void)initialize { |
542 const struct { | 509 const struct { |
543 NSString* attribute; | 510 NSString* attribute; |
544 NSString* methodName; | 511 NSString* methodName; |
545 } attributeToMethodNameContainer[] = { | 512 } attributeToMethodNameContainer[] = { |
546 {NSAccessibilityARIAAtomicAttribute, @"ariaAtomic"}, | 513 {NSAccessibilityARIAAtomicAttribute, @"ariaAtomic"}, |
547 {NSAccessibilityARIABusyAttribute, @"ariaBusy"}, | 514 {NSAccessibilityARIABusyAttribute, @"ariaBusy"}, |
548 {NSAccessibilityARIAColumnCountAttribute, @"ariaColumnCount"}, | 515 {NSAccessibilityARIAColumnCountAttribute, @"ariaColumnCount"}, |
549 {NSAccessibilityARIAColumnIndexAttribute, @"ariaColumnIndex"}, | 516 {NSAccessibilityARIAColumnIndexAttribute, @"ariaColumnIndex"}, |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
972 return nil; | 939 return nil; |
973 } | 940 } |
974 | 941 |
975 - (NSNumber*)enabled { | 942 - (NSNumber*)enabled { |
976 if (![self instanceActive]) | 943 if (![self instanceActive]) |
977 return nil; | 944 return nil; |
978 return [NSNumber numberWithBool: | 945 return [NSNumber numberWithBool: |
979 !GetState(browserAccessibility_, ui::AX_STATE_DISABLED)]; | 946 !GetState(browserAccessibility_, ui::AX_STATE_DISABLED)]; |
980 } | 947 } |
981 | 948 |
982 // Returns a text marker that points to the last character in the document that | |
983 // can be selected with VoiceOver. | |
984 - (id)endTextMarker { | 949 - (id)endTextMarker { |
985 const BrowserAccessibility* root = | 950 return [[self textMarkerHelper] endTextMarker]; |
986 browserAccessibility_->manager()->GetRoot(); | 951 } |
987 if (!root) | |
988 return nil; | |
989 | 952 |
990 AXAbstractPositionInstance position = root->CreatePositionAt(0); | 953 - (id)startTextMarker { |
tapted
2017/06/19 11:44:30
(self review: swap order with endTextMarker)
| |
991 return CreateTextMarker(position->CreatePositionAtEndOfAnchor()); | 954 return [[self textMarkerHelper] startTextMarker]; |
992 } | 955 } |
993 | 956 |
994 - (NSNumber*)expanded { | 957 - (NSNumber*)expanded { |
995 if (![self instanceActive]) | 958 if (![self instanceActive]) |
996 return nil; | 959 return nil; |
997 return [NSNumber numberWithBool: | 960 return [NSNumber numberWithBool: |
998 GetState(browserAccessibility_, ui::AX_STATE_EXPANDED)]; | 961 GetState(browserAccessibility_, ui::AX_STATE_EXPANDED)]; |
999 } | 962 } |
1000 | 963 |
1001 - (NSNumber*)focused { | 964 - (NSNumber*)focused { |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1675 } | 1638 } |
1676 | 1639 |
1677 if (selStart > selEnd) | 1640 if (selStart > selEnd) |
1678 std::swap(selStart, selEnd); | 1641 std::swap(selStart, selEnd); |
1679 | 1642 |
1680 int selLength = selEnd - selStart; | 1643 int selLength = selEnd - selStart; |
1681 return [NSValue valueWithRange:NSMakeRange(selStart, selLength)]; | 1644 return [NSValue valueWithRange:NSMakeRange(selStart, selLength)]; |
1682 } | 1645 } |
1683 | 1646 |
1684 - (id)selectedTextMarkerRange { | 1647 - (id)selectedTextMarkerRange { |
1685 if (![self instanceActive]) | 1648 return [[self textMarkerHelper] selectedTextMarkerRange]; |
1686 return nil; | |
1687 | |
1688 BrowserAccessibilityManager* manager = browserAccessibility_->manager(); | |
1689 if (!manager) | |
1690 return nil; | |
1691 | |
1692 int32_t anchorId = manager->GetTreeData().sel_anchor_object_id; | |
1693 const BrowserAccessibility* anchorObject = manager->GetFromID(anchorId); | |
1694 if (!anchorObject) | |
1695 return nil; | |
1696 | |
1697 int32_t focusId = manager->GetTreeData().sel_focus_object_id; | |
1698 const BrowserAccessibility* focusObject = manager->GetFromID(focusId); | |
1699 if (!focusObject) | |
1700 return nil; | |
1701 | |
1702 int anchorOffset = manager->GetTreeData().sel_anchor_offset; | |
1703 int focusOffset = manager->GetTreeData().sel_focus_offset; | |
1704 if (anchorOffset < 0 || focusOffset < 0) | |
1705 return nil; | |
1706 | |
1707 ui::AXTextAffinity anchorAffinity = | |
1708 manager->GetTreeData().sel_anchor_affinity; | |
1709 ui::AXTextAffinity focusAffinity = manager->GetTreeData().sel_focus_affinity; | |
1710 | |
1711 return CreateTextMarkerRange(CreateTextRange(*anchorObject, anchorOffset, | |
1712 anchorAffinity, *focusObject, | |
1713 focusOffset, focusAffinity)); | |
1714 } | 1649 } |
1715 | 1650 |
1716 - (NSValue*)size { | 1651 - (NSValue*)size { |
1717 if (![self instanceActive]) | 1652 if (![self instanceActive]) |
1718 return nil; | 1653 return nil; |
1719 gfx::Rect bounds = browserAccessibility_->GetPageBoundsRect(); | 1654 gfx::Rect bounds = browserAccessibility_->GetPageBoundsRect(); |
1720 return [NSValue valueWithSize:NSMakeSize(bounds.width(), bounds.height())]; | 1655 return [NSValue valueWithSize:NSMakeSize(bounds.width(), bounds.height())]; |
1721 } | 1656 } |
1722 | 1657 |
1723 - (NSString*)sortDirection { | 1658 - (NSString*)sortDirection { |
(...skipping 13 matching lines...) Expand all Loading... | |
1737 return NSAccessibilityDescendingSortDirectionValue; | 1672 return NSAccessibilityDescendingSortDirectionValue; |
1738 case ui::AX_SORT_DIRECTION_OTHER: | 1673 case ui::AX_SORT_DIRECTION_OTHER: |
1739 return NSAccessibilityUnknownSortDirectionValue; | 1674 return NSAccessibilityUnknownSortDirectionValue; |
1740 default: | 1675 default: |
1741 NOTREACHED(); | 1676 NOTREACHED(); |
1742 } | 1677 } |
1743 | 1678 |
1744 return nil; | 1679 return nil; |
1745 } | 1680 } |
1746 | 1681 |
1747 // Returns a text marker that points to the first character in the document that | |
1748 // can be selected with VoiceOver. | |
1749 - (id)startTextMarker { | |
1750 const BrowserAccessibility* root = | |
1751 browserAccessibility_->manager()->GetRoot(); | |
1752 if (!root) | |
1753 return nil; | |
1754 | |
1755 AXAbstractPositionInstance position = root->CreatePositionAt(0); | |
1756 return CreateTextMarker(position->CreatePositionAtStartOfAnchor()); | |
1757 } | |
1758 | |
1759 // Returns a subrole based upon the role. | 1682 // Returns a subrole based upon the role. |
1760 - (NSString*) subrole { | 1683 - (NSString*) subrole { |
1761 if (![self instanceActive]) | 1684 if (![self instanceActive]) |
1762 return nil; | 1685 return nil; |
1763 ui::AXRole browserAccessibilityRole = [self internalRole]; | 1686 ui::AXRole browserAccessibilityRole = [self internalRole]; |
1764 if (browserAccessibilityRole == ui::AX_ROLE_TEXT_FIELD && | 1687 if (browserAccessibilityRole == ui::AX_ROLE_TEXT_FIELD && |
1765 GetState(browserAccessibility_, ui::AX_STATE_PROTECTED)) { | 1688 GetState(browserAccessibility_, ui::AX_STATE_PROTECTED)) { |
1766 return NSAccessibilitySecureTextFieldSubrole; | 1689 return NSAccessibilitySecureTextFieldSubrole; |
1767 } | 1690 } |
1768 | 1691 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2019 NSString* value = base::SysUTF16ToNSString(browserAccessibility_->GetValue()); | 1942 NSString* value = base::SysUTF16ToNSString(browserAccessibility_->GetValue()); |
2020 NSMutableAttributedString* attributedValue = | 1943 NSMutableAttributedString* attributedValue = |
2021 [[[NSMutableAttributedString alloc] initWithString:value] autorelease]; | 1944 [[[NSMutableAttributedString alloc] initWithString:value] autorelease]; |
2022 std::vector<const BrowserAccessibility*> textOnlyObjects = | 1945 std::vector<const BrowserAccessibility*> textOnlyObjects = |
2023 BrowserAccessibilityManager::FindTextOnlyObjectsInRange( | 1946 BrowserAccessibilityManager::FindTextOnlyObjectsInRange( |
2024 *browserAccessibility_, *browserAccessibility_); | 1947 *browserAccessibility_, *browserAccessibility_); |
2025 AddMisspelledTextAttributes(textOnlyObjects, attributedValue); | 1948 AddMisspelledTextAttributes(textOnlyObjects, attributedValue); |
2026 return [attributedValue attributedSubstringFromRange:range]; | 1949 return [attributedValue attributedSubstringFromRange:range]; |
2027 } | 1950 } |
2028 | 1951 |
1952 - (TextMarkerHelperMac*)textMarkerHelper { | |
1953 if (!textMarkerHelper_) { | |
1954 textMarkerHelper_.reset([[TextMarkerHelperMac alloc] | |
1955 initWithFactory:base::MakeUnique<BrowserPositionFactory>( | |
1956 browserAccessibility_)]); | |
1957 } | |
1958 return textMarkerHelper_; | |
1959 } | |
1960 | |
2029 // Returns the accessibility value for the given attribute. If the value isn't | 1961 // Returns the accessibility value for the given attribute. If the value isn't |
2030 // supported this will return nil. | 1962 // supported this will return nil. |
2031 - (id)accessibilityAttributeValue:(NSString*)attribute { | 1963 - (id)accessibilityAttributeValue:(NSString*)attribute { |
2032 if (![self instanceActive]) | 1964 if (![self instanceActive]) |
2033 return nil; | 1965 return nil; |
2034 | 1966 |
2035 SEL selector = | 1967 SEL selector = |
2036 NSSelectorFromString([self methodNameForAttribute:attribute]); | 1968 NSSelectorFromString([self methodNameForAttribute:attribute]); |
2037 if (selector) | 1969 if (selector) |
2038 return [self performSelector:selector]; | 1970 return [self performSelector:selector]; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2135 } | 2067 } |
2136 if (colIndex == column) | 2068 if (colIndex == column) |
2137 return ToBrowserAccessibilityCocoa(cell); | 2069 return ToBrowserAccessibilityCocoa(cell); |
2138 if (colIndex > column) | 2070 if (colIndex > column) |
2139 break; | 2071 break; |
2140 } | 2072 } |
2141 } | 2073 } |
2142 return nil; | 2074 return nil; |
2143 } | 2075 } |
2144 | 2076 |
2077 SEL selector = NSSelectorFromString(attribute); | |
tapted
2017/06/19 11:44:30
(self review: this needs a colon appended to the s
| |
2078 DCHECK(selector); | |
2079 if ([TextMarkerHelperMac instancesRespondToSelector:selector]) { | |
2080 return | |
2081 [[self textMarkerHelper] performSelector:selector withObject:parameter]; | |
2082 } | |
2083 | |
2145 if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) { | 2084 if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) { |
2146 AXPlatformPositionInstance position = | 2085 AXPlatformPositionInstance position = CreateConcretePositionFromTextMarker( |
2147 CreateConcretePositionFromTextMarker(parameter); | 2086 base::mac::CFCastStrict<AXTextMarkerRef>(parameter)); |
2148 if (!position->IsNullPosition()) | 2087 if (!position->IsNullPosition()) |
2149 return ToBrowserAccessibilityCocoa(position->GetAnchor()); | 2088 return ToBrowserAccessibilityCocoa(position->GetAnchor()); |
2150 | 2089 |
2151 return nil; | 2090 return nil; |
2152 } | 2091 } |
2153 | 2092 |
2154 if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) { | 2093 if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) { |
2155 AXAbstractPositionInstance startPosition = | 2094 return GetTextForTextMarkerRange( |
2156 browserAccessibility_->CreatePositionAt(0); | 2095 base::mac::CFCastStrict<AXTextMarkerRangeRef>(parameter)); |
2157 AXAbstractPositionInstance endPosition = | |
2158 startPosition->CreatePositionAtEndOfAnchor(); | |
2159 ui::AXAbstractRange range = | |
2160 ui::AXAbstractRange(std::move(startPosition), std::move(endPosition)); | |
2161 return CreateTextMarkerRange(std::move(range)); | |
2162 } | 2096 } |
2163 | 2097 |
2164 if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) | 2098 if ([attribute isEqualToString:@"AXAttributedStringForTextMarkerRange"]) { |
2165 return GetTextForTextMarkerRange(parameter); | 2099 return GetAttributedTextForTextMarkerRange( |
2166 | 2100 base::mac::CFCastStrict<AXTextMarkerRangeRef>(parameter)); |
2167 if ([attribute isEqualToString:@"AXAttributedStringForTextMarkerRange"]) | |
2168 return GetAttributedTextForTextMarkerRange(parameter); | |
2169 | |
2170 if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) { | |
2171 AXAbstractPositionInstance position = | |
2172 CreatePositionFromTextMarker(parameter); | |
2173 if (position->IsNullPosition()) | |
2174 return nil; | |
2175 return CreateTextMarker(position->CreateNextCharacterPosition()); | |
2176 } | |
2177 | |
2178 if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) { | |
2179 AXAbstractPositionInstance position = | |
2180 CreatePositionFromTextMarker(parameter); | |
2181 if (position->IsNullPosition()) | |
2182 return nil; | |
2183 return CreateTextMarker(position->CreatePreviousCharacterPosition()); | |
2184 } | |
2185 | |
2186 if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) { | |
2187 AXAbstractPositionInstance endPosition = | |
2188 CreatePositionFromTextMarker(parameter); | |
2189 if (endPosition->IsNullPosition()) | |
2190 return nil; | |
2191 | |
2192 AXAbstractPositionInstance startWordPosition = | |
2193 endPosition->CreatePreviousWordStartPosition(); | |
2194 AXAbstractPositionInstance endWordPosition = | |
2195 endPosition->CreatePreviousWordEndPosition(); | |
2196 AXAbstractPositionInstance startPosition = | |
2197 *startWordPosition <= *endWordPosition ? std::move(endWordPosition) | |
2198 : std::move(startWordPosition); | |
2199 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition)); | |
2200 return CreateTextMarkerRange(std::move(range)); | |
2201 } | |
2202 | |
2203 if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) { | |
2204 AXAbstractPositionInstance startPosition = | |
2205 CreatePositionFromTextMarker(parameter); | |
2206 if (startPosition->IsNullPosition()) | |
2207 return nil; | |
2208 | |
2209 AXAbstractPositionInstance endWordPosition = | |
2210 startPosition->CreateNextWordEndPosition(); | |
2211 AXAbstractPositionInstance startWordPosition = | |
2212 startPosition->CreateNextWordStartPosition(); | |
2213 AXAbstractPositionInstance endPosition = | |
2214 *startWordPosition <= *endWordPosition ? std::move(startWordPosition) | |
2215 : std::move(endWordPosition); | |
2216 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition)); | |
2217 return CreateTextMarkerRange(std::move(range)); | |
2218 } | |
2219 | |
2220 if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) { | |
2221 AXAbstractPositionInstance position = | |
2222 CreatePositionFromTextMarker(parameter); | |
2223 if (position->IsNullPosition()) | |
2224 return nil; | |
2225 return CreateTextMarker(position->CreateNextWordEndPosition()); | |
2226 } | |
2227 | |
2228 if ([attribute | |
2229 isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) { | |
2230 AXAbstractPositionInstance position = | |
2231 CreatePositionFromTextMarker(parameter); | |
2232 if (position->IsNullPosition()) | |
2233 return nil; | |
2234 return CreateTextMarker(position->CreatePreviousWordStartPosition()); | |
2235 } | |
2236 | |
2237 if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) { | |
2238 AXAbstractPositionInstance position = | |
2239 CreatePositionFromTextMarker(parameter); | |
2240 if (position->IsNullPosition()) | |
2241 return nil; | |
2242 | |
2243 AXAbstractPositionInstance startPosition = | |
2244 position->CreatePreviousLineStartPosition(); | |
2245 AXAbstractPositionInstance endPosition = | |
2246 position->CreateNextLineEndPosition(); | |
2247 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition)); | |
2248 return CreateTextMarkerRange(std::move(range)); | |
2249 } | |
2250 | |
2251 if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) { | |
2252 AXAbstractPositionInstance endPosition = | |
2253 CreatePositionFromTextMarker(parameter); | |
2254 if (endPosition->IsNullPosition()) | |
2255 return nil; | |
2256 | |
2257 AXAbstractPositionInstance startLinePosition = | |
2258 endPosition->CreatePreviousLineStartPosition(); | |
2259 AXAbstractPositionInstance endLinePosition = | |
2260 endPosition->CreatePreviousLineEndPosition(); | |
2261 AXAbstractPositionInstance startPosition = | |
2262 *startLinePosition <= *endLinePosition ? std::move(endLinePosition) | |
2263 : std::move(startLinePosition); | |
2264 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition)); | |
2265 return CreateTextMarkerRange(std::move(range)); | |
2266 } | |
2267 | |
2268 if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) { | |
2269 AXAbstractPositionInstance startPosition = | |
2270 CreatePositionFromTextMarker(parameter); | |
2271 if (startPosition->IsNullPosition()) | |
2272 return nil; | |
2273 | |
2274 AXAbstractPositionInstance startLinePosition = | |
2275 startPosition->CreateNextLineStartPosition(); | |
2276 AXAbstractPositionInstance endLinePosition = | |
2277 startPosition->CreateNextLineEndPosition(); | |
2278 AXAbstractPositionInstance endPosition = | |
2279 *startLinePosition <= *endLinePosition ? std::move(startLinePosition) | |
2280 : std::move(endLinePosition); | |
2281 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition)); | |
2282 return CreateTextMarkerRange(std::move(range)); | |
2283 } | |
2284 | |
2285 if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) { | |
2286 AXAbstractPositionInstance position = | |
2287 CreatePositionFromTextMarker(parameter); | |
2288 if (position->IsNullPosition()) | |
2289 return nil; | |
2290 return CreateTextMarker(position->CreateNextLineEndPosition()); | |
2291 } | |
2292 | |
2293 if ([attribute | |
2294 isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) { | |
2295 AXAbstractPositionInstance position = | |
2296 CreatePositionFromTextMarker(parameter); | |
2297 if (position->IsNullPosition()) | |
2298 return nil; | |
2299 return CreateTextMarker(position->CreatePreviousLineStartPosition()); | |
2300 } | 2101 } |
2301 | 2102 |
2302 if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) { | 2103 if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) { |
2303 NSString* text = GetTextForTextMarkerRange(parameter); | 2104 NSString* text = GetTextForTextMarkerRange( |
2105 base::mac::CFCastStrict<AXTextMarkerRangeRef>(parameter)); | |
2304 return [NSNumber numberWithInt:[text length]]; | 2106 return [NSNumber numberWithInt:[text length]]; |
2305 } | 2107 } |
2306 | 2108 |
2307 if ([attribute isEqualToString: | 2109 if ([attribute isEqualToString: |
2308 NSAccessibilityBoundsForRangeParameterizedAttribute]) { | 2110 NSAccessibilityBoundsForRangeParameterizedAttribute]) { |
2309 if ([self internalRole] != ui::AX_ROLE_STATIC_TEXT) | 2111 if ([self internalRole] != ui::AX_ROLE_STATIC_TEXT) |
2310 return nil; | 2112 return nil; |
2311 NSRange range = [(NSValue*)parameter rangeValue]; | 2113 NSRange range = [(NSValue*)parameter rangeValue]; |
2312 gfx::Rect rect = browserAccessibility_->GetScreenBoundsForRange( | 2114 gfx::Rect rect = browserAccessibility_->GetScreenBoundsForRange( |
2313 range.location, range.length); | 2115 range.location, range.length); |
(...skipping 19 matching lines...) Expand all Loading... | |
2333 NSMutableArray* result = [NSMutableArray arrayWithCapacity:count]; | 2135 NSMutableArray* result = [NSMutableArray arrayWithCapacity:count]; |
2334 for (size_t i = 0; i < count; ++i) { | 2136 for (size_t i = 0; i < count; ++i) { |
2335 BrowserAccessibility* match = search.GetMatchAtIndex(i); | 2137 BrowserAccessibility* match = search.GetMatchAtIndex(i); |
2336 [result addObject:ToBrowserAccessibilityCocoa(match)]; | 2138 [result addObject:ToBrowserAccessibilityCocoa(match)]; |
2337 } | 2139 } |
2338 return result; | 2140 return result; |
2339 } | 2141 } |
2340 return nil; | 2142 return nil; |
2341 } | 2143 } |
2342 | 2144 |
2343 if ([attribute isEqualToString: | 2145 // TODO(tapted): Move this to TextMarkerHelper. |
2344 NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute ]) { | |
2345 AXAbstractPositionInstance position = | |
2346 CreatePositionFromTextMarker(parameter); | |
2347 if (position->IsNullPosition()) | |
2348 return nil; | |
2349 | |
2350 ui::AXAbstractRange range(position->CreatePreviousLineStartPosition(), | |
2351 position->CreateNextLineEndPosition()); | |
2352 return CreateTextMarkerRange(std::move(range)); | |
2353 } | |
2354 | |
2355 if ([attribute isEqualToString: | 2146 if ([attribute isEqualToString: |
2356 NSAccessibilityBoundsForTextMarkerRangeParameterizedAttribute]) { | 2147 NSAccessibilityBoundsForTextMarkerRangeParameterizedAttribute]) { |
2357 BrowserAccessibility* startObject; | 2148 BrowserAccessibility* startObject; |
2358 BrowserAccessibility* endObject; | 2149 BrowserAccessibility* endObject; |
2359 int startOffset, endOffset; | 2150 int startOffset, endOffset; |
2360 AXPlatformRange range = CreateRangeFromTextMarkerRange(parameter); | 2151 AXPlatformRange range = CreateRangeFromTextMarkerRange( |
2152 base::mac::CFCastStrict<AXTextMarkerRangeRef>(parameter)); | |
2361 if (range.IsNull()) | 2153 if (range.IsNull()) |
2362 return nil; | 2154 return nil; |
2363 | 2155 |
2364 startObject = range.GetAnchorNode(); | 2156 startObject = range.GetAnchorNode(); |
2365 endObject = range.GetFocusNode(); | 2157 endObject = range.GetFocusNode(); |
2366 startOffset = range.anchor()->text_offset(); | 2158 startOffset = range.anchor()->text_offset(); |
2367 endOffset = range.focus()->text_offset(); | 2159 endOffset = range.focus()->text_offset(); |
2368 DCHECK(startObject && endObject); | 2160 DCHECK(startObject && endObject); |
2369 DCHECK_GE(startOffset, 0); | 2161 DCHECK_GE(startOffset, 0); |
2370 DCHECK_GE(endOffset, 0); | 2162 DCHECK_GE(endOffset, 0); |
2371 | 2163 |
2372 gfx::Rect rect = BrowserAccessibilityManager::GetPageBoundsForRange( | 2164 gfx::Rect rect = BrowserAccessibilityManager::GetPageBoundsForRange( |
2373 *startObject, startOffset, *endObject, endOffset); | 2165 *startObject, startOffset, *endObject, endOffset); |
2374 NSPoint origin = NSMakePoint(rect.x(), rect.y()); | 2166 NSPoint origin = NSMakePoint(rect.x(), rect.y()); |
2375 NSSize size = NSMakeSize(rect.width(), rect.height()); | 2167 NSSize size = NSMakeSize(rect.width(), rect.height()); |
2376 NSPoint pointInScreen = [self pointInScreen:origin size:size]; | 2168 NSPoint pointInScreen = [self pointInScreen:origin size:size]; |
2377 NSRect nsrect = NSMakeRect( | 2169 NSRect nsrect = NSMakeRect( |
2378 pointInScreen.x, pointInScreen.y, rect.width(), rect.height()); | 2170 pointInScreen.x, pointInScreen.y, rect.width(), rect.height()); |
2379 return [NSValue valueWithRect:nsrect]; | 2171 return [NSValue valueWithRect:nsrect]; |
2380 } | 2172 } |
2381 | 2173 |
2382 if ([attribute isEqualToString: | 2174 if ([attribute isEqualToString: |
2383 NSAccessibilityTextMarkerRangeForUnorderedTextMarkersParameterizedAtt ribute]) { | |
2384 if (![parameter isKindOfClass:[NSArray class]]) | |
2385 return nil; | |
2386 | |
2387 NSArray* text_marker_array = parameter; | |
2388 if ([text_marker_array count] != 2) | |
2389 return nil; | |
2390 | |
2391 AXAbstractPositionInstance startPosition = | |
2392 CreatePositionFromTextMarker([text_marker_array objectAtIndex:0]); | |
2393 AXAbstractPositionInstance endPosition = | |
2394 CreatePositionFromTextMarker([text_marker_array objectAtIndex:1]); | |
2395 if (*startPosition <= *endPosition) { | |
2396 return CreateTextMarkerRange(ui::AXAbstractRange(std::move(startPosition), | |
2397 std::move(endPosition))); | |
2398 } else { | |
2399 return CreateTextMarkerRange(ui::AXAbstractRange( | |
2400 std::move(endPosition), std::move(startPosition))); | |
2401 } | |
2402 } | |
2403 | |
2404 if ([attribute isEqualToString: | |
2405 NSAccessibilityIndexForChildUIElementParameterizedAttribute]) { | 2175 NSAccessibilityIndexForChildUIElementParameterizedAttribute]) { |
2406 if (![parameter isKindOfClass:[BrowserAccessibilityCocoa class]]) | 2176 if (![parameter isKindOfClass:[BrowserAccessibilityCocoa class]]) |
2407 return nil; | 2177 return nil; |
2408 | 2178 |
2409 BrowserAccessibilityCocoa* childCocoaObj = | 2179 BrowserAccessibilityCocoa* childCocoaObj = |
2410 (BrowserAccessibilityCocoa*)parameter; | 2180 (BrowserAccessibilityCocoa*)parameter; |
2411 BrowserAccessibility* child = [childCocoaObj browserAccessibility]; | 2181 BrowserAccessibility* child = [childCocoaObj browserAccessibility]; |
2412 if (!child) | 2182 if (!child) |
2413 return nil; | 2183 return nil; |
2414 | 2184 |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2891 } | 2661 } |
2892 | 2662 |
2893 - (BOOL)accessibilityNotifiesWhenDestroyed { | 2663 - (BOOL)accessibilityNotifiesWhenDestroyed { |
2894 // Indicate that BrowserAccessibilityCocoa will post a notification when it's | 2664 // Indicate that BrowserAccessibilityCocoa will post a notification when it's |
2895 // destroyed (see -detach). This allows VoiceOver to do some internal things | 2665 // destroyed (see -detach). This allows VoiceOver to do some internal things |
2896 // more efficiently. | 2666 // more efficiently. |
2897 return YES; | 2667 return YES; |
2898 } | 2668 } |
2899 | 2669 |
2900 @end | 2670 @end |
2671 | |
2672 std::unique_ptr<ui::AXPositionBase> BrowserPositionFactory::GetRoot() const { | |
2673 const BrowserAccessibility* root = | |
2674 browser_accessibility_->manager()->GetRoot(); | |
2675 if (!root) | |
2676 return nullptr; | |
2677 | |
2678 return root->CreatePositionAt(0); | |
2679 } | |
2680 | |
2681 std::unique_ptr<ui::AXAbstractRange> BrowserPositionFactory::GetSelection() | |
2682 const { | |
2683 if (!IsActive()) | |
2684 return nullptr; | |
2685 | |
2686 BrowserAccessibilityManager* manager = browser_accessibility_->manager(); | |
2687 if (!manager) | |
2688 return nullptr; | |
2689 | |
2690 int32_t anchorId = manager->GetTreeData().sel_anchor_object_id; | |
tapted
2017/06/19 11:44:30
(self review: convert to hacker_case)
| |
2691 const BrowserAccessibility* anchorObject = manager->GetFromID(anchorId); | |
2692 if (!anchorObject) | |
2693 return nullptr; | |
2694 | |
2695 int32_t focusId = manager->GetTreeData().sel_focus_object_id; | |
2696 const BrowserAccessibility* focusObject = manager->GetFromID(focusId); | |
2697 if (!focusObject) | |
2698 return nullptr; | |
2699 | |
2700 int anchorOffset = manager->GetTreeData().sel_anchor_offset; | |
2701 int focusOffset = manager->GetTreeData().sel_focus_offset; | |
2702 if (anchorOffset < 0 || focusOffset < 0) | |
2703 return nullptr; | |
2704 | |
2705 ui::AXTextAffinity anchorAffinity = | |
2706 manager->GetTreeData().sel_anchor_affinity; | |
2707 ui::AXTextAffinity focusAffinity = manager->GetTreeData().sel_focus_affinity; | |
2708 | |
2709 return base::MakeUnique<ui::AXAbstractRange>( | |
2710 CreateTextRange(*anchorObject, anchorOffset, anchorAffinity, *focusObject, | |
2711 focusOffset, focusAffinity)); | |
2712 } | |
2713 | |
2714 std::unique_ptr<ui::AXPositionBase> BrowserPositionFactory::ExtractFromMarker( | |
2715 AXTextMarkerRef marker) const { | |
2716 return base::WrapUnique( | |
2717 CreateConcretePositionFromTextMarker(marker).release()); | |
2718 } | |
OLD | NEW |