tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

HTMLLinkAccessible.cpp (4501B)


      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 "CacheConstants.h"
      9 #include "nsCoreUtils.h"
     10 #include "mozilla/a11y/Role.h"
     11 #include "States.h"
     12 
     13 #include "nsContentUtils.h"
     14 #include "nsIMutationObserver.h"
     15 #include "mozilla/a11y/DocAccessible.h"
     16 #include "mozilla/dom/Element.h"
     17 
     18 using namespace mozilla;
     19 using namespace mozilla::a11y;
     20 
     21 ////////////////////////////////////////////////////////////////////////////////
     22 // HTMLLinkAccessible
     23 ////////////////////////////////////////////////////////////////////////////////
     24 
     25 HTMLLinkAccessible::HTMLLinkAccessible(nsIContent* aContent,
     26                                       DocAccessible* aDoc)
     27    : HyperTextAccessible(aContent, aDoc) {
     28  mType = eHTMLLinkType;
     29 }
     30 
     31 ////////////////////////////////////////////////////////////////////////////////
     32 // nsIAccessible
     33 
     34 role HTMLLinkAccessible::NativeRole() const { return roles::LINK; }
     35 
     36 uint64_t HTMLLinkAccessible::NativeState() const {
     37  return HyperTextAccessible::NativeState() & ~states::READONLY;
     38 }
     39 
     40 uint64_t HTMLLinkAccessible::NativeLinkState() const {
     41  dom::ElementState state = mContent->AsElement()->State();
     42  if (state.HasState(dom::ElementState::UNVISITED)) {
     43    return states::LINKED;
     44  }
     45 
     46  if (state.HasState(dom::ElementState::VISITED)) {
     47    return states::LINKED | states::TRAVERSED;
     48  }
     49 
     50  // This is a either named anchor (a link with also a name attribute) or
     51  // it doesn't have any attributes. Check if 'click' event handler is
     52  // registered, otherwise bail out.
     53  return nsCoreUtils::HasClickListener(mContent) ? states::LINKED : 0;
     54 }
     55 
     56 uint64_t HTMLLinkAccessible::NativeInteractiveState() const {
     57  uint64_t state = HyperTextAccessible::NativeInteractiveState();
     58 
     59  // This is how we indicate it is a named anchor. In other words, this anchor
     60  // can be selected as a location :) There is no other better state to use to
     61  // indicate this.
     62  if (mContent->AsElement()->HasAttr(nsGkAtoms::name)) {
     63    state |= states::SELECTABLE;
     64  }
     65 
     66  return state;
     67 }
     68 
     69 void HTMLLinkAccessible::Value(nsString& aValue) const {
     70  aValue.Truncate();
     71 
     72  HyperTextAccessible::Value(aValue);
     73  if (aValue.IsEmpty()) {
     74    nsContentUtils::GetLinkLocation(mContent->AsElement(), aValue);
     75  }
     76 }
     77 
     78 bool HTMLLinkAccessible::HasPrimaryAction() const {
     79  return IsLinked() || HyperTextAccessible::HasPrimaryAction();
     80  ;
     81 }
     82 
     83 void HTMLLinkAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
     84  aName.Truncate();
     85 
     86  if (!IsLinked()) {
     87    HyperTextAccessible::ActionNameAt(aIndex, aName);
     88    return;
     89  }
     90 
     91  // Action 0 (default action): Jump to link
     92  if (aIndex == eAction_Jump) aName.AssignLiteral("jump");
     93 }
     94 
     95 bool HTMLLinkAccessible::AttributeChangesState(nsAtom* aAttribute) {
     96  return aAttribute == nsGkAtoms::href ||
     97         HyperTextAccessible::AttributeChangesState(aAttribute);
     98 }
     99 
    100 void HTMLLinkAccessible::DOMAttributeChanged(int32_t aNameSpaceID,
    101                                             nsAtom* aAttribute,
    102                                             AttrModType aModType,
    103                                             const nsAttrValue* aOldValue,
    104                                             uint64_t aOldState) {
    105  HyperTextAccessible::DOMAttributeChanged(aNameSpaceID, aAttribute, aModType,
    106                                           aOldValue, aOldState);
    107 
    108  if (aAttribute == nsGkAtoms::href && IsAdditionOrRemoval(aModType)) {
    109    mDoc->QueueCacheUpdate(this, CacheDomain::Actions);
    110  }
    111 }
    112 
    113 ENameValueFlag HTMLLinkAccessible::NativeName(nsString& aName) const {
    114  if (mContent->IsSVGElement()) {
    115    mContent->AsElement()->GetAttr(kNameSpaceID_XLink, nsGkAtoms::title, aName);
    116    if (!aName.IsEmpty()) {
    117      return eNameOK;
    118    }
    119  }
    120 
    121  return HyperTextAccessible::NativeName(aName);
    122 }
    123 
    124 ////////////////////////////////////////////////////////////////////////////////
    125 // HyperLinkAccessible
    126 
    127 bool HTMLLinkAccessible::IsLink() const {
    128  // Expose HyperLinkAccessible unconditionally.
    129  return true;
    130 }
    131 
    132 ////////////////////////////////////////////////////////////////////////////////
    133 // HTMLLinkAccessible
    134 
    135 bool HTMLLinkAccessible::IsLinked() const {
    136  dom::ElementState state = mContent->AsElement()->State();
    137  return state.HasAtLeastOneOfStates(dom::ElementState::VISITED_OR_UNVISITED);
    138 }