1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Aaron Leventhal <aaronl@netscape.com> (original author)
24 : * Kyle Yuan <kyle.yuan@sun.com>
25 : * Alexander Surkov <surkov.alexander@gmail.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either of the GNU General Public License Version 2 or later (the "GPL"),
29 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "nsXULListboxAccessible.h"
42 :
43 : #include "nsAccessibilityService.h"
44 : #include "nsAccUtils.h"
45 : #include "nsDocAccessible.h"
46 : #include "Role.h"
47 : #include "States.h"
48 :
49 : #include "nsComponentManagerUtils.h"
50 : #include "nsIAutoCompleteInput.h"
51 : #include "nsIAutoCompletePopup.h"
52 : #include "nsIDOMXULMenuListElement.h"
53 : #include "nsIDOMXULMultSelectCntrlEl.h"
54 : #include "nsIDOMNodeList.h"
55 : #include "nsIDOMXULPopupElement.h"
56 : #include "nsIDOMXULSelectCntrlItemEl.h"
57 :
58 : using namespace mozilla::a11y;
59 :
60 : ////////////////////////////////////////////////////////////////////////////////
61 : // nsXULColumnsAccessible
62 : ////////////////////////////////////////////////////////////////////////////////
63 :
64 0 : nsXULColumnsAccessible::
65 : nsXULColumnsAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
66 0 : nsAccessibleWrap(aContent, aDoc)
67 : {
68 0 : }
69 :
70 : role
71 0 : nsXULColumnsAccessible::NativeRole()
72 : {
73 0 : return roles::LIST;
74 : }
75 :
76 : PRUint64
77 0 : nsXULColumnsAccessible::NativeState()
78 : {
79 0 : return states::READONLY;
80 : }
81 :
82 :
83 : ////////////////////////////////////////////////////////////////////////////////
84 : // nsXULColumnItemAccessible
85 : ////////////////////////////////////////////////////////////////////////////////
86 :
87 0 : nsXULColumnItemAccessible::
88 : nsXULColumnItemAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
89 0 : nsLeafAccessible(aContent, aDoc)
90 : {
91 0 : }
92 :
93 : role
94 0 : nsXULColumnItemAccessible::NativeRole()
95 : {
96 0 : return roles::COLUMNHEADER;
97 : }
98 :
99 : PRUint64
100 0 : nsXULColumnItemAccessible::NativeState()
101 : {
102 0 : return states::READONLY;
103 : }
104 :
105 : PRUint8
106 0 : nsXULColumnItemAccessible::ActionCount()
107 : {
108 0 : return 1;
109 : }
110 :
111 : NS_IMETHODIMP
112 0 : nsXULColumnItemAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
113 : {
114 0 : if (aIndex != eAction_Click)
115 0 : return NS_ERROR_INVALID_ARG;
116 :
117 0 : aName.AssignLiteral("click");
118 0 : return NS_OK;
119 : }
120 :
121 : NS_IMETHODIMP
122 0 : nsXULColumnItemAccessible::DoAction(PRUint8 aIndex)
123 : {
124 0 : if (aIndex != eAction_Click)
125 0 : return NS_ERROR_INVALID_ARG;
126 :
127 0 : DoCommand();
128 0 : return NS_OK;
129 : }
130 :
131 : ////////////////////////////////////////////////////////////////////////////////
132 : // nsXULListboxAccessible
133 : ////////////////////////////////////////////////////////////////////////////////
134 :
135 0 : nsXULListboxAccessible::
136 : nsXULListboxAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
137 0 : XULSelectControlAccessible(aContent, aDoc)
138 : {
139 0 : nsIContent* parentContent = mContent->GetParent();
140 0 : if (parentContent) {
141 : nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm =
142 0 : do_QueryInterface(parentContent);
143 0 : if (autoCompletePopupElm)
144 0 : mFlags |= eAutoCompletePopupAccessible;
145 : }
146 0 : }
147 :
148 0 : NS_IMPL_ADDREF_INHERITED(nsXULListboxAccessible, XULSelectControlAccessible)
149 0 : NS_IMPL_RELEASE_INHERITED(nsXULListboxAccessible, XULSelectControlAccessible)
150 :
151 : nsresult
152 0 : nsXULListboxAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
153 : {
154 0 : nsresult rv = XULSelectControlAccessible::QueryInterface(aIID, aInstancePtr);
155 0 : if (*aInstancePtr)
156 0 : return rv;
157 :
158 0 : if (aIID.Equals(NS_GET_IID(nsIAccessibleTable)) && IsMulticolumn()) {
159 0 : *aInstancePtr = static_cast<nsIAccessibleTable*>(this);
160 0 : NS_ADDREF_THIS();
161 0 : return NS_OK;
162 : }
163 :
164 0 : return NS_ERROR_NO_INTERFACE;
165 : }
166 :
167 : bool
168 0 : nsXULListboxAccessible::IsMulticolumn()
169 : {
170 0 : PRInt32 numColumns = 0;
171 0 : nsresult rv = GetColumnCount(&numColumns);
172 0 : if (NS_FAILED(rv))
173 0 : return false;
174 :
175 0 : return numColumns > 1;
176 : }
177 :
178 : ////////////////////////////////////////////////////////////////////////////////
179 : // nsXULListboxAccessible. nsIAccessible
180 :
181 : PRUint64
182 0 : nsXULListboxAccessible::NativeState()
183 : {
184 : // As a nsXULListboxAccessible we can have the following states:
185 : // FOCUSED, READONLY, FOCUSABLE
186 :
187 : // Get focus status from base class
188 0 : PRUint64 states = nsAccessible::NativeState();
189 :
190 : // see if we are multiple select if so set ourselves as such
191 :
192 0 : if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::seltype,
193 0 : nsGkAtoms::multiple, eCaseMatters)) {
194 0 : states |= states::MULTISELECTABLE | states::EXTSELECTABLE;
195 : }
196 :
197 0 : return states;
198 : }
199 :
200 : /**
201 : * Our value is the label of our ( first ) selected child.
202 : */
203 0 : NS_IMETHODIMP nsXULListboxAccessible::GetValue(nsAString& _retval)
204 : {
205 0 : _retval.Truncate();
206 0 : nsCOMPtr<nsIDOMXULSelectControlElement> select(do_QueryInterface(mContent));
207 0 : if (select) {
208 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> selectedItem;
209 0 : select->GetSelectedItem(getter_AddRefs(selectedItem));
210 0 : if (selectedItem)
211 0 : return selectedItem->GetLabel(_retval);
212 : }
213 0 : return NS_ERROR_FAILURE;
214 : }
215 :
216 : role
217 0 : nsXULListboxAccessible::NativeRole()
218 : {
219 : // A richlistbox is used with the new autocomplete URL bar, and has a parent
220 : // popup <panel>.
221 : nsCOMPtr<nsIDOMXULPopupElement> xulPopup =
222 0 : do_QueryInterface(mContent->GetParent());
223 0 : if (xulPopup)
224 0 : return roles::COMBOBOX_LIST;
225 :
226 0 : return IsMulticolumn() ? roles::TABLE : roles::LISTBOX;
227 : }
228 :
229 : ////////////////////////////////////////////////////////////////////////////////
230 : // nsXULListboxAccessible. nsIAccessibleTable
231 :
232 : NS_IMETHODIMP
233 0 : nsXULListboxAccessible::GetCaption(nsIAccessible **aCaption)
234 : {
235 0 : NS_ENSURE_ARG_POINTER(aCaption);
236 0 : *aCaption = nsnull;
237 :
238 0 : return NS_OK;
239 : }
240 :
241 : NS_IMETHODIMP
242 0 : nsXULListboxAccessible::GetSummary(nsAString &aSummary)
243 : {
244 0 : aSummary.Truncate();
245 :
246 0 : return NS_OK;
247 : }
248 :
249 : NS_IMETHODIMP
250 0 : nsXULListboxAccessible::GetColumnCount(PRInt32 *aColumnsCout)
251 : {
252 0 : NS_ENSURE_ARG_POINTER(aColumnsCout);
253 0 : *aColumnsCout = 0;
254 :
255 0 : if (IsDefunct())
256 0 : return NS_ERROR_FAILURE;
257 :
258 0 : nsIContent* headContent = nsnull;
259 0 : for (nsIContent* childContent = mContent->GetFirstChild(); childContent;
260 0 : childContent = childContent->GetNextSibling()) {
261 0 : if (childContent->NodeInfo()->Equals(nsGkAtoms::listcols,
262 0 : kNameSpaceID_XUL)) {
263 0 : headContent = childContent;
264 : }
265 : }
266 0 : if (!headContent)
267 0 : return NS_OK;
268 :
269 0 : PRUint32 columnCount = 0;
270 0 : for (nsIContent* childContent = headContent->GetFirstChild(); childContent;
271 0 : childContent = childContent->GetNextSibling()) {
272 0 : if (childContent->NodeInfo()->Equals(nsGkAtoms::listcol,
273 0 : kNameSpaceID_XUL)) {
274 0 : columnCount++;
275 : }
276 : }
277 :
278 0 : *aColumnsCout = columnCount;
279 0 : return NS_OK;
280 : }
281 :
282 : NS_IMETHODIMP
283 0 : nsXULListboxAccessible::GetRowCount(PRInt32 *aRowCount)
284 : {
285 0 : NS_ENSURE_ARG_POINTER(aRowCount);
286 0 : *aRowCount = 0;
287 :
288 0 : if (IsDefunct())
289 0 : return NS_ERROR_FAILURE;
290 :
291 0 : nsCOMPtr<nsIDOMXULSelectControlElement> element(do_QueryInterface(mContent));
292 0 : NS_ENSURE_STATE(element);
293 :
294 0 : PRUint32 itemCount = 0;
295 0 : nsresult rv = element->GetItemCount(&itemCount);
296 0 : NS_ENSURE_SUCCESS(rv, rv);
297 :
298 0 : *aRowCount = itemCount;
299 0 : return NS_OK;
300 : }
301 :
302 : NS_IMETHODIMP
303 0 : nsXULListboxAccessible::GetCellAt(PRInt32 aRow, PRInt32 aColumn,
304 : nsIAccessible **aAccessibleCell)
305 : {
306 0 : NS_ENSURE_ARG_POINTER(aAccessibleCell);
307 0 : *aAccessibleCell = nsnull;
308 :
309 0 : if (IsDefunct())
310 0 : return NS_OK;
311 :
312 : nsCOMPtr<nsIDOMXULSelectControlElement> control =
313 0 : do_QueryInterface(mContent);
314 :
315 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
316 0 : control->GetItemAtIndex(aRow, getter_AddRefs(item));
317 0 : NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
318 :
319 0 : nsCOMPtr<nsIContent> itemContent(do_QueryInterface(item));
320 0 : NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE);
321 0 : nsAccessible *row = mDoc->GetAccessible(itemContent);
322 0 : NS_ENSURE_STATE(row);
323 :
324 0 : nsresult rv = row->GetChildAt(aColumn, aAccessibleCell);
325 0 : NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
326 :
327 0 : return NS_OK;
328 : }
329 :
330 : NS_IMETHODIMP
331 0 : nsXULListboxAccessible::GetCellIndexAt(PRInt32 aRow, PRInt32 aColumn,
332 : PRInt32 *aIndex)
333 : {
334 0 : NS_ENSURE_ARG_POINTER(aIndex);
335 0 : *aIndex = -1;
336 :
337 0 : PRInt32 rowCount = 0;
338 0 : nsresult rv = GetRowCount(&rowCount);
339 0 : NS_ENSURE_SUCCESS(rv, rv);
340 0 : NS_ENSURE_TRUE(0 <= aRow && aRow <= rowCount, NS_ERROR_INVALID_ARG);
341 :
342 0 : PRInt32 columnCount = 0;
343 0 : rv = GetColumnCount(&columnCount);
344 0 : NS_ENSURE_SUCCESS(rv, rv);
345 0 : NS_ENSURE_TRUE(0 <= aColumn && aColumn <= columnCount, NS_ERROR_INVALID_ARG);
346 :
347 0 : *aIndex = aRow * columnCount + aColumn;
348 0 : return NS_OK;
349 : }
350 :
351 : NS_IMETHODIMP
352 0 : nsXULListboxAccessible::GetColumnIndexAt(PRInt32 aIndex, PRInt32 *aColumn)
353 : {
354 0 : NS_ENSURE_ARG_POINTER(aColumn);
355 0 : *aColumn = -1;
356 :
357 0 : PRInt32 columnCount = 0;
358 0 : nsresult rv = GetColumnCount(&columnCount);
359 0 : NS_ENSURE_SUCCESS(rv, rv);
360 :
361 0 : *aColumn = aIndex % columnCount;
362 0 : return NS_OK;
363 : }
364 :
365 : NS_IMETHODIMP
366 0 : nsXULListboxAccessible::GetRowIndexAt(PRInt32 aIndex, PRInt32 *aRow)
367 : {
368 0 : NS_ENSURE_ARG_POINTER(aRow);
369 0 : *aRow = -1;
370 :
371 0 : PRInt32 columnCount = 0;
372 0 : nsresult rv = GetColumnCount(&columnCount);
373 0 : NS_ENSURE_SUCCESS(rv, rv);
374 :
375 0 : *aRow = aIndex / columnCount;
376 0 : return NS_OK;
377 : }
378 :
379 : NS_IMETHODIMP
380 0 : nsXULListboxAccessible::GetRowAndColumnIndicesAt(PRInt32 aCellIndex,
381 : PRInt32* aRowIndex,
382 : PRInt32* aColumnIndex)
383 : {
384 0 : NS_ENSURE_ARG_POINTER(aRowIndex);
385 0 : *aRowIndex = -1;
386 0 : NS_ENSURE_ARG_POINTER(aColumnIndex);
387 0 : *aColumnIndex = -1;
388 :
389 0 : if (IsDefunct())
390 0 : return NS_ERROR_FAILURE;
391 :
392 0 : PRInt32 columnCount = 0;
393 0 : nsresult rv = GetColumnCount(&columnCount);
394 0 : NS_ENSURE_SUCCESS(rv, rv);
395 :
396 0 : *aColumnIndex = aCellIndex % columnCount;
397 0 : *aRowIndex = aCellIndex / columnCount;
398 0 : return NS_OK;
399 : }
400 :
401 : NS_IMETHODIMP
402 0 : nsXULListboxAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
403 : PRInt32 *aCellSpans)
404 : {
405 0 : NS_ENSURE_ARG_POINTER(aCellSpans);
406 0 : *aCellSpans = 1;
407 :
408 0 : return NS_OK;
409 : }
410 :
411 : NS_IMETHODIMP
412 0 : nsXULListboxAccessible::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn,
413 : PRInt32 *aCellSpans)
414 : {
415 0 : NS_ENSURE_ARG_POINTER(aCellSpans);
416 0 : *aCellSpans = 1;
417 :
418 0 : return NS_OK;
419 : }
420 :
421 : NS_IMETHODIMP
422 0 : nsXULListboxAccessible::GetColumnDescription(PRInt32 aColumn,
423 : nsAString& aDescription)
424 : {
425 0 : aDescription.Truncate();
426 0 : return NS_OK;
427 : }
428 :
429 : NS_IMETHODIMP
430 0 : nsXULListboxAccessible::GetRowDescription(PRInt32 aRow, nsAString& aDescription)
431 : {
432 0 : aDescription.Truncate();
433 0 : return NS_OK;
434 : }
435 :
436 : NS_IMETHODIMP
437 0 : nsXULListboxAccessible::IsColumnSelected(PRInt32 aColumn, bool *aIsSelected)
438 : {
439 0 : NS_ENSURE_ARG_POINTER(aIsSelected);
440 0 : *aIsSelected = false;
441 :
442 0 : if (IsDefunct())
443 0 : return NS_ERROR_FAILURE;
444 :
445 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
446 0 : do_QueryInterface(mContent);
447 0 : NS_ASSERTION(control,
448 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
449 :
450 0 : PRInt32 selectedrowCount = 0;
451 0 : nsresult rv = control->GetSelectedCount(&selectedrowCount);
452 0 : NS_ENSURE_SUCCESS(rv, rv);
453 :
454 0 : PRInt32 rowCount = 0;
455 0 : rv = GetRowCount(&rowCount);
456 0 : NS_ENSURE_SUCCESS(rv, rv);
457 :
458 0 : *aIsSelected = (selectedrowCount == rowCount);
459 0 : return NS_OK;
460 : }
461 :
462 : NS_IMETHODIMP
463 0 : nsXULListboxAccessible::IsRowSelected(PRInt32 aRow, bool *aIsSelected)
464 : {
465 0 : NS_ENSURE_ARG_POINTER(aIsSelected);
466 0 : *aIsSelected = false;
467 :
468 0 : if (IsDefunct())
469 0 : return NS_ERROR_FAILURE;
470 :
471 : nsCOMPtr<nsIDOMXULSelectControlElement> control =
472 0 : do_QueryInterface(mContent);
473 0 : NS_ASSERTION(control,
474 : "Doesn't implement nsIDOMXULSelectControlElement.");
475 :
476 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
477 0 : control->GetItemAtIndex(aRow, getter_AddRefs(item));
478 0 : NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
479 :
480 0 : return item->GetSelected(aIsSelected);
481 : }
482 :
483 : NS_IMETHODIMP
484 0 : nsXULListboxAccessible::IsCellSelected(PRInt32 aRowIndex, PRInt32 aColumnIndex,
485 : bool *aIsSelected)
486 : {
487 0 : return IsRowSelected(aRowIndex, aIsSelected);
488 : }
489 :
490 : NS_IMETHODIMP
491 0 : nsXULListboxAccessible::GetSelectedCellCount(PRUint32* aCount)
492 : {
493 0 : NS_ENSURE_ARG_POINTER(aCount);
494 0 : *aCount = 0;
495 :
496 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
497 0 : do_QueryInterface(mContent);
498 0 : NS_ASSERTION(control,
499 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
500 :
501 0 : nsCOMPtr<nsIDOMNodeList> selectedItems;
502 0 : control->GetSelectedItems(getter_AddRefs(selectedItems));
503 0 : if (!selectedItems)
504 0 : return NS_OK;
505 :
506 0 : PRUint32 selectedItemsCount = 0;
507 0 : nsresult rv = selectedItems->GetLength(&selectedItemsCount);
508 0 : NS_ENSURE_SUCCESS(rv, rv);
509 :
510 0 : if (!selectedItemsCount)
511 0 : return NS_OK;
512 :
513 0 : PRInt32 columnCount = 0;
514 0 : rv = GetColumnCount(&columnCount);
515 0 : NS_ENSURE_SUCCESS(rv, rv);
516 :
517 0 : *aCount = selectedItemsCount * columnCount;
518 0 : return NS_OK;
519 : }
520 :
521 : NS_IMETHODIMP
522 0 : nsXULListboxAccessible::GetSelectedColumnCount(PRUint32* aCount)
523 : {
524 0 : NS_ENSURE_ARG_POINTER(aCount);
525 0 : *aCount = 0;
526 :
527 0 : if (IsDefunct())
528 0 : return NS_ERROR_FAILURE;
529 :
530 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
531 0 : do_QueryInterface(mContent);
532 0 : NS_ASSERTION(control,
533 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
534 :
535 0 : PRInt32 selectedrowCount = 0;
536 0 : nsresult rv = control->GetSelectedCount(&selectedrowCount);
537 0 : NS_ENSURE_SUCCESS(rv, rv);
538 :
539 0 : PRInt32 rowCount = 0;
540 0 : rv = GetRowCount(&rowCount);
541 0 : NS_ENSURE_SUCCESS(rv, rv);
542 :
543 0 : if (selectedrowCount != rowCount)
544 0 : return NS_OK;
545 :
546 0 : PRInt32 columnCount = 0;
547 0 : rv = GetColumnCount(&columnCount);
548 0 : NS_ENSURE_SUCCESS(rv, rv);
549 :
550 0 : *aCount = columnCount;
551 0 : return NS_OK;
552 : }
553 :
554 : NS_IMETHODIMP
555 0 : nsXULListboxAccessible::GetSelectedRowCount(PRUint32* aCount)
556 : {
557 0 : NS_ENSURE_ARG_POINTER(aCount);
558 0 : *aCount = 0;
559 :
560 0 : if (IsDefunct())
561 0 : return NS_ERROR_FAILURE;
562 :
563 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
564 0 : do_QueryInterface(mContent);
565 0 : NS_ASSERTION(control,
566 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
567 :
568 0 : PRInt32 selectedrowCount = 0;
569 0 : nsresult rv = control->GetSelectedCount(&selectedrowCount);
570 0 : NS_ENSURE_SUCCESS(rv, rv);
571 :
572 0 : *aCount = selectedrowCount;
573 0 : return NS_OK;
574 : }
575 :
576 : NS_IMETHODIMP
577 0 : nsXULListboxAccessible::GetSelectedCells(nsIArray **aCells)
578 : {
579 0 : NS_ENSURE_ARG_POINTER(aCells);
580 0 : *aCells = nsnull;
581 :
582 0 : if (IsDefunct())
583 0 : return NS_ERROR_FAILURE;
584 :
585 0 : nsresult rv = NS_OK;
586 : nsCOMPtr<nsIMutableArray> selCells =
587 0 : do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
588 0 : NS_ENSURE_SUCCESS(rv, rv);
589 :
590 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
591 0 : do_QueryInterface(mContent);
592 0 : NS_ASSERTION(control,
593 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
594 :
595 0 : nsCOMPtr<nsIDOMNodeList> selectedItems;
596 0 : control->GetSelectedItems(getter_AddRefs(selectedItems));
597 0 : if (!selectedItems)
598 0 : return NS_OK;
599 :
600 0 : PRUint32 selectedItemsCount = 0;
601 0 : rv = selectedItems->GetLength(&selectedItemsCount);
602 0 : NS_ENSURE_SUCCESS(rv, rv);
603 :
604 0 : NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE);
605 0 : PRUint32 index = 0;
606 0 : for (; index < selectedItemsCount; index++) {
607 0 : nsCOMPtr<nsIDOMNode> itemNode;
608 0 : selectedItems->Item(index, getter_AddRefs(itemNode));
609 0 : nsCOMPtr<nsIContent> itemContent(do_QueryInterface(itemNode));
610 0 : nsAccessible *item = mDoc->GetAccessible(itemContent);
611 :
612 0 : if (item) {
613 0 : PRInt32 cellCount = item->GetChildCount();
614 0 : for (PRInt32 cellIdx = 0; cellIdx < cellCount; cellIdx++) {
615 0 : nsAccessible *cell = mChildren[cellIdx];
616 0 : if (cell->Role() == roles::CELL)
617 0 : selCells->AppendElement(static_cast<nsIAccessible*>(cell), false);
618 : }
619 : }
620 : }
621 :
622 0 : NS_ADDREF(*aCells = selCells);
623 0 : return NS_OK;
624 : }
625 :
626 : NS_IMETHODIMP
627 0 : nsXULListboxAccessible::GetSelectedCellIndices(PRUint32 *aNumCells,
628 : PRInt32 **aCells)
629 : {
630 0 : NS_ENSURE_ARG_POINTER(aNumCells);
631 0 : *aNumCells = 0;
632 0 : NS_ENSURE_ARG_POINTER(aCells);
633 0 : *aCells = nsnull;
634 :
635 0 : if (IsDefunct())
636 0 : return NS_ERROR_FAILURE;
637 :
638 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
639 0 : do_QueryInterface(mContent);
640 0 : NS_ASSERTION(control,
641 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
642 :
643 0 : nsCOMPtr<nsIDOMNodeList> selectedItems;
644 0 : control->GetSelectedItems(getter_AddRefs(selectedItems));
645 0 : if (!selectedItems)
646 0 : return NS_OK;
647 :
648 0 : PRUint32 selectedItemsCount = 0;
649 0 : nsresult rv = selectedItems->GetLength(&selectedItemsCount);
650 0 : NS_ENSURE_SUCCESS(rv, rv);
651 :
652 0 : PRInt32 columnCount = 0;
653 0 : rv = GetColumnCount(&columnCount);
654 0 : NS_ENSURE_SUCCESS(rv, rv);
655 :
656 0 : PRUint32 cellsCount = selectedItemsCount * columnCount;
657 :
658 : PRInt32 *cellsIdxArray =
659 0 : static_cast<PRInt32*>(nsMemory::Alloc((cellsCount) * sizeof(PRInt32)));
660 0 : NS_ENSURE_TRUE(cellsIdxArray, NS_ERROR_OUT_OF_MEMORY);
661 :
662 0 : PRUint32 index = 0, cellsIdx = 0;
663 0 : for (; index < selectedItemsCount; index++) {
664 0 : nsCOMPtr<nsIDOMNode> itemNode;
665 0 : selectedItems->Item(index, getter_AddRefs(itemNode));
666 : nsCOMPtr<nsIDOMXULSelectControlItemElement> item =
667 0 : do_QueryInterface(itemNode);
668 :
669 0 : if (item) {
670 0 : PRInt32 itemIdx = -1;
671 0 : control->GetIndexOfItem(item, &itemIdx);
672 0 : if (itemIdx != -1) {
673 0 : PRInt32 colIdx = 0;
674 0 : for (; colIdx < columnCount; colIdx++)
675 0 : cellsIdxArray[cellsIdx++] = itemIdx * columnCount + colIdx;
676 : }
677 : }
678 : }
679 :
680 0 : *aNumCells = cellsCount;
681 0 : *aCells = cellsIdxArray;
682 :
683 0 : return NS_OK;
684 : }
685 :
686 : NS_IMETHODIMP
687 0 : nsXULListboxAccessible::GetSelectedColumnIndices(PRUint32 *aNumColumns,
688 : PRInt32 **aColumns)
689 : {
690 0 : NS_ENSURE_ARG_POINTER(aNumColumns);
691 0 : *aNumColumns = 0;
692 0 : NS_ENSURE_ARG_POINTER(aColumns);
693 0 : *aColumns = nsnull;
694 :
695 0 : if (IsDefunct())
696 0 : return NS_ERROR_FAILURE;
697 :
698 0 : PRUint32 columnCount = 0;
699 0 : nsresult rv = GetSelectedColumnCount(&columnCount);
700 0 : NS_ENSURE_SUCCESS(rv, rv);
701 :
702 0 : if (!columnCount)
703 0 : return NS_OK;
704 :
705 : PRInt32 *colsIdxArray =
706 0 : static_cast<PRInt32*>(nsMemory::Alloc((columnCount) * sizeof(PRInt32)));
707 0 : NS_ENSURE_TRUE(colsIdxArray, NS_ERROR_OUT_OF_MEMORY);
708 :
709 0 : PRUint32 colIdx = 0;
710 0 : for (; colIdx < columnCount; colIdx++)
711 0 : colsIdxArray[colIdx] = colIdx;
712 :
713 0 : *aNumColumns = columnCount;
714 0 : *aColumns = colsIdxArray;
715 :
716 0 : return NS_OK;
717 : }
718 :
719 : NS_IMETHODIMP
720 0 : nsXULListboxAccessible::GetSelectedRowIndices(PRUint32 *aNumRows,
721 : PRInt32 **aRows)
722 : {
723 0 : NS_ENSURE_ARG_POINTER(aNumRows);
724 0 : *aNumRows = 0;
725 0 : NS_ENSURE_ARG_POINTER(aRows);
726 0 : *aRows = nsnull;
727 :
728 0 : if (IsDefunct())
729 0 : return NS_ERROR_FAILURE;
730 :
731 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
732 0 : do_QueryInterface(mContent);
733 0 : NS_ASSERTION(control,
734 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
735 :
736 0 : nsCOMPtr<nsIDOMNodeList> selectedItems;
737 0 : control->GetSelectedItems(getter_AddRefs(selectedItems));
738 0 : if (!selectedItems)
739 0 : return NS_OK;
740 :
741 0 : PRUint32 selectedItemsCount = 0;
742 0 : nsresult rv = selectedItems->GetLength(&selectedItemsCount);
743 0 : NS_ENSURE_SUCCESS(rv, rv);
744 :
745 0 : if (!selectedItemsCount)
746 0 : return NS_OK;
747 :
748 : PRInt32 *rowsIdxArray =
749 0 : static_cast<PRInt32*>(nsMemory::Alloc((selectedItemsCount) * sizeof(PRInt32)));
750 0 : NS_ENSURE_TRUE(rowsIdxArray, NS_ERROR_OUT_OF_MEMORY);
751 :
752 0 : PRUint32 index = 0;
753 0 : for (; index < selectedItemsCount; index++) {
754 0 : nsCOMPtr<nsIDOMNode> itemNode;
755 0 : selectedItems->Item(index, getter_AddRefs(itemNode));
756 : nsCOMPtr<nsIDOMXULSelectControlItemElement> item =
757 0 : do_QueryInterface(itemNode);
758 :
759 0 : if (item) {
760 0 : PRInt32 itemIdx = -1;
761 0 : control->GetIndexOfItem(item, &itemIdx);
762 0 : if (itemIdx != -1)
763 0 : rowsIdxArray[index] = itemIdx;
764 : }
765 : }
766 :
767 0 : *aNumRows = selectedItemsCount;
768 0 : *aRows = rowsIdxArray;
769 :
770 0 : return NS_OK;
771 : }
772 :
773 : NS_IMETHODIMP
774 0 : nsXULListboxAccessible::SelectRow(PRInt32 aRow)
775 : {
776 0 : if (IsDefunct())
777 0 : return NS_ERROR_FAILURE;
778 :
779 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
780 0 : do_QueryInterface(mContent);
781 0 : NS_ASSERTION(control,
782 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
783 :
784 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
785 0 : control->GetItemAtIndex(aRow, getter_AddRefs(item));
786 0 : NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
787 :
788 0 : return control->SelectItem(item);
789 : }
790 :
791 : NS_IMETHODIMP
792 0 : nsXULListboxAccessible::SelectColumn(PRInt32 aColumn)
793 : {
794 : // xul:listbox and xul:richlistbox support row selection only.
795 0 : return NS_OK;
796 : }
797 :
798 : NS_IMETHODIMP
799 0 : nsXULListboxAccessible::UnselectRow(PRInt32 aRow)
800 : {
801 0 : if (IsDefunct())
802 0 : return NS_ERROR_FAILURE;
803 :
804 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
805 0 : do_QueryInterface(mContent);
806 0 : NS_ASSERTION(control,
807 : "Doesn't implement nsIDOMXULMultiSelectControlElement.");
808 :
809 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
810 0 : control->GetItemAtIndex(aRow, getter_AddRefs(item));
811 0 : NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
812 :
813 0 : return control->RemoveItemFromSelection(item);
814 : }
815 :
816 : NS_IMETHODIMP
817 0 : nsXULListboxAccessible::UnselectColumn(PRInt32 aColumn)
818 : {
819 : // xul:listbox and xul:richlistbox support row selection only.
820 0 : return NS_OK;
821 : }
822 :
823 : NS_IMETHODIMP
824 0 : nsXULListboxAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
825 : {
826 0 : NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
827 0 : *aIsProbablyForLayout = false;
828 :
829 0 : return NS_OK;
830 : }
831 :
832 : ////////////////////////////////////////////////////////////////////////////////
833 : // nsXULListboxAccessible: Widgets
834 :
835 : bool
836 0 : nsXULListboxAccessible::IsWidget() const
837 : {
838 0 : return true;
839 : }
840 :
841 : bool
842 0 : nsXULListboxAccessible::IsActiveWidget() const
843 : {
844 0 : if (IsAutoCompletePopup()) {
845 : nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm =
846 0 : do_QueryInterface(mContent->GetParent());
847 :
848 0 : if (autoCompletePopupElm) {
849 0 : bool isOpen = false;
850 0 : autoCompletePopupElm->GetPopupOpen(&isOpen);
851 0 : return isOpen;
852 : }
853 : }
854 0 : return FocusMgr()->HasDOMFocus(mContent);
855 : }
856 :
857 : bool
858 0 : nsXULListboxAccessible::AreItemsOperable() const
859 : {
860 0 : if (IsAutoCompletePopup()) {
861 : nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm =
862 0 : do_QueryInterface(mContent->GetParent());
863 :
864 0 : if (autoCompletePopupElm) {
865 0 : bool isOpen = false;
866 0 : autoCompletePopupElm->GetPopupOpen(&isOpen);
867 0 : return isOpen;
868 : }
869 : }
870 0 : return true;
871 : }
872 :
873 : nsAccessible*
874 0 : nsXULListboxAccessible::ContainerWidget() const
875 : {
876 0 : if (IsAutoCompletePopup()) {
877 : // This works for XUL autocompletes. It doesn't work for HTML forms
878 : // autocomplete because of potential crossprocess calls (when autocomplete
879 : // lives in content process while popup lives in chrome process). If that's
880 : // a problem then rethink Widgets interface.
881 : nsCOMPtr<nsIDOMXULMenuListElement> menuListElm =
882 0 : do_QueryInterface(mContent->GetParent());
883 0 : if (menuListElm) {
884 0 : nsCOMPtr<nsIDOMNode> inputElm;
885 0 : menuListElm->GetInputField(getter_AddRefs(inputElm));
886 0 : if (inputElm) {
887 0 : nsCOMPtr<nsINode> inputNode = do_QueryInterface(inputElm);
888 0 : if (inputNode) {
889 : nsAccessible* input =
890 0 : mDoc->GetAccessible(inputNode);
891 0 : return input ? input->ContainerWidget() : nsnull;
892 : }
893 : }
894 : }
895 : }
896 0 : return nsnull;
897 : }
898 :
899 : ////////////////////////////////////////////////////////////////////////////////
900 : // nsXULListitemAccessible
901 : ////////////////////////////////////////////////////////////////////////////////
902 :
903 0 : nsXULListitemAccessible::
904 : nsXULListitemAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
905 0 : nsXULMenuitemAccessible(aContent, aDoc)
906 : {
907 0 : mIsCheckbox = mContent->AttrValueIs(kNameSpaceID_None,
908 : nsGkAtoms::type,
909 : nsGkAtoms::checkbox,
910 0 : eCaseMatters);
911 0 : }
912 :
913 0 : NS_IMPL_ISUPPORTS_INHERITED0(nsXULListitemAccessible, nsAccessible)
914 :
915 : nsAccessible *
916 0 : nsXULListitemAccessible::GetListAccessible()
917 : {
918 0 : if (IsDefunct())
919 0 : return nsnull;
920 :
921 : nsCOMPtr<nsIDOMXULSelectControlItemElement> listItem =
922 0 : do_QueryInterface(mContent);
923 0 : if (!listItem)
924 0 : return nsnull;
925 :
926 0 : nsCOMPtr<nsIDOMXULSelectControlElement> list;
927 0 : listItem->GetControl(getter_AddRefs(list));
928 :
929 0 : nsCOMPtr<nsIContent> listContent(do_QueryInterface(list));
930 0 : if (!listContent)
931 0 : return nsnull;
932 :
933 0 : return mDoc->GetAccessible(listContent);
934 : }
935 :
936 : ////////////////////////////////////////////////////////////////////////////////
937 : // nsXULListitemAccessible nsAccessible
938 :
939 : void
940 0 : nsXULListitemAccessible::Description(nsString& aDesc)
941 : {
942 0 : nsAccessibleWrap::Description(aDesc);
943 0 : }
944 :
945 : ////////////////////////////////////////////////////////////////////////////////
946 : // nsXULListitemAccessible. nsIAccessible
947 :
948 : /**
949 : * If there is a Listcell as a child ( not anonymous ) use it, otherwise
950 : * default to getting the name from GetXULName
951 : */
952 : nsresult
953 0 : nsXULListitemAccessible::GetNameInternal(nsAString& aName)
954 : {
955 0 : nsIContent* childContent = mContent->GetFirstChild();
956 0 : if (childContent) {
957 0 : if (childContent->NodeInfo()->Equals(nsGkAtoms::listcell,
958 0 : kNameSpaceID_XUL)) {
959 0 : childContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
960 0 : return NS_OK;
961 : }
962 : }
963 0 : return GetXULName(aName);
964 : }
965 :
966 : role
967 0 : nsXULListitemAccessible::NativeRole()
968 : {
969 0 : nsAccessible *list = GetListAccessible();
970 0 : if (!list) {
971 0 : NS_ERROR("No list accessible for listitem accessible!");
972 0 : return roles::NOTHING;
973 : }
974 :
975 0 : if (list->Role() == roles::TABLE)
976 0 : return roles::ROW;
977 :
978 0 : if (mIsCheckbox)
979 0 : return roles::CHECKBUTTON;
980 :
981 0 : if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
982 0 : return roles::COMBOBOX_OPTION;
983 :
984 0 : return roles::RICH_OPTION;
985 : }
986 :
987 : PRUint64
988 0 : nsXULListitemAccessible::NativeState()
989 : {
990 0 : if (mIsCheckbox)
991 0 : return nsXULMenuitemAccessible::NativeState();
992 :
993 0 : PRUint64 states = states::FOCUSABLE | states::SELECTABLE;
994 :
995 : nsCOMPtr<nsIDOMXULSelectControlItemElement> listItem =
996 0 : do_QueryInterface(mContent);
997 :
998 0 : if (listItem) {
999 : bool isSelected;
1000 0 : listItem->GetSelected(&isSelected);
1001 0 : if (isSelected)
1002 0 : states |= states::SELECTED;
1003 :
1004 0 : if (FocusMgr()->IsFocused(this))
1005 0 : states |= states::FOCUSED;
1006 : }
1007 :
1008 0 : return states;
1009 : }
1010 :
1011 0 : NS_IMETHODIMP nsXULListitemAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
1012 : {
1013 0 : if (aIndex == eAction_Click && mIsCheckbox) {
1014 : // check or uncheck
1015 0 : PRUint64 states = NativeState();
1016 :
1017 0 : if (states & states::CHECKED)
1018 0 : aName.AssignLiteral("uncheck");
1019 : else
1020 0 : aName.AssignLiteral("check");
1021 :
1022 0 : return NS_OK;
1023 : }
1024 0 : return NS_ERROR_INVALID_ARG;
1025 : }
1026 :
1027 : bool
1028 0 : nsXULListitemAccessible::CanHaveAnonChildren()
1029 : {
1030 : // That indicates we should walk anonymous children for listitems
1031 0 : return true;
1032 : }
1033 :
1034 : void
1035 0 : nsXULListitemAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
1036 : PRInt32 *aSetSize)
1037 : {
1038 : nsAccUtils::GetPositionAndSizeForXULSelectControlItem(mContent, aPosInSet,
1039 0 : aSetSize);
1040 0 : }
1041 :
1042 : ////////////////////////////////////////////////////////////////////////////////
1043 : // nsXULListitemAccessible: Widgets
1044 :
1045 : nsAccessible*
1046 0 : nsXULListitemAccessible::ContainerWidget() const
1047 : {
1048 0 : return Parent();
1049 : }
1050 :
1051 :
1052 : ////////////////////////////////////////////////////////////////////////////////
1053 : // nsXULListCellAccessible
1054 : ////////////////////////////////////////////////////////////////////////////////
1055 :
1056 0 : nsXULListCellAccessible::
1057 : nsXULListCellAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
1058 0 : nsHyperTextAccessibleWrap(aContent, aDoc)
1059 : {
1060 0 : }
1061 :
1062 : ////////////////////////////////////////////////////////////////////////////////
1063 : // nsISupports
1064 :
1065 0 : NS_IMPL_ISUPPORTS_INHERITED1(nsXULListCellAccessible,
1066 : nsHyperTextAccessible,
1067 : nsIAccessibleTableCell)
1068 :
1069 : ////////////////////////////////////////////////////////////////////////////////
1070 : // nsXULListCellAccessible: nsIAccessibleTableCell implementation
1071 :
1072 : NS_IMETHODIMP
1073 0 : nsXULListCellAccessible::GetTable(nsIAccessibleTable **aTable)
1074 : {
1075 0 : NS_ENSURE_ARG_POINTER(aTable);
1076 0 : *aTable = nsnull;
1077 :
1078 0 : if (IsDefunct())
1079 0 : return NS_ERROR_FAILURE;
1080 :
1081 0 : nsAccessible* thisRow = Parent();
1082 0 : if (!thisRow || thisRow->Role() != roles::ROW)
1083 0 : return NS_OK;
1084 :
1085 0 : nsAccessible* table = thisRow->Parent();
1086 0 : if (!table || table->Role() != roles::TABLE)
1087 0 : return NS_OK;
1088 :
1089 0 : CallQueryInterface(table, aTable);
1090 0 : return NS_OK;
1091 : }
1092 :
1093 : NS_IMETHODIMP
1094 0 : nsXULListCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
1095 : {
1096 0 : NS_ENSURE_ARG_POINTER(aColumnIndex);
1097 0 : *aColumnIndex = -1;
1098 :
1099 0 : if (IsDefunct())
1100 0 : return NS_ERROR_FAILURE;
1101 :
1102 0 : nsAccessible* row = Parent();
1103 0 : if (!row)
1104 0 : return NS_OK;
1105 :
1106 0 : *aColumnIndex = 0;
1107 :
1108 0 : PRInt32 indexInRow = IndexInParent();
1109 0 : for (PRInt32 idx = 0; idx < indexInRow; idx++) {
1110 0 : nsAccessible* cell = row->GetChildAt(idx);
1111 0 : roles::Role role = cell->Role();
1112 0 : if (role == roles::CELL || role == roles::GRID_CELL ||
1113 : role == roles::ROWHEADER || role == roles::COLUMNHEADER)
1114 0 : (*aColumnIndex)++;
1115 : }
1116 :
1117 0 : return NS_OK;
1118 : }
1119 :
1120 : NS_IMETHODIMP
1121 0 : nsXULListCellAccessible::GetRowIndex(PRInt32 *aRowIndex)
1122 : {
1123 0 : NS_ENSURE_ARG_POINTER(aRowIndex);
1124 0 : *aRowIndex = -1;
1125 :
1126 0 : if (IsDefunct())
1127 0 : return NS_ERROR_FAILURE;
1128 :
1129 0 : nsAccessible* row = Parent();
1130 0 : if (!row)
1131 0 : return NS_OK;
1132 :
1133 0 : nsAccessible* table = row->Parent();
1134 0 : if (!table)
1135 0 : return NS_OK;
1136 :
1137 0 : *aRowIndex = 0;
1138 :
1139 0 : PRInt32 indexInTable = row->IndexInParent();
1140 0 : for (PRInt32 idx = 0; idx < indexInTable; idx++) {
1141 0 : row = table->GetChildAt(idx);
1142 0 : if (row->Role() == roles::ROW)
1143 0 : (*aRowIndex)++;
1144 : }
1145 :
1146 0 : return NS_OK;
1147 : }
1148 :
1149 : NS_IMETHODIMP
1150 0 : nsXULListCellAccessible::GetColumnExtent(PRInt32 *aExtentCount)
1151 : {
1152 0 : NS_ENSURE_ARG_POINTER(aExtentCount);
1153 0 : *aExtentCount = 0;
1154 :
1155 0 : if (IsDefunct())
1156 0 : return NS_ERROR_FAILURE;
1157 :
1158 0 : *aExtentCount = 1;
1159 0 : return NS_OK;
1160 : }
1161 :
1162 : NS_IMETHODIMP
1163 0 : nsXULListCellAccessible::GetRowExtent(PRInt32 *aExtentCount)
1164 : {
1165 0 : NS_ENSURE_ARG_POINTER(aExtentCount);
1166 0 : *aExtentCount = 0;
1167 :
1168 0 : if (IsDefunct())
1169 0 : return NS_ERROR_FAILURE;
1170 :
1171 0 : *aExtentCount = 1;
1172 0 : return NS_OK;
1173 : }
1174 :
1175 : NS_IMETHODIMP
1176 0 : nsXULListCellAccessible::GetColumnHeaderCells(nsIArray **aHeaderCells)
1177 : {
1178 0 : NS_ENSURE_ARG_POINTER(aHeaderCells);
1179 0 : *aHeaderCells = nsnull;
1180 :
1181 0 : if (IsDefunct())
1182 0 : return NS_ERROR_FAILURE;
1183 :
1184 0 : nsCOMPtr<nsIAccessibleTable> table;
1185 0 : GetTable(getter_AddRefs(table));
1186 0 : NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
1187 :
1188 : // Get column header cell from XUL listhead.
1189 0 : nsAccessible *list = nsnull;
1190 :
1191 0 : nsRefPtr<nsAccessible> tableAcc(do_QueryObject(table));
1192 0 : PRInt32 tableChildCount = tableAcc->GetChildCount();
1193 0 : for (PRInt32 childIdx = 0; childIdx < tableChildCount; childIdx++) {
1194 0 : nsAccessible *child = tableAcc->GetChildAt(childIdx);
1195 0 : if (child->Role() == roles::LIST) {
1196 0 : list = child;
1197 0 : break;
1198 : }
1199 : }
1200 :
1201 0 : if (list) {
1202 0 : PRInt32 colIdx = -1;
1203 0 : GetColumnIndex(&colIdx);
1204 :
1205 0 : nsIAccessible *headerCell = list->GetChildAt(colIdx);
1206 0 : if (headerCell) {
1207 0 : nsresult rv = NS_OK;
1208 : nsCOMPtr<nsIMutableArray> headerCells =
1209 0 : do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
1210 0 : NS_ENSURE_SUCCESS(rv, rv);
1211 :
1212 0 : headerCells->AppendElement(headerCell, false);
1213 0 : NS_ADDREF(*aHeaderCells = headerCells);
1214 0 : return NS_OK;
1215 : }
1216 : }
1217 :
1218 : // No column header cell from XUL markup, try to get it from ARIA markup.
1219 : return nsAccUtils::GetHeaderCellsFor(table, this,
1220 : nsAccUtils::eColumnHeaderCells,
1221 0 : aHeaderCells);
1222 : }
1223 :
1224 : NS_IMETHODIMP
1225 0 : nsXULListCellAccessible::GetRowHeaderCells(nsIArray **aHeaderCells)
1226 : {
1227 0 : NS_ENSURE_ARG_POINTER(aHeaderCells);
1228 0 : *aHeaderCells = nsnull;
1229 :
1230 0 : if (IsDefunct())
1231 0 : return NS_ERROR_FAILURE;
1232 :
1233 0 : nsCOMPtr<nsIAccessibleTable> table;
1234 0 : GetTable(getter_AddRefs(table));
1235 0 : NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
1236 :
1237 : // Calculate row header cells from ARIA markup.
1238 : return nsAccUtils::GetHeaderCellsFor(table, this,
1239 : nsAccUtils::eRowHeaderCells,
1240 0 : aHeaderCells);
1241 : }
1242 :
1243 : NS_IMETHODIMP
1244 0 : nsXULListCellAccessible::IsSelected(bool *aIsSelected)
1245 : {
1246 0 : NS_ENSURE_ARG_POINTER(aIsSelected);
1247 0 : *aIsSelected = false;
1248 :
1249 0 : if (IsDefunct())
1250 0 : return NS_ERROR_FAILURE;
1251 :
1252 0 : nsCOMPtr<nsIAccessibleTable> table;
1253 0 : GetTable(getter_AddRefs(table));
1254 0 : NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
1255 :
1256 0 : PRInt32 rowIdx = -1;
1257 0 : GetRowIndex(&rowIdx);
1258 :
1259 0 : return table->IsRowSelected(rowIdx, aIsSelected);
1260 : }
1261 :
1262 : ////////////////////////////////////////////////////////////////////////////////
1263 : // nsXULListCellAccessible. nsAccessible implementation
1264 :
1265 : role
1266 0 : nsXULListCellAccessible::NativeRole()
1267 : {
1268 0 : return roles::CELL;
1269 : }
1270 :
1271 : nsresult
1272 0 : nsXULListCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
1273 : {
1274 0 : NS_ENSURE_ARG_POINTER(aAttributes);
1275 :
1276 0 : if (IsDefunct())
1277 0 : return NS_ERROR_FAILURE;
1278 :
1279 : // "table-cell-index" attribute
1280 0 : nsCOMPtr<nsIAccessibleTable> table;
1281 0 : GetTable(getter_AddRefs(table));
1282 0 : NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
1283 :
1284 0 : PRInt32 rowIdx = -1;
1285 0 : GetRowIndex(&rowIdx);
1286 0 : PRInt32 colIdx = -1;
1287 0 : GetColumnIndex(&colIdx);
1288 :
1289 0 : PRInt32 cellIdx = -1;
1290 0 : table->GetCellIndexAt(rowIdx, colIdx, &cellIdx);
1291 :
1292 0 : nsAutoString stringIdx;
1293 0 : stringIdx.AppendInt(cellIdx);
1294 : nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
1295 0 : stringIdx);
1296 :
1297 0 : return NS_OK;
1298 : }
|