no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / accessible / xul / XULElementAccessibles.cpp
blobc999ffa468f44c2be310660dc967d8fea99dcdad
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/. */
6 #include "XULElementAccessibles.h"
8 #include "LocalAccessible-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 "mozilla/a11y/Role.h"
16 #include "States.h"
17 #include "TextUpdater.h"
19 #ifdef A11Y_LOG
20 # include "Logging.h"
21 #endif
23 #include "nsNameSpaceManager.h"
24 #include "nsNetUtil.h"
25 #include "nsString.h"
26 #include "nsXULElement.h"
28 using namespace mozilla::a11y;
30 ////////////////////////////////////////////////////////////////////////////////
31 // XULLabelAccessible
32 ////////////////////////////////////////////////////////////////////////////////
34 XULLabelAccessible::XULLabelAccessible(nsIContent* aContent,
35 DocAccessible* aDoc)
36 : HyperTextAccessible(aContent, aDoc) {
37 mType = eXULLabelType;
40 void XULLabelAccessible::Shutdown() {
41 mValueTextLeaf = nullptr;
42 HyperTextAccessible::Shutdown();
45 void XULLabelAccessible::DispatchClickEvent(nsIContent* aContent,
46 uint32_t aActionIndex) const {
47 // Bug 1578140: For labels inside buttons, The base implementation of
48 // DispatchClickEvent doesn't fire a command event on the button.
49 RefPtr<nsXULElement> el = nsXULElement::FromNodeOrNull(aContent);
50 if (el) {
51 el->Click(mozilla::dom::CallerType::System);
55 ENameValueFlag XULLabelAccessible::NativeName(nsString& aName) const {
56 // if the value attr doesn't exist, the screen reader must get the accessible
57 // text from the accessible text interface or from the children
58 if (mValueTextLeaf) return mValueTextLeaf->Name(aName);
60 return LocalAccessible::NativeName(aName);
63 role XULLabelAccessible::NativeRole() const { return roles::LABEL; }
65 uint64_t XULLabelAccessible::NativeState() const {
66 // Labels and description have read only state
67 // They are not focusable or selectable
68 return HyperTextAccessible::NativeState() | states::READONLY;
71 Relation XULLabelAccessible::RelationByType(RelationType aType) const {
72 Relation rel = HyperTextAccessible::RelationByType(aType);
74 // The label for xul:groupbox is generated from the first xul:label
75 if (aType == RelationType::LABEL_FOR) {
76 LocalAccessible* parent = LocalParent();
77 if (parent && parent->Role() == roles::GROUPING &&
78 parent->LocalChildAt(0) == this) {
79 nsIContent* parentContent = parent->GetContent();
80 if (parentContent && parentContent->IsXULElement(nsGkAtoms::groupbox)) {
81 rel.AppendTarget(parent);
86 return rel;
89 void XULLabelAccessible::UpdateLabelValue(const nsString& aValue) {
90 #ifdef A11Y_LOG
91 if (logging::IsEnabled(logging::eText)) {
92 logging::MsgBegin("TEXT", "text may be changed (xul:label @value update)");
93 logging::Node("container", mContent);
94 logging::MsgEntry("old text '%s'",
95 NS_ConvertUTF16toUTF8(mValueTextLeaf->Text()).get());
96 logging::MsgEntry("new text: '%s'", NS_ConvertUTF16toUTF8(aValue).get());
97 logging::MsgEnd();
99 #endif
101 TextUpdater::Run(mDoc, mValueTextLeaf, aValue);
104 ////////////////////////////////////////////////////////////////////////////////
105 // XULLabelTextLeafAccessible
106 ////////////////////////////////////////////////////////////////////////////////
108 role XULLabelTextLeafAccessible::NativeRole() const { return roles::TEXT_LEAF; }
110 uint64_t XULLabelTextLeafAccessible::NativeState() const {
111 return TextLeafAccessible::NativeState() | states::READONLY;
114 ////////////////////////////////////////////////////////////////////////////////
115 // XULTooltipAccessible
116 ////////////////////////////////////////////////////////////////////////////////
118 XULTooltipAccessible::XULTooltipAccessible(nsIContent* aContent,
119 DocAccessible* aDoc)
120 : LeafAccessible(aContent, aDoc) {
121 mType = eXULTooltipType;
124 uint64_t XULTooltipAccessible::NativeState() const {
125 return LeafAccessible::NativeState() | states::READONLY;
128 role XULTooltipAccessible::NativeRole() const { return roles::TOOLTIP; }
130 ////////////////////////////////////////////////////////////////////////////////
131 // XULLinkAccessible
132 ////////////////////////////////////////////////////////////////////////////////
134 XULLinkAccessible::XULLinkAccessible(nsIContent* aContent, DocAccessible* aDoc)
135 : XULLabelAccessible(aContent, aDoc) {}
137 XULLinkAccessible::~XULLinkAccessible() {}
139 ////////////////////////////////////////////////////////////////////////////////
140 // XULLinkAccessible: LocalAccessible
142 void XULLinkAccessible::Value(nsString& aValue) const {
143 aValue.Truncate();
145 mContent->AsElement()->GetAttr(nsGkAtoms::href, aValue);
148 ENameValueFlag XULLinkAccessible::NativeName(nsString& aName) const {
149 mContent->AsElement()->GetAttr(nsGkAtoms::value, aName);
150 if (!aName.IsEmpty()) return eNameOK;
152 nsTextEquivUtils::GetNameFromSubtree(this, aName);
153 return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
156 role XULLinkAccessible::NativeRole() const { return roles::LINK; }
158 uint64_t XULLinkAccessible::NativeLinkState() const { return states::LINKED; }
160 bool XULLinkAccessible::HasPrimaryAction() const { return true; }
162 void XULLinkAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
163 aName.Truncate();
165 if (aIndex == eAction_Jump) aName.AssignLiteral("jump");
168 ////////////////////////////////////////////////////////////////////////////////
169 // XULLinkAccessible: HyperLinkAccessible
171 bool XULLinkAccessible::IsLink() const {
172 // Expose HyperLinkAccessible unconditionally.
173 return true;
176 uint32_t XULLinkAccessible::StartOffset() {
177 // If XUL link accessible is not contained by hypertext accessible then
178 // start offset matches index in parent because the parent doesn't contains
179 // a text.
180 // XXX: accessible parent of XUL link accessible should be a hypertext
181 // accessible.
182 if (LocalAccessible::IsLink()) return LocalAccessible::StartOffset();
183 return IndexInParent();
186 uint32_t XULLinkAccessible::EndOffset() {
187 if (LocalAccessible::IsLink()) return LocalAccessible::EndOffset();
188 return IndexInParent() + 1;
191 already_AddRefed<nsIURI> XULLinkAccessible::AnchorURIAt(
192 uint32_t aAnchorIndex) const {
193 if (aAnchorIndex != 0) return nullptr;
195 nsAutoString href;
196 mContent->AsElement()->GetAttr(nsGkAtoms::href, href);
198 dom::Document* document = mContent->OwnerDoc();
200 nsCOMPtr<nsIURI> anchorURI;
201 NS_NewURI(getter_AddRefs(anchorURI), href,
202 document->GetDocumentCharacterSet(), mContent->GetBaseURI());
204 return anchorURI.forget();