Bug 1867925 - Mark some storage-access-api tests as intermittent after wpt-sync....
[gecko.git] / accessible / base / CachedTableAccessible.h
blob780334307020b874fcc02350f3a863c97224773b
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/. */
7 #ifndef CACHED_TABLE_ACCESSIBLE_H
8 #define CACHED_TABLE_ACCESSIBLE_H
10 #include "mozilla/a11y/TableAccessible.h"
11 #include "mozilla/a11y/TableCellAccessible.h"
12 #include "mozilla/UniquePtr.h"
13 #include "nsTHashMap.h"
15 namespace mozilla::a11y {
17 const uint32_t kNoCellIdx = UINT32_MAX;
19 class AccIterable;
21 class CachedTableAccessible;
23 class CachedTableCellAccessible final : public TableCellAccessible {
24 public:
25 static CachedTableCellAccessible* GetFrom(Accessible* aAcc);
27 virtual TableAccessible* Table() const override;
29 virtual uint32_t ColIdx() const override {
30 return static_cast<int32_t>(mColIdx);
33 virtual uint32_t RowIdx() const override {
34 return static_cast<int32_t>(mRowIdx);
37 virtual uint32_t ColExtent() const override;
39 virtual uint32_t RowExtent() const override;
41 virtual void ColHeaderCells(nsTArray<Accessible*>* aCells) override;
43 virtual void RowHeaderCells(nsTArray<Accessible*>* aCells) override;
45 virtual bool Selected() override;
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) {}
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;
60 UniquePtr<AccIterable> GetExplicitHeadersIterator();
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;
76 /**
77 * TableAccessible implementation which builds and queries a cache.
79 class CachedTableAccessible final : public TableAccessible {
80 public:
81 static CachedTableAccessible* GetFrom(Accessible* aAcc);
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.
88 static void Invalidate(Accessible* aAcc);
90 virtual Accessible* Caption() const override;
91 virtual void Summary(nsString& aSummary) override;
93 virtual uint32_t ColCount() const override { return mColCount; }
95 virtual uint32_t RowCount() override { return mRowColToCellIdx.Length(); }
97 virtual int32_t ColIndexAt(uint32_t aCellIdx) override {
98 if (aCellIdx < mCells.Length()) {
99 return static_cast<int32_t>(mCells[aCellIdx].mColIdx);
101 return -1;
104 virtual int32_t RowIndexAt(uint32_t aCellIdx) override {
105 if (aCellIdx < mCells.Length()) {
106 return static_cast<int32_t>(mCells[aCellIdx].mRowIdx);
108 return -1;
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;
119 *aRowIdx = -1;
120 *aColIdx = -1;
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;
128 // Verify that the cell's Accessible is valid.
129 mCells[cellIdx].Acc(mAcc);
130 return mCells[cellIdx].ColExtent();
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;
138 // Verify that the cell's Accessible is valid.
139 mCells[cellIdx].Acc(mAcc);
140 return mCells[cellIdx].RowExtent();
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);
153 return -1;
156 virtual Accessible* CellAt(uint32_t aRowIdx, uint32_t aColIdx) override;
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;
166 return selected;
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;
177 return selected;
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;
185 // Verify that the cell's Accessible is valid.
186 mCells[cellIdx].Acc(mAcc);
187 return mCells[cellIdx].Selected();
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;
199 return count;
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;
209 return count;
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;
219 return count;
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);
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);
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);
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);
259 virtual Accessible* AsAccessible() override { return mAcc; }
261 virtual bool IsProbablyLayoutTable() override;
263 private:
264 explicit CachedTableAccessible(Accessible* aAcc);
266 // Ensure that the given row exists in our data structure, creating array
267 // elements as needed.
268 void EnsureRow(uint32_t aRowIdx);
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);
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;
289 friend class CachedTableCellAccessible;
292 } // namespace mozilla::a11y
294 #endif