XULSelectControlAccessible.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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 "XULSelectControlAccessible.h"
  6. #include "nsAccessibilityService.h"
  7. #include "DocAccessible.h"
  8. #include "nsIDOMXULContainerElement.h"
  9. #include "nsIDOMXULSelectCntrlItemEl.h"
  10. #include "nsIDOMXULMultSelectCntrlEl.h"
  11. #include "nsIDOMKeyEvent.h"
  12. #include "nsIDOMElement.h"
  13. #include "nsIDOMXULElement.h"
  14. #include "nsIMutableArray.h"
  15. #include "nsIServiceManager.h"
  16. #include "mozilla/dom/Element.h"
  17. using namespace mozilla;
  18. using namespace mozilla::a11y;
  19. ////////////////////////////////////////////////////////////////////////////////
  20. // XULSelectControlAccessible
  21. ////////////////////////////////////////////////////////////////////////////////
  22. XULSelectControlAccessible::
  23. XULSelectControlAccessible(nsIContent* aContent, DocAccessible* aDoc) :
  24. AccessibleWrap(aContent, aDoc)
  25. {
  26. mGenericTypes |= eSelect;
  27. mSelectControl = do_QueryInterface(aContent);
  28. }
  29. ////////////////////////////////////////////////////////////////////////////////
  30. // XULSelectControlAccessible: Accessible
  31. void
  32. XULSelectControlAccessible::Shutdown()
  33. {
  34. mSelectControl = nullptr;
  35. AccessibleWrap::Shutdown();
  36. }
  37. ////////////////////////////////////////////////////////////////////////////////
  38. // XULSelectControlAccessible: SelectAccessible
  39. void
  40. XULSelectControlAccessible::SelectedItems(nsTArray<Accessible*>* aItems)
  41. {
  42. // For XUL multi-select control
  43. nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
  44. do_QueryInterface(mSelectControl);
  45. if (xulMultiSelect) {
  46. int32_t length = 0;
  47. xulMultiSelect->GetSelectedCount(&length);
  48. for (int32_t index = 0; index < length; index++) {
  49. nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
  50. xulMultiSelect->MultiGetSelectedItem(index, getter_AddRefs(itemElm));
  51. nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
  52. Accessible* item = mDoc->GetAccessible(itemNode);
  53. if (item)
  54. aItems->AppendElement(item);
  55. }
  56. } else { // Single select?
  57. nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
  58. mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
  59. nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
  60. if (itemNode) {
  61. Accessible* item = mDoc->GetAccessible(itemNode);
  62. if (item)
  63. aItems->AppendElement(item);
  64. }
  65. }
  66. }
  67. Accessible*
  68. XULSelectControlAccessible::GetSelectedItem(uint32_t aIndex)
  69. {
  70. nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
  71. do_QueryInterface(mSelectControl);
  72. nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
  73. if (multiSelectControl)
  74. multiSelectControl->MultiGetSelectedItem(aIndex, getter_AddRefs(itemElm));
  75. else if (aIndex == 0)
  76. mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
  77. nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
  78. return itemNode && mDoc ? mDoc->GetAccessible(itemNode) : nullptr;
  79. }
  80. uint32_t
  81. XULSelectControlAccessible::SelectedItemCount()
  82. {
  83. // For XUL multi-select control
  84. nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
  85. do_QueryInterface(mSelectControl);
  86. if (multiSelectControl) {
  87. int32_t count = 0;
  88. multiSelectControl->GetSelectedCount(&count);
  89. return count;
  90. }
  91. // For XUL single-select control/menulist
  92. int32_t index;
  93. mSelectControl->GetSelectedIndex(&index);
  94. return (index >= 0) ? 1 : 0;
  95. }
  96. bool
  97. XULSelectControlAccessible::AddItemToSelection(uint32_t aIndex)
  98. {
  99. Accessible* item = GetChildAt(aIndex);
  100. if (!item)
  101. return false;
  102. nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
  103. do_QueryInterface(item->GetContent());
  104. if (!itemElm)
  105. return false;
  106. bool isItemSelected = false;
  107. itemElm->GetSelected(&isItemSelected);
  108. if (isItemSelected)
  109. return true;
  110. nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
  111. do_QueryInterface(mSelectControl);
  112. if (multiSelectControl)
  113. multiSelectControl->AddItemToSelection(itemElm);
  114. else
  115. mSelectControl->SetSelectedItem(itemElm);
  116. return true;
  117. }
  118. bool
  119. XULSelectControlAccessible::RemoveItemFromSelection(uint32_t aIndex)
  120. {
  121. Accessible* item = GetChildAt(aIndex);
  122. if (!item)
  123. return false;
  124. nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
  125. do_QueryInterface(item->GetContent());
  126. if (!itemElm)
  127. return false;
  128. bool isItemSelected = false;
  129. itemElm->GetSelected(&isItemSelected);
  130. if (!isItemSelected)
  131. return true;
  132. nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
  133. do_QueryInterface(mSelectControl);
  134. if (multiSelectControl)
  135. multiSelectControl->RemoveItemFromSelection(itemElm);
  136. else
  137. mSelectControl->SetSelectedItem(nullptr);
  138. return true;
  139. }
  140. bool
  141. XULSelectControlAccessible::IsItemSelected(uint32_t aIndex)
  142. {
  143. Accessible* item = GetChildAt(aIndex);
  144. if (!item)
  145. return false;
  146. nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
  147. do_QueryInterface(item->GetContent());
  148. if (!itemElm)
  149. return false;
  150. bool isItemSelected = false;
  151. itemElm->GetSelected(&isItemSelected);
  152. return isItemSelected;
  153. }
  154. bool
  155. XULSelectControlAccessible::UnselectAll()
  156. {
  157. nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
  158. do_QueryInterface(mSelectControl);
  159. multiSelectControl ?
  160. multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1);
  161. return true;
  162. }
  163. bool
  164. XULSelectControlAccessible::SelectAll()
  165. {
  166. nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
  167. do_QueryInterface(mSelectControl);
  168. if (multiSelectControl) {
  169. multiSelectControl->SelectAll();
  170. return true;
  171. }
  172. // otherwise, don't support this method
  173. return false;
  174. }
  175. ////////////////////////////////////////////////////////////////////////////////
  176. // XULSelectControlAccessible: Widgets
  177. Accessible*
  178. XULSelectControlAccessible::CurrentItem()
  179. {
  180. if (!mSelectControl)
  181. return nullptr;
  182. nsCOMPtr<nsIDOMXULSelectControlItemElement> currentItemElm;
  183. nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
  184. do_QueryInterface(mSelectControl);
  185. if (multiSelectControl)
  186. multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm));
  187. else
  188. mSelectControl->GetSelectedItem(getter_AddRefs(currentItemElm));
  189. nsCOMPtr<nsINode> DOMNode;
  190. if (currentItemElm)
  191. DOMNode = do_QueryInterface(currentItemElm);
  192. if (DOMNode) {
  193. DocAccessible* document = Document();
  194. if (document)
  195. return document->GetAccessible(DOMNode);
  196. }
  197. return nullptr;
  198. }
  199. void
  200. XULSelectControlAccessible::SetCurrentItem(Accessible* aItem)
  201. {
  202. if (!mSelectControl)
  203. return;
  204. nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
  205. do_QueryInterface(aItem->GetContent());
  206. nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
  207. do_QueryInterface(mSelectControl);
  208. if (multiSelectControl)
  209. multiSelectControl->SetCurrentItem(itemElm);
  210. else
  211. mSelectControl->SetSelectedItem(itemElm);
  212. }