Line data Source code
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 "XULElementAccessibles.h"
7 :
8 : #include "Accessible-inl.h"
9 : #include "BaseAccessibles.h"
10 : #include "DocAccessible-inl.h"
11 : #include "nsAccUtils.h"
12 : #include "nsCoreUtils.h"
13 : #include "nsTextEquivUtils.h"
14 : #include "Relation.h"
15 : #include "Role.h"
16 : #include "States.h"
17 : #include "TextUpdater.h"
18 :
19 : #ifdef A11Y_LOG
20 : #include "Logging.h"
21 : #endif
22 :
23 : #include "nsIDOMXULDescriptionElement.h"
24 : #include "nsNameSpaceManager.h"
25 : #include "nsNetUtil.h"
26 : #include "nsString.h"
27 : #include "nsTextBoxFrame.h"
28 :
29 : using namespace mozilla::a11y;
30 :
31 : ////////////////////////////////////////////////////////////////////////////////
32 : // XULLabelAccessible
33 : ////////////////////////////////////////////////////////////////////////////////
34 :
35 0 : XULLabelAccessible::
36 0 : XULLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
37 0 : HyperTextAccessibleWrap(aContent, aDoc)
38 : {
39 0 : mType = eXULLabelType;
40 :
41 : // If @value attribute is given then it's rendered instead text content. In
42 : // this case we need to create a text leaf accessible to make @value attribute
43 : // accessible.
44 : // XXX: text interface doesn't let you get the text by words.
45 0 : nsTextBoxFrame* textBoxFrame = do_QueryFrame(mContent->GetPrimaryFrame());
46 0 : if (textBoxFrame) {
47 0 : mValueTextLeaf = new XULLabelTextLeafAccessible(mContent, mDoc);
48 0 : mDoc->BindToDocument(mValueTextLeaf, nullptr);
49 :
50 0 : nsAutoString text;
51 0 : textBoxFrame->GetCroppedTitle(text);
52 0 : mValueTextLeaf->SetText(text);
53 0 : AppendChild(mValueTextLeaf);
54 : }
55 0 : }
56 :
57 : void
58 0 : XULLabelAccessible::Shutdown()
59 : {
60 0 : mValueTextLeaf = nullptr;
61 0 : HyperTextAccessibleWrap::Shutdown();
62 0 : }
63 :
64 : ENameValueFlag
65 0 : XULLabelAccessible::NativeName(nsString& aName)
66 : {
67 : // if the value attr doesn't exist, the screen reader must get the accessible text
68 : // from the accessible text interface or from the children
69 0 : if (mValueTextLeaf)
70 0 : return mValueTextLeaf->Name(aName);
71 :
72 0 : return Accessible::NativeName(aName);
73 : }
74 :
75 : role
76 0 : XULLabelAccessible::NativeRole()
77 : {
78 0 : return roles::LABEL;
79 : }
80 :
81 : uint64_t
82 0 : XULLabelAccessible::NativeState()
83 : {
84 : // Labels and description have read only state
85 : // They are not focusable or selectable
86 0 : return HyperTextAccessibleWrap::NativeState() | states::READONLY;
87 : }
88 :
89 : Relation
90 0 : XULLabelAccessible::RelationByType(RelationType aType)
91 : {
92 0 : Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
93 0 : if (aType == RelationType::LABEL_FOR) {
94 : // Caption is the label for groupbox
95 0 : nsIContent* parent = mContent->GetFlattenedTreeParent();
96 0 : if (parent && parent->IsXULElement(nsGkAtoms::caption)) {
97 0 : Accessible* parent = Parent();
98 0 : if (parent && parent->Role() == roles::GROUPING)
99 0 : rel.AppendTarget(parent);
100 : }
101 : }
102 :
103 0 : return rel;
104 : }
105 :
106 : void
107 0 : XULLabelAccessible::UpdateLabelValue(const nsString& aValue)
108 : {
109 : #ifdef A11Y_LOG
110 0 : if (logging::IsEnabled(logging::eText)) {
111 0 : logging::MsgBegin("TEXT", "text may be changed (xul:label @value update)");
112 0 : logging::Node("container", mContent);
113 0 : logging::MsgEntry("old text '%s'",
114 0 : NS_ConvertUTF16toUTF8(mValueTextLeaf->Text()).get());
115 0 : logging::MsgEntry("new text: '%s'",
116 0 : NS_ConvertUTF16toUTF8(aValue).get());
117 0 : logging::MsgEnd();
118 : }
119 : #endif
120 :
121 0 : TextUpdater::Run(mDoc, mValueTextLeaf, aValue);
122 0 : }
123 :
124 :
125 : ////////////////////////////////////////////////////////////////////////////////
126 : // XULLabelTextLeafAccessible
127 : ////////////////////////////////////////////////////////////////////////////////
128 :
129 : role
130 0 : XULLabelTextLeafAccessible::NativeRole()
131 : {
132 0 : return roles::TEXT_LEAF;
133 : }
134 :
135 : uint64_t
136 0 : XULLabelTextLeafAccessible::NativeState()
137 : {
138 0 : return TextLeafAccessibleWrap::NativeState() | states::READONLY;
139 : }
140 :
141 :
142 : ////////////////////////////////////////////////////////////////////////////////
143 : // XULTooltipAccessible
144 : ////////////////////////////////////////////////////////////////////////////////
145 :
146 0 : XULTooltipAccessible::
147 0 : XULTooltipAccessible(nsIContent* aContent, DocAccessible* aDoc) :
148 0 : LeafAccessible(aContent, aDoc)
149 : {
150 0 : }
151 :
152 : uint64_t
153 0 : XULTooltipAccessible::NativeState()
154 : {
155 0 : return LeafAccessible::NativeState() | states::READONLY;
156 : }
157 :
158 : role
159 0 : XULTooltipAccessible::NativeRole()
160 : {
161 0 : return roles::TOOLTIP;
162 : }
163 :
164 :
165 : ////////////////////////////////////////////////////////////////////////////////
166 : // XULLinkAccessible
167 : ////////////////////////////////////////////////////////////////////////////////
168 :
169 0 : XULLinkAccessible::
170 0 : XULLinkAccessible(nsIContent* aContent, DocAccessible* aDoc) :
171 0 : XULLabelAccessible(aContent, aDoc)
172 : {
173 0 : }
174 :
175 0 : XULLinkAccessible::~XULLinkAccessible()
176 : {
177 0 : }
178 :
179 : ////////////////////////////////////////////////////////////////////////////////
180 : // XULLinkAccessible: Accessible
181 :
182 : void
183 0 : XULLinkAccessible::Value(nsString& aValue)
184 : {
185 0 : aValue.Truncate();
186 :
187 0 : mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, aValue);
188 0 : }
189 :
190 : ENameValueFlag
191 0 : XULLinkAccessible::NativeName(nsString& aName)
192 : {
193 0 : mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
194 0 : if (!aName.IsEmpty())
195 0 : return eNameOK;
196 :
197 0 : nsTextEquivUtils::GetNameFromSubtree(this, aName);
198 0 : return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
199 : }
200 :
201 : role
202 0 : XULLinkAccessible::NativeRole()
203 : {
204 0 : return roles::LINK;
205 : }
206 :
207 :
208 : uint64_t
209 0 : XULLinkAccessible::NativeLinkState() const
210 : {
211 0 : return states::LINKED;
212 : }
213 :
214 : uint8_t
215 0 : XULLinkAccessible::ActionCount()
216 : {
217 0 : return 1;
218 : }
219 :
220 : void
221 0 : XULLinkAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
222 : {
223 0 : aName.Truncate();
224 :
225 0 : if (aIndex == eAction_Jump)
226 0 : aName.AssignLiteral("jump");
227 0 : }
228 :
229 : bool
230 0 : XULLinkAccessible::DoAction(uint8_t aIndex)
231 : {
232 0 : if (aIndex != eAction_Jump)
233 0 : return false;
234 :
235 0 : DoCommand();
236 0 : return true;
237 : }
238 :
239 : ////////////////////////////////////////////////////////////////////////////////
240 : // XULLinkAccessible: HyperLinkAccessible
241 :
242 : bool
243 0 : XULLinkAccessible::IsLink()
244 : {
245 : // Expose HyperLinkAccessible unconditionally.
246 0 : return true;
247 : }
248 :
249 : uint32_t
250 0 : XULLinkAccessible::StartOffset()
251 : {
252 : // If XUL link accessible is not contained by hypertext accessible then
253 : // start offset matches index in parent because the parent doesn't contains
254 : // a text.
255 : // XXX: accessible parent of XUL link accessible should be a hypertext
256 : // accessible.
257 0 : if (Accessible::IsLink())
258 0 : return Accessible::StartOffset();
259 0 : return IndexInParent();
260 : }
261 :
262 : uint32_t
263 0 : XULLinkAccessible::EndOffset()
264 : {
265 0 : if (Accessible::IsLink())
266 0 : return Accessible::EndOffset();
267 0 : return IndexInParent() + 1;
268 : }
269 :
270 : already_AddRefed<nsIURI>
271 0 : XULLinkAccessible::AnchorURIAt(uint32_t aAnchorIndex)
272 : {
273 0 : if (aAnchorIndex != 0)
274 0 : return nullptr;
275 :
276 0 : nsAutoString href;
277 0 : mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
278 :
279 0 : nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
280 0 : nsIDocument* document = mContent->OwnerDoc();
281 :
282 0 : nsCOMPtr<nsIURI> anchorURI;
283 0 : NS_NewURI(getter_AddRefs(anchorURI), href,
284 : document->GetDocumentCharacterSet(),
285 0 : baseURI);
286 :
287 0 : return anchorURI.forget();
288 : }
|