1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "XULTreeGridAccessible.h"
9 #include "AccAttributes.h"
10 #include "LocalAccessible-inl.h"
11 #include "nsAccCache.h"
12 #include "nsAccessibilityService.h"
13 #include "nsAccUtils.h"
14 #include "DocAccessible.h"
15 #include "nsEventShell.h"
17 #include "mozilla/a11y/Role.h"
19 #include "nsQueryObject.h"
20 #include "nsTreeColumns.h"
22 #include "nsITreeSelection.h"
23 #include "nsComponentManagerUtils.h"
24 #include "mozilla/PresShell.h"
25 #include "mozilla/a11y/TableAccessible.h"
26 #include "mozilla/dom/Element.h"
27 #include "mozilla/dom/TreeColumnBinding.h"
28 #include "mozilla/dom/XULTreeElementBinding.h"
30 using namespace mozilla::a11y
;
31 using namespace mozilla
;
33 XULTreeGridAccessible::~XULTreeGridAccessible() {}
35 ////////////////////////////////////////////////////////////////////////////////
36 // XULTreeGridAccessible: Table
38 uint32_t XULTreeGridAccessible::ColCount() const {
39 return nsCoreUtils::GetSensibleColumnCount(mTree
);
42 uint32_t XULTreeGridAccessible::RowCount() {
43 if (!mTreeView
) return 0;
46 mTreeView
->GetRowCount(&rowCount
);
47 return rowCount
>= 0 ? rowCount
: 0;
50 uint32_t XULTreeGridAccessible::SelectedCellCount() {
51 return SelectedRowCount() * ColCount();
54 uint32_t XULTreeGridAccessible::SelectedColCount() {
55 // If all the row has been selected, then all the columns are selected,
56 // because we can't select a column alone.
58 uint32_t selectedRowCount
= SelectedItemCount();
59 return selectedRowCount
> 0 && selectedRowCount
== RowCount() ? ColCount()
63 uint32_t XULTreeGridAccessible::SelectedRowCount() {
64 return SelectedItemCount();
67 void XULTreeGridAccessible::SelectedCells(nsTArray
<Accessible
*>* aCells
) {
68 uint32_t colCount
= ColCount(), rowCount
= RowCount();
70 for (uint32_t rowIdx
= 0; rowIdx
< rowCount
; rowIdx
++) {
71 if (IsRowSelected(rowIdx
)) {
72 for (uint32_t colIdx
= 0; colIdx
< colCount
; colIdx
++) {
73 LocalAccessible
* cell
= CellAt(rowIdx
, colIdx
);
74 aCells
->AppendElement(cell
);
80 void XULTreeGridAccessible::SelectedCellIndices(nsTArray
<uint32_t>* aCells
) {
81 uint32_t colCount
= ColCount(), rowCount
= RowCount();
83 for (uint32_t rowIdx
= 0; rowIdx
< rowCount
; rowIdx
++) {
84 if (IsRowSelected(rowIdx
)) {
85 for (uint32_t colIdx
= 0; colIdx
< colCount
; colIdx
++) {
86 aCells
->AppendElement(rowIdx
* colCount
+ colIdx
);
92 void XULTreeGridAccessible::SelectedColIndices(nsTArray
<uint32_t>* aCols
) {
93 if (RowCount() != SelectedRowCount()) return;
95 uint32_t colCount
= ColCount();
96 aCols
->SetCapacity(colCount
);
97 for (uint32_t colIdx
= 0; colIdx
< colCount
; colIdx
++) {
98 aCols
->AppendElement(colIdx
);
102 void XULTreeGridAccessible::SelectedRowIndices(nsTArray
<uint32_t>* aRows
) {
103 uint32_t rowCount
= RowCount();
104 for (uint32_t rowIdx
= 0; rowIdx
< rowCount
; rowIdx
++) {
105 if (IsRowSelected(rowIdx
)) aRows
->AppendElement(rowIdx
);
109 LocalAccessible
* XULTreeGridAccessible::CellAt(uint32_t aRowIndex
,
110 uint32_t aColumnIndex
) {
111 XULTreeItemAccessibleBase
* rowAcc
= GetTreeItemAccessible(aRowIndex
);
112 if (!rowAcc
) return nullptr;
114 RefPtr
<nsTreeColumn
> column
=
115 nsCoreUtils::GetSensibleColumnAt(mTree
, aColumnIndex
);
116 if (!column
) return nullptr;
118 return rowAcc
->GetCellAccessible(column
);
121 void XULTreeGridAccessible::ColDescription(uint32_t aColIdx
,
122 nsString
& aDescription
) {
123 aDescription
.Truncate();
125 LocalAccessible
* treeColumns
= LocalAccessible::LocalChildAt(0);
127 LocalAccessible
* treeColumnItem
= treeColumns
->LocalChildAt(aColIdx
);
128 if (treeColumnItem
) treeColumnItem
->Name(aDescription
);
132 bool XULTreeGridAccessible::IsColSelected(uint32_t aColIdx
) {
133 // If all the row has been selected, then all the columns are selected.
134 // Because we can't select a column alone.
135 return SelectedItemCount() == RowCount();
138 bool XULTreeGridAccessible::IsRowSelected(uint32_t aRowIdx
) {
139 if (!mTreeView
) return false;
141 nsCOMPtr
<nsITreeSelection
> selection
;
142 nsresult rv
= mTreeView
->GetSelection(getter_AddRefs(selection
));
143 NS_ENSURE_SUCCESS(rv
, false);
145 bool isSelected
= false;
146 selection
->IsSelected(aRowIdx
, &isSelected
);
150 bool XULTreeGridAccessible::IsCellSelected(uint32_t aRowIdx
, uint32_t aColIdx
) {
151 return IsRowSelected(aRowIdx
);
154 int32_t XULTreeGridAccessible::ColIndexAt(uint32_t aCellIdx
) {
155 uint32_t colCount
= ColCount();
156 if (colCount
< 1 || aCellIdx
>= colCount
* RowCount()) {
157 return -1; // Error: column count is 0 or index out of bounds.
160 return static_cast<int32_t>(aCellIdx
% colCount
);
163 int32_t XULTreeGridAccessible::RowIndexAt(uint32_t aCellIdx
) {
164 uint32_t colCount
= ColCount();
165 if (colCount
< 1 || aCellIdx
>= colCount
* RowCount()) {
166 return -1; // Error: column count is 0 or index out of bounds.
169 return static_cast<int32_t>(aCellIdx
/ colCount
);
172 void XULTreeGridAccessible::RowAndColIndicesAt(uint32_t aCellIdx
,
175 uint32_t colCount
= ColCount();
176 if (colCount
< 1 || aCellIdx
>= colCount
* RowCount()) {
179 return; // Error: column count is 0 or index out of bounds.
182 *aRowIdx
= static_cast<int32_t>(aCellIdx
/ colCount
);
183 *aColIdx
= static_cast<int32_t>(aCellIdx
% colCount
);
186 ////////////////////////////////////////////////////////////////////////////////
187 // XULTreeGridAccessible: LocalAccessible implementation
189 role
XULTreeGridAccessible::NativeRole() const {
190 RefPtr
<nsTreeColumns
> treeColumns
= mTree
->GetColumns(FlushType::None
);
192 NS_ERROR("No treecolumns object for tree!");
193 return roles::NOTHING
;
196 nsTreeColumn
* primaryColumn
= treeColumns
->GetPrimaryColumn();
198 return primaryColumn
? roles::TREE_TABLE
: roles::TABLE
;
201 ////////////////////////////////////////////////////////////////////////////////
202 // XULTreeGridAccessible: XULTreeAccessible implementation
204 already_AddRefed
<XULTreeItemAccessibleBase
>
205 XULTreeGridAccessible::CreateTreeItemAccessible(int32_t aRow
) const {
206 RefPtr
<XULTreeItemAccessibleBase
> accessible
= new XULTreeGridRowAccessible(
207 mContent
, mDoc
, const_cast<XULTreeGridAccessible
*>(this), mTree
,
210 return accessible
.forget();
213 ////////////////////////////////////////////////////////////////////////////////
214 // XULTreeGridRowAccessible
215 ////////////////////////////////////////////////////////////////////////////////
217 XULTreeGridRowAccessible::XULTreeGridRowAccessible(
218 nsIContent
* aContent
, DocAccessible
* aDoc
, LocalAccessible
* aTreeAcc
,
219 dom::XULTreeElement
* aTree
, nsITreeView
* aTreeView
, int32_t aRow
)
220 : XULTreeItemAccessibleBase(aContent
, aDoc
, aTreeAcc
, aTree
, aTreeView
,
222 mAccessibleCache(kDefaultTreeCacheLength
) {
223 mGenericTypes
|= eTableRow
;
224 mStateFlags
|= eNoKidsFromDOM
;
227 XULTreeGridRowAccessible::~XULTreeGridRowAccessible() {}
229 ////////////////////////////////////////////////////////////////////////////////
230 // XULTreeGridRowAccessible: nsISupports and cycle collection implementation
232 NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridRowAccessible
,
233 XULTreeItemAccessibleBase
, mAccessibleCache
)
235 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeGridRowAccessible
)
236 NS_INTERFACE_MAP_END_INHERITING(XULTreeItemAccessibleBase
)
238 NS_IMPL_ADDREF_INHERITED(XULTreeGridRowAccessible
, XULTreeItemAccessibleBase
)
239 NS_IMPL_RELEASE_INHERITED(XULTreeGridRowAccessible
, XULTreeItemAccessibleBase
)
241 ////////////////////////////////////////////////////////////////////////////////
242 // XULTreeGridRowAccessible: LocalAccessible implementation
244 void XULTreeGridRowAccessible::Shutdown() {
245 if (mDoc
&& !mDoc
->IsDefunct()) {
246 UnbindCacheEntriesFromDocument(mAccessibleCache
);
249 XULTreeItemAccessibleBase::Shutdown();
252 role
XULTreeGridRowAccessible::NativeRole() const { return roles::ROW
; }
254 ENameValueFlag
XULTreeGridRowAccessible::Name(nsString
& aName
) const {
257 // XXX: the row name sholdn't be a concatenation of cell names (bug 664384).
258 RefPtr
<nsTreeColumn
> column
= nsCoreUtils::GetFirstSensibleColumn(mTree
);
260 if (!aName
.IsEmpty()) aName
.Append(' ');
262 nsAutoString cellName
;
263 GetCellName(column
, cellName
);
264 aName
.Append(cellName
);
266 column
= nsCoreUtils::GetNextSensibleColumn(column
);
272 LocalAccessible
* XULTreeGridRowAccessible::LocalChildAtPoint(
273 int32_t aX
, int32_t aY
, EWhichChildAtPoint aWhichChild
) {
274 nsIFrame
* frame
= GetFrame();
275 if (!frame
) return nullptr;
277 nsPresContext
* presContext
= frame
->PresContext();
278 PresShell
* presShell
= presContext
->PresShell();
280 nsIFrame
* rootFrame
= presShell
->GetRootFrame();
281 NS_ENSURE_TRUE(rootFrame
, nullptr);
283 CSSIntRect rootRect
= rootFrame
->GetScreenRect();
285 int32_t clientX
= presContext
->DevPixelsToIntCSSPixels(aX
) - rootRect
.X();
286 int32_t clientY
= presContext
->DevPixelsToIntCSSPixels(aY
) - rootRect
.Y();
289 dom::TreeCellInfo cellInfo
;
290 mTree
->GetCellAt(clientX
, clientY
, cellInfo
, rv
);
292 // Return if we failed to find tree cell in the row for the given point.
293 if (cellInfo
.mRow
!= mRow
|| !cellInfo
.mCol
) return nullptr;
295 return GetCellAccessible(cellInfo
.mCol
);
298 LocalAccessible
* XULTreeGridRowAccessible::LocalChildAt(uint32_t aIndex
) const {
299 if (IsDefunct()) return nullptr;
301 RefPtr
<nsTreeColumn
> column
= nsCoreUtils::GetSensibleColumnAt(mTree
, aIndex
);
302 if (!column
) return nullptr;
304 return GetCellAccessible(column
);
307 uint32_t XULTreeGridRowAccessible::ChildCount() const {
308 return nsCoreUtils::GetSensibleColumnCount(mTree
);
311 ////////////////////////////////////////////////////////////////////////////////
312 // XULTreeGridRowAccessible: XULTreeItemAccessibleBase implementation
314 XULTreeGridCellAccessible
* XULTreeGridRowAccessible::GetCellAccessible(
315 nsTreeColumn
* aColumn
) const {
316 MOZ_ASSERT(aColumn
, "No tree column!");
318 void* key
= static_cast<void*>(aColumn
);
319 XULTreeGridCellAccessible
* cachedCell
= mAccessibleCache
.GetWeak(key
);
320 if (cachedCell
) return cachedCell
;
322 RefPtr
<XULTreeGridCellAccessible
> cell
= new XULTreeGridCellAccessible(
323 mContent
, mDoc
, const_cast<XULTreeGridRowAccessible
*>(this), mTree
,
324 mTreeView
, mRow
, aColumn
);
325 mAccessibleCache
.InsertOrUpdate(key
, RefPtr
{cell
});
326 Document()->BindToDocument(cell
, nullptr);
330 void XULTreeGridRowAccessible::RowInvalidated(int32_t aStartColIdx
,
331 int32_t aEndColIdx
) {
332 RefPtr
<nsTreeColumns
> treeColumns
= mTree
->GetColumns(FlushType::None
);
333 if (!treeColumns
) return;
335 bool nameChanged
= false;
336 for (int32_t colIdx
= aStartColIdx
; colIdx
<= aEndColIdx
; ++colIdx
) {
337 nsTreeColumn
* column
= treeColumns
->GetColumnAt(colIdx
);
338 if (column
&& !nsCoreUtils::IsColumnHidden(column
)) {
339 XULTreeGridCellAccessible
* cell
= GetCellAccessible(column
);
340 if (cell
) nameChanged
|= cell
->CellInvalidated();
345 nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE
, this);
349 ////////////////////////////////////////////////////////////////////////////////
350 // XULTreeGridCellAccessible
351 ////////////////////////////////////////////////////////////////////////////////
353 XULTreeGridCellAccessible::XULTreeGridCellAccessible(
354 nsIContent
* aContent
, DocAccessible
* aDoc
,
355 XULTreeGridRowAccessible
* aRowAcc
, dom::XULTreeElement
* aTree
,
356 nsITreeView
* aTreeView
, int32_t aRow
, nsTreeColumn
* aColumn
)
357 : LeafAccessible(aContent
, aDoc
),
359 mTreeView(aTreeView
),
363 mStateFlags
|= eSharedNode
;
364 mGenericTypes
|= eTableCell
;
366 NS_ASSERTION(mTreeView
, "mTreeView is null");
368 if (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
) {
369 mTreeView
->GetCellValue(mRow
, mColumn
, mCachedTextEquiv
);
371 mTreeView
->GetCellText(mRow
, mColumn
, mCachedTextEquiv
);
375 XULTreeGridCellAccessible::~XULTreeGridCellAccessible() {}
377 ////////////////////////////////////////////////////////////////////////////////
378 // XULTreeGridCellAccessible: nsISupports implementation
380 NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridCellAccessible
, LeafAccessible
,
383 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeGridCellAccessible
)
384 NS_INTERFACE_MAP_END_INHERITING(LeafAccessible
)
385 NS_IMPL_ADDREF_INHERITED(XULTreeGridCellAccessible
, LeafAccessible
)
386 NS_IMPL_RELEASE_INHERITED(XULTreeGridCellAccessible
, LeafAccessible
)
388 ////////////////////////////////////////////////////////////////////////////////
389 // XULTreeGridCellAccessible: LocalAccessible
391 void XULTreeGridCellAccessible::Shutdown() {
396 mParent
= nullptr; // null-out to prevent base class's shutdown ops
398 LeafAccessible::Shutdown();
401 Accessible
* XULTreeGridCellAccessible::FocusedChild() { return nullptr; }
403 ENameValueFlag
XULTreeGridCellAccessible::Name(nsString
& aName
) const {
406 if (!mTreeView
) return eNameOK
;
408 mTreeView
->GetCellText(mRow
, mColumn
, aName
);
410 // If there is still no name try the cell value:
411 // This is for graphical cells. We need tree/table view implementors to
412 // implement FooView::GetCellValue to return a meaningful string for cases
413 // where there is something shown in the cell (non-text) such as a star icon;
414 // in which case GetCellValue for that cell would return "starred" or
415 // "flagged" for example.
416 if (aName
.IsEmpty()) mTreeView
->GetCellValue(mRow
, mColumn
, aName
);
421 nsIntRect
XULTreeGridCellAccessible::BoundsInCSSPixels() const {
422 // Get bounds for tree cell and add x and y of treechildren element to
423 // x and y of the cell.
425 nsIntRect rect
= mTree
->GetCoordsForCellItem(mRow
, mColumn
, u
"cell"_ns
, rv
);
430 RefPtr
<dom::Element
> bodyElement
= mTree
->GetTreeBody();
431 if (!bodyElement
|| !bodyElement
->IsXULElement()) {
435 nsIFrame
* bodyFrame
= bodyElement
->GetPrimaryFrame();
440 CSSIntRect screenRect
= bodyFrame
->GetScreenRect();
441 rect
.x
+= screenRect
.x
;
442 rect
.y
+= screenRect
.y
;
446 nsRect
XULTreeGridCellAccessible::BoundsInAppUnits() const {
447 nsIntRect bounds
= BoundsInCSSPixels();
448 nsPresContext
* presContext
= mDoc
->PresContext();
449 return nsRect(presContext
->CSSPixelsToAppUnits(bounds
.X()),
450 presContext
->CSSPixelsToAppUnits(bounds
.Y()),
451 presContext
->CSSPixelsToAppUnits(bounds
.Width()),
452 presContext
->CSSPixelsToAppUnits(bounds
.Height()));
455 bool XULTreeGridCellAccessible::HasPrimaryAction() const {
456 return mColumn
->Cycler() ||
457 (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
&&
461 void XULTreeGridCellAccessible::ActionNameAt(uint8_t aIndex
, nsAString
& aName
) {
464 if (aIndex
!= eAction_Click
|| !mTreeView
) return;
466 if (mColumn
->Cycler()) {
467 aName
.AssignLiteral("cycle");
471 if (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
&&
474 mTreeView
->GetCellValue(mRow
, mColumn
, value
);
475 if (value
.EqualsLiteral("true")) {
476 aName
.AssignLiteral("uncheck");
478 aName
.AssignLiteral("check");
483 ////////////////////////////////////////////////////////////////////////////////
484 // XULTreeGridCellAccessible: TableCell
486 TableAccessible
* XULTreeGridCellAccessible::Table() const {
487 LocalAccessible
* grandParent
= mParent
->LocalParent();
488 if (grandParent
) return grandParent
->AsTable();
493 uint32_t XULTreeGridCellAccessible::ColIdx() const {
495 RefPtr
<nsTreeColumn
> column
= mColumn
;
496 while ((column
= nsCoreUtils::GetPreviousSensibleColumn(column
))) colIdx
++;
501 uint32_t XULTreeGridCellAccessible::RowIdx() const { return mRow
; }
503 void XULTreeGridCellAccessible::ColHeaderCells(
504 nsTArray
<Accessible
*>* aHeaderCells
) {
505 dom::Element
* columnElm
= mColumn
->Element();
507 LocalAccessible
* headerCell
= mDoc
->GetAccessible(columnElm
);
508 if (headerCell
) aHeaderCells
->AppendElement(headerCell
);
511 bool XULTreeGridCellAccessible::Selected() {
512 nsCOMPtr
<nsITreeSelection
> selection
;
513 nsresult rv
= mTreeView
->GetSelection(getter_AddRefs(selection
));
514 NS_ENSURE_SUCCESS(rv
, false);
516 bool selected
= false;
517 selection
->IsSelected(mRow
, &selected
);
521 ////////////////////////////////////////////////////////////////////////////////
522 // XULTreeGridCellAccessible: LocalAccessible public implementation
524 already_AddRefed
<AccAttributes
> XULTreeGridCellAccessible::NativeAttributes() {
525 RefPtr
<AccAttributes
> attributes
= new AccAttributes();
527 // "table-cell-index" attribute
528 TableAccessible
* table
= Table();
529 if (!table
) return attributes
.forget();
531 attributes
->SetAttribute(nsGkAtoms::tableCellIndex
,
532 table
->CellIndexAt(mRow
, ColIdx()));
534 // "cycles" attribute
535 if (mColumn
->Cycler()) {
536 attributes
->SetAttribute(nsGkAtoms::cycles
, true);
539 return attributes
.forget();
542 role
XULTreeGridCellAccessible::NativeRole() const { return roles::GRID_CELL
; }
544 uint64_t XULTreeGridCellAccessible::NativeState() const {
545 if (!mTreeView
) return states::DEFUNCT
;
547 // selectable/selected state
549 states::SELECTABLE
; // keep in sync with NativeInteractiveState
551 nsCOMPtr
<nsITreeSelection
> selection
;
552 mTreeView
->GetSelection(getter_AddRefs(selection
));
554 bool isSelected
= false;
555 selection
->IsSelected(mRow
, &isSelected
);
556 if (isSelected
) states
|= states::SELECTED
;
560 if (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
) {
561 states
|= states::CHECKABLE
;
562 nsAutoString checked
;
563 mTreeView
->GetCellValue(mRow
, mColumn
, checked
);
564 if (checked
.EqualsIgnoreCase("true")) states
|= states::CHECKED
;
570 uint64_t XULTreeGridCellAccessible::NativeInteractiveState() const {
571 return states::SELECTABLE
;
574 int32_t XULTreeGridCellAccessible::IndexInParent() const { return ColIdx(); }
576 Relation
XULTreeGridCellAccessible::RelationByType(RelationType aType
) const {
580 ////////////////////////////////////////////////////////////////////////////////
581 // XULTreeGridCellAccessible: public implementation
583 bool XULTreeGridCellAccessible::CellInvalidated() {
584 nsAutoString textEquiv
;
586 if (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
) {
587 mTreeView
->GetCellValue(mRow
, mColumn
, textEquiv
);
588 if (mCachedTextEquiv
!= textEquiv
) {
589 bool isEnabled
= textEquiv
.EqualsLiteral("true");
590 RefPtr
<AccEvent
> accEvent
=
591 new AccStateChangeEvent(this, states::CHECKED
, isEnabled
);
592 nsEventShell::FireEvent(accEvent
);
594 mCachedTextEquiv
= textEquiv
;
601 mTreeView
->GetCellText(mRow
, mColumn
, textEquiv
);
602 if (mCachedTextEquiv
!= textEquiv
) {
603 nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE
, this);
604 mCachedTextEquiv
= textEquiv
;
611 ////////////////////////////////////////////////////////////////////////////////
612 // XULTreeGridCellAccessible: LocalAccessible protected implementation
614 LocalAccessible
* XULTreeGridCellAccessible::GetSiblingAtOffset(
615 int32_t aOffset
, nsresult
* aError
) const {
616 if (aError
) *aError
= NS_OK
; // fail peacefully
618 RefPtr
<nsTreeColumn
> columnAtOffset(mColumn
), column
;
620 for (int32_t index
= aOffset
; index
< 0 && columnAtOffset
; index
++) {
621 column
= nsCoreUtils::GetPreviousSensibleColumn(columnAtOffset
);
622 column
.swap(columnAtOffset
);
625 for (int32_t index
= aOffset
; index
> 0 && columnAtOffset
; index
--) {
626 column
= nsCoreUtils::GetNextSensibleColumn(columnAtOffset
);
627 column
.swap(columnAtOffset
);
631 if (!columnAtOffset
) return nullptr;
633 XULTreeItemAccessibleBase
* rowAcc
=
634 static_cast<XULTreeItemAccessibleBase
*>(LocalParent());
635 return rowAcc
->GetCellAccessible(columnAtOffset
);
638 void XULTreeGridCellAccessible::DispatchClickEvent(
639 nsIContent
* aContent
, uint32_t aActionIndex
) const {
640 if (IsDefunct()) return;
642 RefPtr
<dom::XULTreeElement
> tree
= mTree
;
643 RefPtr
<nsTreeColumn
> column
= mColumn
;
644 nsCoreUtils::DispatchClickEvent(tree
, mRow
, column
);
647 ////////////////////////////////////////////////////////////////////////////////
648 // XULTreeGridCellAccessible: protected implementation
650 bool XULTreeGridCellAccessible::IsEditable() const {
651 // XXX: logic corresponds to tree.xml, it's preferable to have interface
652 // method to check it.
653 bool isEditable
= false;
654 nsresult rv
= mTreeView
->IsEditable(mRow
, mColumn
, &isEditable
);
655 if (NS_FAILED(rv
) || !isEditable
) return false;
657 dom::Element
* columnElm
= mColumn
->Element();
659 if (!columnElm
->AttrValueIs(kNameSpaceID_None
, nsGkAtoms::editable
,
660 nsGkAtoms::_true
, eCaseMatters
)) {
664 return mContent
->AsElement()->AttrValueIs(
665 kNameSpaceID_None
, nsGkAtoms::editable
, nsGkAtoms::_true
, eCaseMatters
);