tor-browser

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

XULElementAccessibles.cpp (6667B)


      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 "XULElementAccessibles.h"
      7 
      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"
     18 
     19 #ifdef A11Y_LOG
     20 #  include "Logging.h"
     21 #endif
     22 
     23 #include "nsNameSpaceManager.h"
     24 #include "nsNetUtil.h"
     25 #include "nsString.h"
     26 #include "nsXULElement.h"
     27 
     28 using namespace mozilla::a11y;
     29 
     30 ////////////////////////////////////////////////////////////////////////////////
     31 // XULLabelAccessible
     32 ////////////////////////////////////////////////////////////////////////////////
     33 
     34 XULLabelAccessible::XULLabelAccessible(nsIContent* aContent,
     35                                       DocAccessible* aDoc)
     36    : HyperTextAccessible(aContent, aDoc) {
     37  mType = eXULLabelType;
     38 }
     39 
     40 void XULLabelAccessible::Shutdown() {
     41  mValueTextLeaf = nullptr;
     42  HyperTextAccessible::Shutdown();
     43 }
     44 
     45 void XULLabelAccessible::DispatchClickEvent(uint32_t aActionIndex) const {
     46  // Bug 1578140: For labels inside buttons, The base implementation of
     47  // DispatchClickEvent doesn't fire a command event on the button.
     48  RefPtr<nsXULElement> el = nsXULElement::FromNodeOrNull(mContent);
     49  if (el) {
     50    el->Click(mozilla::dom::CallerType::System);
     51  }
     52 }
     53 
     54 ENameValueFlag XULLabelAccessible::NativeName(nsString& aName) const {
     55  // if the value attr doesn't exist, the screen reader must get the accessible
     56  // text from the accessible text interface or from the children
     57  if (mValueTextLeaf) return mValueTextLeaf->Name(aName);
     58 
     59  return LocalAccessible::NativeName(aName);
     60 }
     61 
     62 role XULLabelAccessible::NativeRole() const { return roles::LABEL; }
     63 
     64 uint64_t XULLabelAccessible::NativeState() const {
     65  // Labels and description have read only state
     66  // They are not focusable or selectable
     67  return HyperTextAccessible::NativeState() | states::READONLY;
     68 }
     69 
     70 Relation XULLabelAccessible::RelationByType(RelationType aType) const {
     71  Relation rel = HyperTextAccessible::RelationByType(aType);
     72 
     73  // The label for xul:groupbox is generated from the first xul:label
     74  if (aType == RelationType::LABEL_FOR) {
     75    LocalAccessible* parent = LocalParent();
     76    if (parent && parent->Role() == roles::GROUPING &&
     77        parent->LocalChildAt(0) == this) {
     78      nsIContent* parentContent = parent->GetContent();
     79      if (parentContent && parentContent->IsXULElement(nsGkAtoms::groupbox)) {
     80        rel.AppendTarget(parent);
     81      }
     82    }
     83  }
     84 
     85  return rel;
     86 }
     87 
     88 void XULLabelAccessible::UpdateLabelValue(const nsString& aValue) {
     89 #ifdef A11Y_LOG
     90  if (logging::IsEnabled(logging::eText)) {
     91    logging::MsgBegin("TEXT", "text may be changed (xul:label @value update)");
     92    logging::Node("container", mContent);
     93    logging::MsgEntry("old text '%s'",
     94                      NS_ConvertUTF16toUTF8(mValueTextLeaf->Text()).get());
     95    logging::MsgEntry("new text: '%s'", NS_ConvertUTF16toUTF8(aValue).get());
     96    logging::MsgEnd();
     97  }
     98 #endif
     99 
    100  TextUpdater::Run(mDoc, mValueTextLeaf, aValue);
    101 }
    102 
    103 ////////////////////////////////////////////////////////////////////////////////
    104 // XULLabelTextLeafAccessible
    105 ////////////////////////////////////////////////////////////////////////////////
    106 
    107 role XULLabelTextLeafAccessible::NativeRole() const { return roles::TEXT_LEAF; }
    108 
    109 uint64_t XULLabelTextLeafAccessible::NativeState() const {
    110  return TextLeafAccessible::NativeState() | states::READONLY;
    111 }
    112 
    113 ////////////////////////////////////////////////////////////////////////////////
    114 // XULTooltipAccessible
    115 ////////////////////////////////////////////////////////////////////////////////
    116 
    117 XULTooltipAccessible::XULTooltipAccessible(nsIContent* aContent,
    118                                           DocAccessible* aDoc)
    119    : LeafAccessible(aContent, aDoc) {
    120  mType = eXULTooltipType;
    121 }
    122 
    123 uint64_t XULTooltipAccessible::NativeState() const {
    124  return LeafAccessible::NativeState() | states::READONLY;
    125 }
    126 
    127 role XULTooltipAccessible::NativeRole() const { return roles::TOOLTIP; }
    128 
    129 ////////////////////////////////////////////////////////////////////////////////
    130 // XULLinkAccessible
    131 ////////////////////////////////////////////////////////////////////////////////
    132 
    133 XULLinkAccessible::XULLinkAccessible(nsIContent* aContent, DocAccessible* aDoc)
    134    : XULLabelAccessible(aContent, aDoc) {}
    135 
    136 XULLinkAccessible::~XULLinkAccessible() {}
    137 
    138 ////////////////////////////////////////////////////////////////////////////////
    139 // XULLinkAccessible: LocalAccessible
    140 
    141 void XULLinkAccessible::Value(nsString& aValue) const {
    142  aValue.Truncate();
    143 
    144  mContent->AsElement()->GetAttr(nsGkAtoms::href, aValue);
    145 }
    146 
    147 ENameValueFlag XULLinkAccessible::NativeName(nsString& aName) const {
    148  mContent->AsElement()->GetAttr(nsGkAtoms::value, aName);
    149  return eNameOK;
    150 }
    151 
    152 role XULLinkAccessible::NativeRole() const { return roles::LINK; }
    153 
    154 uint64_t XULLinkAccessible::NativeLinkState() const { return states::LINKED; }
    155 
    156 bool XULLinkAccessible::HasPrimaryAction() const { return true; }
    157 
    158 void XULLinkAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
    159  aName.Truncate();
    160 
    161  if (aIndex == eAction_Jump) aName.AssignLiteral("jump");
    162 }
    163 
    164 ////////////////////////////////////////////////////////////////////////////////
    165 // XULLinkAccessible: HyperLinkAccessible
    166 
    167 bool XULLinkAccessible::IsLink() const {
    168  // Expose HyperLinkAccessible unconditionally.
    169  return true;
    170 }
    171 
    172 uint32_t XULLinkAccessible::StartOffset() {
    173  // If XUL link accessible is not contained by hypertext accessible then
    174  // start offset matches index in parent because the parent doesn't contains
    175  // a text.
    176  // XXX: accessible parent of XUL link accessible should be a hypertext
    177  // accessible.
    178  if (LocalAccessible::IsLink()) return LocalAccessible::StartOffset();
    179  return IndexInParent();
    180 }
    181 
    182 uint32_t XULLinkAccessible::EndOffset() {
    183  if (LocalAccessible::IsLink()) return LocalAccessible::EndOffset();
    184  return IndexInParent() + 1;
    185 }
    186 
    187 already_AddRefed<nsIURI> XULLinkAccessible::AnchorURIAt(
    188    uint32_t aAnchorIndex) const {
    189  if (aAnchorIndex != 0) return nullptr;
    190 
    191  nsAutoString href;
    192  mContent->AsElement()->GetAttr(nsGkAtoms::href, href);
    193 
    194  dom::Document* document = mContent->OwnerDoc();
    195 
    196  nsCOMPtr<nsIURI> anchorURI;
    197  NS_NewURI(getter_AddRefs(anchorURI), href,
    198            document->GetDocumentCharacterSet(), mContent->GetBaseURI());
    199 
    200  return anchorURI.forget();
    201 }