tor-browser

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

Platform.cpp (7925B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "Platform.h"
      8 #include "DocAccessibleWrap.h"
      9 #include "SessionAccessibility.h"
     10 #include "mozilla/a11y/RemoteAccessible.h"
     11 #include "mozilla/Components.h"
     12 #include "nsIAccessibleEvent.h"
     13 #include "nsIAccessiblePivot.h"
     14 #include "nsIStringBundle.h"
     15 #include "TextLeafRange.h"
     16 
     17 #define ROLE_STRINGS_URL "chrome://global/locale/AccessFu.properties"
     18 
     19 using namespace mozilla;
     20 using namespace mozilla::a11y;
     21 
     22 MOZ_RUNINIT static nsTHashMap<nsStringHashKey, nsString> sLocalizedStrings;
     23 
     24 void a11y::PlatformInit() {
     25  nsresult rv = NS_OK;
     26  nsCOMPtr<nsIStringBundleService> stringBundleService =
     27      components::StringBundle::Service();
     28  if (!stringBundleService) return;
     29 
     30  nsCOMPtr<nsIStringBundle> stringBundle;
     31  nsCOMPtr<nsIStringBundleService> sbs = components::StringBundle::Service();
     32  if (NS_FAILED(rv)) {
     33    NS_WARNING("Failed to get string bundle service");
     34    return;
     35  }
     36 
     37  rv = sbs->CreateBundle(ROLE_STRINGS_URL, getter_AddRefs(stringBundle));
     38  if (NS_FAILED(rv)) {
     39    NS_WARNING("Failed to get string bundle");
     40    return;
     41  }
     42 
     43  nsString localizedStr;
     44  // Preload the state required localized string.
     45  rv = stringBundle->GetStringFromName("stateRequired", localizedStr);
     46  if (NS_SUCCEEDED(rv)) {
     47    sLocalizedStrings.InsertOrUpdate(u"stateRequired"_ns, localizedStr);
     48  }
     49 
     50  // Preload heading level localized descriptions 1 thru 6.
     51  for (int32_t level = 1; level <= 6; level++) {
     52    nsAutoString token;
     53    token.AppendPrintf("heading-%d", level);
     54 
     55    nsAutoString formatString;
     56    formatString.AppendInt(level);
     57    AutoTArray<nsString, 1> formatParams;
     58    formatParams.AppendElement(formatString);
     59    rv = stringBundle->FormatStringFromName("headingLevel", formatParams,
     60                                            localizedStr);
     61    if (NS_SUCCEEDED(rv)) {
     62      sLocalizedStrings.InsertOrUpdate(token, localizedStr);
     63    }
     64  }
     65 
     66  // Preload any roles that have localized versions
     67 #define ROLE(geckoRole, stringRole, ariaRole, atkRole, macRole, macSubrole, \
     68             msaaRole, ia2Role, androidClass, iosIsElement, uiaControlType, \
     69             nameRule)                                                      \
     70  rv = stringBundle->GetStringFromName(stringRole, localizedStr);           \
     71  if (NS_SUCCEEDED(rv)) {                                                   \
     72    sLocalizedStrings.InsertOrUpdate(u##stringRole##_ns, localizedStr);     \
     73  }
     74 
     75 #include "RoleMap.h"
     76 #undef ROLE
     77 }
     78 
     79 void a11y::PlatformShutdown() { sLocalizedStrings.Clear(); }
     80 
     81 void a11y::ProxyCreated(RemoteAccessible* aProxy) {
     82  SessionAccessibility::RegisterAccessible(aProxy);
     83 }
     84 
     85 void a11y::ProxyDestroyed(RemoteAccessible* aProxy) {
     86  SessionAccessibility::UnregisterAccessible(aProxy);
     87 }
     88 
     89 void a11y::PlatformEvent(Accessible* aTarget, uint32_t aEventType) {
     90  RefPtr<SessionAccessibility> sessionAcc =
     91      SessionAccessibility::GetInstanceFor(aTarget);
     92  if (!sessionAcc) {
     93    return;
     94  }
     95 
     96  switch (aEventType) {
     97    case nsIAccessibleEvent::EVENT_REORDER:
     98      sessionAcc->SendWindowContentChangedEvent();
     99      break;
    100    case nsIAccessibleEvent::EVENT_SCROLLING_START:
    101      if (Accessible* result = AccessibleWrap::DoPivot(
    102              aTarget, java::SessionAccessibility::HTML_GRANULARITY_DEFAULT,
    103              true, true)) {
    104        sessionAcc->SendAccessibilityFocusedEvent(result, false);
    105      }
    106      break;
    107    default:
    108      break;
    109  }
    110 }
    111 
    112 void a11y::PlatformStateChangeEvent(Accessible* aTarget, uint64_t aState,
    113                                    bool aEnabled) {
    114  RefPtr<SessionAccessibility> sessionAcc =
    115      SessionAccessibility::GetInstanceFor(aTarget);
    116 
    117  if (!sessionAcc) {
    118    return;
    119  }
    120 
    121  if (aState & states::CHECKED) {
    122    sessionAcc->SendClickedEvent(
    123        aTarget, java::SessionAccessibility::FLAG_CHECKABLE |
    124                     (aEnabled ? java::SessionAccessibility::FLAG_CHECKED : 0));
    125  }
    126 
    127  if (aState & states::EXPANDED) {
    128    sessionAcc->SendClickedEvent(
    129        aTarget,
    130        java::SessionAccessibility::FLAG_EXPANDABLE |
    131            (aEnabled ? java::SessionAccessibility::FLAG_EXPANDED : 0));
    132  }
    133 
    134  if (aState & states::SELECTED) {
    135    sessionAcc->SendSelectedEvent(aTarget, aEnabled);
    136  }
    137 
    138  if (aState & states::BUSY) {
    139    sessionAcc->SendWindowStateChangedEvent(aTarget);
    140  }
    141 }
    142 
    143 void a11y::PlatformFocusEvent(Accessible* aTarget) {
    144  if (RefPtr<SessionAccessibility> sessionAcc =
    145          SessionAccessibility::GetInstanceFor(aTarget)) {
    146    sessionAcc->SendFocusEvent(aTarget);
    147  }
    148 }
    149 
    150 void a11y::PlatformCaretMoveEvent(Accessible* aTarget, int32_t aOffset,
    151                                  bool aIsSelectionCollapsed,
    152                                  int32_t aGranularity, bool aFromUser) {
    153  RefPtr<SessionAccessibility> sessionAcc =
    154      SessionAccessibility::GetInstanceFor(aTarget);
    155  if (!sessionAcc) {
    156    return;
    157  }
    158 
    159  if (!aTarget->IsDoc() && !aFromUser && !aIsSelectionCollapsed) {
    160    // Pivot to the caret's position if it has an expanded selection.
    161    // This is used mostly for find in page.
    162    Accessible* leaf = TextLeafPoint::GetCaret(aTarget).mAcc;
    163    MOZ_ASSERT(leaf);
    164    if (leaf) {
    165      if (Accessible* result = AccessibleWrap::DoPivot(
    166              leaf, java::SessionAccessibility::HTML_GRANULARITY_DEFAULT, true,
    167              true)) {
    168        sessionAcc->SendAccessibilityFocusedEvent(result, false);
    169      }
    170    }
    171  }
    172 
    173  sessionAcc->SendTextSelectionChangedEvent(aTarget, aOffset);
    174 }
    175 
    176 void a11y::PlatformTextChangeEvent(Accessible* aTarget, const nsAString& aStr,
    177                                   int32_t aStart, uint32_t aLen,
    178                                   bool aIsInsert, bool aFromUser) {
    179  RefPtr<SessionAccessibility> sessionAcc =
    180      SessionAccessibility::GetInstanceFor(aTarget);
    181 
    182  if (sessionAcc) {
    183    sessionAcc->SendTextChangedEvent(aTarget, aStr, aStart, aLen, aIsInsert,
    184                                     aFromUser);
    185  }
    186 }
    187 
    188 void a11y::PlatformShowHideEvent(Accessible* aTarget, Accessible* aParent,
    189                                 bool aInsert, bool aFromUser) {
    190  // We rely on the window content changed events to be dispatched
    191  // after the viewport cache is refreshed.
    192 }
    193 
    194 void a11y::PlatformSelectionEvent(Accessible*, Accessible*, uint32_t) {}
    195 
    196 void a11y::PlatformScrollingEvent(Accessible* aTarget, uint32_t aEventType,
    197                                  uint32_t aScrollX, uint32_t aScrollY,
    198                                  uint32_t aMaxScrollX, uint32_t aMaxScrollY) {
    199  if (aEventType == nsIAccessibleEvent::EVENT_SCROLLING) {
    200    RefPtr<SessionAccessibility> sessionAcc =
    201        SessionAccessibility::GetInstanceFor(aTarget);
    202 
    203    if (sessionAcc) {
    204      sessionAcc->SendScrollingEvent(aTarget, aScrollX, aScrollY, aMaxScrollX,
    205                                     aMaxScrollY);
    206    }
    207  }
    208 }
    209 
    210 void a11y::PlatformAnnouncementEvent(Accessible* aTarget,
    211                                     const nsAString& aAnnouncement,
    212                                     uint16_t aPriority) {
    213  RefPtr<SessionAccessibility> sessionAcc =
    214      SessionAccessibility::GetInstanceFor(aTarget);
    215 
    216  if (sessionAcc) {
    217    sessionAcc->SendAnnouncementEvent(aTarget, aAnnouncement, aPriority);
    218  }
    219 }
    220 
    221 bool a11y::LocalizeString(const nsAString& aToken, nsAString& aLocalized) {
    222  MOZ_ASSERT(XRE_IsParentProcess());
    223 
    224  auto str = sLocalizedStrings.Lookup(aToken);
    225  if (str) {
    226    aLocalized.Assign(*str);
    227  } else {
    228  }
    229 
    230  return !!str;
    231 }
    232 
    233 uint64_t a11y::GetCacheDomainsForKnownClients(uint64_t aCacheDomains) {
    234  (void)aCacheDomains;
    235  // XXX: Respond to clients such as TalkBack. For now, be safe and default to
    236  // caching all domains.
    237  return CacheDomain::All;
    238 }