Bug 1700051: part 36) Reduce accessibility of `SoftText::mBegin` to `private`. r...
[gecko.git] / accessible / atk / nsMaiInterfaceText.cpp
blob09e378a59d3476f82ba9c11ecb165e72ce8f9bba
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "InterfaceInitFuncs.h"
8 #include "mozilla/a11y/PDocAccessible.h"
9 #include "LocalAccessible-inl.h"
10 #include "HyperTextAccessible-inl.h"
11 #include "nsMai.h"
12 #include "RemoteAccessible.h"
14 #include "nsIAccessibleTypes.h"
15 #include "nsIPersistentProperties2.h"
16 #include "nsISimpleEnumerator.h"
17 #include "nsUTF8Utils.h"
19 #include "mozilla/Likely.h"
21 #include "DOMtoATK.h"
23 using namespace mozilla;
24 using namespace mozilla::a11y;
26 static const char* sAtkTextAttrNames[ATK_TEXT_ATTR_LAST_DEFINED];
28 void ConvertTextAttributeToAtkAttribute(const nsACString& aName,
29 const nsAString& aValue,
30 AtkAttributeSet** aAttributeSet) {
31 // Handle attributes where atk has its own name.
32 const char* atkName = nullptr;
33 nsAutoString atkValue;
34 if (aName.EqualsLiteral("color")) {
35 // The format of the atk attribute is r,g,b and the gecko one is
36 // rgb(r, g, b).
37 atkValue = Substring(aValue, 4, aValue.Length() - 5);
38 atkValue.StripWhitespace();
39 atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR];
40 } else if (aName.EqualsLiteral("background-color")) {
41 // The format of the atk attribute is r,g,b and the gecko one is
42 // rgb(r, g, b).
43 atkValue = Substring(aValue, 4, aValue.Length() - 5);
44 atkValue.StripWhitespace();
45 atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR];
46 } else if (aName.EqualsLiteral("font-family")) {
47 atkValue = aValue;
48 atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME];
49 } else if (aName.EqualsLiteral("font-size")) {
50 // ATK wants the number of pixels without px at the end.
51 atkValue = StringHead(aValue, aValue.Length() - 2);
52 atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE];
53 } else if (aName.EqualsLiteral("font-weight")) {
54 atkValue = aValue;
55 atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT];
56 } else if (aName.EqualsLiteral("invalid")) {
57 atkValue = aValue;
58 atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID];
61 if (atkName) {
62 AtkAttribute* objAttr =
63 static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
64 objAttr->name = g_strdup(atkName);
65 objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get());
66 *aAttributeSet = g_slist_prepend(*aAttributeSet, objAttr);
70 static AtkAttributeSet* ConvertToAtkTextAttributeSet(
71 nsTArray<Attribute>& aAttributes) {
72 AtkAttributeSet* objAttributeSet = nullptr;
73 for (size_t i = 0; i < aAttributes.Length(); ++i) {
74 AtkAttribute* objAttr = (AtkAttribute*)g_malloc(sizeof(AtkAttribute));
75 objAttr->name = g_strdup(aAttributes[i].Name().get());
76 objAttr->value =
77 g_strdup(NS_ConvertUTF16toUTF8(aAttributes[i].Value()).get());
78 objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
79 ConvertTextAttributeToAtkAttribute(
80 aAttributes[i].Name(), aAttributes[i].Value(), &objAttributeSet);
82 return objAttributeSet;
85 static AtkAttributeSet* ConvertToAtkTextAttributeSet(
86 nsIPersistentProperties* aAttributes) {
87 if (!aAttributes) return nullptr;
89 AtkAttributeSet* objAttributeSet = nullptr;
90 nsCOMPtr<nsISimpleEnumerator> propEnum;
91 nsresult rv = aAttributes->Enumerate(getter_AddRefs(propEnum));
92 NS_ENSURE_SUCCESS(rv, nullptr);
94 bool hasMore = false;
95 while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
96 nsCOMPtr<nsISupports> sup;
97 rv = propEnum->GetNext(getter_AddRefs(sup));
98 NS_ENSURE_SUCCESS(rv, objAttributeSet);
100 nsCOMPtr<nsIPropertyElement> propElem(do_QueryInterface(sup));
101 NS_ENSURE_TRUE(propElem, objAttributeSet);
103 nsAutoCString name;
104 rv = propElem->GetKey(name);
105 NS_ENSURE_SUCCESS(rv, objAttributeSet);
107 nsAutoString value;
108 rv = propElem->GetValue(value);
109 NS_ENSURE_SUCCESS(rv, objAttributeSet);
111 AtkAttribute* objAttr = (AtkAttribute*)g_malloc(sizeof(AtkAttribute));
112 objAttr->name = g_strdup(name.get());
113 objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(value).get());
114 objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
116 ConvertTextAttributeToAtkAttribute(name, value, &objAttributeSet);
119 // libatk-adaptor will free it
120 return objAttributeSet;
123 static void ConvertTexttoAsterisks(AccessibleWrap* accWrap,
124 nsAString& aString) {
125 // convert each char to "*" when it's "password text"
126 if (accWrap->IsPassword()) {
127 DOMtoATK::ConvertTexttoAsterisks(aString);
131 extern "C" {
133 static gchar* getTextCB(AtkText* aText, gint aStartOffset, gint aEndOffset) {
134 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
135 nsAutoString autoStr;
136 if (accWrap) {
137 HyperTextAccessible* text = accWrap->AsHyperText();
138 if (!text || !text->IsTextRole() || text->IsDefunct()) return nullptr;
140 return DOMtoATK::NewATKString(
141 text, aStartOffset, aEndOffset,
142 accWrap->IsPassword()
143 ? DOMtoATK::AtkStringConvertFlags::ConvertTextToAsterisks
144 : DOMtoATK::AtkStringConvertFlags::None);
146 } else if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
147 return DOMtoATK::NewATKString(proxy, aStartOffset, aEndOffset,
148 DOMtoATK::AtkStringConvertFlags::None);
151 return nullptr;
154 static gint getCharacterCountCB(AtkText* aText);
156 // Note: this does not support magic offsets, which is fine for its callers
157 // which do not implement any.
158 static gchar* getCharTextAtOffset(AtkText* aText, gint aOffset,
159 gint* aStartOffset, gint* aEndOffset) {
160 gint end = aOffset + 1;
161 gint count = getCharacterCountCB(aText);
163 if (aOffset > count) {
164 aOffset = count;
166 if (end > count) {
167 end = count;
169 if (aOffset < 0) {
170 aOffset = 0;
172 if (end < 0) {
173 end = 0;
175 *aStartOffset = aOffset;
176 *aEndOffset = end;
178 return getTextCB(aText, aOffset, end);
181 static gchar* getTextAfterOffsetCB(AtkText* aText, gint aOffset,
182 AtkTextBoundary aBoundaryType,
183 gint* aStartOffset, gint* aEndOffset) {
184 if (aBoundaryType == ATK_TEXT_BOUNDARY_CHAR) {
185 return getCharTextAtOffset(aText, aOffset + 1, aStartOffset, aEndOffset);
188 nsAutoString autoStr;
189 int32_t startOffset = 0, endOffset = 0;
190 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
191 if (accWrap) {
192 HyperTextAccessible* text = accWrap->AsHyperText();
193 if (!text || !text->IsTextRole()) return nullptr;
195 text->TextAfterOffset(aOffset, aBoundaryType, &startOffset, &endOffset,
196 autoStr);
197 ConvertTexttoAsterisks(accWrap, autoStr);
198 } else if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
199 proxy->GetTextAfterOffset(aOffset, aBoundaryType, autoStr, &startOffset,
200 &endOffset);
203 *aStartOffset = startOffset;
204 *aEndOffset = endOffset;
206 // libspi will free it.
207 return DOMtoATK::Convert(autoStr);
210 static gchar* getTextAtOffsetCB(AtkText* aText, gint aOffset,
211 AtkTextBoundary aBoundaryType,
212 gint* aStartOffset, gint* aEndOffset) {
213 if (aBoundaryType == ATK_TEXT_BOUNDARY_CHAR) {
214 return getCharTextAtOffset(aText, aOffset, aStartOffset, aEndOffset);
217 nsAutoString autoStr;
218 int32_t startOffset = 0, endOffset = 0;
219 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
220 if (accWrap) {
221 HyperTextAccessible* text = accWrap->AsHyperText();
222 if (!text || !text->IsTextRole()) return nullptr;
224 text->TextAtOffset(aOffset, aBoundaryType, &startOffset, &endOffset,
225 autoStr);
226 ConvertTexttoAsterisks(accWrap, autoStr);
227 } else if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
228 proxy->GetTextAtOffset(aOffset, aBoundaryType, autoStr, &startOffset,
229 &endOffset);
232 *aStartOffset = startOffset;
233 *aEndOffset = endOffset;
235 // libspi will free it.
236 return DOMtoATK::Convert(autoStr);
239 static gunichar getCharacterAtOffsetCB(AtkText* aText, gint aOffset) {
240 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
241 if (accWrap) {
242 HyperTextAccessible* text = accWrap->AsHyperText();
243 if (!text || !text->IsTextRole()) {
244 return 0;
246 return DOMtoATK::ATKCharacter(text, aOffset);
249 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
250 return DOMtoATK::ATKCharacter(proxy, aOffset);
253 return 0;
256 static gchar* getTextBeforeOffsetCB(AtkText* aText, gint aOffset,
257 AtkTextBoundary aBoundaryType,
258 gint* aStartOffset, gint* aEndOffset) {
259 if (aBoundaryType == ATK_TEXT_BOUNDARY_CHAR) {
260 return getCharTextAtOffset(aText, aOffset - 1, aStartOffset, aEndOffset);
263 nsAutoString autoStr;
264 int32_t startOffset = 0, endOffset = 0;
265 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
266 if (accWrap) {
267 HyperTextAccessible* text = accWrap->AsHyperText();
268 if (!text || !text->IsTextRole()) return nullptr;
270 text->TextBeforeOffset(aOffset, aBoundaryType, &startOffset, &endOffset,
271 autoStr);
272 ConvertTexttoAsterisks(accWrap, autoStr);
273 } else if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
274 proxy->GetTextBeforeOffset(aOffset, aBoundaryType, autoStr, &startOffset,
275 &endOffset);
278 *aStartOffset = startOffset;
279 *aEndOffset = endOffset;
281 // libspi will free it.
282 return DOMtoATK::Convert(autoStr);
285 static gint getCaretOffsetCB(AtkText* aText) {
286 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
287 if (accWrap) {
288 HyperTextAccessible* text = accWrap->AsHyperText();
289 if (!text || !text->IsTextRole()) {
290 return -1;
293 return static_cast<gint>(text->CaretOffset());
296 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
297 return static_cast<gint>(proxy->CaretOffset());
300 return -1;
303 static AtkAttributeSet* getRunAttributesCB(AtkText* aText, gint aOffset,
304 gint* aStartOffset,
305 gint* aEndOffset) {
306 *aStartOffset = -1;
307 *aEndOffset = -1;
308 int32_t startOffset = 0, endOffset = 0;
310 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
311 if (accWrap) {
312 HyperTextAccessible* text = accWrap->AsHyperText();
313 if (!text || !text->IsTextRole()) {
314 return nullptr;
317 nsCOMPtr<nsIPersistentProperties> attributes =
318 text->TextAttributes(false, aOffset, &startOffset, &endOffset);
320 *aStartOffset = startOffset;
321 *aEndOffset = endOffset;
323 return ConvertToAtkTextAttributeSet(attributes);
326 RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText));
327 if (!proxy) {
328 return nullptr;
331 AutoTArray<Attribute, 10> attrs;
332 proxy->TextAttributes(false, aOffset, &attrs, &startOffset, &endOffset);
333 *aStartOffset = startOffset;
334 *aEndOffset = endOffset;
335 return ConvertToAtkTextAttributeSet(attrs);
338 static AtkAttributeSet* getDefaultAttributesCB(AtkText* aText) {
339 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
340 if (accWrap) {
341 HyperTextAccessible* text = accWrap->AsHyperText();
342 if (!text || !text->IsTextRole()) {
343 return nullptr;
346 nsCOMPtr<nsIPersistentProperties> attributes =
347 text->DefaultTextAttributes();
348 return ConvertToAtkTextAttributeSet(attributes);
351 RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText));
352 if (!proxy) {
353 return nullptr;
356 AutoTArray<Attribute, 10> attrs;
357 proxy->DefaultTextAttributes(&attrs);
358 return ConvertToAtkTextAttributeSet(attrs);
361 static void getCharacterExtentsCB(AtkText* aText, gint aOffset, gint* aX,
362 gint* aY, gint* aWidth, gint* aHeight,
363 AtkCoordType aCoords) {
364 if (!aX || !aY || !aWidth || !aHeight) {
365 return;
367 *aX = *aY = *aWidth = *aHeight = -1;
369 nsIntRect rect;
370 uint32_t geckoCoordType;
371 if (aCoords == ATK_XY_SCREEN) {
372 geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
373 } else {
374 geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
377 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
378 if (accWrap) {
379 HyperTextAccessible* text = accWrap->AsHyperText();
380 if (!text || !text->IsTextRole()) {
381 return;
384 rect = text->CharBounds(aOffset, geckoCoordType);
385 } else if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
386 rect = proxy->CharBounds(aOffset, geckoCoordType);
387 } else {
388 return;
391 *aX = rect.x;
392 *aY = rect.y;
393 *aWidth = rect.width;
394 *aHeight = rect.height;
397 static void getRangeExtentsCB(AtkText* aText, gint aStartOffset,
398 gint aEndOffset, AtkCoordType aCoords,
399 AtkTextRectangle* aRect) {
400 if (!aRect) {
401 return;
403 aRect->x = aRect->y = aRect->width = aRect->height = -1;
405 nsIntRect rect;
406 uint32_t geckoCoordType;
407 if (aCoords == ATK_XY_SCREEN) {
408 geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
409 } else {
410 geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
413 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
414 if (accWrap) {
415 HyperTextAccessible* text = accWrap->AsHyperText();
416 if (!text || !text->IsTextRole()) {
417 return;
420 rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType);
421 } else if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
422 rect = proxy->TextBounds(aStartOffset, aEndOffset, geckoCoordType);
423 } else {
424 return;
427 aRect->x = rect.x;
428 aRect->y = rect.y;
429 aRect->width = rect.width;
430 aRect->height = rect.height;
433 static gint getCharacterCountCB(AtkText* aText) {
434 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
435 if (accWrap) {
436 HyperTextAccessible* textAcc = accWrap->AsHyperText();
437 return !textAcc || textAcc->IsDefunct()
439 : static_cast<gint>(textAcc->CharacterCount());
442 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
443 return proxy->CharacterCount();
446 return 0;
449 static gint getOffsetAtPointCB(AtkText* aText, gint aX, gint aY,
450 AtkCoordType aCoords) {
451 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
452 if (accWrap) {
453 HyperTextAccessible* text = accWrap->AsHyperText();
454 if (!text || !text->IsTextRole()) {
455 return -1;
458 return static_cast<gint>(text->OffsetAtPoint(
459 aX, aY,
460 (aCoords == ATK_XY_SCREEN
461 ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE
462 : nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE)));
465 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
466 return static_cast<gint>(proxy->OffsetAtPoint(
467 aX, aY,
468 (aCoords == ATK_XY_SCREEN
469 ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE
470 : nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE)));
473 return -1;
476 static gint getTextSelectionCountCB(AtkText* aText) {
477 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
478 if (accWrap) {
479 HyperTextAccessible* text = accWrap->AsHyperText();
480 if (!text || !text->IsTextRole()) {
481 return 0;
484 return text->SelectionCount();
487 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
488 return proxy->SelectionCount();
491 return 0;
494 static gchar* getTextSelectionCB(AtkText* aText, gint aSelectionNum,
495 gint* aStartOffset, gint* aEndOffset) {
496 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
497 int32_t startOffset = 0, endOffset = 0;
498 if (accWrap) {
499 HyperTextAccessible* text = accWrap->AsHyperText();
500 if (!text || !text->IsTextRole()) {
501 return nullptr;
504 text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset);
505 *aStartOffset = startOffset;
506 *aEndOffset = endOffset;
508 return getTextCB(aText, *aStartOffset, *aEndOffset);
510 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
511 nsString data;
512 proxy->SelectionBoundsAt(aSelectionNum, data, &startOffset, &endOffset);
513 *aStartOffset = startOffset;
514 *aEndOffset = endOffset;
516 NS_ConvertUTF16toUTF8 dataAsUTF8(data);
517 return (dataAsUTF8.get()) ? g_strdup(dataAsUTF8.get()) : nullptr;
519 return nullptr;
522 // set methods
523 static gboolean addTextSelectionCB(AtkText* aText, gint aStartOffset,
524 gint aEndOffset) {
525 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
526 if (accWrap) {
527 HyperTextAccessible* text = accWrap->AsHyperText();
528 if (!text || !text->IsTextRole()) {
529 return FALSE;
532 return text->AddToSelection(aStartOffset, aEndOffset);
534 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
535 return proxy->AddToSelection(aStartOffset, aEndOffset);
538 return FALSE;
541 static gboolean removeTextSelectionCB(AtkText* aText, gint aSelectionNum) {
542 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
543 if (accWrap) {
544 HyperTextAccessible* text = accWrap->AsHyperText();
545 if (!text || !text->IsTextRole()) {
546 return FALSE;
549 return text->RemoveFromSelection(aSelectionNum);
551 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
552 return proxy->RemoveFromSelection(aSelectionNum);
555 return FALSE;
558 static gboolean setTextSelectionCB(AtkText* aText, gint aSelectionNum,
559 gint aStartOffset, gint aEndOffset) {
560 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
561 if (accWrap) {
562 HyperTextAccessible* text = accWrap->AsHyperText();
563 if (!text || !text->IsTextRole()) {
564 return FALSE;
567 return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
569 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
570 return proxy->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
573 return FALSE;
576 static gboolean setCaretOffsetCB(AtkText* aText, gint aOffset) {
577 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
578 if (accWrap) {
579 HyperTextAccessible* text = accWrap->AsHyperText();
580 if (!text || !text->IsTextRole() || !text->IsValidOffset(aOffset)) {
581 return FALSE;
584 text->SetCaretOffset(aOffset);
585 return TRUE;
588 if (RemoteAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
589 proxy->SetCaretOffset(aOffset);
590 return TRUE;
593 return FALSE;
596 static gboolean scrollSubstringToCB(AtkText* aText, gint aStartOffset,
597 gint aEndOffset, AtkScrollType aType) {
598 AtkObject* atkObject = ATK_OBJECT(aText);
599 AccessibleWrap* accWrap = GetAccessibleWrap(atkObject);
600 if (accWrap) {
601 HyperTextAccessible* text = accWrap->AsHyperText();
602 if (!text || !text->IsTextRole() ||
603 !text->IsValidRange(aStartOffset, aEndOffset)) {
604 return FALSE;
606 text->ScrollSubstringTo(aStartOffset, aEndOffset, aType);
607 return TRUE;
610 RemoteAccessible* proxy = GetProxy(atkObject);
611 if (proxy) {
612 proxy->ScrollSubstringTo(aStartOffset, aEndOffset, aType);
613 return TRUE;
616 return FALSE;
619 static gboolean scrollSubstringToPointCB(AtkText* aText, gint aStartOffset,
620 gint aEndOffset, AtkCoordType aCoords,
621 gint aX, gint aY) {
622 AtkObject* atkObject = ATK_OBJECT(aText);
623 AccessibleWrap* accWrap = GetAccessibleWrap(atkObject);
624 if (accWrap) {
625 HyperTextAccessible* text = accWrap->AsHyperText();
626 if (!text || !text->IsTextRole() ||
627 !text->IsValidRange(aStartOffset, aEndOffset)) {
628 return FALSE;
630 text->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoords, aX, aY);
631 return TRUE;
634 RemoteAccessible* proxy = GetProxy(atkObject);
635 if (proxy) {
636 proxy->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoords, aX, aY);
637 return TRUE;
640 return FALSE;
644 void textInterfaceInitCB(AtkTextIface* aIface) {
645 NS_ASSERTION(aIface, "Invalid aIface");
646 if (MOZ_UNLIKELY(!aIface)) return;
648 aIface->get_text = getTextCB;
649 aIface->get_text_after_offset = getTextAfterOffsetCB;
650 aIface->get_text_at_offset = getTextAtOffsetCB;
651 aIface->get_character_at_offset = getCharacterAtOffsetCB;
652 aIface->get_text_before_offset = getTextBeforeOffsetCB;
653 aIface->get_caret_offset = getCaretOffsetCB;
654 aIface->get_run_attributes = getRunAttributesCB;
655 aIface->get_default_attributes = getDefaultAttributesCB;
656 aIface->get_character_extents = getCharacterExtentsCB;
657 aIface->get_range_extents = getRangeExtentsCB;
658 aIface->get_character_count = getCharacterCountCB;
659 aIface->get_offset_at_point = getOffsetAtPointCB;
660 aIface->get_n_selections = getTextSelectionCountCB;
661 aIface->get_selection = getTextSelectionCB;
663 // set methods
664 aIface->add_selection = addTextSelectionCB;
665 aIface->remove_selection = removeTextSelectionCB;
666 aIface->set_selection = setTextSelectionCB;
667 aIface->set_caret_offset = setCaretOffsetCB;
669 if (IsAtkVersionAtLeast(2, 32)) {
670 aIface->scroll_substring_to = scrollSubstringToCB;
671 aIface->scroll_substring_to_point = scrollSubstringToPointCB;
674 // Cache the string values of the atk text attribute names.
675 for (uint32_t i = 0; i < ArrayLength(sAtkTextAttrNames); i++) {
676 sAtkTextAttrNames[i] =
677 atk_text_attribute_get_name(static_cast<AtkTextAttribute>(i));