Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
8 #include "ia2AccessibleTable.h"
10 #include "Accessible2.h"
11 #include "AccessibleTable_i.c"
12 #include "AccessibleTable2_i.c"
14 #include "AccessibleWrap.h"
15 #include "IUnknownImpl.h"
16 #include "Statistics.h"
17 #include "TableAccessible.h"
19 #include "nsCOMPtr.h"
20 #include "nsString.h"
22 using namespace mozilla::a11y;
24 // IUnknown
26 STDMETHODIMP
27 ia2AccessibleTable::QueryInterface(REFIID iid, void** ppv)
28 {
29 if (!ppv)
30 return E_INVALIDARG;
32 *ppv = nullptr;
34 if (IID_IAccessibleTable == iid) {
35 statistics::IAccessibleTableUsed();
36 *ppv = static_cast<IAccessibleTable*>(this);
37 (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
38 return S_OK;
39 }
41 if (IID_IAccessibleTable2 == iid) {
42 *ppv = static_cast<IAccessibleTable2*>(this);
43 (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
44 return S_OK;
45 }
47 return E_NOINTERFACE;
48 }
50 ////////////////////////////////////////////////////////////////////////////////
51 // IAccessibleTable
53 STDMETHODIMP
54 ia2AccessibleTable::get_accessibleAt(long aRowIdx, long aColIdx,
55 IUnknown** aAccessible)
56 {
57 return get_cellAt(aRowIdx, aColIdx, aAccessible);
58 }
60 STDMETHODIMP
61 ia2AccessibleTable::get_caption(IUnknown** aAccessible)
62 {
63 A11Y_TRYBLOCK_BEGIN
65 if (!aAccessible)
66 return E_INVALIDARG;
68 *aAccessible = nullptr;
69 if (!mTable)
70 return CO_E_OBJNOTCONNECTED;
72 AccessibleWrap* caption = static_cast<AccessibleWrap*>(mTable->Caption());
73 if (!caption)
74 return S_FALSE;
76 (*aAccessible = static_cast<IAccessible*>(caption))->AddRef();
77 return S_OK;
79 A11Y_TRYBLOCK_END
80 }
82 STDMETHODIMP
83 ia2AccessibleTable::get_childIndex(long aRowIdx, long aColIdx,
84 long* aChildIdx)
85 {
86 A11Y_TRYBLOCK_BEGIN
88 if (!aChildIdx)
89 return E_INVALIDARG;
91 *aChildIdx = 0;
92 if (!mTable)
93 return CO_E_OBJNOTCONNECTED;
95 if (aRowIdx < 0 || aColIdx < 0 ||
96 static_cast<uint32_t>(aRowIdx) >= mTable->RowCount() ||
97 static_cast<uint32_t>(aColIdx) >= mTable->ColCount())
98 return E_INVALIDARG;
100 *aChildIdx = mTable->CellIndexAt(aRowIdx, aColIdx);
101 return S_OK;
103 A11Y_TRYBLOCK_END
104 }
106 STDMETHODIMP
107 ia2AccessibleTable::get_columnDescription(long aColIdx, BSTR* aDescription)
108 {
109 A11Y_TRYBLOCK_BEGIN
111 if (!aDescription)
112 return E_INVALIDARG;
114 *aDescription = nullptr;
115 if (!mTable)
116 return CO_E_OBJNOTCONNECTED;
118 if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount())
119 return E_INVALIDARG;
121 nsAutoString descr;
122 mTable->ColDescription(aColIdx, descr);
123 if (descr.IsEmpty())
124 return S_FALSE;
126 *aDescription = ::SysAllocStringLen(descr.get(), descr.Length());
127 return *aDescription ? S_OK : E_OUTOFMEMORY;
129 A11Y_TRYBLOCK_END
130 }
132 STDMETHODIMP
133 ia2AccessibleTable::get_columnExtentAt(long aRowIdx, long aColIdx,
134 long* aSpan)
135 {
136 A11Y_TRYBLOCK_BEGIN
138 if (!aSpan)
139 return E_INVALIDARG;
141 *aSpan = 0;
142 if (!mTable)
143 return CO_E_OBJNOTCONNECTED;
145 if (aRowIdx < 0 || aColIdx < 0 ||
146 static_cast<uint32_t>(aRowIdx) >= mTable->RowCount() ||
147 static_cast<uint32_t>(aColIdx) >= mTable->ColCount())
148 return E_INVALIDARG;
150 *aSpan = mTable->ColExtentAt(aRowIdx, aColIdx);
151 return S_OK;
153 A11Y_TRYBLOCK_END
154 }
156 STDMETHODIMP
157 ia2AccessibleTable::get_columnHeader(IAccessibleTable** aAccessibleTable,
158 long* aStartingRowIndex)
159 {
160 A11Y_TRYBLOCK_BEGIN
162 if (!aAccessibleTable || !aStartingRowIndex)
163 return E_INVALIDARG;
165 *aAccessibleTable = nullptr;
166 *aStartingRowIndex = -1;
167 return E_NOTIMPL;
169 A11Y_TRYBLOCK_END
170 }
172 STDMETHODIMP
173 ia2AccessibleTable::get_columnIndex(long aCellIdx, long* aColIdx)
174 {
175 A11Y_TRYBLOCK_BEGIN
177 if (!aColIdx)
178 return E_INVALIDARG;
180 *aColIdx = 0;
181 if (!mTable)
182 return CO_E_OBJNOTCONNECTED;
184 if (aCellIdx < 0 ||
185 static_cast<uint32_t>(aCellIdx) >= mTable->ColCount() * mTable->RowCount())
186 return E_INVALIDARG;
188 *aColIdx = mTable->ColIndexAt(aCellIdx);
189 return S_OK;
191 A11Y_TRYBLOCK_END
192 }
194 STDMETHODIMP
195 ia2AccessibleTable::get_nColumns(long* aColCount)
196 {
197 A11Y_TRYBLOCK_BEGIN
199 if (!aColCount)
200 return E_INVALIDARG;
202 *aColCount = 0;
203 if (!mTable)
204 return CO_E_OBJNOTCONNECTED;
206 *aColCount = mTable->ColCount();
207 return S_OK;
209 A11Y_TRYBLOCK_END
210 }
212 STDMETHODIMP
213 ia2AccessibleTable::get_nRows(long* aRowCount)
214 {
215 A11Y_TRYBLOCK_BEGIN
217 if (!aRowCount)
218 return E_INVALIDARG;
220 *aRowCount = 0;
221 if (!mTable)
222 return CO_E_OBJNOTCONNECTED;
224 *aRowCount = mTable->RowCount();
225 return S_OK;
227 A11Y_TRYBLOCK_END
228 }
230 STDMETHODIMP
231 ia2AccessibleTable::get_nSelectedChildren(long* aChildCount)
232 {
233 return get_nSelectedCells(aChildCount);
234 }
236 STDMETHODIMP
237 ia2AccessibleTable::get_nSelectedColumns(long* aColCount)
238 {
239 A11Y_TRYBLOCK_BEGIN
241 if (!aColCount)
242 return E_INVALIDARG;
244 *aColCount = 0;
245 if (!mTable)
246 return CO_E_OBJNOTCONNECTED;
248 *aColCount = mTable->SelectedColCount();
249 return S_OK;
251 A11Y_TRYBLOCK_END
252 }
254 STDMETHODIMP
255 ia2AccessibleTable::get_nSelectedRows(long* aRowCount)
256 {
257 A11Y_TRYBLOCK_BEGIN
259 if (!aRowCount)
260 return E_INVALIDARG;
262 *aRowCount = 0;
263 if (!mTable)
264 return CO_E_OBJNOTCONNECTED;
266 *aRowCount = mTable->SelectedRowCount();
268 return S_OK;
270 A11Y_TRYBLOCK_END
271 }
273 STDMETHODIMP
274 ia2AccessibleTable::get_rowDescription(long aRowIdx, BSTR* aDescription)
275 {
276 A11Y_TRYBLOCK_BEGIN
278 if (!aDescription)
279 return E_INVALIDARG;
281 *aDescription = nullptr;
282 if (!mTable)
283 return CO_E_OBJNOTCONNECTED;
285 if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount())
286 return E_INVALIDARG;
288 nsAutoString descr;
289 mTable->RowDescription(aRowIdx, descr);
290 if (descr.IsEmpty())
291 return S_FALSE;
293 *aDescription = ::SysAllocStringLen(descr.get(), descr.Length());
294 return *aDescription ? S_OK : E_OUTOFMEMORY;
296 A11Y_TRYBLOCK_END
297 }
299 STDMETHODIMP
300 ia2AccessibleTable::get_rowExtentAt(long aRowIdx, long aColIdx, long* aSpan)
301 {
302 A11Y_TRYBLOCK_BEGIN
304 if (!aSpan)
305 return E_INVALIDARG;
307 *aSpan = 0;
308 if (!mTable)
309 return CO_E_OBJNOTCONNECTED;
311 if (aRowIdx < 0 || aColIdx < 0 ||
312 static_cast<uint32_t>(aRowIdx) >= mTable->RowCount() ||
313 static_cast<uint32_t>(aColIdx) >= mTable->ColCount())
314 return E_INVALIDARG;
316 *aSpan = mTable->RowExtentAt(aRowIdx, aColIdx);
317 return S_OK;
319 A11Y_TRYBLOCK_END
320 }
322 STDMETHODIMP
323 ia2AccessibleTable::get_rowHeader(IAccessibleTable** aAccessibleTable,
324 long* aStartingColumnIndex)
325 {
326 A11Y_TRYBLOCK_BEGIN
328 if (!aAccessibleTable || !aStartingColumnIndex)
329 return E_INVALIDARG;
331 *aAccessibleTable = nullptr;
332 *aStartingColumnIndex = -1;
333 return E_NOTIMPL;
335 A11Y_TRYBLOCK_END
336 }
338 STDMETHODIMP
339 ia2AccessibleTable::get_rowIndex(long aCellIdx, long* aRowIdx)
340 {
341 A11Y_TRYBLOCK_BEGIN
343 if (!aRowIdx)
344 return E_INVALIDARG;
346 *aRowIdx = 0;
347 if (!mTable)
348 return CO_E_OBJNOTCONNECTED;
350 if (aCellIdx < 0 ||
351 static_cast<uint32_t>(aCellIdx) >= mTable->ColCount() * mTable->RowCount())
352 return E_INVALIDARG;
354 *aRowIdx = mTable->RowIndexAt(aCellIdx);
355 return S_OK;
357 A11Y_TRYBLOCK_END
358 }
360 STDMETHODIMP
361 ia2AccessibleTable::get_selectedChildren(long aMaxChildren, long** aChildren,
362 long* aNChildren)
363 {
364 A11Y_TRYBLOCK_BEGIN
366 if (!aChildren || !aNChildren)
367 return E_INVALIDARG;
369 *aChildren = nullptr;
370 *aNChildren = 0;
371 if (!mTable)
372 return CO_E_OBJNOTCONNECTED;
374 nsAutoTArray<uint32_t, 30> cellIndices;
375 mTable->SelectedCellIndices(&cellIndices);
377 uint32_t maxCells = cellIndices.Length();
378 if (maxCells == 0)
379 return S_FALSE;
381 *aChildren = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxCells));
382 *aNChildren = maxCells;
383 for (uint32_t i = 0; i < maxCells; i++)
384 (*aChildren)[i] = cellIndices[i];
386 return S_OK;
388 A11Y_TRYBLOCK_END
389 }
391 STDMETHODIMP
392 ia2AccessibleTable::get_selectedColumns(long aMaxColumns, long** aColumns,
393 long* aNColumns)
394 {
395 A11Y_TRYBLOCK_BEGIN
397 return get_selectedColumns(aColumns, aNColumns);
399 A11Y_TRYBLOCK_END
400 }
402 STDMETHODIMP
403 ia2AccessibleTable::get_selectedRows(long aMaxRows, long** aRows, long* aNRows)
404 {
405 A11Y_TRYBLOCK_BEGIN
407 return get_selectedRows(aRows, aNRows);
409 A11Y_TRYBLOCK_END
410 }
412 STDMETHODIMP
413 ia2AccessibleTable::get_summary(IUnknown** aAccessible)
414 {
415 A11Y_TRYBLOCK_BEGIN
417 if (!aAccessible)
418 return E_INVALIDARG;
420 // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
421 // link an accessible object to specify a summary. There is closes method
422 // in nsIAccessibleTable::summary to get a summary as a string which is not
423 // mapped directly to IAccessible2.
425 *aAccessible = nullptr;
426 return S_FALSE;
428 A11Y_TRYBLOCK_END
429 }
431 STDMETHODIMP
432 ia2AccessibleTable::get_isColumnSelected(long aColIdx, boolean* aIsSelected)
433 {
434 A11Y_TRYBLOCK_BEGIN
436 if (!aIsSelected)
437 return E_INVALIDARG;
439 *aIsSelected = false;
440 if (!mTable)
441 return CO_E_OBJNOTCONNECTED;
443 if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount())
444 return E_INVALIDARG;
446 *aIsSelected = mTable->IsColSelected(aColIdx);
447 return S_OK;
449 A11Y_TRYBLOCK_END
450 }
452 STDMETHODIMP
453 ia2AccessibleTable::get_isRowSelected(long aRowIdx, boolean* aIsSelected)
454 {
455 A11Y_TRYBLOCK_BEGIN
457 if (!aIsSelected)
458 return E_INVALIDARG;
460 *aIsSelected = false;
461 if (!mTable)
462 return CO_E_OBJNOTCONNECTED;
464 if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount())
465 return E_INVALIDARG;
467 *aIsSelected = mTable->IsRowSelected(aRowIdx);
468 return S_OK;
470 A11Y_TRYBLOCK_END
471 }
473 STDMETHODIMP
474 ia2AccessibleTable::get_isSelected(long aRowIdx, long aColIdx,
475 boolean* aIsSelected)
476 {
477 A11Y_TRYBLOCK_BEGIN
479 if (!aIsSelected)
480 return E_INVALIDARG;
482 *aIsSelected = false;
483 if (!mTable)
484 return CO_E_OBJNOTCONNECTED;
486 if (aRowIdx < 0 || aColIdx < 0 ||
487 static_cast<uint32_t>(aColIdx) >= mTable->ColCount() ||
488 static_cast<uint32_t>(aRowIdx) >= mTable->RowCount())
489 return E_INVALIDARG;
491 *aIsSelected = mTable->IsCellSelected(aRowIdx, aColIdx);
492 return S_OK;
494 A11Y_TRYBLOCK_END
495 }
497 STDMETHODIMP
498 ia2AccessibleTable::selectRow(long aRowIdx)
499 {
500 A11Y_TRYBLOCK_BEGIN
502 if (!mTable)
503 return CO_E_OBJNOTCONNECTED;
505 if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount())
506 return E_INVALIDARG;
508 mTable->SelectRow(aRowIdx);
509 return S_OK;
511 A11Y_TRYBLOCK_END
512 }
514 STDMETHODIMP
515 ia2AccessibleTable::selectColumn(long aColIdx)
516 {
517 A11Y_TRYBLOCK_BEGIN
519 if (!mTable)
520 return CO_E_OBJNOTCONNECTED;
522 if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount())
523 return E_INVALIDARG;
525 mTable->SelectCol(aColIdx);
526 return S_OK;
528 A11Y_TRYBLOCK_END
529 }
531 STDMETHODIMP
532 ia2AccessibleTable::unselectRow(long aRowIdx)
533 {
534 A11Y_TRYBLOCK_BEGIN
536 if (!mTable)
537 return CO_E_OBJNOTCONNECTED;
539 if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount())
540 return E_INVALIDARG;
542 mTable->UnselectRow(aRowIdx);
543 return S_OK;
545 A11Y_TRYBLOCK_END
546 }
548 STDMETHODIMP
549 ia2AccessibleTable::unselectColumn(long aColIdx)
550 {
551 A11Y_TRYBLOCK_BEGIN
553 if (!mTable)
554 return CO_E_OBJNOTCONNECTED;
556 if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount())
557 return E_INVALIDARG;
559 mTable->UnselectCol(aColIdx);
560 return S_OK;
562 A11Y_TRYBLOCK_END
563 }
565 STDMETHODIMP
566 ia2AccessibleTable::get_rowColumnExtentsAtIndex(long aCellIdx, long* aRowIdx,
567 long* aColIdx,
568 long* aRowExtents,
569 long* aColExtents,
570 boolean* aIsSelected)
571 {
572 A11Y_TRYBLOCK_BEGIN
574 if (!aRowIdx || !aColIdx || !aRowExtents || !aColExtents || !aIsSelected)
575 return E_INVALIDARG;
577 *aRowIdx = 0;
578 *aColIdx = 0;
579 *aRowExtents = 0;
580 *aColExtents = 0;
581 *aIsSelected = false;
582 if (!mTable)
583 return CO_E_OBJNOTCONNECTED;
585 if (aCellIdx < 0 ||
586 static_cast<uint32_t>(aCellIdx) >= mTable->ColCount() * mTable->RowCount())
587 return E_INVALIDARG;
589 int32_t colIdx = 0, rowIdx = 0;
590 mTable->RowAndColIndicesAt(aCellIdx, &rowIdx, &colIdx);
591 *aRowIdx = rowIdx;
592 *aColIdx = colIdx;
593 *aRowExtents = mTable->RowExtentAt(rowIdx, colIdx);
594 *aColExtents = mTable->ColExtentAt(rowIdx, colIdx);
595 *aIsSelected = mTable->IsCellSelected(rowIdx, colIdx);
597 return S_OK;
599 A11Y_TRYBLOCK_END
600 }
602 STDMETHODIMP
603 ia2AccessibleTable::get_modelChange(IA2TableModelChange* aModelChange)
604 {
605 return E_NOTIMPL;
606 }
608 ////////////////////////////////////////////////////////////////////////////////
609 // IAccessibleTable2
611 STDMETHODIMP
612 ia2AccessibleTable::get_cellAt(long aRowIdx, long aColIdx, IUnknown** aCell)
613 {
614 A11Y_TRYBLOCK_BEGIN
616 if (!aCell)
617 return E_INVALIDARG;
619 *aCell = nullptr;
621 if (!mTable)
622 return CO_E_OBJNOTCONNECTED;
624 AccessibleWrap* cell =
625 static_cast<AccessibleWrap*>(mTable->CellAt(aRowIdx, aColIdx));
626 if (!cell)
627 return E_INVALIDARG;
629 (*aCell = static_cast<IAccessible*>(cell))->AddRef();
630 return S_OK;
632 A11Y_TRYBLOCK_END
633 }
635 STDMETHODIMP
636 ia2AccessibleTable::get_nSelectedCells(long* aCellCount)
637 {
638 A11Y_TRYBLOCK_BEGIN
640 if (!aCellCount)
641 return E_INVALIDARG;
643 *aCellCount = 0;
644 if (!mTable)
645 return CO_E_OBJNOTCONNECTED;
647 *aCellCount = mTable->SelectedCellCount();
648 return S_OK;
650 A11Y_TRYBLOCK_END
651 }
653 STDMETHODIMP
654 ia2AccessibleTable::get_selectedCells(IUnknown*** aCells, long* aNSelectedCells)
655 {
656 A11Y_TRYBLOCK_BEGIN
658 if (!aCells || !aNSelectedCells)
659 return E_INVALIDARG;
661 *aCells = nullptr;
662 *aNSelectedCells = 0;
663 if (!mTable)
664 return CO_E_OBJNOTCONNECTED;
666 nsAutoTArray<Accessible*, 30> cells;
667 mTable->SelectedCells(&cells);
668 if (cells.IsEmpty())
669 return S_FALSE;
671 *aCells =
672 static_cast<IUnknown**>(::CoTaskMemAlloc(sizeof(IUnknown*) *
673 cells.Length()));
674 if (!*aCells)
675 return E_OUTOFMEMORY;
677 for (uint32_t i = 0; i < cells.Length(); i++) {
678 (*aCells)[i] =
679 static_cast<IAccessible*>(static_cast<AccessibleWrap*>(cells[i]));
680 ((*aCells)[i])->AddRef();
681 }
683 *aNSelectedCells = cells.Length();
684 return S_OK;
686 A11Y_TRYBLOCK_END
687 }
689 STDMETHODIMP
690 ia2AccessibleTable::get_selectedColumns(long** aColumns, long* aNColumns)
691 {
692 A11Y_TRYBLOCK_BEGIN
694 if (!aColumns || !aNColumns)
695 return E_INVALIDARG;
697 *aColumns = nullptr;
698 *aNColumns = 0;
699 if (!mTable)
700 return CO_E_OBJNOTCONNECTED;
702 nsAutoTArray<uint32_t, 30> colIndices;
703 mTable->SelectedColIndices(&colIndices);
705 uint32_t maxCols = colIndices.Length();
706 if (maxCols == 0)
707 return S_FALSE;
709 *aColumns = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxCols));
710 *aNColumns = maxCols;
711 for (uint32_t i = 0; i < maxCols; i++)
712 (*aColumns)[i] = colIndices[i];
714 return S_OK;
716 A11Y_TRYBLOCK_END
717 }
719 STDMETHODIMP
720 ia2AccessibleTable::get_selectedRows(long** aRows, long* aNRows)
721 {
722 A11Y_TRYBLOCK_BEGIN
724 if (!aRows || !aNRows)
725 return E_INVALIDARG;
727 *aRows = nullptr;
728 *aNRows = 0;
729 if (!mTable)
730 return CO_E_OBJNOTCONNECTED;
732 nsAutoTArray<uint32_t, 30> rowIndices;
733 mTable->SelectedRowIndices(&rowIndices);
735 uint32_t maxRows = rowIndices.Length();
736 if (maxRows == 0)
737 return S_FALSE;
739 *aRows = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxRows));
740 *aNRows = maxRows;
741 for (uint32_t i = 0; i < maxRows; i++)
742 (*aRows)[i] = rowIndices[i];
744 return S_OK;
746 A11Y_TRYBLOCK_END
747 }