Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "ia2AccessibleText.h"
10 #include "Accessible2.h"
11 #include "AccessibleText_i.c"
13 #include "HyperTextAccessibleWrap.h"
14 #include "HyperTextAccessible-inl.h"
16 using namespace mozilla::a11y;
18 // IAccessibleText
20 STDMETHODIMP
21 ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset)
22 {
23 A11Y_TRYBLOCK_BEGIN
25 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
26 if (textAcc->IsDefunct())
27 return CO_E_OBJNOTCONNECTED;
29 return textAcc->AddToSelection(aStartOffset, aEndOffset) ?
30 S_OK : E_INVALIDARG;
32 A11Y_TRYBLOCK_END
33 }
35 STDMETHODIMP
36 ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset,
37 long *aEndOffset, BSTR *aTextAttributes)
38 {
39 A11Y_TRYBLOCK_BEGIN
41 if (!aStartOffset || !aEndOffset || !aTextAttributes)
42 return E_INVALIDARG;
44 *aStartOffset = 0;
45 *aEndOffset = 0;
46 *aTextAttributes = nullptr;
48 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
49 if (textAcc->IsDefunct())
50 return CO_E_OBJNOTCONNECTED;
52 int32_t startOffset = 0, endOffset = 0;
53 nsCOMPtr<nsIPersistentProperties> attributes =
54 textAcc->TextAttributes(true, aOffset, &startOffset, &endOffset);
56 HRESULT hr = AccessibleWrap::ConvertToIA2Attributes(attributes,
57 aTextAttributes);
58 if (FAILED(hr))
59 return hr;
61 *aStartOffset = startOffset;
62 *aEndOffset = endOffset;
64 return S_OK;
66 A11Y_TRYBLOCK_END
67 }
69 STDMETHODIMP
70 ia2AccessibleText::get_caretOffset(long *aOffset)
71 {
72 A11Y_TRYBLOCK_BEGIN
74 if (!aOffset)
75 return E_INVALIDARG;
77 *aOffset = -1;
79 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
80 if (textAcc->IsDefunct())
81 return CO_E_OBJNOTCONNECTED;
83 *aOffset = textAcc->CaretOffset();
84 return *aOffset != -1 ? S_OK : S_FALSE;
86 A11Y_TRYBLOCK_END
87 }
89 STDMETHODIMP
90 ia2AccessibleText::get_characterExtents(long aOffset,
91 enum IA2CoordinateType aCoordType,
92 long* aX, long* aY,
93 long* aWidth, long* aHeight)
94 {
95 A11Y_TRYBLOCK_BEGIN
97 if (!aX || !aY || !aWidth || !aHeight)
98 return E_INVALIDARG;
99 *aX = *aY = *aWidth = *aHeight = 0;
101 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
102 if (textAcc->IsDefunct())
103 return CO_E_OBJNOTCONNECTED;
105 uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
106 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
107 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
109 nsIntRect rect = textAcc->CharBounds(aOffset, geckoCoordType);
111 *aX = rect.x;
112 *aY = rect.y;
113 *aWidth = rect.width;
114 *aHeight = rect.height;
115 return S_OK;
117 A11Y_TRYBLOCK_END
118 }
120 STDMETHODIMP
121 ia2AccessibleText::get_nSelections(long* aNSelections)
122 {
123 A11Y_TRYBLOCK_BEGIN
125 if (!aNSelections)
126 return E_INVALIDARG;
127 *aNSelections = 0;
129 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
130 if (textAcc->IsDefunct())
131 return CO_E_OBJNOTCONNECTED;
133 *aNSelections = textAcc->SelectionCount();
134 return S_OK;
136 A11Y_TRYBLOCK_END
137 }
139 STDMETHODIMP
140 ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
141 enum IA2CoordinateType aCoordType,
142 long* aOffset)
143 {
144 A11Y_TRYBLOCK_BEGIN
146 if (!aOffset)
147 return E_INVALIDARG;
148 *aOffset = 0;
150 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
151 if (textAcc->IsDefunct())
152 return CO_E_OBJNOTCONNECTED;
154 uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
155 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
156 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
158 *aOffset = textAcc->OffsetAtPoint(aX, aY, geckoCoordType);
159 return *aOffset == -1 ? S_FALSE : S_OK;
161 A11Y_TRYBLOCK_END
162 }
164 STDMETHODIMP
165 ia2AccessibleText::get_selection(long aSelectionIndex, long* aStartOffset,
166 long* aEndOffset)
167 {
168 A11Y_TRYBLOCK_BEGIN
170 if (!aStartOffset || !aEndOffset)
171 return E_INVALIDARG;
172 *aStartOffset = *aEndOffset = 0;
174 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
175 if (textAcc->IsDefunct())
176 return CO_E_OBJNOTCONNECTED;
178 int32_t startOffset = 0, endOffset = 0;
179 if (!textAcc->SelectionBoundsAt(aSelectionIndex, &startOffset, &endOffset))
180 return E_INVALIDARG;
182 *aStartOffset = startOffset;
183 *aEndOffset = endOffset;
184 return S_OK;
186 A11Y_TRYBLOCK_END
187 }
189 STDMETHODIMP
190 ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR* aText)
191 {
192 A11Y_TRYBLOCK_BEGIN
194 if (!aText)
195 return E_INVALIDARG;
197 *aText = nullptr;
199 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
200 if (textAcc->IsDefunct())
201 return CO_E_OBJNOTCONNECTED;
203 if (!textAcc->IsValidRange(aStartOffset, aEndOffset))
204 return E_INVALIDARG;
206 nsAutoString text;
207 textAcc->TextSubstring(aStartOffset, aEndOffset, text);
208 if (text.IsEmpty())
209 return S_FALSE;
211 *aText = ::SysAllocStringLen(text.get(), text.Length());
212 return *aText ? S_OK : E_OUTOFMEMORY;
214 A11Y_TRYBLOCK_END
215 }
217 STDMETHODIMP
218 ia2AccessibleText::get_textBeforeOffset(long aOffset,
219 enum IA2TextBoundaryType aBoundaryType,
220 long* aStartOffset, long* aEndOffset,
221 BSTR* aText)
222 {
223 A11Y_TRYBLOCK_BEGIN
225 if (!aStartOffset || !aEndOffset || !aText)
226 return E_INVALIDARG;
228 *aStartOffset = *aEndOffset = 0;
229 *aText = nullptr;
231 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
232 if (textAcc->IsDefunct())
233 return CO_E_OBJNOTCONNECTED;
235 if (!textAcc->IsValidOffset(aOffset))
236 return E_INVALIDARG;
238 nsAutoString text;
239 int32_t startOffset = 0, endOffset = 0;
241 if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
242 startOffset = 0;
243 endOffset = textAcc->CharacterCount();
244 textAcc->TextSubstring(startOffset, endOffset, text);
245 } else {
246 AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
247 if (boundaryType == -1)
248 return S_FALSE;
250 textAcc->TextBeforeOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
251 }
253 *aStartOffset = startOffset;
254 *aEndOffset = endOffset;
256 if (text.IsEmpty())
257 return S_FALSE;
259 *aText = ::SysAllocStringLen(text.get(), text.Length());
260 return *aText ? S_OK : E_OUTOFMEMORY;
262 A11Y_TRYBLOCK_END
263 }
265 STDMETHODIMP
266 ia2AccessibleText::get_textAfterOffset(long aOffset,
267 enum IA2TextBoundaryType aBoundaryType,
268 long* aStartOffset, long* aEndOffset,
269 BSTR* aText)
270 {
271 A11Y_TRYBLOCK_BEGIN
273 if (!aStartOffset || !aEndOffset || !aText)
274 return E_INVALIDARG;
276 *aStartOffset = 0;
277 *aEndOffset = 0;
278 *aText = nullptr;
280 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
281 if (textAcc->IsDefunct())
282 return CO_E_OBJNOTCONNECTED;
284 if (!textAcc->IsValidOffset(aOffset))
285 return E_INVALIDARG;
287 nsAutoString text;
288 int32_t startOffset = 0, endOffset = 0;
290 if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
291 startOffset = 0;
292 endOffset = textAcc->CharacterCount();
293 textAcc->TextSubstring(startOffset, endOffset, text);
294 } else {
295 AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
296 if (boundaryType == -1)
297 return S_FALSE;
298 textAcc->TextAfterOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
299 }
301 *aStartOffset = startOffset;
302 *aEndOffset = endOffset;
304 if (text.IsEmpty())
305 return S_FALSE;
307 *aText = ::SysAllocStringLen(text.get(), text.Length());
308 return *aText ? S_OK : E_OUTOFMEMORY;
310 A11Y_TRYBLOCK_END
311 }
313 STDMETHODIMP
314 ia2AccessibleText::get_textAtOffset(long aOffset,
315 enum IA2TextBoundaryType aBoundaryType,
316 long* aStartOffset, long* aEndOffset,
317 BSTR* aText)
318 {
319 A11Y_TRYBLOCK_BEGIN
321 if (!aStartOffset || !aEndOffset || !aText)
322 return E_INVALIDARG;
324 *aStartOffset = *aEndOffset = 0;
325 *aText = nullptr;
327 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
328 if (textAcc->IsDefunct())
329 return CO_E_OBJNOTCONNECTED;
331 if (!textAcc->IsValidOffset(aOffset))
332 return E_INVALIDARG;
334 nsAutoString text;
335 int32_t startOffset = 0, endOffset = 0;
336 if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
337 startOffset = 0;
338 endOffset = textAcc->CharacterCount();
339 textAcc->TextSubstring(startOffset, endOffset, text);
340 } else {
341 AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
342 if (boundaryType == -1)
343 return S_FALSE;
344 textAcc->TextAtOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
345 }
347 *aStartOffset = startOffset;
348 *aEndOffset = endOffset;
350 if (text.IsEmpty())
351 return S_FALSE;
353 *aText = ::SysAllocStringLen(text.get(), text.Length());
354 return *aText ? S_OK : E_OUTOFMEMORY;
356 A11Y_TRYBLOCK_END
357 }
359 STDMETHODIMP
360 ia2AccessibleText::removeSelection(long aSelectionIndex)
361 {
362 A11Y_TRYBLOCK_BEGIN
364 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
365 if (textAcc->IsDefunct())
366 return CO_E_OBJNOTCONNECTED;
368 return textAcc->RemoveFromSelection(aSelectionIndex) ?
369 S_OK : E_INVALIDARG;
371 A11Y_TRYBLOCK_END
372 }
374 STDMETHODIMP
375 ia2AccessibleText::setCaretOffset(long aOffset)
376 {
377 A11Y_TRYBLOCK_BEGIN
379 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
380 if (textAcc->IsDefunct())
381 return CO_E_OBJNOTCONNECTED;
383 if (!textAcc->IsValidOffset(aOffset))
384 return E_INVALIDARG;
386 textAcc->SetCaretOffset(aOffset);
387 return S_OK;
389 A11Y_TRYBLOCK_END
390 }
392 STDMETHODIMP
393 ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
394 long aEndOffset)
395 {
396 A11Y_TRYBLOCK_BEGIN
398 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
399 if (textAcc->IsDefunct())
400 return CO_E_OBJNOTCONNECTED;
402 return textAcc->SetSelectionBoundsAt(aSelectionIndex, aStartOffset, aEndOffset) ?
403 S_OK : E_INVALIDARG;
405 A11Y_TRYBLOCK_END
406 }
408 STDMETHODIMP
409 ia2AccessibleText::get_nCharacters(long* aNCharacters)
410 {
411 A11Y_TRYBLOCK_BEGIN
413 if (!aNCharacters)
414 return E_INVALIDARG;
415 *aNCharacters = 0;
417 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
418 if (textAcc->IsDefunct())
419 return CO_E_OBJNOTCONNECTED;
421 *aNCharacters = textAcc->CharacterCount();
422 return S_OK;
424 A11Y_TRYBLOCK_END
425 }
427 STDMETHODIMP
428 ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
429 enum IA2ScrollType aScrollType)
430 {
431 A11Y_TRYBLOCK_BEGIN
433 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
434 if (textAcc->IsDefunct())
435 return CO_E_OBJNOTCONNECTED;
437 if (!textAcc->IsValidRange(aStartIndex, aEndIndex))
438 return E_INVALIDARG;
440 textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
441 return S_OK;
443 A11Y_TRYBLOCK_END
444 }
446 STDMETHODIMP
447 ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
448 enum IA2CoordinateType aCoordType,
449 long aX, long aY)
450 {
451 A11Y_TRYBLOCK_BEGIN
453 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
454 if (textAcc->IsDefunct())
455 return CO_E_OBJNOTCONNECTED;
457 if (!textAcc->IsValidRange(aStartIndex, aEndIndex))
458 return E_INVALIDARG;
460 uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
461 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
462 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
464 textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex,
465 geckoCoordType, aX, aY);
466 return S_OK;
468 A11Y_TRYBLOCK_END
469 }
471 STDMETHODIMP
472 ia2AccessibleText::get_newText(IA2TextSegment *aNewText)
473 {
474 A11Y_TRYBLOCK_BEGIN
476 return GetModifiedText(true, aNewText);
478 A11Y_TRYBLOCK_END
479 }
481 STDMETHODIMP
482 ia2AccessibleText::get_oldText(IA2TextSegment *aOldText)
483 {
484 A11Y_TRYBLOCK_BEGIN
486 return GetModifiedText(false, aOldText);
488 A11Y_TRYBLOCK_END
489 }
491 // ia2AccessibleText
493 HRESULT
494 ia2AccessibleText::GetModifiedText(bool aGetInsertedText,
495 IA2TextSegment *aText)
496 {
497 if (!aText)
498 return E_INVALIDARG;
500 uint32_t startOffset = 0, endOffset = 0;
501 nsAutoString text;
503 nsresult rv = GetModifiedText(aGetInsertedText, text,
504 &startOffset, &endOffset);
505 if (NS_FAILED(rv))
506 return GetHRESULT(rv);
508 aText->start = startOffset;
509 aText->end = endOffset;
511 if (text.IsEmpty())
512 return S_FALSE;
514 aText->text = ::SysAllocStringLen(text.get(), text.Length());
515 return aText->text ? S_OK : E_OUTOFMEMORY;
516 }
518 AccessibleTextBoundary
519 ia2AccessibleText::GetGeckoTextBoundary(enum IA2TextBoundaryType aBoundaryType)
520 {
521 switch (aBoundaryType) {
522 case IA2_TEXT_BOUNDARY_CHAR:
523 return nsIAccessibleText::BOUNDARY_CHAR;
524 case IA2_TEXT_BOUNDARY_WORD:
525 return nsIAccessibleText::BOUNDARY_WORD_START;
526 case IA2_TEXT_BOUNDARY_LINE:
527 return nsIAccessibleText::BOUNDARY_LINE_START;
528 //case IA2_TEXT_BOUNDARY_SENTENCE:
529 //case IA2_TEXT_BOUNDARY_PARAGRAPH:
530 // XXX: not implemented
531 default:
532 return -1;
533 }
534 }