accessible/src/atk/nsMaiInterfaceTable.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "InterfaceInitFuncs.h"
michael@0 8
michael@0 9 #include "Accessible-inl.h"
michael@0 10 #include "AccessibleWrap.h"
michael@0 11 #include "nsAccUtils.h"
michael@0 12 #include "TableAccessible.h"
michael@0 13 #include "TableCellAccessible.h"
michael@0 14 #include "nsMai.h"
michael@0 15
michael@0 16 #include "nsArrayUtils.h"
michael@0 17
michael@0 18 #include "mozilla/Likely.h"
michael@0 19
michael@0 20 using namespace mozilla::a11y;
michael@0 21
michael@0 22 extern "C" {
michael@0 23 static AtkObject*
michael@0 24 refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
michael@0 25 {
michael@0 26 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 27 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
michael@0 28 return nullptr;
michael@0 29
michael@0 30 Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
michael@0 31 if (!cell)
michael@0 32 return nullptr;
michael@0 33
michael@0 34 AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell);
michael@0 35 if (cellAtkObj)
michael@0 36 g_object_ref(cellAtkObj);
michael@0 37
michael@0 38 return cellAtkObj;
michael@0 39 }
michael@0 40
michael@0 41 static gint
michael@0 42 getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
michael@0 43 {
michael@0 44 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 45 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
michael@0 46 return -1;
michael@0 47
michael@0 48 return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
michael@0 49 }
michael@0 50
michael@0 51 static gint
michael@0 52 getColumnAtIndexCB(AtkTable *aTable, gint aIdx)
michael@0 53 {
michael@0 54 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 55 if (!accWrap || aIdx < 0)
michael@0 56 return -1;
michael@0 57
michael@0 58 return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx));
michael@0 59 }
michael@0 60
michael@0 61 static gint
michael@0 62 getRowAtIndexCB(AtkTable *aTable, gint aIdx)
michael@0 63 {
michael@0 64 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 65 if (!accWrap || aIdx < 0)
michael@0 66 return -1;
michael@0 67
michael@0 68 return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx));
michael@0 69 }
michael@0 70
michael@0 71 static gint
michael@0 72 getColumnCountCB(AtkTable *aTable)
michael@0 73 {
michael@0 74 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 75 if (!accWrap)
michael@0 76 return -1;
michael@0 77
michael@0 78 return static_cast<gint>(accWrap->AsTable()->ColCount());
michael@0 79 }
michael@0 80
michael@0 81 static gint
michael@0 82 getRowCountCB(AtkTable *aTable)
michael@0 83 {
michael@0 84 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 85 if (!accWrap)
michael@0 86 return -1;
michael@0 87
michael@0 88 return static_cast<gint>(accWrap->AsTable()->RowCount());
michael@0 89 }
michael@0 90
michael@0 91 static gint
michael@0 92 getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
michael@0 93 {
michael@0 94 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 95 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
michael@0 96 return -1;
michael@0 97
michael@0 98 return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx));
michael@0 99 }
michael@0 100
michael@0 101 static gint
michael@0 102 getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
michael@0 103 {
michael@0 104 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 105 if (!accWrap)
michael@0 106 return -1;
michael@0 107
michael@0 108 return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
michael@0 109 }
michael@0 110
michael@0 111 static AtkObject*
michael@0 112 getCaptionCB(AtkTable* aTable)
michael@0 113 {
michael@0 114 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 115 if (!accWrap)
michael@0 116 return nullptr;
michael@0 117
michael@0 118 Accessible* caption = accWrap->AsTable()->Caption();
michael@0 119 return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
michael@0 120 }
michael@0 121
michael@0 122 static const gchar*
michael@0 123 getColumnDescriptionCB(AtkTable *aTable, gint aColumn)
michael@0 124 {
michael@0 125 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 126 if (!accWrap)
michael@0 127 return nullptr;
michael@0 128
michael@0 129 nsAutoString autoStr;
michael@0 130 accWrap->AsTable()->ColDescription(aColumn, autoStr);
michael@0 131
michael@0 132 return AccessibleWrap::ReturnString(autoStr);
michael@0 133 }
michael@0 134
michael@0 135 static AtkObject*
michael@0 136 getColumnHeaderCB(AtkTable *aTable, gint aColIdx)
michael@0 137 {
michael@0 138 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 139 if (!accWrap)
michael@0 140 return nullptr;
michael@0 141
michael@0 142 Accessible* cell = accWrap->AsTable()->CellAt(0, aColIdx);
michael@0 143 if (!cell)
michael@0 144 return nullptr;
michael@0 145
michael@0 146 // If the cell at the first row is column header then assume it is column
michael@0 147 // header for all rows,
michael@0 148 if (cell->Role() == roles::COLUMNHEADER)
michael@0 149 return AccessibleWrap::GetAtkObject(cell);
michael@0 150
michael@0 151 // otherwise get column header for the data cell at the first row.
michael@0 152 TableCellAccessible* tableCell = cell->AsTableCell();
michael@0 153 if (!tableCell)
michael@0 154 return nullptr;
michael@0 155
michael@0 156 nsAutoTArray<Accessible*, 10> headerCells;
michael@0 157 tableCell->ColHeaderCells(&headerCells);
michael@0 158 if (headerCells.IsEmpty())
michael@0 159 return nullptr;
michael@0 160
michael@0 161 return AccessibleWrap::GetAtkObject(headerCells[0]);
michael@0 162 }
michael@0 163
michael@0 164 static const gchar*
michael@0 165 getRowDescriptionCB(AtkTable *aTable, gint aRow)
michael@0 166 {
michael@0 167 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 168 if (!accWrap)
michael@0 169 return nullptr;
michael@0 170
michael@0 171 nsAutoString autoStr;
michael@0 172 accWrap->AsTable()->RowDescription(aRow, autoStr);
michael@0 173
michael@0 174 return AccessibleWrap::ReturnString(autoStr);
michael@0 175 }
michael@0 176
michael@0 177 static AtkObject*
michael@0 178 getRowHeaderCB(AtkTable *aTable, gint aRowIdx)
michael@0 179 {
michael@0 180 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 181 if (!accWrap)
michael@0 182 return nullptr;
michael@0 183
michael@0 184 Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, 0);
michael@0 185 if (!cell)
michael@0 186 return nullptr;
michael@0 187
michael@0 188 // If the cell at the first column is row header then assume it is row
michael@0 189 // header for all columns,
michael@0 190 if (cell->Role() == roles::ROWHEADER)
michael@0 191 return AccessibleWrap::GetAtkObject(cell);
michael@0 192
michael@0 193 // otherwise get row header for the data cell at the first column.
michael@0 194 TableCellAccessible* tableCell = cell->AsTableCell();
michael@0 195 if (!tableCell)
michael@0 196 return nullptr;
michael@0 197
michael@0 198 nsAutoTArray<Accessible*, 10> headerCells;
michael@0 199 tableCell->RowHeaderCells(&headerCells);
michael@0 200 if (headerCells.IsEmpty())
michael@0 201 return nullptr;
michael@0 202
michael@0 203 return AccessibleWrap::GetAtkObject(headerCells[0]);
michael@0 204 }
michael@0 205
michael@0 206 static AtkObject*
michael@0 207 getSummaryCB(AtkTable *aTable)
michael@0 208 {
michael@0 209 // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
michael@0 210 // link an accessible object to specify a summary. There is closes method
michael@0 211 // in TableAccessible::summary to get a summary as a string which is not
michael@0 212 // mapped directly to ATK.
michael@0 213 return nullptr;
michael@0 214 }
michael@0 215
michael@0 216 static gint
michael@0 217 getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
michael@0 218 {
michael@0 219 *aSelected = nullptr;
michael@0 220
michael@0 221 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 222 if (!accWrap)
michael@0 223 return 0;
michael@0 224
michael@0 225 nsAutoTArray<uint32_t, 10> cols;
michael@0 226 accWrap->AsTable()->SelectedColIndices(&cols);
michael@0 227 if (cols.IsEmpty())
michael@0 228 return 0;
michael@0 229
michael@0 230 gint* atkColumns = g_new(gint, cols.Length());
michael@0 231 if (!atkColumns) {
michael@0 232 NS_WARNING("OUT OF MEMORY");
michael@0 233 return 0;
michael@0 234 }
michael@0 235
michael@0 236 memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
michael@0 237 *aSelected = atkColumns;
michael@0 238 return cols.Length();
michael@0 239 }
michael@0 240
michael@0 241 static gint
michael@0 242 getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
michael@0 243 {
michael@0 244 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 245 if (!accWrap)
michael@0 246 return 0;
michael@0 247
michael@0 248 nsAutoTArray<uint32_t, 10> rows;
michael@0 249 accWrap->AsTable()->SelectedRowIndices(&rows);
michael@0 250
michael@0 251 gint* atkRows = g_new(gint, rows.Length());
michael@0 252 if (!atkRows) {
michael@0 253 NS_WARNING("OUT OF MEMORY");
michael@0 254 return 0;
michael@0 255 }
michael@0 256
michael@0 257 memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t));
michael@0 258 *aSelected = atkRows;
michael@0 259 return rows.Length();
michael@0 260 }
michael@0 261
michael@0 262 static gboolean
michael@0 263 isColumnSelectedCB(AtkTable *aTable, gint aColIdx)
michael@0 264 {
michael@0 265 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 266 if (!accWrap)
michael@0 267 return FALSE;
michael@0 268
michael@0 269 return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
michael@0 270 }
michael@0 271
michael@0 272 static gboolean
michael@0 273 isRowSelectedCB(AtkTable *aTable, gint aRowIdx)
michael@0 274 {
michael@0 275 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 276 if (!accWrap)
michael@0 277 return FALSE;
michael@0 278
michael@0 279 return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
michael@0 280 }
michael@0 281
michael@0 282 static gboolean
michael@0 283 isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
michael@0 284 {
michael@0 285 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
michael@0 286 if (!accWrap)
michael@0 287 return FALSE;
michael@0 288
michael@0 289 return static_cast<gboolean>(accWrap->AsTable()->
michael@0 290 IsCellSelected(aRowIdx, aColIdx));
michael@0 291 }
michael@0 292 }
michael@0 293
michael@0 294 void
michael@0 295 tableInterfaceInitCB(AtkTableIface* aIface)
michael@0 296 {
michael@0 297 NS_ASSERTION(aIface, "no interface!");
michael@0 298 if (MOZ_UNLIKELY(!aIface))
michael@0 299 return;
michael@0 300
michael@0 301 aIface->ref_at = refAtCB;
michael@0 302 aIface->get_index_at = getIndexAtCB;
michael@0 303 aIface->get_column_at_index = getColumnAtIndexCB;
michael@0 304 aIface->get_row_at_index = getRowAtIndexCB;
michael@0 305 aIface->get_n_columns = getColumnCountCB;
michael@0 306 aIface->get_n_rows = getRowCountCB;
michael@0 307 aIface->get_column_extent_at = getColumnExtentAtCB;
michael@0 308 aIface->get_row_extent_at = getRowExtentAtCB;
michael@0 309 aIface->get_caption = getCaptionCB;
michael@0 310 aIface->get_column_description = getColumnDescriptionCB;
michael@0 311 aIface->get_column_header = getColumnHeaderCB;
michael@0 312 aIface->get_row_description = getRowDescriptionCB;
michael@0 313 aIface->get_row_header = getRowHeaderCB;
michael@0 314 aIface->get_summary = getSummaryCB;
michael@0 315 aIface->get_selected_columns = getSelectedColumnsCB;
michael@0 316 aIface->get_selected_rows = getSelectedRowsCB;
michael@0 317 aIface->is_column_selected = isColumnSelectedCB;
michael@0 318 aIface->is_row_selected = isRowSelectedCB;
michael@0 319 aIface->is_selected = isCellSelectedCB;
michael@0 320 }

mercurial