accessible/src/html/HTMLLinkAccessible.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:90c6af75161e
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 "HTMLLinkAccessible.h"
7
8 #include "nsCoreUtils.h"
9 #include "DocAccessible.h"
10 #include "Role.h"
11 #include "States.h"
12
13 #include "nsContentUtils.h"
14 #include "mozilla/EventStates.h"
15 #include "mozilla/dom/Element.h"
16
17 using namespace mozilla;
18 using namespace mozilla::a11y;
19
20 ////////////////////////////////////////////////////////////////////////////////
21 // HTMLLinkAccessible
22 ////////////////////////////////////////////////////////////////////////////////
23
24 HTMLLinkAccessible::
25 HTMLLinkAccessible(nsIContent* aContent, DocAccessible* aDoc) :
26 HyperTextAccessibleWrap(aContent, aDoc)
27 {
28 }
29
30 // Expose nsIAccessibleHyperLink unconditionally
31 NS_IMPL_ISUPPORTS_INHERITED(HTMLLinkAccessible, HyperTextAccessibleWrap,
32 nsIAccessibleHyperLink)
33
34 ////////////////////////////////////////////////////////////////////////////////
35 // nsIAccessible
36
37 role
38 HTMLLinkAccessible::NativeRole()
39 {
40 return roles::LINK;
41 }
42
43 uint64_t
44 HTMLLinkAccessible::NativeState()
45 {
46 return HyperTextAccessibleWrap::NativeState() & ~states::READONLY;
47 }
48
49 uint64_t
50 HTMLLinkAccessible::NativeLinkState() const
51 {
52 EventStates eventState = mContent->AsElement()->State();
53 if (eventState.HasState(NS_EVENT_STATE_UNVISITED))
54 return states::LINKED;
55
56 if (eventState.HasState(NS_EVENT_STATE_VISITED))
57 return states::LINKED | states::TRAVERSED;
58
59 // This is a either named anchor (a link with also a name attribute) or
60 // it doesn't have any attributes. Check if 'click' event handler is
61 // registered, otherwise bail out.
62 return nsCoreUtils::HasClickListener(mContent) ? states::LINKED : 0;
63 }
64
65 uint64_t
66 HTMLLinkAccessible::NativeInteractiveState() const
67 {
68 uint64_t state = HyperTextAccessibleWrap::NativeInteractiveState();
69
70 // This is how we indicate it is a named anchor. In other words, this anchor
71 // can be selected as a location :) There is no other better state to use to
72 // indicate this.
73 if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::name))
74 state |= states::SELECTABLE;
75
76 return state;
77 }
78
79 void
80 HTMLLinkAccessible::Value(nsString& aValue)
81 {
82 aValue.Truncate();
83
84 HyperTextAccessible::Value(aValue);
85 if (aValue.IsEmpty())
86 nsContentUtils::GetLinkLocation(mContent->AsElement(), aValue);
87 }
88
89 uint8_t
90 HTMLLinkAccessible::ActionCount()
91 {
92 return IsLinked() ? 1 : HyperTextAccessible::ActionCount();
93 }
94
95 NS_IMETHODIMP
96 HTMLLinkAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
97 {
98 aName.Truncate();
99
100 if (!IsLinked())
101 return HyperTextAccessible::GetActionName(aIndex, aName);
102
103 // Action 0 (default action): Jump to link
104 if (aIndex != eAction_Jump)
105 return NS_ERROR_INVALID_ARG;
106
107 aName.AssignLiteral("jump");
108 return NS_OK;
109 }
110
111 NS_IMETHODIMP
112 HTMLLinkAccessible::DoAction(uint8_t aIndex)
113 {
114 if (!IsLinked())
115 return HyperTextAccessible::DoAction(aIndex);
116
117 // Action 0 (default action): Jump to link
118 if (aIndex != eAction_Jump)
119 return NS_ERROR_INVALID_ARG;
120
121 if (IsDefunct())
122 return NS_ERROR_FAILURE;
123
124 DoCommand();
125 return NS_OK;
126 }
127
128 ////////////////////////////////////////////////////////////////////////////////
129 // HyperLinkAccessible
130
131 bool
132 HTMLLinkAccessible::IsLink()
133 {
134 // Expose HyperLinkAccessible unconditionally.
135 return true;
136 }
137
138 already_AddRefed<nsIURI>
139 HTMLLinkAccessible::AnchorURIAt(uint32_t aAnchorIndex)
140 {
141 return aAnchorIndex == 0 ? mContent->GetHrefURI() : nullptr;
142 }
143
144 ////////////////////////////////////////////////////////////////////////////////
145 // Protected members
146
147 bool
148 HTMLLinkAccessible::IsLinked()
149 {
150 if (IsDefunct())
151 return false;
152
153 EventStates state = mContent->AsElement()->State();
154 return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED |
155 NS_EVENT_STATE_UNVISITED);
156 }

mercurial