Bug 1878814: Handle Yelp suggestion as sponsored r=adw,fluent-reviewers
[gecko.git] / accessible / xpcom / xpcAccessible.cpp
blob37901e3ec27db42ea024def5163a6689491b0d61
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "AccAttributes.h"
8 #include "nsAccUtils.h"
9 #include "nsComponentManagerUtils.h"
10 #include "nsIAccessibleRelation.h"
11 #include "nsIAccessibleRole.h"
12 #include "nsAccessibleRelation.h"
13 #include "Relation.h"
14 #include "RootAccessible.h"
15 #include "xpcAccessibleDocument.h"
17 #include "nsIMutableArray.h"
18 #include "nsPersistentProperties.h"
20 #ifdef MOZ_WIDGET_COCOA
21 # include "xpcAccessibleMacInterface.h"
22 #endif
24 using namespace mozilla::a11y;
26 NS_IMETHODIMP
27 xpcAccessible::GetParent(nsIAccessible** aParent) {
28 NS_ENSURE_ARG_POINTER(aParent);
29 *aParent = nullptr;
30 if (!IntlGeneric()) return NS_ERROR_FAILURE;
32 Accessible* parent = IntlGeneric()->Parent();
33 NS_IF_ADDREF(*aParent = ToXPC(parent));
34 return NS_OK;
37 NS_IMETHODIMP
38 xpcAccessible::GetNextSibling(nsIAccessible** aNextSibling) {
39 NS_ENSURE_ARG_POINTER(aNextSibling);
40 *aNextSibling = nullptr;
41 if (!IntlGeneric()) return NS_ERROR_FAILURE;
43 NS_IF_ADDREF(*aNextSibling = ToXPC(IntlGeneric()->NextSibling()));
45 return NS_OK;
48 NS_IMETHODIMP
49 xpcAccessible::GetPreviousSibling(nsIAccessible** aPreviousSibling) {
50 NS_ENSURE_ARG_POINTER(aPreviousSibling);
51 *aPreviousSibling = nullptr;
52 if (!IntlGeneric()) return NS_ERROR_FAILURE;
54 NS_IF_ADDREF(*aPreviousSibling = ToXPC(IntlGeneric()->PrevSibling()));
56 return NS_OK;
59 NS_IMETHODIMP
60 xpcAccessible::GetFirstChild(nsIAccessible** aFirstChild) {
61 NS_ENSURE_ARG_POINTER(aFirstChild);
62 *aFirstChild = nullptr;
64 if (!IntlGeneric()) return NS_ERROR_FAILURE;
66 NS_IF_ADDREF(*aFirstChild = ToXPC(IntlGeneric()->FirstChild()));
67 return NS_OK;
70 NS_IMETHODIMP
71 xpcAccessible::GetLastChild(nsIAccessible** aLastChild) {
72 NS_ENSURE_ARG_POINTER(aLastChild);
73 *aLastChild = nullptr;
75 if (!IntlGeneric()) return NS_ERROR_FAILURE;
77 NS_IF_ADDREF(*aLastChild = ToXPC(IntlGeneric()->LastChild()));
78 return NS_OK;
81 NS_IMETHODIMP
82 xpcAccessible::GetChildCount(int32_t* aChildCount) {
83 NS_ENSURE_ARG_POINTER(aChildCount);
85 if (!IntlGeneric()) return NS_ERROR_FAILURE;
87 *aChildCount = IntlGeneric()->ChildCount();
88 return NS_OK;
91 NS_IMETHODIMP
92 xpcAccessible::GetChildAt(int32_t aChildIndex, nsIAccessible** aChild) {
93 NS_ENSURE_ARG_POINTER(aChild);
94 *aChild = nullptr;
96 if (!IntlGeneric()) return NS_ERROR_FAILURE;
98 // If child index is negative, then return last child.
99 // XXX: do we really need this?
100 if (aChildIndex < 0) aChildIndex = IntlGeneric()->ChildCount() - 1;
102 Accessible* child = IntlGeneric()->ChildAt(aChildIndex);
103 if (!child) return NS_ERROR_INVALID_ARG;
105 NS_ADDREF(*aChild = ToXPC(child));
106 return NS_OK;
109 NS_IMETHODIMP
110 xpcAccessible::GetChildren(nsIArray** aChildren) {
111 NS_ENSURE_ARG_POINTER(aChildren);
112 *aChildren = nullptr;
114 if (!IntlGeneric()) return NS_ERROR_FAILURE;
116 nsresult rv = NS_OK;
117 nsCOMPtr<nsIMutableArray> children =
118 do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
119 NS_ENSURE_SUCCESS(rv, rv);
121 uint32_t childCount = IntlGeneric()->ChildCount();
122 for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
123 Accessible* child = IntlGeneric()->ChildAt(childIdx);
124 children->AppendElement(static_cast<nsIAccessible*>(ToXPC(child)));
127 children.forget(aChildren);
128 return NS_OK;
131 NS_IMETHODIMP
132 xpcAccessible::GetIndexInParent(int32_t* aIndexInParent) {
133 NS_ENSURE_ARG_POINTER(aIndexInParent);
134 *aIndexInParent = -1;
135 if (!IntlGeneric()) return NS_ERROR_FAILURE;
137 *aIndexInParent = IntlGeneric()->IndexInParent();
139 return *aIndexInParent != -1 ? NS_OK : NS_ERROR_FAILURE;
142 NS_IMETHODIMP
143 xpcAccessible::GetUniqueID(int64_t* aUniqueID) {
144 NS_ENSURE_ARG_POINTER(aUniqueID);
146 if (!IntlGeneric()) return NS_ERROR_FAILURE;
148 if (IntlGeneric()->IsLocal()) {
149 *aUniqueID = reinterpret_cast<uintptr_t>(Intl()->UniqueID());
150 } else if (IntlGeneric()->IsRemote()) {
151 *aUniqueID = IntlGeneric()->AsRemote()->ID();
154 return NS_OK;
157 NS_IMETHODIMP
158 xpcAccessible::GetDOMNode(nsINode** aDOMNode) {
159 NS_ENSURE_ARG_POINTER(aDOMNode);
160 *aDOMNode = nullptr;
162 if (!Intl()) return NS_ERROR_FAILURE;
164 nsCOMPtr<nsINode> node = Intl()->GetNode();
165 node.forget(aDOMNode);
167 return NS_OK;
170 NS_IMETHODIMP
171 xpcAccessible::GetId(nsAString& aID) {
172 if (!IntlGeneric()) {
173 return NS_ERROR_FAILURE;
176 RemoteAccessible* proxy = IntlGeneric()->AsRemote();
177 if (!proxy) {
178 return NS_ERROR_FAILURE;
181 nsString id;
182 proxy->DOMNodeID(id);
183 aID.Assign(id);
185 return NS_OK;
188 NS_IMETHODIMP
189 xpcAccessible::GetDocument(nsIAccessibleDocument** aDocument) {
190 NS_ENSURE_ARG_POINTER(aDocument);
191 *aDocument = nullptr;
193 if (!Intl()) return NS_ERROR_FAILURE;
195 NS_IF_ADDREF(*aDocument = ToXPCDocument(Intl()->Document()));
196 return NS_OK;
199 NS_IMETHODIMP
200 xpcAccessible::GetRootDocument(nsIAccessibleDocument** aRootDocument) {
201 NS_ENSURE_ARG_POINTER(aRootDocument);
202 *aRootDocument = nullptr;
204 if (!Intl()) return NS_ERROR_FAILURE;
206 NS_IF_ADDREF(*aRootDocument = ToXPCDocument(Intl()->RootAccessible()));
207 return NS_OK;
210 NS_IMETHODIMP
211 xpcAccessible::GetRole(uint32_t* aRole) {
212 NS_ENSURE_ARG_POINTER(aRole);
213 *aRole = nsIAccessibleRole::ROLE_NOTHING;
215 if (!IntlGeneric()) return NS_ERROR_FAILURE;
217 *aRole = IntlGeneric()->Role();
218 return NS_OK;
221 NS_IMETHODIMP
222 xpcAccessible::GetState(uint32_t* aState, uint32_t* aExtraState) {
223 NS_ENSURE_ARG_POINTER(aState);
225 Accessible* acc = IntlGeneric();
226 if (acc) {
227 nsAccUtils::To32States(acc->State(), aState, aExtraState);
228 } else {
229 nsAccUtils::To32States(states::DEFUNCT, aState, aExtraState);
232 return NS_OK;
235 NS_IMETHODIMP
236 xpcAccessible::GetName(nsAString& aName) {
237 aName.Truncate();
239 if (!IntlGeneric()) return NS_ERROR_FAILURE;
241 nsAutoString name;
242 IntlGeneric()->Name(name);
244 aName.Assign(name);
246 return NS_OK;
249 NS_IMETHODIMP
250 xpcAccessible::GetDescription(nsAString& aDescription) {
251 if (!IntlGeneric()) return NS_ERROR_FAILURE;
253 nsAutoString desc;
254 IntlGeneric()->Description(desc);
256 aDescription.Assign(desc);
258 return NS_OK;
261 NS_IMETHODIMP
262 xpcAccessible::GetLanguage(nsAString& aLanguage) {
263 if (!IntlGeneric()) return NS_ERROR_FAILURE;
265 nsAutoString lang;
266 IntlGeneric()->Language(lang);
268 aLanguage.Assign(lang);
269 return NS_OK;
272 NS_IMETHODIMP
273 xpcAccessible::GetValue(nsAString& aValue) {
274 if (!IntlGeneric()) return NS_ERROR_FAILURE;
276 nsAutoString value;
277 IntlGeneric()->Value(value);
279 aValue.Assign(value);
281 return NS_OK;
284 NS_IMETHODIMP
285 xpcAccessible::GetAccessKey(nsAString& aAccessKey) {
286 aAccessKey.Truncate();
288 if (!IntlGeneric()) return NS_ERROR_FAILURE;
290 IntlGeneric()->AccessKey().ToString(aAccessKey);
291 return NS_OK;
294 NS_IMETHODIMP
295 xpcAccessible::GetKeyboardShortcut(nsAString& aKeyBinding) {
296 aKeyBinding.Truncate();
297 if (!IntlGeneric()) return NS_ERROR_FAILURE;
299 if (IntlGeneric()->IsRemote()) {
300 return NS_ERROR_NOT_IMPLEMENTED;
302 Intl()->KeyboardShortcut().ToString(aKeyBinding);
303 return NS_OK;
306 NS_IMETHODIMP
307 xpcAccessible::GetAttributes(nsIPersistentProperties** aAttributes) {
308 NS_ENSURE_ARG_POINTER(aAttributes);
309 *aAttributes = nullptr;
311 if (!IntlGeneric()) {
312 return NS_ERROR_FAILURE;
315 RefPtr<nsPersistentProperties> props = new nsPersistentProperties();
317 RefPtr<AccAttributes> attributes = IntlGeneric()->Attributes();
319 nsAutoString unused;
320 for (auto iter : *attributes) {
321 nsAutoString name;
322 iter.NameAsString(name);
324 nsAutoString value;
325 iter.ValueAsString(value);
327 props->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused);
330 props.forget(aAttributes);
331 return NS_OK;
334 NS_IMETHODIMP
335 xpcAccessible::GetCache(nsIPersistentProperties** aCachedFields) {
336 NS_ENSURE_ARG_POINTER(aCachedFields);
337 *aCachedFields = nullptr;
339 if (!IntlGeneric()) {
340 return NS_ERROR_FAILURE;
343 RefPtr<nsPersistentProperties> props = new nsPersistentProperties();
344 if (RemoteAccessible* remoteAcc = IntlGeneric()->AsRemote()) {
345 if (RefPtr<AccAttributes> cachedFields = remoteAcc->mCachedFields) {
346 nsAutoString unused;
347 for (auto iter : *cachedFields) {
348 nsAutoString name;
349 iter.NameAsString(name);
351 nsAutoString value;
352 iter.ValueAsString(value);
354 props->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused);
359 props.forget(aCachedFields);
360 return NS_OK;
363 NS_IMETHODIMP
364 xpcAccessible::GetNativeInterface(nsISupports** aNativeInterface) {
365 #ifdef MOZ_WIDGET_COCOA
366 NS_ENSURE_ARG_POINTER(aNativeInterface);
368 // We don't cache or store this instance anywhere so each get returns a
369 // different instance. So `acc.nativeInterface != acc.nativeInterface`. This
370 // just seems simpler and more robust for now.
371 nsCOMPtr<nsISupports> macIface = static_cast<nsIAccessibleMacInterface*>(
372 new xpcAccessibleMacInterface(IntlGeneric()));
373 macIface.swap(*aNativeInterface);
375 return NS_OK;
376 #else
377 return NS_ERROR_NOT_IMPLEMENTED;
378 #endif
381 NS_IMETHODIMP
382 xpcAccessible::GetBounds(int32_t* aX, int32_t* aY, int32_t* aWidth,
383 int32_t* aHeight) {
384 NS_ENSURE_ARG_POINTER(aX);
385 *aX = 0;
386 NS_ENSURE_ARG_POINTER(aY);
387 *aY = 0;
388 NS_ENSURE_ARG_POINTER(aWidth);
389 *aWidth = 0;
390 NS_ENSURE_ARG_POINTER(aHeight);
391 *aHeight = 0;
393 if (!IntlGeneric()) return NS_ERROR_FAILURE;
395 LayoutDeviceIntRect rect = IntlGeneric()->Bounds();
396 rect.GetRect(aX, aY, aWidth, aHeight);
397 return NS_OK;
400 NS_IMETHODIMP
401 xpcAccessible::GetBoundsInCSSPixels(int32_t* aX, int32_t* aY, int32_t* aWidth,
402 int32_t* aHeight) {
403 NS_ENSURE_ARG_POINTER(aX);
404 *aX = 0;
405 NS_ENSURE_ARG_POINTER(aY);
406 *aY = 0;
407 NS_ENSURE_ARG_POINTER(aWidth);
408 *aWidth = 0;
409 NS_ENSURE_ARG_POINTER(aHeight);
410 *aHeight = 0;
412 if (!IntlGeneric()) {
413 return NS_ERROR_FAILURE;
416 nsIntRect rect = IntlGeneric()->BoundsInCSSPixels();
417 rect.GetRect(aX, aY, aWidth, aHeight);
418 return NS_OK;
421 NS_IMETHODIMP
422 xpcAccessible::GroupPosition(int32_t* aGroupLevel,
423 int32_t* aSimilarItemsInGroup,
424 int32_t* aPositionInGroup) {
425 NS_ENSURE_ARG_POINTER(aGroupLevel);
426 NS_ENSURE_ARG_POINTER(aSimilarItemsInGroup);
427 NS_ENSURE_ARG_POINTER(aPositionInGroup);
429 GroupPos groupPos = IntlGeneric()->GroupPosition();
431 *aGroupLevel = groupPos.level;
432 *aSimilarItemsInGroup = groupPos.setSize;
433 *aPositionInGroup = groupPos.posInSet;
435 return NS_OK;
438 NS_IMETHODIMP
439 xpcAccessible::GetRelationByType(uint32_t aType,
440 nsIAccessibleRelation** aRelation) {
441 NS_ENSURE_ARG_POINTER(aRelation);
442 *aRelation = nullptr;
444 NS_ENSURE_ARG(aType <= static_cast<uint32_t>(RelationType::LAST));
446 if (!IntlGeneric()) return NS_ERROR_FAILURE;
448 Relation rel =
449 IntlGeneric()->RelationByType(static_cast<RelationType>(aType));
450 NS_ADDREF(*aRelation = new nsAccessibleRelation(aType, &rel));
451 return NS_OK;
454 NS_IMETHODIMP
455 xpcAccessible::GetRelations(nsIArray** aRelations) {
456 NS_ENSURE_ARG_POINTER(aRelations);
457 *aRelations = nullptr;
459 if (!IntlGeneric()) return NS_ERROR_FAILURE;
461 nsCOMPtr<nsIMutableArray> relations = do_CreateInstance(NS_ARRAY_CONTRACTID);
462 NS_ENSURE_TRUE(relations, NS_ERROR_OUT_OF_MEMORY);
464 for (uint32_t type = 0; type <= static_cast<uint32_t>(RelationType::LAST);
465 ++type) {
466 nsCOMPtr<nsIAccessibleRelation> relation;
467 nsresult rv = GetRelationByType(type, getter_AddRefs(relation));
469 if (NS_SUCCEEDED(rv) && relation) {
470 uint32_t targets = 0;
471 relation->GetTargetsCount(&targets);
472 if (targets) relations->AppendElement(relation);
476 NS_ADDREF(*aRelations = relations);
477 return NS_OK;
480 NS_IMETHODIMP
481 xpcAccessible::GetFocusedChild(nsIAccessible** aChild) {
482 NS_ENSURE_ARG_POINTER(aChild);
483 *aChild = nullptr;
485 if (!IntlGeneric()) return NS_ERROR_FAILURE;
487 NS_IF_ADDREF(*aChild = ToXPC(IntlGeneric()->FocusedChild()));
489 return NS_OK;
492 NS_IMETHODIMP
493 xpcAccessible::GetChildAtPoint(int32_t aX, int32_t aY,
494 nsIAccessible** aAccessible) {
495 NS_ENSURE_ARG_POINTER(aAccessible);
496 *aAccessible = nullptr;
498 if (!IntlGeneric()) return NS_ERROR_FAILURE;
500 NS_IF_ADDREF(*aAccessible = ToXPC(IntlGeneric()->ChildAtPoint(
501 aX, aY, Accessible::EWhichChildAtPoint::DirectChild)));
503 return NS_OK;
506 NS_IMETHODIMP
507 xpcAccessible::GetDeepestChildAtPoint(int32_t aX, int32_t aY,
508 nsIAccessible** aAccessible) {
509 NS_ENSURE_ARG_POINTER(aAccessible);
510 *aAccessible = nullptr;
512 if (!IntlGeneric()) return NS_ERROR_FAILURE;
514 NS_IF_ADDREF(*aAccessible = ToXPC(IntlGeneric()->ChildAtPoint(
515 aX, aY, Accessible::EWhichChildAtPoint::DeepestChild)));
517 return NS_OK;
520 NS_IMETHODIMP
521 xpcAccessible::GetDeepestChildAtPointInProcess(int32_t aX, int32_t aY,
522 nsIAccessible** aAccessible) {
523 NS_ENSURE_ARG_POINTER(aAccessible);
524 *aAccessible = nullptr;
526 Accessible* generic = IntlGeneric();
527 if (!generic || generic->IsRemote()) {
528 return NS_ERROR_FAILURE;
531 NS_IF_ADDREF(*aAccessible = ToXPC(Intl()->LocalChildAtPoint(
532 aX, aY, Accessible::EWhichChildAtPoint::DeepestChild)));
533 return NS_OK;
536 NS_IMETHODIMP
537 xpcAccessible::SetSelected(bool aSelect) {
538 if (!IntlGeneric()) return NS_ERROR_FAILURE;
540 IntlGeneric()->SetSelected(aSelect);
542 return NS_OK;
545 NS_IMETHODIMP
546 xpcAccessible::TakeSelection() {
547 if (!IntlGeneric()) return NS_ERROR_FAILURE;
549 IntlGeneric()->TakeSelection();
551 return NS_OK;
554 NS_IMETHODIMP
555 xpcAccessible::TakeFocus() {
556 if (!IntlGeneric()) return NS_ERROR_FAILURE;
558 IntlGeneric()->TakeFocus();
559 return NS_OK;
562 NS_IMETHODIMP
563 xpcAccessible::GetActionCount(uint8_t* aActionCount) {
564 NS_ENSURE_ARG_POINTER(aActionCount);
565 *aActionCount = 0;
566 if (!IntlGeneric()) return NS_ERROR_FAILURE;
568 *aActionCount = IntlGeneric()->ActionCount();
570 return NS_OK;
573 NS_IMETHODIMP
574 xpcAccessible::GetActionName(uint8_t aIndex, nsAString& aName) {
575 aName.Truncate();
577 if (!IntlGeneric()) {
578 return NS_ERROR_FAILURE;
581 if (aIndex >= IntlGeneric()->ActionCount()) {
582 return NS_ERROR_INVALID_ARG;
585 nsAutoString name;
586 IntlGeneric()->ActionNameAt(aIndex, name);
588 aName.Assign(name);
590 return NS_OK;
593 NS_IMETHODIMP
594 xpcAccessible::GetActionDescription(uint8_t aIndex, nsAString& aDescription) {
595 aDescription.Truncate();
597 if (!IntlGeneric()) {
598 return NS_ERROR_FAILURE;
601 if (aIndex >= IntlGeneric()->ActionCount()) {
602 return NS_ERROR_INVALID_ARG;
605 nsAutoString description;
606 IntlGeneric()->ActionDescriptionAt(aIndex, description);
608 aDescription.Assign(description);
610 return NS_OK;
613 NS_IMETHODIMP
614 xpcAccessible::DoAction(uint8_t aIndex) {
615 if (!IntlGeneric()) return NS_ERROR_FAILURE;
617 return IntlGeneric()->DoAction(aIndex) ? NS_OK : NS_ERROR_INVALID_ARG;
620 NS_IMETHODIMP
621 xpcAccessible::ScrollTo(uint32_t aHow) {
622 if (!IntlGeneric()) return NS_ERROR_FAILURE;
624 IntlGeneric()->ScrollTo(aHow);
625 return NS_OK;
628 NS_IMETHODIMP
629 xpcAccessible::ScrollToPoint(uint32_t aCoordinateType, int32_t aX, int32_t aY) {
630 if (!IntlGeneric()) return NS_ERROR_FAILURE;
632 IntlGeneric()->ScrollToPoint(aCoordinateType, aX, aY);
634 return NS_OK;
637 NS_IMETHODIMP
638 xpcAccessible::Announce(const nsAString& aAnnouncement, uint16_t aPriority) {
639 if (RemoteAccessible* proxy = IntlGeneric()->AsRemote()) {
640 #if defined(XP_WIN)
641 return NS_ERROR_NOT_IMPLEMENTED;
642 #else
643 nsString announcement(aAnnouncement);
644 proxy->Announce(announcement, aPriority);
645 #endif
646 } else {
647 Intl()->Announce(aAnnouncement, aPriority);
650 return NS_OK;
653 NS_IMETHODIMP
654 xpcAccessible::GetComputedARIARole(nsAString& aRole) {
655 if (!IntlGeneric()) {
656 return NS_ERROR_FAILURE;
659 nsStaticAtom* ariaRole = IntlGeneric()->ComputedARIARole();
660 if (ariaRole) {
661 ariaRole->ToString(aRole);
664 return NS_OK;