tor-browser

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

ia2AccessibleTable.cpp (14746B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:expandtab:shiftwidth=2:tabstop=2:
      3 */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "ia2AccessibleTable.h"
      9 
     10 #include "Accessible2.h"
     11 #include "AccessibleTable_i.c"
     12 #include "AccessibleTable2_i.c"
     13 
     14 #include "IUnknownImpl.h"
     15 #include "mozilla/a11y/Accessible.h"
     16 #include "mozilla/a11y/TableAccessible.h"
     17 #include "nsCOMPtr.h"
     18 #include "nsString.h"
     19 
     20 using namespace mozilla::a11y;
     21 
     22 TableAccessible* ia2AccessibleTable::TableAcc() {
     23  Accessible* acc = MsaaAccessible::Acc();
     24  return acc ? acc->AsTable() : nullptr;
     25 }
     26 
     27 // IUnknown
     28 
     29 STDMETHODIMP
     30 ia2AccessibleTable::QueryInterface(REFIID iid, void** ppv) {
     31  if (!ppv) return E_INVALIDARG;
     32 
     33  *ppv = nullptr;
     34 
     35  if (IID_IAccessibleTable == iid) {
     36    *ppv = static_cast<IAccessibleTable*>(this);
     37    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     38    return S_OK;
     39  }
     40 
     41  if (IID_IAccessibleTable2 == iid) {
     42    *ppv = static_cast<IAccessibleTable2*>(this);
     43    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     44    return S_OK;
     45  }
     46 
     47  if (IID_IGridProvider == iid) {
     48    *ppv = static_cast<IGridProvider*>(this);
     49    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     50    return S_OK;
     51  }
     52 
     53  if (IID_ITableProvider == iid) {
     54    *ppv = static_cast<ITableProvider*>(this);
     55    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     56    return S_OK;
     57  }
     58 
     59  return ia2AccessibleHypertext::QueryInterface(iid, ppv);
     60 }
     61 
     62 ////////////////////////////////////////////////////////////////////////////////
     63 // IAccessibleTable
     64 
     65 STDMETHODIMP
     66 ia2AccessibleTable::get_accessibleAt(long aRowIdx, long aColIdx,
     67                                     IUnknown** aAccessible) {
     68  return get_cellAt(aRowIdx, aColIdx, aAccessible);
     69 }
     70 
     71 STDMETHODIMP
     72 ia2AccessibleTable::get_caption(IUnknown** aAccessible) {
     73  if (!aAccessible) return E_INVALIDARG;
     74 
     75  *aAccessible = nullptr;
     76  TableAccessible* table = TableAcc();
     77  if (!table) return CO_E_OBJNOTCONNECTED;
     78 
     79  Accessible* caption = table->Caption();
     80  if (!caption) return S_FALSE;
     81 
     82  RefPtr<IAccessible> result = MsaaAccessible::GetFrom(caption);
     83  result.forget(aAccessible);
     84  return S_OK;
     85 }
     86 
     87 STDMETHODIMP
     88 ia2AccessibleTable::get_childIndex(long aRowIdx, long aColIdx,
     89                                   long* aChildIdx) {
     90  if (!aChildIdx) return E_INVALIDARG;
     91 
     92  *aChildIdx = 0;
     93  TableAccessible* table = TableAcc();
     94  if (!table) return CO_E_OBJNOTCONNECTED;
     95 
     96  if (aRowIdx < 0 || aColIdx < 0 ||
     97      static_cast<uint32_t>(aRowIdx) >= table->RowCount() ||
     98      static_cast<uint32_t>(aColIdx) >= table->ColCount())
     99    return E_INVALIDARG;
    100 
    101  *aChildIdx = table->CellIndexAt(aRowIdx, aColIdx);
    102  return S_OK;
    103 }
    104 
    105 STDMETHODIMP
    106 ia2AccessibleTable::get_columnDescription(long aColIdx, BSTR* aDescription) {
    107  if (!aDescription) return E_INVALIDARG;
    108 
    109  *aDescription = nullptr;
    110  TableAccessible* table = TableAcc();
    111  if (!table) return CO_E_OBJNOTCONNECTED;
    112 
    113  if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= table->ColCount())
    114    return E_INVALIDARG;
    115 
    116  nsAutoString descr;
    117  table->ColDescription(aColIdx, descr);
    118  if (descr.IsEmpty()) return S_FALSE;
    119 
    120  *aDescription = ::SysAllocStringLen(descr.get(), descr.Length());
    121  return *aDescription ? S_OK : E_OUTOFMEMORY;
    122 }
    123 
    124 STDMETHODIMP
    125 ia2AccessibleTable::get_columnExtentAt(long aRowIdx, long aColIdx,
    126                                       long* aSpan) {
    127  if (!aSpan) return E_INVALIDARG;
    128 
    129  *aSpan = 0;
    130  TableAccessible* table = TableAcc();
    131  if (!table) return CO_E_OBJNOTCONNECTED;
    132 
    133  if (aRowIdx < 0 || aColIdx < 0 ||
    134      static_cast<uint32_t>(aRowIdx) >= table->RowCount() ||
    135      static_cast<uint32_t>(aColIdx) >= table->ColCount())
    136    return E_INVALIDARG;
    137 
    138  *aSpan = table->ColExtentAt(aRowIdx, aColIdx);
    139  return S_OK;
    140 }
    141 
    142 STDMETHODIMP
    143 ia2AccessibleTable::get_columnHeader(IAccessibleTable** aAccessibleTable,
    144                                     long* aStartingRowIndex) {
    145  if (!aAccessibleTable || !aStartingRowIndex) return E_INVALIDARG;
    146 
    147  *aAccessibleTable = nullptr;
    148  *aStartingRowIndex = -1;
    149  return E_NOTIMPL;
    150 }
    151 
    152 STDMETHODIMP
    153 ia2AccessibleTable::get_columnIndex(long aCellIdx, long* aColIdx) {
    154  if (!aColIdx) return E_INVALIDARG;
    155 
    156  *aColIdx = 0;
    157  TableAccessible* table = TableAcc();
    158  if (!table) return CO_E_OBJNOTCONNECTED;
    159 
    160  if (aCellIdx < 0) {
    161    return E_INVALIDARG;
    162  }
    163 
    164  long colIdx = table->ColIndexAt(aCellIdx);
    165  if (colIdx == -1) {  // Indicates an error.
    166    return E_INVALIDARG;
    167  }
    168 
    169  *aColIdx = colIdx;
    170  return S_OK;
    171 }
    172 
    173 STDMETHODIMP
    174 ia2AccessibleTable::get_nColumns(long* aColCount) {
    175  if (!aColCount) return E_INVALIDARG;
    176 
    177  *aColCount = 0;
    178  TableAccessible* table = TableAcc();
    179  if (!table) return CO_E_OBJNOTCONNECTED;
    180 
    181  *aColCount = table->ColCount();
    182  return S_OK;
    183 }
    184 
    185 STDMETHODIMP
    186 ia2AccessibleTable::get_nRows(long* aRowCount) {
    187  if (!aRowCount) return E_INVALIDARG;
    188 
    189  *aRowCount = 0;
    190  TableAccessible* table = TableAcc();
    191  if (!table) return CO_E_OBJNOTCONNECTED;
    192 
    193  *aRowCount = table->RowCount();
    194  return S_OK;
    195 }
    196 
    197 STDMETHODIMP
    198 ia2AccessibleTable::get_nSelectedChildren(long* aChildCount) {
    199  return get_nSelectedCells(aChildCount);
    200 }
    201 
    202 STDMETHODIMP
    203 ia2AccessibleTable::get_nSelectedColumns(long* aColCount) {
    204  if (!aColCount) return E_INVALIDARG;
    205 
    206  *aColCount = 0;
    207  TableAccessible* table = TableAcc();
    208  if (!table) return CO_E_OBJNOTCONNECTED;
    209 
    210  *aColCount = table->SelectedColCount();
    211  return S_OK;
    212 }
    213 
    214 STDMETHODIMP
    215 ia2AccessibleTable::get_nSelectedRows(long* aRowCount) {
    216  if (!aRowCount) return E_INVALIDARG;
    217 
    218  *aRowCount = 0;
    219  TableAccessible* table = TableAcc();
    220  if (!table) return CO_E_OBJNOTCONNECTED;
    221 
    222  *aRowCount = table->SelectedRowCount();
    223 
    224  return S_OK;
    225 }
    226 
    227 STDMETHODIMP
    228 ia2AccessibleTable::get_rowDescription(long aRowIdx, BSTR* aDescription) {
    229  if (!aDescription) return E_INVALIDARG;
    230 
    231  *aDescription = nullptr;
    232  TableAccessible* table = TableAcc();
    233  if (!table) return CO_E_OBJNOTCONNECTED;
    234 
    235  if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= table->RowCount())
    236    return E_INVALIDARG;
    237 
    238  nsAutoString descr;
    239  table->RowDescription(aRowIdx, descr);
    240  if (descr.IsEmpty()) return S_FALSE;
    241 
    242  *aDescription = ::SysAllocStringLen(descr.get(), descr.Length());
    243  return *aDescription ? S_OK : E_OUTOFMEMORY;
    244 }
    245 
    246 STDMETHODIMP
    247 ia2AccessibleTable::get_rowExtentAt(long aRowIdx, long aColIdx, long* aSpan) {
    248  if (!aSpan) return E_INVALIDARG;
    249 
    250  *aSpan = 0;
    251  TableAccessible* table = TableAcc();
    252  if (!table) return CO_E_OBJNOTCONNECTED;
    253 
    254  if (aRowIdx < 0 || aColIdx < 0 ||
    255      static_cast<uint32_t>(aRowIdx) >= table->RowCount() ||
    256      static_cast<uint32_t>(aColIdx) >= table->ColCount())
    257    return E_INVALIDARG;
    258 
    259  *aSpan = table->RowExtentAt(aRowIdx, aColIdx);
    260  return S_OK;
    261 }
    262 
    263 STDMETHODIMP
    264 ia2AccessibleTable::get_rowHeader(IAccessibleTable** aAccessibleTable,
    265                                  long* aStartingColumnIndex) {
    266  if (!aAccessibleTable || !aStartingColumnIndex) return E_INVALIDARG;
    267 
    268  *aAccessibleTable = nullptr;
    269  *aStartingColumnIndex = -1;
    270  return E_NOTIMPL;
    271 }
    272 
    273 STDMETHODIMP
    274 ia2AccessibleTable::get_rowIndex(long aCellIdx, long* aRowIdx) {
    275  if (!aRowIdx) return E_INVALIDARG;
    276 
    277  *aRowIdx = 0;
    278  TableAccessible* table = TableAcc();
    279  if (!table) return CO_E_OBJNOTCONNECTED;
    280 
    281  if (aCellIdx < 0) {
    282    return E_INVALIDARG;
    283  }
    284 
    285  long rowIdx = table->RowIndexAt(aCellIdx);
    286  if (rowIdx == -1) {  // Indicates an error.
    287    return E_INVALIDARG;
    288  }
    289 
    290  *aRowIdx = rowIdx;
    291  return S_OK;
    292 }
    293 
    294 STDMETHODIMP
    295 ia2AccessibleTable::get_selectedChildren(long aMaxChildren, long** aChildren,
    296                                         long* aNChildren) {
    297  if (!aChildren || !aNChildren) return E_INVALIDARG;
    298 
    299  *aChildren = nullptr;
    300  *aNChildren = 0;
    301  TableAccessible* table = TableAcc();
    302  if (!table) return CO_E_OBJNOTCONNECTED;
    303 
    304  AutoTArray<uint32_t, 30> cellIndices;
    305  table->SelectedCellIndices(&cellIndices);
    306 
    307  uint32_t maxCells = cellIndices.Length();
    308  if (maxCells == 0) return S_FALSE;
    309 
    310  *aChildren = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxCells));
    311  *aNChildren = maxCells;
    312  for (uint32_t i = 0; i < maxCells; i++) (*aChildren)[i] = cellIndices[i];
    313 
    314  return S_OK;
    315 }
    316 
    317 STDMETHODIMP
    318 ia2AccessibleTable::get_selectedColumns(long aMaxColumns, long** aColumns,
    319                                        long* aNColumns) {
    320  return get_selectedColumns(aColumns, aNColumns);
    321 }
    322 
    323 STDMETHODIMP
    324 ia2AccessibleTable::get_selectedRows(long aMaxRows, long** aRows,
    325                                     long* aNRows) {
    326  return get_selectedRows(aRows, aNRows);
    327 }
    328 
    329 STDMETHODIMP
    330 ia2AccessibleTable::get_summary(IUnknown** aAccessible) {
    331  if (!aAccessible) return E_INVALIDARG;
    332 
    333  // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
    334  // link an accessible object to specify a summary. There is closes method
    335  // in Table::summary to get a summary as a string which is not mapped
    336  // directly to IAccessible2.
    337 
    338  *aAccessible = nullptr;
    339  return S_FALSE;
    340 }
    341 
    342 STDMETHODIMP
    343 ia2AccessibleTable::get_isColumnSelected(long aColIdx, boolean* aIsSelected) {
    344  if (!aIsSelected) return E_INVALIDARG;
    345 
    346  *aIsSelected = false;
    347  TableAccessible* table = TableAcc();
    348  if (!table) return CO_E_OBJNOTCONNECTED;
    349 
    350  if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= table->ColCount())
    351    return E_INVALIDARG;
    352 
    353  *aIsSelected = table->IsColSelected(aColIdx);
    354  return S_OK;
    355 }
    356 
    357 STDMETHODIMP
    358 ia2AccessibleTable::get_isRowSelected(long aRowIdx, boolean* aIsSelected) {
    359  if (!aIsSelected) return E_INVALIDARG;
    360 
    361  *aIsSelected = false;
    362  TableAccessible* table = TableAcc();
    363  if (!table) return CO_E_OBJNOTCONNECTED;
    364 
    365  if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= table->RowCount())
    366    return E_INVALIDARG;
    367 
    368  *aIsSelected = table->IsRowSelected(aRowIdx);
    369  return S_OK;
    370 }
    371 
    372 STDMETHODIMP
    373 ia2AccessibleTable::get_isSelected(long aRowIdx, long aColIdx,
    374                                   boolean* aIsSelected) {
    375  if (!aIsSelected) return E_INVALIDARG;
    376 
    377  *aIsSelected = false;
    378  TableAccessible* table = TableAcc();
    379  if (!table) return CO_E_OBJNOTCONNECTED;
    380 
    381  if (aRowIdx < 0 || aColIdx < 0 ||
    382      static_cast<uint32_t>(aColIdx) >= table->ColCount() ||
    383      static_cast<uint32_t>(aRowIdx) >= table->RowCount())
    384    return E_INVALIDARG;
    385 
    386  *aIsSelected = table->IsCellSelected(aRowIdx, aColIdx);
    387  return S_OK;
    388 }
    389 
    390 STDMETHODIMP
    391 ia2AccessibleTable::selectRow(long aRowIdx) { return E_NOTIMPL; }
    392 
    393 STDMETHODIMP
    394 ia2AccessibleTable::selectColumn(long aColIdx) { return E_NOTIMPL; }
    395 
    396 STDMETHODIMP
    397 ia2AccessibleTable::unselectRow(long aRowIdx) { return E_NOTIMPL; }
    398 
    399 STDMETHODIMP
    400 ia2AccessibleTable::unselectColumn(long aColIdx) { return E_NOTIMPL; }
    401 
    402 STDMETHODIMP
    403 ia2AccessibleTable::get_rowColumnExtentsAtIndex(long aCellIdx, long* aRowIdx,
    404                                                long* aColIdx,
    405                                                long* aRowExtents,
    406                                                long* aColExtents,
    407                                                boolean* aIsSelected) {
    408  if (!aRowIdx || !aColIdx || !aRowExtents || !aColExtents || !aIsSelected)
    409    return E_INVALIDARG;
    410 
    411  *aRowIdx = 0;
    412  *aColIdx = 0;
    413  *aRowExtents = 0;
    414  *aColExtents = 0;
    415  *aIsSelected = false;
    416  TableAccessible* table = TableAcc();
    417  if (!table) return CO_E_OBJNOTCONNECTED;
    418 
    419  if (aCellIdx < 0) {
    420    return E_INVALIDARG;
    421  }
    422 
    423  int32_t colIdx = 0, rowIdx = 0;
    424  table->RowAndColIndicesAt(aCellIdx, &rowIdx, &colIdx);
    425  if (rowIdx == -1 || colIdx == -1) {  // Indicates an error.
    426    return E_INVALIDARG;
    427  }
    428 
    429  *aRowIdx = rowIdx;
    430  *aColIdx = colIdx;
    431  *aRowExtents = table->RowExtentAt(rowIdx, colIdx);
    432  *aColExtents = table->ColExtentAt(rowIdx, colIdx);
    433  *aIsSelected = table->IsCellSelected(rowIdx, colIdx);
    434 
    435  return S_OK;
    436 }
    437 
    438 STDMETHODIMP
    439 ia2AccessibleTable::get_modelChange(IA2TableModelChange* aModelChange) {
    440  return E_NOTIMPL;
    441 }
    442 
    443 ////////////////////////////////////////////////////////////////////////////////
    444 // IAccessibleTable2
    445 
    446 STDMETHODIMP
    447 ia2AccessibleTable::get_cellAt(long aRowIdx, long aColIdx, IUnknown** aCell) {
    448  if (!aCell) return E_INVALIDARG;
    449 
    450  *aCell = nullptr;
    451 
    452  TableAccessible* table = TableAcc();
    453  if (!table) return CO_E_OBJNOTCONNECTED;
    454 
    455  Accessible* cell = table->CellAt(aRowIdx, aColIdx);
    456  if (!cell) return E_INVALIDARG;
    457 
    458  RefPtr<IAccessible> result = MsaaAccessible::GetFrom(cell);
    459  result.forget(aCell);
    460  return S_OK;
    461 }
    462 
    463 STDMETHODIMP
    464 ia2AccessibleTable::get_nSelectedCells(long* aCellCount) {
    465  if (!aCellCount) return E_INVALIDARG;
    466 
    467  *aCellCount = 0;
    468  TableAccessible* table = TableAcc();
    469  if (!table) return CO_E_OBJNOTCONNECTED;
    470 
    471  *aCellCount = table->SelectedCellCount();
    472  return S_OK;
    473 }
    474 
    475 STDMETHODIMP
    476 ia2AccessibleTable::get_selectedCells(IUnknown*** aCells,
    477                                      long* aNSelectedCells) {
    478  if (!aCells || !aNSelectedCells) return E_INVALIDARG;
    479 
    480  *aCells = nullptr;
    481  *aNSelectedCells = 0;
    482  TableAccessible* table = TableAcc();
    483  if (!table) return CO_E_OBJNOTCONNECTED;
    484 
    485  AutoTArray<Accessible*, 30> cells;
    486  table->SelectedCells(&cells);
    487  if (cells.IsEmpty()) return S_FALSE;
    488 
    489  *aCells = static_cast<IUnknown**>(
    490      ::CoTaskMemAlloc(sizeof(IUnknown*) * cells.Length()));
    491  if (!*aCells) return E_OUTOFMEMORY;
    492 
    493  for (uint32_t i = 0; i < cells.Length(); i++) {
    494    RefPtr<IAccessible> cell = MsaaAccessible::GetFrom(cells[i]);
    495    cell.forget(&(*aCells)[i]);
    496  }
    497 
    498  *aNSelectedCells = cells.Length();
    499  return S_OK;
    500 }
    501 
    502 STDMETHODIMP
    503 ia2AccessibleTable::get_selectedColumns(long** aColumns, long* aNColumns) {
    504  if (!aColumns || !aNColumns) return E_INVALIDARG;
    505 
    506  *aColumns = nullptr;
    507  *aNColumns = 0;
    508  TableAccessible* table = TableAcc();
    509  if (!table) return CO_E_OBJNOTCONNECTED;
    510 
    511  AutoTArray<uint32_t, 30> colIndices;
    512  table->SelectedColIndices(&colIndices);
    513 
    514  uint32_t maxCols = colIndices.Length();
    515  if (maxCols == 0) return S_FALSE;
    516 
    517  *aColumns = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxCols));
    518  *aNColumns = maxCols;
    519  for (uint32_t i = 0; i < maxCols; i++) (*aColumns)[i] = colIndices[i];
    520 
    521  return S_OK;
    522 }
    523 
    524 STDMETHODIMP
    525 ia2AccessibleTable::get_selectedRows(long** aRows, long* aNRows) {
    526  if (!aRows || !aNRows) return E_INVALIDARG;
    527 
    528  *aRows = nullptr;
    529  *aNRows = 0;
    530  TableAccessible* table = TableAcc();
    531  if (!table) return CO_E_OBJNOTCONNECTED;
    532 
    533  AutoTArray<uint32_t, 30> rowIndices;
    534  table->SelectedRowIndices(&rowIndices);
    535 
    536  uint32_t maxRows = rowIndices.Length();
    537  if (maxRows == 0) return S_FALSE;
    538 
    539  *aRows = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxRows));
    540  *aNRows = maxRows;
    541  for (uint32_t i = 0; i < maxRows; i++) (*aRows)[i] = rowIndices[i];
    542 
    543  return S_OK;
    544 }