1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/html/HTMLLinkAccessible.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,156 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "HTMLLinkAccessible.h" 1.10 + 1.11 +#include "nsCoreUtils.h" 1.12 +#include "DocAccessible.h" 1.13 +#include "Role.h" 1.14 +#include "States.h" 1.15 + 1.16 +#include "nsContentUtils.h" 1.17 +#include "mozilla/EventStates.h" 1.18 +#include "mozilla/dom/Element.h" 1.19 + 1.20 +using namespace mozilla; 1.21 +using namespace mozilla::a11y; 1.22 + 1.23 +//////////////////////////////////////////////////////////////////////////////// 1.24 +// HTMLLinkAccessible 1.25 +//////////////////////////////////////////////////////////////////////////////// 1.26 + 1.27 +HTMLLinkAccessible:: 1.28 + HTMLLinkAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.29 + HyperTextAccessibleWrap(aContent, aDoc) 1.30 +{ 1.31 +} 1.32 + 1.33 +// Expose nsIAccessibleHyperLink unconditionally 1.34 +NS_IMPL_ISUPPORTS_INHERITED(HTMLLinkAccessible, HyperTextAccessibleWrap, 1.35 + nsIAccessibleHyperLink) 1.36 + 1.37 +//////////////////////////////////////////////////////////////////////////////// 1.38 +// nsIAccessible 1.39 + 1.40 +role 1.41 +HTMLLinkAccessible::NativeRole() 1.42 +{ 1.43 + return roles::LINK; 1.44 +} 1.45 + 1.46 +uint64_t 1.47 +HTMLLinkAccessible::NativeState() 1.48 +{ 1.49 + return HyperTextAccessibleWrap::NativeState() & ~states::READONLY; 1.50 +} 1.51 + 1.52 +uint64_t 1.53 +HTMLLinkAccessible::NativeLinkState() const 1.54 +{ 1.55 + EventStates eventState = mContent->AsElement()->State(); 1.56 + if (eventState.HasState(NS_EVENT_STATE_UNVISITED)) 1.57 + return states::LINKED; 1.58 + 1.59 + if (eventState.HasState(NS_EVENT_STATE_VISITED)) 1.60 + return states::LINKED | states::TRAVERSED; 1.61 + 1.62 + // This is a either named anchor (a link with also a name attribute) or 1.63 + // it doesn't have any attributes. Check if 'click' event handler is 1.64 + // registered, otherwise bail out. 1.65 + return nsCoreUtils::HasClickListener(mContent) ? states::LINKED : 0; 1.66 +} 1.67 + 1.68 +uint64_t 1.69 +HTMLLinkAccessible::NativeInteractiveState() const 1.70 +{ 1.71 + uint64_t state = HyperTextAccessibleWrap::NativeInteractiveState(); 1.72 + 1.73 + // This is how we indicate it is a named anchor. In other words, this anchor 1.74 + // can be selected as a location :) There is no other better state to use to 1.75 + // indicate this. 1.76 + if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::name)) 1.77 + state |= states::SELECTABLE; 1.78 + 1.79 + return state; 1.80 +} 1.81 + 1.82 +void 1.83 +HTMLLinkAccessible::Value(nsString& aValue) 1.84 +{ 1.85 + aValue.Truncate(); 1.86 + 1.87 + HyperTextAccessible::Value(aValue); 1.88 + if (aValue.IsEmpty()) 1.89 + nsContentUtils::GetLinkLocation(mContent->AsElement(), aValue); 1.90 +} 1.91 + 1.92 +uint8_t 1.93 +HTMLLinkAccessible::ActionCount() 1.94 +{ 1.95 + return IsLinked() ? 1 : HyperTextAccessible::ActionCount(); 1.96 +} 1.97 + 1.98 +NS_IMETHODIMP 1.99 +HTMLLinkAccessible::GetActionName(uint8_t aIndex, nsAString& aName) 1.100 +{ 1.101 + aName.Truncate(); 1.102 + 1.103 + if (!IsLinked()) 1.104 + return HyperTextAccessible::GetActionName(aIndex, aName); 1.105 + 1.106 + // Action 0 (default action): Jump to link 1.107 + if (aIndex != eAction_Jump) 1.108 + return NS_ERROR_INVALID_ARG; 1.109 + 1.110 + aName.AssignLiteral("jump"); 1.111 + return NS_OK; 1.112 +} 1.113 + 1.114 +NS_IMETHODIMP 1.115 +HTMLLinkAccessible::DoAction(uint8_t aIndex) 1.116 +{ 1.117 + if (!IsLinked()) 1.118 + return HyperTextAccessible::DoAction(aIndex); 1.119 + 1.120 + // Action 0 (default action): Jump to link 1.121 + if (aIndex != eAction_Jump) 1.122 + return NS_ERROR_INVALID_ARG; 1.123 + 1.124 + if (IsDefunct()) 1.125 + return NS_ERROR_FAILURE; 1.126 + 1.127 + DoCommand(); 1.128 + return NS_OK; 1.129 +} 1.130 + 1.131 +//////////////////////////////////////////////////////////////////////////////// 1.132 +// HyperLinkAccessible 1.133 + 1.134 +bool 1.135 +HTMLLinkAccessible::IsLink() 1.136 +{ 1.137 + // Expose HyperLinkAccessible unconditionally. 1.138 + return true; 1.139 +} 1.140 + 1.141 +already_AddRefed<nsIURI> 1.142 +HTMLLinkAccessible::AnchorURIAt(uint32_t aAnchorIndex) 1.143 +{ 1.144 + return aAnchorIndex == 0 ? mContent->GetHrefURI() : nullptr; 1.145 +} 1.146 + 1.147 +//////////////////////////////////////////////////////////////////////////////// 1.148 +// Protected members 1.149 + 1.150 +bool 1.151 +HTMLLinkAccessible::IsLinked() 1.152 +{ 1.153 + if (IsDefunct()) 1.154 + return false; 1.155 + 1.156 + EventStates state = mContent->AsElement()->State(); 1.157 + return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | 1.158 + NS_EVENT_STATE_UNVISITED); 1.159 +}