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

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

Issue 2940923003: a11y: Move CreateTextMarker[Range] to TextMarkerHelperMac.
Patch Set: self review Created 3 years, 6 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
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 extern "C" {
15
16 // The following are private accessibility APIs required for cursor navigation
17 // and text selection. VoiceOver started relying on them in Mac OS X 10.11.
18 AXTextMarkerRef AXTextMarkerCreate(CFAllocatorRef allocator,
19 const UInt8* bytes,
20 CFIndex length);
21
22 AXTextMarkerRangeRef AXTextMarkerRangeCreate(CFAllocatorRef allocator,
23 AXTextMarkerRef start_marker,
24 AXTextMarkerRef end_marker);
25
26 } // extern "C"
27
28 namespace {
29
30 // to call |release| on it to transfer ownership of the position to the text
31 // marker object.
32 id CreateTextMarker(std::unique_ptr<ui::AXPositionBase> position) {
33 AXTextMarkerRef text_marker = AXTextMarkerCreate(
34 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(position.release()),
35 sizeof(ui::AXPositionBase));
36 return static_cast<id>(
37 base::mac::CFTypeRefToNSObjectAutorelease(text_marker));
38 }
39
40 // |range| is destructed at the end of this method and ownership of its |anchor|
41 // and |focus| are transfered to the marker range object.
42 id CreateTextMarkerRange(const ui::AXAbstractRange range) {
43 AXTextMarkerRef start_marker = AXTextMarkerCreate(
44 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(range.anchor()),
45 sizeof(ui::AXPositionBase));
46 AXTextMarkerRef end_marker = AXTextMarkerCreate(
47 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(range.focus()),
48 sizeof(ui::AXPositionBase));
49 AXTextMarkerRangeRef marker_range =
50 AXTextMarkerRangeCreate(kCFAllocatorDefault, start_marker, end_marker);
51 return static_cast<id>(
52 base::mac::CFTypeRefToNSObjectAutorelease(marker_range));
53 }
54
55 } // namespace
56
57 @interface TextMarkerHelperMac ()
58 - (std::unique_ptr<ui::AXPositionBase>)extractFrom:(id)parameter;
59 @end
60
61 @implementation TextMarkerHelperMac {
62 std::unique_ptr<ui::PositionFactory> factory_;
63 }
64
65 - (instancetype)initWithFactory:(std::unique_ptr<ui::PositionFactory>)factory {
66 if ((self = [super init])) {
67 factory_ = std::move(factory);
68 }
69 return self;
70 }
71
72 - (id)startTextMarker {
73 std::unique_ptr<ui::AXPositionBase> root = factory_->GetRoot();
74 return root ? CreateTextMarker(root->CreatePositionAtStartOfAnchor()) : nil;
75 }
76
77 - (id)endTextMarker {
78 std::unique_ptr<ui::AXPositionBase> root = factory_->GetRoot();
79 return root ? CreateTextMarker(root->CreatePositionAtEndOfAnchor()) : nil;
80 }
81
82 - (id)selectedTextMarkerRange {
83 std::unique_ptr<ui::AXAbstractRange> selection = factory_->GetSelection();
84 return selection ? CreateTextMarkerRange(std::move(*selection)) : nil;
85 }
86
87 - (std::unique_ptr<ui::AXPositionBase>)extractFrom:(id)parameter {
88 AXTextMarkerRef marker = base::mac::CFCastStrict<AXTextMarkerRef>(parameter);
89 return factory_->ExtractFromMarker(marker);
90 }
91
92 - (id)AXTextMarkerRangeForUIElement:(id)parameter {
93 std::unique_ptr<ui::AXPositionBase> startPosition = factory_->GetRoot();
94 std::unique_ptr<ui::AXPositionBase> endPosition =
95 startPosition->CreatePositionAtEndOfAnchor();
96 ui::AXAbstractRange range =
97 ui::AXAbstractRange(std::move(startPosition), std::move(endPosition));
98 return CreateTextMarkerRange(std::move(range));
99 }
100
101 - (id)AXNextTextMarkerForTextMarker:(id)parameter {
102 std::unique_ptr<ui::AXPositionBase> position = [self extractFrom:parameter];
103 if (position->IsNullPosition())
104 return nil;
105 return CreateTextMarker(position->CreateNextCharacterPosition());
106 }
107
108 - (id)AXPreviousTextMarkerForTextMarker:(id)parameter {
109 std::unique_ptr<ui::AXPositionBase> position = [self extractFrom:parameter];
110 if (position->IsNullPosition())
111 return nil;
112 return CreateTextMarker(position->CreatePreviousCharacterPosition());
113 }
114
115 - (id)AXLeftWordTextMarkerRangeForTextMarker:(id)parameter {
116 std::unique_ptr<ui::AXPositionBase> endPosition =
117 [self extractFrom:parameter];
118 if (endPosition->IsNullPosition())
119 return nil;
120
121 std::unique_ptr<ui::AXPositionBase> startWordPosition =
122 endPosition->CreatePreviousWordStartPosition();
123 std::unique_ptr<ui::AXPositionBase> endWordPosition =
124 endPosition->CreatePreviousWordEndPosition();
125 std::unique_ptr<ui::AXPositionBase> startPosition =
126 *startWordPosition <= *endWordPosition ? std::move(endWordPosition)
127 : std::move(startWordPosition);
128 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition));
129 return CreateTextMarkerRange(std::move(range));
130 }
131
132 - (id)AXRightWordTextMarkerRangeForTextMarker:(id)parameter {
133 std::unique_ptr<ui::AXPositionBase> startPosition =
134 [self extractFrom:parameter];
135 if (startPosition->IsNullPosition())
136 return nil;
137
138 std::unique_ptr<ui::AXPositionBase> endWordPosition =
139 startPosition->CreateNextWordEndPosition();
140 std::unique_ptr<ui::AXPositionBase> startWordPosition =
141 startPosition->CreateNextWordStartPosition();
142 std::unique_ptr<ui::AXPositionBase> endPosition =
143 *startWordPosition <= *endWordPosition ? std::move(startWordPosition)
144 : std::move(endWordPosition);
145 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition));
146 return CreateTextMarkerRange(std::move(range));
147 }
148
149 - (id)AXNextWordEndTextMarkerForTextMarker:(id)parameter {
150 std::unique_ptr<ui::AXPositionBase> position = [self extractFrom:parameter];
151 if (position->IsNullPosition())
152 return nil;
153 return CreateTextMarker(position->CreateNextWordEndPosition());
154 }
155
156 - (id)AXPreviousWordStartTextMarkerForTextMarker:(id)parameter {
157 std::unique_ptr<ui::AXPositionBase> position = [self extractFrom:parameter];
158 if (position->IsNullPosition())
159 return nil;
160 return CreateTextMarker(position->CreatePreviousWordStartPosition());
161 }
162
163 - (id)AXTextMarkerRangeForLine:(id)parameter {
164 std::unique_ptr<ui::AXPositionBase> position = [self extractFrom:parameter];
165 if (position->IsNullPosition())
166 return nil;
167
168 std::unique_ptr<ui::AXPositionBase> startPosition =
169 position->CreatePreviousLineStartPosition();
170 std::unique_ptr<ui::AXPositionBase> endPosition =
171 position->CreateNextLineEndPosition();
172 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition));
173 return CreateTextMarkerRange(std::move(range));
174 }
175
176 - (id)AXLeftLineTextMarkerRangeForTextMarker:(id)parameter {
177 std::unique_ptr<ui::AXPositionBase> endPosition =
178 [self extractFrom:parameter];
179 if (endPosition->IsNullPosition())
180 return nil;
181
182 std::unique_ptr<ui::AXPositionBase> startLinePosition =
183 endPosition->CreatePreviousLineStartPosition();
184 std::unique_ptr<ui::AXPositionBase> endLinePosition =
185 endPosition->CreatePreviousLineEndPosition();
186 std::unique_ptr<ui::AXPositionBase> startPosition =
187 *startLinePosition <= *endLinePosition ? std::move(endLinePosition)
188 : std::move(startLinePosition);
189 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition));
190 return CreateTextMarkerRange(std::move(range));
191 }
192
193 - (id)AXRightLineTextMarkerRangeForTextMarker:(id)parameter {
194 std::unique_ptr<ui::AXPositionBase> startPosition =
195 [self extractFrom:parameter];
196 if (startPosition->IsNullPosition())
197 return nil;
198
199 std::unique_ptr<ui::AXPositionBase> startLinePosition =
200 startPosition->CreateNextLineStartPosition();
201 std::unique_ptr<ui::AXPositionBase> endLinePosition =
202 startPosition->CreateNextLineEndPosition();
203 std::unique_ptr<ui::AXPositionBase> endPosition =
204 *startLinePosition <= *endLinePosition ? std::move(startLinePosition)
205 : std::move(endLinePosition);
206 ui::AXAbstractRange range(std::move(startPosition), std::move(endPosition));
207 return CreateTextMarkerRange(std::move(range));
208 }
209
210 - (id)AXNextLineEndTextMarkerForTextMarker:(id)parameter {
211 std::unique_ptr<ui::AXPositionBase> position = [self extractFrom:parameter];
212 if (position->IsNullPosition())
213 return nil;
214 return CreateTextMarker(position->CreateNextLineEndPosition());
215 }
216
217 - (id)AXPreviousLineStartTextMarkerForTextMarker:(id)parameter {
218 std::unique_ptr<ui::AXPositionBase> position = [self extractFrom:parameter];
219 if (position->IsNullPosition())
220 return nil;
221 return CreateTextMarker(position->CreatePreviousLineStartPosition());
222 }
223
224 - (id)AXLineTextMarkerRangeForTextMarker:(id)parameter {
225 std::unique_ptr<ui::AXPositionBase> position = [self extractFrom:parameter];
226 if (position->IsNullPosition())
227 return nil;
228
229 ui::AXAbstractRange range(position->CreatePreviousLineStartPosition(),
230 position->CreateNextLineEndPosition());
231 return CreateTextMarkerRange(std::move(range));
232 }
233
234 - (id)AXTextMarkerRangeForUnorderedTextMarkers:(id)parameter {
235 if (![parameter isKindOfClass:[NSArray class]])
236 return nil;
237
238 NSArray* text_marker_array = parameter;
239 if ([text_marker_array count] != 2)
240 return nil;
241
242 std::unique_ptr<ui::AXPositionBase> startPosition =
243 [self extractFrom:[text_marker_array objectAtIndex:0]];
244 std::unique_ptr<ui::AXPositionBase> endPosition =
245 [self extractFrom:[text_marker_array objectAtIndex:1]];
246 if (*startPosition <= *endPosition) {
247 return CreateTextMarkerRange(
248 ui::AXAbstractRange(std::move(startPosition), std::move(endPosition)));
249 } else {
250 return CreateTextMarkerRange(
251 ui::AXAbstractRange(std::move(endPosition), std::move(startPosition)));
252 }
253 }
254
255 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698