/src/mozilla-central/accessible/html/HTMLElementAccessibles.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
6 | | #include "HTMLElementAccessibles.h" |
7 | | |
8 | | #include "DocAccessible.h" |
9 | | #include "nsAccUtils.h" |
10 | | #include "nsIPersistentProperties2.h" |
11 | | #include "nsTextEquivUtils.h" |
12 | | #include "Relation.h" |
13 | | #include "Role.h" |
14 | | #include "States.h" |
15 | | |
16 | | #include "mozilla/dom/HTMLLabelElement.h" |
17 | | #include "mozilla/dom/HTMLDetailsElement.h" |
18 | | #include "mozilla/dom/HTMLSummaryElement.h" |
19 | | |
20 | | using namespace mozilla::a11y; |
21 | | |
22 | | //////////////////////////////////////////////////////////////////////////////// |
23 | | // HTMLHRAccessible |
24 | | //////////////////////////////////////////////////////////////////////////////// |
25 | | |
26 | | role |
27 | | HTMLHRAccessible::NativeRole() const |
28 | 0 | { |
29 | 0 | return roles::SEPARATOR; |
30 | 0 | } |
31 | | |
32 | | //////////////////////////////////////////////////////////////////////////////// |
33 | | // HTMLBRAccessible |
34 | | //////////////////////////////////////////////////////////////////////////////// |
35 | | |
36 | | role |
37 | | HTMLBRAccessible::NativeRole() const |
38 | 0 | { |
39 | 0 | return roles::WHITESPACE; |
40 | 0 | } |
41 | | |
42 | | uint64_t |
43 | | HTMLBRAccessible::NativeState() const |
44 | 0 | { |
45 | 0 | return states::READONLY; |
46 | 0 | } |
47 | | |
48 | | ENameValueFlag |
49 | | HTMLBRAccessible::NativeName(nsString& aName) const |
50 | 0 | { |
51 | 0 | aName = static_cast<char16_t>('\n'); // Newline char |
52 | 0 | return eNameOK; |
53 | 0 | } |
54 | | |
55 | | //////////////////////////////////////////////////////////////////////////////// |
56 | | // HTMLLabelAccessible |
57 | | //////////////////////////////////////////////////////////////////////////////// |
58 | | |
59 | | ENameValueFlag |
60 | | HTMLLabelAccessible::NativeName(nsString& aName) const |
61 | 0 | { |
62 | 0 | nsTextEquivUtils::GetNameFromSubtree(this, aName); |
63 | 0 | return aName.IsEmpty() ? eNameOK : eNameFromSubtree; |
64 | 0 | } |
65 | | |
66 | | Relation |
67 | | HTMLLabelAccessible::RelationByType(RelationType aType) const |
68 | 0 | { |
69 | 0 | Relation rel = AccessibleWrap::RelationByType(aType); |
70 | 0 | if (aType == RelationType::LABEL_FOR) { |
71 | 0 | dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromNode(mContent); |
72 | 0 | rel.AppendTarget(mDoc, label->GetControl()); |
73 | 0 | } |
74 | 0 |
|
75 | 0 | return rel; |
76 | 0 | } |
77 | | |
78 | | uint8_t |
79 | | HTMLLabelAccessible::ActionCount() const |
80 | 0 | { |
81 | 0 | return nsCoreUtils::IsLabelWithControl(mContent) ? 1 : 0; |
82 | 0 | } |
83 | | |
84 | | void |
85 | | HTMLLabelAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) |
86 | 0 | { |
87 | 0 | if (aIndex == 0) { |
88 | 0 | if (nsCoreUtils::IsLabelWithControl(mContent)) |
89 | 0 | aName.AssignLiteral("click"); |
90 | 0 | } |
91 | 0 | } |
92 | | |
93 | | bool |
94 | | HTMLLabelAccessible::DoAction(uint8_t aIndex) const |
95 | 0 | { |
96 | 0 | if (aIndex != 0) |
97 | 0 | return false; |
98 | 0 | |
99 | 0 | DoCommand(); |
100 | 0 | return true; |
101 | 0 | } |
102 | | |
103 | | |
104 | | //////////////////////////////////////////////////////////////////////////////// |
105 | | // nsHTMLOuputAccessible |
106 | | //////////////////////////////////////////////////////////////////////////////// |
107 | | |
108 | | Relation |
109 | | HTMLOutputAccessible::RelationByType(RelationType aType) const |
110 | 0 | { |
111 | 0 | Relation rel = AccessibleWrap::RelationByType(aType); |
112 | 0 | if (aType == RelationType::CONTROLLED_BY) |
113 | 0 | rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::_for)); |
114 | 0 |
|
115 | 0 | return rel; |
116 | 0 | } |
117 | | |
118 | | //////////////////////////////////////////////////////////////////////////////// |
119 | | // HTMLSummaryAccessible |
120 | | //////////////////////////////////////////////////////////////////////////////// |
121 | | |
122 | | HTMLSummaryAccessible:: |
123 | | HTMLSummaryAccessible(nsIContent* aContent, DocAccessible* aDoc) : |
124 | | HyperTextAccessibleWrap(aContent, aDoc) |
125 | 0 | { |
126 | 0 | mGenericTypes |= eButton; |
127 | 0 | } |
128 | | |
129 | | uint8_t |
130 | | HTMLSummaryAccessible::ActionCount() const |
131 | 0 | { |
132 | 0 | return 1; |
133 | 0 | } |
134 | | |
135 | | void |
136 | | HTMLSummaryAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) |
137 | 0 | { |
138 | 0 | if (aIndex != eAction_Click) { |
139 | 0 | return; |
140 | 0 | } |
141 | 0 | |
142 | 0 | dom::HTMLSummaryElement* summary = dom::HTMLSummaryElement::FromNode(mContent); |
143 | 0 | if (!summary) { |
144 | 0 | return; |
145 | 0 | } |
146 | 0 | |
147 | 0 | dom::HTMLDetailsElement* details = summary->GetDetails(); |
148 | 0 | if (!details) { |
149 | 0 | return; |
150 | 0 | } |
151 | 0 | |
152 | 0 | if (details->Open()) { |
153 | 0 | aName.AssignLiteral("collapse"); |
154 | 0 | } else { |
155 | 0 | aName.AssignLiteral("expand"); |
156 | 0 | } |
157 | 0 | } |
158 | | |
159 | | bool |
160 | | HTMLSummaryAccessible::DoAction(uint8_t aIndex) const |
161 | 0 | { |
162 | 0 | if (aIndex != eAction_Click) |
163 | 0 | return false; |
164 | 0 | |
165 | 0 | DoCommand(); |
166 | 0 | return true; |
167 | 0 | } |
168 | | |
169 | | uint64_t |
170 | | HTMLSummaryAccessible::NativeState() const |
171 | 0 | { |
172 | 0 | uint64_t state = HyperTextAccessibleWrap::NativeState(); |
173 | 0 |
|
174 | 0 | dom::HTMLSummaryElement* summary = dom::HTMLSummaryElement::FromNode(mContent); |
175 | 0 | if (!summary) { |
176 | 0 | return state; |
177 | 0 | } |
178 | 0 | |
179 | 0 | dom::HTMLDetailsElement* details = summary->GetDetails(); |
180 | 0 | if (!details) { |
181 | 0 | return state; |
182 | 0 | } |
183 | 0 | |
184 | 0 | if (details->Open()) { |
185 | 0 | state |= states::EXPANDED; |
186 | 0 | } else { |
187 | 0 | state |= states::COLLAPSED; |
188 | 0 | } |
189 | 0 |
|
190 | 0 | return state; |
191 | 0 | } |
192 | | |
193 | | //////////////////////////////////////////////////////////////////////////////// |
194 | | // HTMLSummaryAccessible: Widgets |
195 | | |
196 | | bool |
197 | | HTMLSummaryAccessible::IsWidget() const |
198 | 0 | { |
199 | 0 | return true; |
200 | 0 | } |
201 | | |
202 | | |
203 | | //////////////////////////////////////////////////////////////////////////////// |
204 | | // HTMLHeaderOrFooterAccessible |
205 | | //////////////////////////////////////////////////////////////////////////////// |
206 | | |
207 | | role |
208 | | HTMLHeaderOrFooterAccessible::NativeRole() const |
209 | 0 | { |
210 | 0 | // Only map header and footer if they are direct descendants of the body tag. |
211 | 0 | // If other sectioning or sectioning root elements, they become sections. |
212 | 0 | nsIContent* parent = mContent->GetParent(); |
213 | 0 | while (parent) { |
214 | 0 | if (parent->IsAnyOfHTMLElements(nsGkAtoms::article, nsGkAtoms::aside, |
215 | 0 | nsGkAtoms::nav, nsGkAtoms::section, |
216 | 0 | nsGkAtoms::blockquote, nsGkAtoms::details, |
217 | 0 | nsGkAtoms::dialog, nsGkAtoms::fieldset, |
218 | 0 | nsGkAtoms::figure, nsGkAtoms::td)) { |
219 | 0 | break; |
220 | 0 | } |
221 | 0 | parent = parent->GetParent(); |
222 | 0 | } |
223 | 0 |
|
224 | 0 | // No sectioning or sectioning root elements found. |
225 | 0 | if (!parent) { |
226 | 0 | if (mContent->IsHTMLElement(nsGkAtoms::header)) { |
227 | 0 | return roles::HEADER; |
228 | 0 | } |
229 | 0 | |
230 | 0 | if (mContent->IsHTMLElement(nsGkAtoms::footer)) { |
231 | 0 | return roles::FOOTER; |
232 | 0 | } |
233 | 0 | } |
234 | 0 | |
235 | 0 | return roles::SECTION; |
236 | 0 | } |
237 | | |
238 | | nsAtom* |
239 | | HTMLHeaderOrFooterAccessible::LandmarkRole() const |
240 | 0 | { |
241 | 0 | if (!HasOwnContent()) |
242 | 0 | return nullptr; |
243 | 0 | |
244 | 0 | a11y::role r = const_cast<HTMLHeaderOrFooterAccessible*>(this)->Role(); |
245 | 0 | if (r == roles::HEADER) { |
246 | 0 | return nsGkAtoms::banner; |
247 | 0 | } |
248 | 0 | |
249 | 0 | if (r == roles::FOOTER) { |
250 | 0 | return nsGkAtoms::contentinfo; |
251 | 0 | } |
252 | 0 | |
253 | 0 | return nullptr; |
254 | 0 | } |