tor-browser

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

CachedTableAccessible.h (8807B)


      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 #ifndef CACHED_TABLE_ACCESSIBLE_H
      8 #define CACHED_TABLE_ACCESSIBLE_H
      9 
     10 #include "mozilla/a11y/TableAccessible.h"
     11 #include "mozilla/a11y/TableCellAccessible.h"
     12 #include "mozilla/UniquePtr.h"
     13 #include "nsTHashMap.h"
     14 
     15 namespace mozilla::a11y {
     16 
     17 const uint32_t kNoCellIdx = UINT32_MAX;
     18 
     19 class AccIterable;
     20 
     21 class CachedTableAccessible;
     22 
     23 class CachedTableCellAccessible final : public TableCellAccessible {
     24 public:
     25  static CachedTableCellAccessible* GetFrom(Accessible* aAcc);
     26 
     27  virtual TableAccessible* Table() const override;
     28 
     29  virtual uint32_t ColIdx() const override {
     30    return static_cast<int32_t>(mColIdx);
     31  }
     32 
     33  virtual uint32_t RowIdx() const override {
     34    return static_cast<int32_t>(mRowIdx);
     35  }
     36 
     37  virtual uint32_t ColExtent() const override;
     38 
     39  virtual uint32_t RowExtent() const override;
     40 
     41  virtual void ColHeaderCells(nsTArray<Accessible*>* aCells) override;
     42 
     43  virtual void RowHeaderCells(nsTArray<Accessible*>* aCells) override;
     44 
     45  virtual bool Selected() override;
     46 
     47 private:
     48  CachedTableCellAccessible(uint64_t aAccID, Accessible* aAcc, uint32_t aRowIdx,
     49                            uint32_t aColIdx, uint32_t aPrevColHeaderCellIdx)
     50      : mAccID(aAccID),
     51        mAcc(aAcc),
     52        mRowIdx(aRowIdx),
     53        mColIdx(aColIdx),
     54        mPrevColHeaderCellIdx(aPrevColHeaderCellIdx) {}
     55 
     56  // Get the Accessible for this table cell given its ancestor table Accessible,
     57  // verifying that the Accessible is valid.
     58  Accessible* Acc(Accessible* aTableAcc) const;
     59 
     60  UniquePtr<AccIterable> GetExplicitHeadersIterator();
     61 
     62  uint64_t mAccID;
     63  // CachedTableAccessible methods which fetch a cell should retrieve the
     64  // Accessible using Acc() rather than using mAcc. We need mAcc for some
     65  // methods because we can't fetch a document by id. It's okay to use mAcc in
     66  // these methods because the caller has to hold the Accessible in order to
     67  // call them.
     68  Accessible* mAcc;
     69  uint32_t mRowIdx;
     70  uint32_t mColIdx;
     71  // The cell index of the previous implicit column header.
     72  uint32_t mPrevColHeaderCellIdx;
     73  friend class CachedTableAccessible;
     74 };
     75 
     76 /**
     77 * TableAccessible implementation which builds and queries a cache.
     78 */
     79 class CachedTableAccessible final : public TableAccessible {
     80 public:
     81  static CachedTableAccessible* GetFrom(Accessible* aAcc);
     82 
     83  /**
     84   * This must be called whenever a table is destroyed or the structure of a
     85   * table changes; e.g. cells wer added or removed. It can be called with
     86   * either a table or a cell.
     87   */
     88  static void Invalidate(Accessible* aAcc);
     89 
     90  virtual Accessible* Caption() const override;
     91  virtual void Summary(nsString& aSummary) override;
     92 
     93  virtual uint32_t ColCount() const override { return mColCount; }
     94 
     95  virtual uint32_t RowCount() override { return mRowColToCellIdx.Length(); }
     96 
     97  virtual int32_t ColIndexAt(uint32_t aCellIdx) override {
     98    if (aCellIdx < mCells.Length()) {
     99      return static_cast<int32_t>(mCells[aCellIdx].mColIdx);
    100    }
    101    return -1;
    102  }
    103 
    104  virtual int32_t RowIndexAt(uint32_t aCellIdx) override {
    105    if (aCellIdx < mCells.Length()) {
    106      return static_cast<int32_t>(mCells[aCellIdx].mRowIdx);
    107    }
    108    return -1;
    109  }
    110 
    111  virtual void RowAndColIndicesAt(uint32_t aCellIdx, int32_t* aRowIdx,
    112                                  int32_t* aColIdx) override {
    113    if (aCellIdx < mCells.Length()) {
    114      CachedTableCellAccessible& cell = mCells[aCellIdx];
    115      *aRowIdx = static_cast<int32_t>(cell.mRowIdx);
    116      *aColIdx = static_cast<int32_t>(cell.mColIdx);
    117      return;
    118    }
    119    *aRowIdx = -1;
    120    *aColIdx = -1;
    121  }
    122 
    123  virtual uint32_t ColExtentAt(uint32_t aRowIdx, uint32_t aColIdx) override {
    124    int32_t cellIdx = CellIndexAt(aRowIdx, aColIdx);
    125    if (cellIdx == -1) {
    126      return 0;
    127    }
    128    // Verify that the cell's Accessible is valid.
    129    mCells[cellIdx].Acc(mAcc);
    130    return mCells[cellIdx].ColExtent();
    131  }
    132 
    133  virtual uint32_t RowExtentAt(uint32_t aRowIdx, uint32_t aColIdx) override {
    134    int32_t cellIdx = CellIndexAt(aRowIdx, aColIdx);
    135    if (cellIdx == -1) {
    136      return 0;
    137    }
    138    // Verify that the cell's Accessible is valid.
    139    mCells[cellIdx].Acc(mAcc);
    140    return mCells[cellIdx].RowExtent();
    141  }
    142 
    143  virtual int32_t CellIndexAt(uint32_t aRowIdx, uint32_t aColIdx) override {
    144    if (aRowIdx < mRowColToCellIdx.Length()) {
    145      auto& row = mRowColToCellIdx[aRowIdx];
    146      if (aColIdx < row.Length()) {
    147        uint32_t cellIdx = row[aColIdx];
    148        if (cellIdx != kNoCellIdx) {
    149          return static_cast<int32_t>(cellIdx);
    150        }
    151      }
    152    }
    153    return -1;
    154  }
    155 
    156  virtual Accessible* CellAt(uint32_t aRowIdx, uint32_t aColIdx) override;
    157 
    158  virtual bool IsColSelected(uint32_t aColIdx) override {
    159    bool selected = false;
    160    for (uint32_t row = 0; row < RowCount(); ++row) {
    161      selected = IsCellSelected(row, aColIdx);
    162      if (!selected) {
    163        break;
    164      }
    165    }
    166    return selected;
    167  }
    168 
    169  virtual bool IsRowSelected(uint32_t aRowIdx) override {
    170    bool selected = false;
    171    for (uint32_t col = 0; col < mColCount; ++col) {
    172      selected = IsCellSelected(aRowIdx, col);
    173      if (!selected) {
    174        break;
    175      }
    176    }
    177    return selected;
    178  }
    179 
    180  virtual bool IsCellSelected(uint32_t aRowIdx, uint32_t aColIdx) override {
    181    int32_t cellIdx = CellIndexAt(aRowIdx, aColIdx);
    182    if (cellIdx == -1) {
    183      return false;
    184    }
    185    // Verify that the cell's Accessible is valid.
    186    mCells[cellIdx].Acc(mAcc);
    187    return mCells[cellIdx].Selected();
    188  }
    189 
    190  virtual uint32_t SelectedCellCount() override {
    191    uint32_t count = 0;
    192    for (auto& cell : mCells) {
    193      // Verify that the cell's Accessible is valid.
    194      cell.Acc(mAcc);
    195      if (cell.Selected()) {
    196        ++count;
    197      }
    198    }
    199    return count;
    200  }
    201 
    202  virtual uint32_t SelectedColCount() override {
    203    uint32_t count = 0;
    204    for (uint32_t col = 0; col < mColCount; ++col) {
    205      if (IsColSelected(col)) {
    206        ++count;
    207      }
    208    }
    209    return count;
    210  }
    211 
    212  virtual uint32_t SelectedRowCount() override {
    213    uint32_t count = 0;
    214    for (uint32_t row = 0; row < RowCount(); ++row) {
    215      if (IsRowSelected(row)) {
    216        ++count;
    217      }
    218    }
    219    return count;
    220  }
    221 
    222  virtual void SelectedCells(nsTArray<Accessible*>* aCells) override {
    223    for (auto& cell : mCells) {
    224      // Verify that the cell's Accessible is valid.
    225      Accessible* acc = cell.Acc(mAcc);
    226      if (cell.Selected()) {
    227        aCells->AppendElement(acc);
    228      }
    229    }
    230  }
    231 
    232  virtual void SelectedCellIndices(nsTArray<uint32_t>* aCells) override {
    233    for (uint32_t idx = 0; idx < mCells.Length(); ++idx) {
    234      CachedTableCellAccessible& cell = mCells[idx];
    235      // Verify that the cell's Accessible is valid.
    236      cell.Acc(mAcc);
    237      if (cell.Selected()) {
    238        aCells->AppendElement(idx);
    239      }
    240    }
    241  }
    242 
    243  virtual void SelectedColIndices(nsTArray<uint32_t>* aCols) override {
    244    for (uint32_t col = 0; col < mColCount; ++col) {
    245      if (IsColSelected(col)) {
    246        aCols->AppendElement(col);
    247      }
    248    }
    249  }
    250 
    251  virtual void SelectedRowIndices(nsTArray<uint32_t>* aRows) override {
    252    for (uint32_t row = 0; row < RowCount(); ++row) {
    253      if (IsRowSelected(row)) {
    254        aRows->AppendElement(row);
    255      }
    256    }
    257  }
    258 
    259  virtual Accessible* AsAccessible() override { return mAcc; }
    260 
    261  virtual bool IsProbablyLayoutTable() override;
    262 
    263 private:
    264  explicit CachedTableAccessible(Accessible* aAcc);
    265 
    266  // Ensure that the given row exists in our data structure, creating array
    267  // elements as needed.
    268  void EnsureRow(uint32_t aRowIdx);
    269 
    270  // Ensure that the given row and column coordinate exists in our data
    271  // structure, creating array elements as needed. A newly created coordinate
    272  // will be set to kNoCellIdx.
    273  void EnsureRowCol(uint32_t aRowIdx, uint32_t aColIdx);
    274 
    275  Accessible* mAcc;  // The table Accessible.
    276  // We track the column count because it might not be uniform across rows in
    277  // malformed tables.
    278  uint32_t mColCount = 0;
    279  // An array of cell instances. A cell index is an index into this array.
    280  nsTArray<CachedTableCellAccessible> mCells;
    281  // Maps row and column coordinates to cell indices.
    282  nsTArray<nsTArray<uint32_t>> mRowColToCellIdx;
    283  // Maps Accessibles to cell indexes to facilitate retrieval of a cell
    284  // instance from a cell Accessible. The Accessible* keys should only be used
    285  // for lookup. They should not be dereferenced.
    286  nsTHashMap<Accessible*, uint32_t> mAccToCellIdx;
    287  uint64_t mCaptionAccID = 0;
    288 
    289  friend class CachedTableCellAccessible;
    290 };
    291 
    292 }  // namespace mozilla::a11y
    293 
    294 #endif