Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: ui/accessibility/platform/text_marker_helper_mac.mm

Issue 2940923003: a11y: Move CreateTextMarker[Range] to TextMarkerHelperMac.
Patch Set: squish? Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/accessibility/platform/text_marker_helper_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "ui/accessibility/platform/text_marker_helper_mac.h"
6
7 #import <Cocoa/Cocoa.h>
8
9 #import "base/mac/foundation_util.h"
10 #include "base/mac/scoped_cftyperef.h"
11 #include "ui/accessibility/ax_position.h"
12 #include "ui/accessibility/ax_range.h"
13
14 using ui::AXPositionPointer;
15 using ui::AXRangePointer;
16 using ui::AXPositionData;
17
18 extern "C" {
19
20 // The following are private accessibility APIs required for cursor navigation
21 // and text selection. VoiceOver started relying on them in Mac OS X 10.11.
22 AXTextMarkerRef AXTextMarkerCreate(CFAllocatorRef allocator,
23 const UInt8* bytes,
24 CFIndex length);
25
26 AXTextMarkerRangeRef AXTextMarkerRangeCreate(CFAllocatorRef allocator,
27 AXTextMarkerRef start_marker,
28 AXTextMarkerRef end_marker);
29 const UInt8* AXTextMarkerGetBytePtr(AXTextMarkerRef text_marker);
30 size_t AXTextMarkerGetLength(AXTextMarkerRef text_marker);
31 AXTextMarkerRef AXTextMarkerRangeCopyStartMarker(
32 AXTextMarkerRangeRef text_marker_range);
33 AXTextMarkerRef AXTextMarkerRangeCopyEndMarker(
34 AXTextMarkerRangeRef text_marker_range);
35
36 } // extern "C"
37
38 namespace {
39
40 constexpr size_t kDataSize = sizeof(AXPositionData);
41
42 // AXTextMarkerCreate copies from data buffer given to it.
43 id CreateTextMarker(AXPositionPointer position) {
44 AXPositionData data;
45 position->ToData(&data);
46
47 AXTextMarkerRef text_marker = AXTextMarkerCreate(
48 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(&data), kDataSize);
49 return static_cast<id>(
50 base::mac::CFTypeRefToNSObjectAutorelease(text_marker));
51 }
52
53 // |range| is destructed at the end of this method. |anchor| and |focus| are
54 // copied into the individual text markers.
55 id CreateTextMarkerRange(AXRangePointer range) {
56 AXPositionData anchor, focus;
57 range.first->ToData(&anchor);
58 range.second->ToData(&focus);
59
60 base::ScopedCFTypeRef<AXTextMarkerRef> start_marker(AXTextMarkerCreate(
61 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(&anchor), kDataSize));
62 base::ScopedCFTypeRef<AXTextMarkerRef> end_marker(AXTextMarkerCreate(
63 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(&focus), kDataSize));
64 AXTextMarkerRangeRef marker_range =
65 AXTextMarkerRangeCreate(kCFAllocatorDefault, start_marker, end_marker);
66 return static_cast<id>(
67 base::mac::CFTypeRefToNSObjectAutorelease(marker_range));
68 }
69
70 bool ExtractData(AXTextMarkerRef text_marker, AXPositionData* data) {
71 DCHECK(text_marker);
72
73 if (AXTextMarkerGetLength(text_marker) != kDataSize)
74 return false;
75
76 const UInt8* source_buffer = AXTextMarkerGetBytePtr(text_marker);
77 if (!source_buffer)
78 return false;
79
80 *data = *reinterpret_cast<const AXPositionData*>(source_buffer);
81 return true;
82 }
83
84 // Of two positions, returns the one that comes first (destroys the other).
85 AXPositionPointer FirstOf(AXPositionPointer a, AXPositionPointer b) {
86 return b->Compare(a) ? std::move(b) : std::move(a);
87 }
88
89 } // namespace
90
91 @interface TextMarkerHelperMac ()
92 - (AXPositionPointer)extractFrom:(id)parameter;
93 @end
94
95 @implementation TextMarkerHelperMac {
96 std::unique_ptr<ui::PositionFactory> factory_;
97 }
98
99 - (instancetype)initWithFactory:(std::unique_ptr<ui::PositionFactory>)factory {
100 if ((self = [super init])) {
101 factory_ = std::move(factory);
102 }
103 return self;
104 }
105
106 - (id)startTextMarker {
107 AXPositionPointer root = factory_->GetRoot();
108 return root ? CreateTextMarker(root->PositionAtStartOfAnchor()) : nil;
109 }
110
111 - (id)endTextMarker {
112 AXPositionPointer root = factory_->GetRoot();
113 return root ? CreateTextMarker(root->PositionAtEndOfAnchor()) : nil;
114 }
115
116 - (id)selectedTextMarkerRange {
117 AXRangePointer selection = factory_->GetSelection();
118 if (!selection.first || !selection.second)
119 return nil;
120 return CreateTextMarkerRange(std::move(selection));
121 }
122
123 - (AXPositionPointer)extractFrom:(id)parameter {
124 AXPositionData data;
125 if (ExtractData(base::mac::CFCastStrict<AXTextMarkerRef>(parameter), &data))
126 return factory_->GetFromData(data);
127 return factory_->GetFromData(ui::AXAbstractPosition::kNullData);
128 }
129
130 - (id)AXTextMarkerRangeForUIElement:(id)parameter {
131 AXPositionPointer startPosition = factory_->GetRoot();
132 AXPositionPointer endPosition = startPosition->PositionAtEndOfAnchor();
133 AXRangePointer range =
134 AXRangePointer(std::move(startPosition), std::move(endPosition));
135 return CreateTextMarkerRange(std::move(range));
136 }
137
138 - (id)AXUIElementForTextMarker:(id)parameter {
139 AXPositionData data;
140 if (ExtractData(base::mac::CFCastStrict<AXTextMarkerRef>(parameter), &data))
141 return factory_->GetAccessibilityObject(data);
142 return nil;
143 }
144
145 - (id)AXNextTextMarkerForTextMarker:(id)parameter {
146 AXPositionPointer position = [self extractFrom:parameter];
147 if (position->IsNull())
148 return nil;
149 return CreateTextMarker(position->NextCharacterPosition());
150 }
151
152 - (id)AXPreviousTextMarkerForTextMarker:(id)parameter {
153 AXPositionPointer position = [self extractFrom:parameter];
154 if (position->IsNull())
155 return nil;
156 return CreateTextMarker(position->PreviousCharacterPosition());
157 }
158
159 - (id)AXLeftWordTextMarkerRangeForTextMarker:(id)parameter {
160 AXPositionPointer endPosition = [self extractFrom:parameter];
161 if (endPosition->IsNull())
162 return nil;
163
164 AXPositionPointer startPosition =
165 FirstOf(endPosition->PreviousWordStartPosition(),
166 endPosition->PreviousWordEndPosition());
167 AXRangePointer range(std::move(startPosition), std::move(endPosition));
168 return CreateTextMarkerRange(std::move(range));
169 }
170
171 - (id)AXRightWordTextMarkerRangeForTextMarker:(id)parameter {
172 AXPositionPointer startPosition = [self extractFrom:parameter];
173 if (startPosition->IsNull())
174 return nil;
175
176 AXPositionPointer endPosition =
177 FirstOf(startPosition->NextWordEndPosition(),
178 startPosition->NextWordStartPosition());
179 AXRangePointer range(std::move(startPosition), std::move(endPosition));
180 return CreateTextMarkerRange(std::move(range));
181 }
182
183 - (id)AXNextWordEndTextMarkerForTextMarker:(id)parameter {
184 AXPositionPointer position = [self extractFrom:parameter];
185 if (position->IsNull())
186 return nil;
187 return CreateTextMarker(position->NextWordEndPosition());
188 }
189
190 - (id)AXPreviousWordStartTextMarkerForTextMarker:(id)parameter {
191 AXPositionPointer position = [self extractFrom:parameter];
192 if (position->IsNull())
193 return nil;
194 return CreateTextMarker(position->PreviousWordStartPosition());
195 }
196
197 - (id)AXTextMarkerRangeForLine:(id)parameter {
198 AXPositionPointer position = [self extractFrom:parameter];
199 if (position->IsNull())
200 return nil;
201
202 AXPositionPointer startPosition = position->PreviousLineStartPosition();
203 AXPositionPointer endPosition = position->NextLineEndPosition();
204 AXRangePointer range(std::move(startPosition), std::move(endPosition));
205 return CreateTextMarkerRange(std::move(range));
206 }
207
208 - (id)AXLeftLineTextMarkerRangeForTextMarker:(id)parameter {
209 AXPositionPointer endPosition = [self extractFrom:parameter];
210 if (endPosition->IsNull())
211 return nil;
212
213 AXPositionPointer startPosition =
214 FirstOf(endPosition->PreviousLineStartPosition(),
215 endPosition->PreviousLineEndPosition());
216 AXRangePointer range(std::move(startPosition), std::move(endPosition));
217 return CreateTextMarkerRange(std::move(range));
218 }
219
220 - (id)AXRightLineTextMarkerRangeForTextMarker:(id)parameter {
221 AXPositionPointer startPosition = [self extractFrom:parameter];
222 if (startPosition->IsNull())
223 return nil;
224
225 AXPositionPointer endPosition =
226 FirstOf(startPosition->NextLineStartPosition(),
227 startPosition->NextLineEndPosition());
228 AXRangePointer range(std::move(startPosition), std::move(endPosition));
229 return CreateTextMarkerRange(std::move(range));
230 }
231
232 - (id)AXNextLineEndTextMarkerForTextMarker:(id)parameter {
233 AXPositionPointer position = [self extractFrom:parameter];
234 if (position->IsNull())
235 return nil;
236 return CreateTextMarker(position->NextLineEndPosition());
237 }
238
239 - (id)AXPreviousLineStartTextMarkerForTextMarker:(id)parameter {
240 AXPositionPointer position = [self extractFrom:parameter];
241 if (position->IsNull())
242 return nil;
243 return CreateTextMarker(position->PreviousLineStartPosition());
244 }
245
246 - (id)AXLineTextMarkerRangeForTextMarker:(id)parameter {
247 AXPositionPointer position = [self extractFrom:parameter];
248 if (position->IsNull())
249 return nil;
250
251 AXRangePointer range(position->PreviousLineStartPosition(),
252 position->NextLineEndPosition());
253 return CreateTextMarkerRange(std::move(range));
254 }
255
256 - (id)AXTextMarkerRangeForUnorderedTextMarkers:(id)parameter {
257 if (![parameter isKindOfClass:[NSArray class]])
258 return nil;
259
260 NSArray* textMarkerArray = parameter;
261 if ([textMarkerArray count] != 2)
262 return nil;
263
264 AXPositionPointer startPosition =
265 [self extractFrom:[textMarkerArray objectAtIndex:0]];
266 AXPositionPointer endPosition =
267 [self extractFrom:[textMarkerArray objectAtIndex:1]];
268 if (endPosition->Compare(startPosition)) {
269 return CreateTextMarkerRange(
270 AXRangePointer(std::move(endPosition), std::move(startPosition)));
271 }
272 return CreateTextMarkerRange(
273 AXRangePointer(std::move(startPosition), std::move(endPosition)));
274 }
275
276 + (BOOL)getRangeDataFromMarkerRange:(id)parameter
277 start:(ui::AXPositionData*)start
278 end:(ui::AXPositionData*)end {
279 AXTextMarkerRangeRef markerRange =
280 base::mac::CFCastStrict<AXTextMarkerRangeRef>(parameter);
281 DCHECK(markerRange);
282
283 base::ScopedCFTypeRef<AXTextMarkerRef> startMarker(
284 AXTextMarkerRangeCopyStartMarker(markerRange));
285 base::ScopedCFTypeRef<AXTextMarkerRef> endMarker(
286 AXTextMarkerRangeCopyEndMarker(markerRange));
287 if (!startMarker || !endMarker)
288 return NO;
289
290 return ExtractData(startMarker, start) && ExtractData(endMarker, end);
291 }
292
293 @end
OLDNEW
« no previous file with comments | « ui/accessibility/platform/text_marker_helper_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698