tor-browser

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

AccessibleNode.cpp (4665B)


      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 "AccessibleNode.h"
      7 #include "mozilla/dom/AccessibleNodeBinding.h"
      8 #include "mozilla/dom/BindingDeclarations.h"
      9 #include "mozilla/dom/DOMStringList.h"
     10 #include "mozilla/StaticPrefs_accessibility.h"
     11 #include "nsContentUtils.h"
     12 
     13 #include "LocalAccessible-inl.h"
     14 #include "nsAccessibilityService.h"
     15 #include "DocAccessible.h"
     16 
     17 #include "mozilla/dom/ToJSValue.h"
     18 
     19 using namespace mozilla;
     20 using namespace mozilla::a11y;
     21 using namespace mozilla::dom;
     22 
     23 bool AccessibleNode::IsAOMEnabled(JSContext* aCx, JSObject* /*unused*/) {
     24  return nsContentUtils::IsSystemCaller(aCx) ||
     25         StaticPrefs::accessibility_AOM_enabled();
     26 }
     27 
     28 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AccessibleNode, mRelationProperties,
     29                                      mIntl, mDOMNode, mStates)
     30 
     31 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AccessibleNode)
     32  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     33  NS_INTERFACE_MAP_ENTRY(nsISupports)
     34 NS_INTERFACE_MAP_END
     35 
     36 NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode)
     37 NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
     38 
     39 AccessibleNode::AccessibleNode(nsINode* aNode)
     40    : mDoubleProperties(3),
     41      mIntProperties(3),
     42      mUIntProperties(6),
     43      mBooleanProperties(0),
     44      mRelationProperties(3),
     45      mStringProperties(16),
     46      mDOMNode(aNode) {
     47  nsAccessibilityService* accService = GetOrCreateAccService();
     48  if (!accService) {
     49    return;
     50  }
     51 
     52  DocAccessible* doc = accService->GetDocAccessible(mDOMNode->OwnerDoc());
     53  if (doc) {
     54    mIntl = doc->GetAccessible(mDOMNode);
     55  }
     56 }
     57 
     58 AccessibleNode::~AccessibleNode() {}
     59 
     60 /* virtual */
     61 JSObject* AccessibleNode::WrapObject(JSContext* aCx,
     62                                     JS::Handle<JSObject*> aGivenProto) {
     63  return AccessibleNode_Binding::Wrap(aCx, this, aGivenProto);
     64 }
     65 
     66 /* virtual */
     67 ParentObject AccessibleNode::GetParentObject() const {
     68  return mDOMNode->GetParentObject();
     69 }
     70 
     71 void AccessibleNode::GetComputedRole(nsAString& aRole) {
     72  if (mIntl) {
     73    nsAccessibilityService* accService = GetOrCreateAccService();
     74    if (accService) {
     75      accService->GetStringRole(mIntl->Role(), aRole);
     76      return;
     77    }
     78  }
     79 
     80  aRole.AssignLiteral("unknown");
     81 }
     82 
     83 void AccessibleNode::GetStates(nsTArray<nsString>& aStates) {
     84  nsAccessibilityService* accService = GetOrCreateAccService();
     85  if (!mIntl || !accService) {
     86    aStates.AppendElement(u"defunct"_ns);
     87    return;
     88  }
     89 
     90  if (mStates) {
     91    aStates = mStates->StringArray().Clone();
     92    return;
     93  }
     94 
     95  mStates = accService->GetStringStates(mIntl->State());
     96  aStates = mStates->StringArray().Clone();
     97 }
     98 
     99 void AccessibleNode::GetAttributes(nsTArray<nsString>& aAttributes) {
    100  if (!mIntl) {
    101    return;
    102  }
    103 
    104  RefPtr<AccAttributes> attrs = mIntl->Attributes();
    105 
    106  for (const auto& iter : *attrs) {
    107    aAttributes.AppendElement(nsAtomString(iter.Name()));
    108  }
    109 }
    110 
    111 bool AccessibleNode::Is(const Sequence<nsString>& aFlavors) {
    112  nsAccessibilityService* accService = GetOrCreateAccService();
    113  if (!mIntl || !accService) {
    114    for (const auto& flavor : aFlavors) {
    115      if (!flavor.EqualsLiteral("unknown") &&
    116          !flavor.EqualsLiteral("defunct")) {
    117        return false;
    118      }
    119    }
    120    return true;
    121  }
    122 
    123  nsAutoString role;
    124  accService->GetStringRole(mIntl->Role(), role);
    125 
    126  if (!mStates) {
    127    mStates = accService->GetStringStates(mIntl->State());
    128  }
    129 
    130  for (const auto& flavor : aFlavors) {
    131    if (!flavor.Equals(role) && !mStates->Contains(flavor)) {
    132      return false;
    133    }
    134  }
    135  return true;
    136 }
    137 
    138 bool AccessibleNode::Has(const Sequence<nsString>& aAttributes) {
    139  if (!mIntl) {
    140    return false;
    141  }
    142  RefPtr<AccAttributes> attrs = mIntl->Attributes();
    143  for (const auto& attr : aAttributes) {
    144    RefPtr<nsAtom> attrAtom = NS_Atomize(attr);
    145    if (!attrs->HasAttribute(attrAtom)) {
    146      return false;
    147    }
    148  }
    149  return true;
    150 }
    151 
    152 void AccessibleNode::Get(JSContext* aCX, const nsAString& aAttribute,
    153                         JS::MutableHandle<JS::Value> aValue,
    154                         ErrorResult& aRv) {
    155  if (!mIntl) {
    156    aRv.ThrowInvalidStateError("No attributes available");
    157    return;
    158  }
    159 
    160  RefPtr<nsAtom> attrAtom = NS_Atomize(aAttribute);
    161  RefPtr<AccAttributes> attrs = mIntl->Attributes();
    162  nsAutoString valueStr;
    163  attrs->GetAttribute(attrAtom, valueStr);
    164  if (!ToJSValue(aCX, valueStr, aValue)) {
    165    aRv.NoteJSContextException(aCX);
    166    return;
    167  }
    168 }
    169 
    170 nsINode* AccessibleNode::GetDOMNode() { return mDOMNode; }