tor-browser

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

UiaGrid.cpp (3957B)


      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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "ia2AccessibleTable.h"
      8 #include "mozilla/a11y/TableAccessible.h"
      9 #include "nsIAccessiblePivot.h"
     10 #include "Pivot.h"
     11 #include "UiaGrid.h"
     12 
     13 using namespace mozilla;
     14 using namespace mozilla::a11y;
     15 
     16 // Helpers
     17 
     18 // Used to search for all row and column headers in a table. This could be slow,
     19 // as it potentially walks all cells in the table. However, it's unclear if,
     20 // when or how often clients will use this. If this proves to be a performance
     21 // problem, we will need to add methods to TableAccessible to get all row and
     22 // column headers in a faster way.
     23 class HeaderRule : public PivotRule {
     24 public:
     25  explicit HeaderRule(role aRole) : mRole(aRole) {}
     26 
     27  virtual uint16_t Match(Accessible* aAcc) override {
     28    role accRole = aAcc->Role();
     29    if (accRole == mRole) {
     30      return nsIAccessibleTraversalRule::FILTER_MATCH |
     31             nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
     32    }
     33    if (accRole == roles::CAPTION || aAcc->IsTableCell()) {
     34      return nsIAccessibleTraversalRule::FILTER_IGNORE |
     35             nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
     36    }
     37    return nsIAccessibleTraversalRule::FILTER_IGNORE;
     38  }
     39 
     40 private:
     41  role mRole;
     42 };
     43 
     44 static SAFEARRAY* GetAllHeaders(Accessible* aTable, role aRole) {
     45  AutoTArray<Accessible*, 20> headers;
     46  Pivot pivot(aTable);
     47  HeaderRule rule(aRole);
     48  for (Accessible* header = pivot.Next(aTable, rule); header;
     49       header = pivot.Next(header, rule)) {
     50    headers.AppendElement(header);
     51  }
     52  return AccessibleArrayToUiaArray(headers);
     53 }
     54 
     55 // UiaGrid
     56 
     57 Accessible* UiaGrid::Acc() {
     58  auto* ia2t = static_cast<ia2AccessibleTable*>(this);
     59  return ia2t->MsaaAccessible::Acc();
     60 }
     61 
     62 TableAccessible* UiaGrid::TableAcc() {
     63  Accessible* acc = Acc();
     64  return acc ? acc->AsTable() : nullptr;
     65 }
     66 
     67 // IGridProvider methods
     68 
     69 STDMETHODIMP
     70 UiaGrid::GetItem(int aRow, int aColumn,
     71                 __RPC__deref_out_opt IRawElementProviderSimple** aRetVal) {
     72  if (!aRetVal) {
     73    return E_INVALIDARG;
     74  }
     75  *aRetVal = nullptr;
     76  TableAccessible* table = TableAcc();
     77  if (!table) {
     78    return CO_E_OBJNOTCONNECTED;
     79  }
     80  Accessible* cell = table->CellAt(aRow, aColumn);
     81  if (!cell) {
     82    return E_INVALIDARG;
     83  }
     84  RefPtr<IRawElementProviderSimple> uia = MsaaAccessible::GetFrom(cell);
     85  uia.forget(aRetVal);
     86  return S_OK;
     87 }
     88 
     89 STDMETHODIMP
     90 UiaGrid::get_RowCount(__RPC__out int* aRetVal) {
     91  if (!aRetVal) {
     92    return E_INVALIDARG;
     93  }
     94  TableAccessible* table = TableAcc();
     95  if (!table) {
     96    return CO_E_OBJNOTCONNECTED;
     97  }
     98  *aRetVal = table->RowCount();
     99  return S_OK;
    100 }
    101 
    102 STDMETHODIMP
    103 UiaGrid::get_ColumnCount(__RPC__out int* aRetVal) {
    104  if (!aRetVal) {
    105    return E_INVALIDARG;
    106  }
    107  TableAccessible* table = TableAcc();
    108  if (!table) {
    109    return CO_E_OBJNOTCONNECTED;
    110  }
    111  *aRetVal = table->ColCount();
    112  return S_OK;
    113 }
    114 
    115 // ITableProvider methods
    116 
    117 STDMETHODIMP
    118 UiaGrid::GetRowHeaders(__RPC__deref_out_opt SAFEARRAY** aRetVal) {
    119  if (!aRetVal) {
    120    return E_INVALIDARG;
    121  }
    122  Accessible* acc = Acc();
    123  if (!acc) {
    124    return CO_E_OBJNOTCONNECTED;
    125  }
    126  *aRetVal = GetAllHeaders(acc, roles::ROWHEADER);
    127  return S_OK;
    128 }
    129 
    130 STDMETHODIMP
    131 UiaGrid::GetColumnHeaders(__RPC__deref_out_opt SAFEARRAY** aRetVal) {
    132  if (!aRetVal) {
    133    return E_INVALIDARG;
    134  }
    135  Accessible* acc = Acc();
    136  if (!acc) {
    137    return CO_E_OBJNOTCONNECTED;
    138  }
    139  *aRetVal = GetAllHeaders(acc, roles::COLUMNHEADER);
    140  return S_OK;
    141 }
    142 
    143 STDMETHODIMP
    144 UiaGrid::get_RowOrColumnMajor(__RPC__out enum RowOrColumnMajor* aRetVal) {
    145  if (!aRetVal) {
    146    return E_INVALIDARG;
    147  }
    148  // HTML and ARIA tables are always in row major order.
    149  *aRetVal = RowOrColumnMajor_RowMajor;
    150  return S_OK;
    151 }