no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / accessible / xul / XULComboboxAccessible.cpp
blob2e22a33e51581e616fb80ec26389b5f576a92f83
1 /* -*- Mode: C++; tab-width: 4; 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 "XULComboboxAccessible.h"
8 #include "LocalAccessible-inl.h"
9 #include "nsAccessibilityService.h"
10 #include "DocAccessible.h"
11 #include "nsCoreUtils.h"
12 #include "mozilla/a11y/Role.h"
13 #include "States.h"
15 #include "mozilla/dom/Element.h"
16 #include "nsIDOMXULMenuListElement.h"
18 using namespace mozilla::a11y;
20 ////////////////////////////////////////////////////////////////////////////////
21 // XULComboboxAccessible
22 ////////////////////////////////////////////////////////////////////////////////
24 XULComboboxAccessible::XULComboboxAccessible(nsIContent* aContent,
25 DocAccessible* aDoc)
26 : AccessibleWrap(aContent, aDoc) {
27 mGenericTypes |= eCombobox;
30 role XULComboboxAccessible::NativeRole() const { return roles::COMBOBOX; }
32 uint64_t XULComboboxAccessible::NativeState() const {
33 // As a nsComboboxAccessible we can have the following states:
34 // STATE_FOCUSED
35 // STATE_FOCUSABLE
36 // STATE_HASPOPUP
37 // STATE_EXPANDED
38 // STATE_COLLAPSED
40 // Get focus status from base class
41 uint64_t state = LocalAccessible::NativeState();
43 nsCOMPtr<nsIDOMXULMenuListElement> menuList = Elm()->AsXULMenuList();
44 if (menuList) {
45 bool isOpen = false;
46 menuList->GetOpen(&isOpen);
47 if (isOpen) {
48 state |= states::EXPANDED;
49 } else {
50 state |= states::COLLAPSED;
54 return state | states::HASPOPUP;
57 bool XULComboboxAccessible::IsAcceptableChild(nsIContent* aContent) const {
58 return AccessibleWrap::IsAcceptableChild(aContent) && !aContent->IsText();
61 void XULComboboxAccessible::Description(nsString& aDescription) const {
62 aDescription.Truncate();
63 // Use description of currently focused option
64 nsCOMPtr<nsIDOMXULMenuListElement> menuListElm = Elm()->AsXULMenuList();
65 if (!menuListElm) return;
67 nsCOMPtr<dom::Element> focusedOptionItem;
68 menuListElm->GetSelectedItem(getter_AddRefs(focusedOptionItem));
69 if (focusedOptionItem && mDoc) {
70 LocalAccessible* focusedOptionAcc = mDoc->GetAccessible(focusedOptionItem);
71 if (focusedOptionAcc) focusedOptionAcc->Description(aDescription);
75 void XULComboboxAccessible::Value(nsString& aValue) const {
76 aValue.Truncate();
78 // The value is the option or text shown entered in the combobox.
79 nsCOMPtr<nsIDOMXULMenuListElement> menuList = Elm()->AsXULMenuList();
80 if (menuList) menuList->GetLabel(aValue);
83 bool XULComboboxAccessible::HasPrimaryAction() const { return true; }
85 bool XULComboboxAccessible::DoAction(uint8_t aIndex) const {
86 if (aIndex != XULComboboxAccessible::eAction_Click) return false;
88 // Programmaticaly toggle the combo box.
89 nsCOMPtr<nsIDOMXULMenuListElement> menuList = Elm()->AsXULMenuList();
90 if (!menuList) return false;
92 bool isDroppedDown = false;
93 menuList->GetOpen(&isDroppedDown);
94 menuList->SetOpen(!isDroppedDown);
95 return true;
98 void XULComboboxAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
99 aName.Truncate();
100 if (aIndex != XULComboboxAccessible::eAction_Click) return;
102 nsCOMPtr<nsIDOMXULMenuListElement> menuList = Elm()->AsXULMenuList();
103 if (!menuList) return;
105 bool isDroppedDown = false;
106 menuList->GetOpen(&isDroppedDown);
107 if (isDroppedDown) {
108 aName.AssignLiteral("close");
109 } else {
110 aName.AssignLiteral("open");
114 ////////////////////////////////////////////////////////////////////////////////
115 // Widgets
117 bool XULComboboxAccessible::IsActiveWidget() const {
118 if (mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
119 nsGkAtoms::_true, eIgnoreCase)) {
120 int32_t childCount = mChildren.Length();
121 for (int32_t idx = 0; idx < childCount; idx++) {
122 LocalAccessible* child = mChildren[idx];
123 if (child->Role() == roles::ENTRY) {
124 return FocusMgr()->HasDOMFocus(child->GetContent());
127 return false;
130 return FocusMgr()->HasDOMFocus(mContent);
133 bool XULComboboxAccessible::AreItemsOperable() const {
134 nsCOMPtr<nsIDOMXULMenuListElement> menuListElm = Elm()->AsXULMenuList();
135 if (menuListElm) {
136 bool isOpen = false;
137 menuListElm->GetOpen(&isOpen);
138 return isOpen;
141 return false;