22 {
23
24AXPlatformNodeTextProviderWin::AXPlatformNodeTextProviderWin() {}
25
26AXPlatformNodeTextProviderWin::~AXPlatformNodeTextProviderWin() {}
27
28
29AXPlatformNodeTextProviderWin* AXPlatformNodeTextProviderWin::Create(
30 AXPlatformNodeWin* owner) {
31 CComObject<AXPlatformNodeTextProviderWin>* text_provider = nullptr;
32 if (
SUCCEEDED(CComObject<AXPlatformNodeTextProviderWin>::CreateInstance(
33 &text_provider))) {
35 text_provider->owner_ = owner;
36 text_provider->AddRef();
37 return text_provider;
38 }
39
40 return nullptr;
41}
42
43
44void AXPlatformNodeTextProviderWin::CreateIUnknown(AXPlatformNodeWin* owner,
45 IUnknown** unknown) {
46 Microsoft::WRL::ComPtr<AXPlatformNodeTextProviderWin> text_provider(
48 if (text_provider)
49 *unknown = text_provider.Detach();
50}
51
52
53
54
55
56HRESULT AXPlatformNodeTextProviderWin::GetSelection(SAFEARRAY** selection) {
58
59 *selection = nullptr;
60
61 AXPlatformNodeDelegate* delegate = owner()->GetDelegate();
62 AXTree::Selection unignored_selection = delegate->GetUnignoredSelection();
63
64 AXPlatformNode* anchor_object =
65 delegate->GetFromNodeID(unignored_selection.anchor_object_id);
66 AXPlatformNode* focus_object =
67 delegate->GetFromNodeID(unignored_selection.focus_object_id);
68
69
70
71 auto start_offset = unignored_selection.anchor_offset;
72 auto end_offset = unignored_selection.focus_offset;
73
74
75 if (!anchor_object || !focus_object)
76 return S_OK;
77
78 AXNodePosition::AXPositionInstance
start =
79 anchor_object->GetDelegate()->CreateTextPositionAt(start_offset);
80 AXNodePosition::AXPositionInstance
end =
81 focus_object->GetDelegate()->CreateTextPositionAt(end_offset);
82
85
86
89
90 Microsoft::WRL::ComPtr<ITextRangeProvider> text_range_provider =
91 AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
93 if (&text_range_provider == nullptr)
94 return E_OUTOFMEMORY;
95
96
97
99 SafeArrayCreateVector(VT_UNKNOWN , 0 ,
100 1 ));
101
102 if (!selections_to_return.Get())
103 return E_OUTOFMEMORY;
104
106 HRESULT hr = SafeArrayPutElement(selections_to_return.Get(), &index,
107 text_range_provider.Get());
109
110
111
113 return E_FAIL;
114
115 *selection = selections_to_return.Release();
116
117 return S_OK;
118}
119
120HRESULT AXPlatformNodeTextProviderWin::GetVisibleRanges(
121 SAFEARRAY** visible_ranges) {
123
124 const AXPlatformNodeDelegate* delegate = owner()->GetDelegate();
125
126
127
128
129 const gfx::Rect frame_rect = delegate->GetBoundsRect(
130 AXCoordinateSystem::kFrame, AXClippingBehavior::kClipped);
131
132 const auto start = delegate->CreateTextPositionAt(0);
133 const auto end =
start->CreatePositionAtEndOfAnchor();
135
136
137
138 std::vector<Microsoft::WRL::ComPtr<ITextRangeProvider>> ranges;
139
140 auto current_line_start =
start->Clone();
141 while (!current_line_start->IsNullPosition() && *current_line_start < *
end) {
142 auto current_line_end = current_line_start->CreateNextLineEndPosition(
143 AXBoundaryBehavior::CrossBoundary);
144 if (current_line_end->IsNullPosition() || *current_line_end > *
end)
145 current_line_end =
end->Clone();
146
147 gfx::Rect current_rect = delegate->GetInnerTextRangeBoundsRect(
148 current_line_start->text_offset(), current_line_end->text_offset(),
149 AXCoordinateSystem::kFrame, AXClippingBehavior::kUnclipped);
150
151 if (frame_rect.
Contains(current_rect)) {
152 Microsoft::WRL::ComPtr<ITextRangeProvider> text_range_provider =
153 AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
154 current_line_start->Clone(), current_line_end->Clone());
155
156 ranges.emplace_back(text_range_provider);
157 }
158
159 current_line_start = current_line_start->CreateNextLineStartPosition(
160 AXBoundaryBehavior::CrossBoundary);
161 }
162
164 SafeArrayCreateVector(VT_UNKNOWN , 0 ,
165 ranges.size() ));
166
167 if (!scoped_visible_ranges.Get())
168 return E_OUTOFMEMORY;
169
171 for (Microsoft::WRL::ComPtr<ITextRangeProvider>& current_provider : ranges) {
172 HRESULT hr = SafeArrayPutElement(scoped_visible_ranges.Get(), &index,
173 current_provider.Get());
175
176
177
179 return E_FAIL;
180
181 ++index;
182 }
183
184 *visible_ranges = scoped_visible_ranges.Release();
185
186 return S_OK;
187}
188
189HRESULT AXPlatformNodeTextProviderWin::RangeFromChild(
190 IRawElementProviderSimple* child,
191 ITextRangeProvider** range) {
193
194 *range = nullptr;
195
196 Microsoft::WRL::ComPtr<ui::AXPlatformNodeWin> child_platform_node;
197 if (!
SUCCEEDED(child->QueryInterface(IID_PPV_ARGS(&child_platform_node))))
198 return UIA_E_INVALIDOPERATION;
199
200 if (!owner()->IsDescendant(child_platform_node.Get()))
201 return E_INVALIDARG;
202
203 *range = GetRangeFromChild(owner(), child_platform_node.Get());
204
205 return S_OK;
206}
207
208HRESULT AXPlatformNodeTextProviderWin::RangeFromPoint(
209 UiaPoint uia_point,
210 ITextRangeProvider** range) {
212 *range = nullptr;
213
215
216
217
218 AXPlatformNodeWin* nearest_node =
219 static_cast<AXPlatformNodeWin*>(owner()->NearestLeafToPoint(point));
222
223 AXNodePosition::AXPositionInstance
start,
end;
224 start = nearest_node->GetDelegate()->CreateTextPositionAt(
225 nearest_node->NearestTextIndexToPoint(point));
228
229 *range = AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
231 return S_OK;
232}
233
234HRESULT AXPlatformNodeTextProviderWin::get_DocumentRange(
235 ITextRangeProvider** range) {
237
238
239
240 *range = GetRangeFromChild(owner(), owner());
241
242 return S_OK;
243}
244
245HRESULT AXPlatformNodeTextProviderWin::get_SupportedTextSelection(
246 enum SupportedTextSelection* text_selection) {
248
249 *text_selection = SupportedTextSelection_Single;
250 return S_OK;
251}
252
253
254
255
256
257HRESULT AXPlatformNodeTextProviderWin::GetActiveComposition(
258 ITextRangeProvider** range) {
260
261 *range = nullptr;
262 return GetTextRangeProviderFromActiveComposition(range);
263}
264
265HRESULT AXPlatformNodeTextProviderWin::GetConversionTarget(
266 ITextRangeProvider** range) {
268
269 *range = nullptr;
270 return GetTextRangeProviderFromActiveComposition(range);
271}
272
273ITextRangeProvider* AXPlatformNodeTextProviderWin::GetRangeFromChild(
274 ui::AXPlatformNodeWin* ancestor,
275 ui::AXPlatformNodeWin* descendant) {
280
281
282
283
284 AXNodePosition::AXPositionInstance
start =
285 descendant->GetDelegate()->CreateTextPositionAt(0)->AsLeafTextPosition();
286
287 AXNodePosition::AXPositionInstance
end;
288 if (descendant->GetChildCount() == 0) {
289 end = descendant->GetDelegate()
290 ->CreateTextPositionAt(0)
291 ->CreatePositionAtEndOfAnchor()
292 ->AsLeafTextPosition();
293 } else {
294 AXPlatformNodeBase* deepest_last_child = descendant->GetLastChild();
295 while (deepest_last_child && deepest_last_child->GetChildCount() > 0)
296 deepest_last_child = deepest_last_child->GetLastChild();
297
298 end = deepest_last_child->GetDelegate()
299 ->CreateTextPositionAt(0)
300 ->CreatePositionAtEndOfAnchor()
301 ->AsLeafTextPosition();
302 }
303
304 return AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
306}
307
308ITextRangeProvider* AXPlatformNodeTextProviderWin::CreateDegenerateRangeAtStart(
309 ui::AXPlatformNodeWin* node) {
312
313
314 AXNodePosition::AXPositionInstance
start,
end;
315 start = node->GetDelegate()->CreateTextPositionAt(0)->AsLeafTextPosition();
317 return AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
319}
320
321ui::AXPlatformNodeWin* AXPlatformNodeTextProviderWin::owner() const {
322 return owner_.Get();
323}
324
325HRESULT
326AXPlatformNodeTextProviderWin::GetTextRangeProviderFromActiveComposition(
327 ITextRangeProvider** range) {
328 *range = nullptr;
329
330
331
332
333
334 if ((AXPlatformNode::FromNativeViewAccessible(
335 owner()->GetDelegate()->GetFocus()) ==
336 static_cast<AXPlatformNode*>(owner())) &&
337 owner()->HasActiveComposition()) {
339 owner()->GetActiveCompositionOffsets();
340 AXNodePosition::AXPositionInstance
start =
341 owner()->GetDelegate()->CreateTextPositionAt(
342 active_composition_offset.
start());
343 AXNodePosition::AXPositionInstance
end =
344 owner()->GetDelegate()->CreateTextPositionAt(
345 active_composition_offset.
end());
346
347 *range = AXPlatformNodeTextRangeProviderWin::CreateTextRangeProvider(
349 }
350
351 return S_OK;
352}
353
354}
static sk_sp< Effect > Create()
#define UIA_VALIDATE_TEXTPROVIDER_CALL()
#define UIA_VALIDATE_TEXTPROVIDER_CALL_1_ARG(arg)
constexpr uint32_t end() const
constexpr uint32_t start() const
bool Contains(int point_x, int point_y) const
#define BASE_DCHECK(condition)