BaseAccessibles.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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/. */
  5. #include "BaseAccessibles.h"
  6. #include "Accessible-inl.h"
  7. #include "HyperTextAccessibleWrap.h"
  8. #include "nsAccessibilityService.h"
  9. #include "nsAccUtils.h"
  10. #include "nsCoreUtils.h"
  11. #include "Role.h"
  12. #include "States.h"
  13. #include "nsIURI.h"
  14. using namespace mozilla::a11y;
  15. ////////////////////////////////////////////////////////////////////////////////
  16. // LeafAccessible
  17. ////////////////////////////////////////////////////////////////////////////////
  18. LeafAccessible::
  19. LeafAccessible(nsIContent* aContent, DocAccessible* aDoc) :
  20. AccessibleWrap(aContent, aDoc)
  21. {
  22. mStateFlags |= eNoKidsFromDOM;
  23. }
  24. NS_IMPL_ISUPPORTS_INHERITED0(LeafAccessible, Accessible)
  25. ////////////////////////////////////////////////////////////////////////////////
  26. // LeafAccessible: Accessible public
  27. Accessible*
  28. LeafAccessible::ChildAtPoint(int32_t aX, int32_t aY,
  29. EWhichChildAtPoint aWhichChild)
  30. {
  31. // Don't walk into leaf accessibles.
  32. return this;
  33. }
  34. bool
  35. LeafAccessible::InsertChildAt(uint32_t aIndex, Accessible* aChild)
  36. {
  37. NS_NOTREACHED("InsertChildAt called on leaf accessible!");
  38. return false;
  39. }
  40. bool
  41. LeafAccessible::RemoveChild(Accessible* aChild)
  42. {
  43. NS_NOTREACHED("RemoveChild called on leaf accessible!");
  44. return false;
  45. }
  46. bool
  47. LeafAccessible::IsAcceptableChild(nsIContent* aEl) const
  48. {
  49. // No children for leaf accessible.
  50. return false;
  51. }
  52. ////////////////////////////////////////////////////////////////////////////////
  53. // LinkableAccessible
  54. ////////////////////////////////////////////////////////////////////////////////
  55. NS_IMPL_ISUPPORTS_INHERITED0(LinkableAccessible, AccessibleWrap)
  56. ////////////////////////////////////////////////////////////////////////////////
  57. // LinkableAccessible. nsIAccessible
  58. void
  59. LinkableAccessible::TakeFocus()
  60. {
  61. if (Accessible* actionAcc = ActionWalk()) {
  62. actionAcc->TakeFocus();
  63. } else {
  64. AccessibleWrap::TakeFocus();
  65. }
  66. }
  67. uint64_t
  68. LinkableAccessible::NativeLinkState() const
  69. {
  70. bool isLink;
  71. Accessible* actionAcc =
  72. const_cast<LinkableAccessible*>(this)->ActionWalk(&isLink);
  73. if (isLink) {
  74. return states::LINKED | (actionAcc->LinkState() & states::TRAVERSED);
  75. }
  76. return 0;
  77. }
  78. void
  79. LinkableAccessible::Value(nsString& aValue)
  80. {
  81. aValue.Truncate();
  82. Accessible::Value(aValue);
  83. if (!aValue.IsEmpty()) {
  84. return;
  85. }
  86. bool isLink;
  87. Accessible* actionAcc = ActionWalk(&isLink);
  88. if (isLink) {
  89. actionAcc->Value(aValue);
  90. }
  91. }
  92. uint8_t
  93. LinkableAccessible::ActionCount()
  94. {
  95. bool isLink, isOnclick, isLabelWithControl;
  96. ActionWalk(&isLink, &isOnclick, &isLabelWithControl);
  97. return (isLink || isOnclick || isLabelWithControl) ? 1 : 0;
  98. }
  99. Accessible*
  100. LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick,
  101. bool* aIsLabelWithControl)
  102. {
  103. if (aIsOnclick) {
  104. *aIsOnclick = false;
  105. }
  106. if (aIsLink) {
  107. *aIsLink = false;
  108. }
  109. if (aIsLabelWithControl) {
  110. *aIsLabelWithControl = false;
  111. }
  112. if (nsCoreUtils::HasClickListener(mContent)) {
  113. if (aIsOnclick) {
  114. *aIsOnclick = true;
  115. }
  116. return nullptr;
  117. }
  118. // XXX: The logic looks broken since the click listener may be registered
  119. // on non accessible node in parent chain but this node is skipped when tree
  120. // is traversed.
  121. Accessible* walkUpAcc = this;
  122. while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) {
  123. if (walkUpAcc->LinkState() & states::LINKED) {
  124. if (aIsLink) {
  125. *aIsLink = true;
  126. }
  127. return walkUpAcc;
  128. }
  129. if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
  130. if (aIsOnclick) {
  131. *aIsOnclick = true;
  132. }
  133. return walkUpAcc;
  134. }
  135. if (nsCoreUtils::IsLabelWithControl(walkUpAcc->GetContent())) {
  136. if (aIsLabelWithControl) {
  137. *aIsLabelWithControl = true;
  138. }
  139. return walkUpAcc;
  140. }
  141. }
  142. return nullptr;
  143. }
  144. void
  145. LinkableAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
  146. {
  147. aName.Truncate();
  148. // Action 0 (default action): Jump to link
  149. if (aIndex == eAction_Jump) {
  150. bool isOnclick, isLink, isLabelWithControl;
  151. ActionWalk(&isLink, &isOnclick, &isLabelWithControl);
  152. if (isLink) {
  153. aName.AssignLiteral("jump");
  154. } else if (isOnclick || isLabelWithControl) {
  155. aName.AssignLiteral("click");
  156. }
  157. }
  158. }
  159. bool
  160. LinkableAccessible::DoAction(uint8_t aIndex)
  161. {
  162. if (aIndex != eAction_Jump) {
  163. return false;
  164. }
  165. if (Accessible* actionAcc = ActionWalk()) {
  166. return actionAcc->DoAction(aIndex);
  167. }
  168. return AccessibleWrap::DoAction(aIndex);
  169. }
  170. KeyBinding
  171. LinkableAccessible::AccessKey() const
  172. {
  173. if (const Accessible* actionAcc =
  174. const_cast<LinkableAccessible*>(this)->ActionWalk()) {
  175. return actionAcc->AccessKey();
  176. }
  177. return Accessible::AccessKey();
  178. }
  179. ////////////////////////////////////////////////////////////////////////////////
  180. // LinkableAccessible: HyperLinkAccessible
  181. already_AddRefed<nsIURI>
  182. LinkableAccessible::AnchorURIAt(uint32_t aAnchorIndex)
  183. {
  184. bool isLink;
  185. Accessible* actionAcc = ActionWalk(&isLink);
  186. if (isLink) {
  187. NS_ASSERTION(actionAcc->IsLink(), "HyperLink isn't implemented.");
  188. if (actionAcc->IsLink()) {
  189. return actionAcc->AnchorURIAt(aAnchorIndex);
  190. }
  191. }
  192. return nullptr;
  193. }
  194. ////////////////////////////////////////////////////////////////////////////////
  195. // DummyAccessible
  196. ////////////////////////////////////////////////////////////////////////////////
  197. uint64_t
  198. DummyAccessible::NativeState()
  199. {
  200. return 0;
  201. }
  202. uint64_t
  203. DummyAccessible::NativeInteractiveState() const
  204. {
  205. return 0;
  206. }
  207. uint64_t
  208. DummyAccessible::NativeLinkState() const
  209. {
  210. return 0;
  211. }
  212. bool
  213. DummyAccessible::NativelyUnavailable() const
  214. {
  215. return false;
  216. }
  217. void
  218. DummyAccessible::ApplyARIAState(uint64_t* aState) const
  219. {
  220. }