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