Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/accessible/xul/XULComboboxAccessible.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
5
6
#include "XULComboboxAccessible.h"
7
8
#include "Accessible-inl.h"
9
#include "nsAccessibilityService.h"
10
#include "DocAccessible.h"
11
#include "nsCoreUtils.h"
12
#include "Role.h"
13
#include "States.h"
14
15
#include "nsIAutoCompleteInput.h"
16
#include "nsIDOMXULMenuListElement.h"
17
#include "nsIDOMXULSelectCntrlItemEl.h"
18
19
using namespace mozilla::a11y;
20
21
////////////////////////////////////////////////////////////////////////////////
22
// XULComboboxAccessible
23
////////////////////////////////////////////////////////////////////////////////
24
25
XULComboboxAccessible::
26
  XULComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
27
  AccessibleWrap(aContent, aDoc)
28
0
{
29
0
  if (mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
30
0
                                         nsGkAtoms::autocomplete, eIgnoreCase))
31
0
    mGenericTypes |= eAutoComplete;
32
0
  else
33
0
    mGenericTypes |= eCombobox;
34
0
35
0
  // The XUL <textbox type="autocomplete"> uses XULComboboxAccessible. We need
36
0
  // to walk the anonymous children for these so that the entry field is a
37
0
  // child. Otherwise no XBL children.
38
0
  if (!mContent->NodeInfo()->Equals(nsGkAtoms::textbox, kNameSpaceID_XUL)) {
39
0
    mStateFlags |= eNoXBLKids;
40
0
  }
41
0
}
42
43
role
44
XULComboboxAccessible::NativeRole() const
45
0
{
46
0
  return IsAutoComplete() ? roles::AUTOCOMPLETE : roles::COMBOBOX;
47
0
}
48
49
uint64_t
50
XULComboboxAccessible::NativeState() const
51
0
{
52
0
  // As a nsComboboxAccessible we can have the following states:
53
0
  //     STATE_FOCUSED
54
0
  //     STATE_FOCUSABLE
55
0
  //     STATE_HASPOPUP
56
0
  //     STATE_EXPANDED
57
0
  //     STATE_COLLAPSED
58
0
59
0
  // Get focus status from base class
60
0
  uint64_t state = Accessible::NativeState();
61
0
62
0
  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
63
0
  if (menuList) {
64
0
    bool isOpen = false;
65
0
    menuList->GetOpen(&isOpen);
66
0
    if (isOpen)
67
0
      state |= states::EXPANDED;
68
0
    else
69
0
      state |= states::COLLAPSED;
70
0
  }
71
0
72
0
  return state | states::HASPOPUP;
73
0
}
74
75
void
76
XULComboboxAccessible::Description(nsString& aDescription)
77
0
{
78
0
  aDescription.Truncate();
79
0
  // Use description of currently focused option
80
0
  nsCOMPtr<nsIDOMXULMenuListElement> menuListElm(do_QueryInterface(mContent));
81
0
  if (!menuListElm)
82
0
    return;
83
0
84
0
  nsCOMPtr<nsIDOMXULSelectControlItemElement> focusedOptionItem;
85
0
  menuListElm->GetSelectedItem(getter_AddRefs(focusedOptionItem));
86
0
  nsCOMPtr<nsIContent> focusedOptionContent =
87
0
    do_QueryInterface(focusedOptionItem);
88
0
  if (focusedOptionContent && mDoc) {
89
0
    Accessible* focusedOptionAcc = mDoc->GetAccessible(focusedOptionContent);
90
0
    if (focusedOptionAcc)
91
0
      focusedOptionAcc->Description(aDescription);
92
0
  }
93
0
}
94
95
void
96
XULComboboxAccessible::Value(nsString& aValue) const
97
0
{
98
0
  aValue.Truncate();
99
0
100
0
  // The value is the option or text shown entered in the combobox.
101
0
  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
102
0
  if (menuList)
103
0
    menuList->GetLabel(aValue);
104
0
}
105
106
uint8_t
107
XULComboboxAccessible::ActionCount() const
108
0
{
109
0
  // Just one action (click).
110
0
  return 1;
111
0
}
112
113
bool
114
XULComboboxAccessible::DoAction(uint8_t aIndex) const
115
0
{
116
0
  if (aIndex != XULComboboxAccessible::eAction_Click)
117
0
    return false;
118
0
119
0
  // Programmaticaly toggle the combo box.
120
0
  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
121
0
  if (!menuList)
122
0
    return false;
123
0
124
0
  bool isDroppedDown = false;
125
0
  menuList->GetOpen(&isDroppedDown);
126
0
  menuList->SetOpen(!isDroppedDown);
127
0
  return true;
128
0
}
129
130
void
131
XULComboboxAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
132
0
{
133
0
  aName.Truncate();
134
0
  if (aIndex != XULComboboxAccessible::eAction_Click)
135
0
    return;
136
0
137
0
  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
138
0
  if (!menuList)
139
0
    return;
140
0
141
0
  bool isDroppedDown = false;
142
0
  menuList->GetOpen(&isDroppedDown);
143
0
  if (isDroppedDown)
144
0
    aName.AssignLiteral("close");
145
0
  else
146
0
    aName.AssignLiteral("open");
147
0
}
148
149
////////////////////////////////////////////////////////////////////////////////
150
// Widgets
151
152
bool
153
XULComboboxAccessible::IsActiveWidget() const
154
0
{
155
0
  if (IsAutoComplete() ||
156
0
     mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
157
0
                                        nsGkAtoms::_true, eIgnoreCase)) {
158
0
    int32_t childCount = mChildren.Length();
159
0
    for (int32_t idx = 0; idx < childCount; idx++) {
160
0
      Accessible* child = mChildren[idx];
161
0
      if (child->Role() == roles::ENTRY)
162
0
        return FocusMgr()->HasDOMFocus(child->GetContent());
163
0
    }
164
0
    return false;
165
0
  }
166
0
167
0
  return FocusMgr()->HasDOMFocus(mContent);
168
0
}
169
170
bool
171
XULComboboxAccessible::AreItemsOperable() const
172
0
{
173
0
  if (IsAutoComplete()) {
174
0
    nsCOMPtr<nsIAutoCompleteInput> autoCompleteInputElm =
175
0
      do_QueryInterface(mContent);
176
0
    if (autoCompleteInputElm) {
177
0
      bool isOpen = false;
178
0
      autoCompleteInputElm->GetPopupOpen(&isOpen);
179
0
      return isOpen;
180
0
    }
181
0
    return false;
182
0
  }
183
0
184
0
  nsCOMPtr<nsIDOMXULMenuListElement> menuListElm = do_QueryInterface(mContent);
185
0
  if (menuListElm) {
186
0
    bool isOpen = false;
187
0
    menuListElm->GetOpen(&isOpen);
188
0
    return isOpen;
189
0
  }
190
0
191
0
  return false;
192
0
}