1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "BaseAccessibles.h"
8 #include "LocalAccessible-inl.h"
9 #include "HyperTextAccessibleWrap.h"
10 #include "nsAccessibilityService.h"
11 #include "nsAccUtils.h"
12 #include "nsCoreUtils.h"
17 using namespace mozilla::a11y
;
19 ////////////////////////////////////////////////////////////////////////////////
21 ////////////////////////////////////////////////////////////////////////////////
23 LeafAccessible::LeafAccessible(nsIContent
* aContent
, DocAccessible
* aDoc
)
24 : AccessibleWrap(aContent
, aDoc
) {
25 mStateFlags
|= eNoKidsFromDOM
;
28 ////////////////////////////////////////////////////////////////////////////////
29 // LeafAccessible: LocalAccessible public
31 LocalAccessible
* LeafAccessible::LocalChildAtPoint(
32 int32_t aX
, int32_t aY
, EWhichChildAtPoint aWhichChild
) {
33 // Don't walk into leaf accessibles.
37 bool LeafAccessible::InsertChildAt(uint32_t aIndex
, LocalAccessible
* aChild
) {
38 MOZ_ASSERT_UNREACHABLE("InsertChildAt called on leaf accessible!");
42 bool LeafAccessible::RemoveChild(LocalAccessible
* aChild
) {
43 MOZ_ASSERT_UNREACHABLE("RemoveChild called on leaf accessible!");
47 bool LeafAccessible::IsAcceptableChild(nsIContent
* aEl
) const {
48 // No children for leaf accessible.
52 ////////////////////////////////////////////////////////////////////////////////
54 ////////////////////////////////////////////////////////////////////////////////
56 ////////////////////////////////////////////////////////////////////////////////
57 // LinkableAccessible. nsIAccessible
59 void LinkableAccessible::TakeFocus() const {
60 if (const LocalAccessible
* actionAcc
= ActionWalk()) {
61 actionAcc
->TakeFocus();
63 AccessibleWrap::TakeFocus();
67 uint64_t LinkableAccessible::NativeLinkState() const {
69 const LocalAccessible
* actionAcc
= ActionWalk(&isLink
);
71 return states::LINKED
| (actionAcc
->LinkState() & states::TRAVERSED
);
77 void LinkableAccessible::Value(nsString
& aValue
) const {
80 LocalAccessible::Value(aValue
);
81 if (!aValue
.IsEmpty()) {
86 const LocalAccessible
* actionAcc
= ActionWalk(&isLink
);
88 actionAcc
->Value(aValue
);
92 uint8_t LinkableAccessible::ActionCount() const {
93 bool isLink
, isOnclick
, isLabelWithControl
;
94 ActionWalk(&isLink
, &isOnclick
, &isLabelWithControl
);
95 return (isLink
|| isOnclick
|| isLabelWithControl
) ? 1 : 0;
98 const LocalAccessible
* LinkableAccessible::ActionWalk(
99 bool* aIsLink
, bool* aIsOnclick
, bool* aIsLabelWithControl
) const {
106 if (aIsLabelWithControl
) {
107 *aIsLabelWithControl
= false;
110 if (nsCoreUtils::HasClickListener(mContent
)) {
117 // XXX: The logic looks broken since the click listener may be registered
118 // on non accessible node in parent chain but this node is skipped when tree
120 const LocalAccessible
* walkUpAcc
= this;
121 while ((walkUpAcc
= walkUpAcc
->LocalParent()) && !walkUpAcc
->IsDoc()) {
122 if (walkUpAcc
->LinkState() & states::LINKED
) {
129 if (nsCoreUtils::HasClickListener(walkUpAcc
->GetContent())) {
136 if (nsCoreUtils::IsLabelWithControl(walkUpAcc
->GetContent())) {
137 if (aIsLabelWithControl
) {
138 *aIsLabelWithControl
= true;
146 void LinkableAccessible::ActionNameAt(uint8_t aIndex
, nsAString
& aName
) {
149 // Action 0 (default action): Jump to link
150 if (aIndex
== eAction_Jump
) {
151 bool isOnclick
, isLink
, isLabelWithControl
;
152 ActionWalk(&isLink
, &isOnclick
, &isLabelWithControl
);
154 aName
.AssignLiteral("jump");
155 } else if (isOnclick
|| isLabelWithControl
) {
156 aName
.AssignLiteral("click");
161 bool LinkableAccessible::DoAction(uint8_t aIndex
) const {
162 if (aIndex
!= eAction_Jump
) {
166 if (const LocalAccessible
* actionAcc
= ActionWalk()) {
167 return actionAcc
->DoAction(aIndex
);
170 return AccessibleWrap::DoAction(aIndex
);
173 KeyBinding
LinkableAccessible::AccessKey() const {
174 if (const LocalAccessible
* actionAcc
=
175 const_cast<LinkableAccessible
*>(this)->ActionWalk()) {
176 return actionAcc
->AccessKey();
179 return LocalAccessible::AccessKey();
182 ////////////////////////////////////////////////////////////////////////////////
183 // LinkableAccessible: HyperLinkAccessible
185 already_AddRefed
<nsIURI
> LinkableAccessible::AnchorURIAt(
186 uint32_t aAnchorIndex
) const {
188 const LocalAccessible
* actionAcc
= ActionWalk(&isLink
);
190 NS_ASSERTION(actionAcc
->IsLink(), "HyperLink isn't implemented.");
192 if (actionAcc
->IsLink()) {
193 return actionAcc
->AnchorURIAt(aAnchorIndex
);
200 ////////////////////////////////////////////////////////////////////////////////
202 ////////////////////////////////////////////////////////////////////////////////
204 uint64_t DummyAccessible::NativeState() const { return 0; }
205 uint64_t DummyAccessible::NativeInteractiveState() const { return 0; }
207 uint64_t DummyAccessible::NativeLinkState() const { return 0; }
209 bool DummyAccessible::NativelyUnavailable() const { return false; }
211 void DummyAccessible::ApplyARIAState(uint64_t* aState
) const {}