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"
8 #include "AccAttributes.h"
9 #include "LocalAccessible-inl.h"
10 #include "nsAccCache.h"
11 #include "nsAccessibilityService.h"
12 #include "nsAccUtils.h"
13 #include "DocAccessible.h"
14 #include "nsEventShell.h"
18 #include "nsQueryObject.h"
19 #include "nsTreeColumns.h"
21 #include "nsITreeSelection.h"
22 #include "nsComponentManagerUtils.h"
23 #include "mozilla/PresShell.h"
24 #include "mozilla/dom/Element.h"
25 #include "mozilla/dom/TreeColumnBinding.h"
26 #include "mozilla/dom/XULTreeElementBinding.h"
28 using namespace mozilla::a11y
;
29 using namespace mozilla
;
31 XULTreeGridAccessible::~XULTreeGridAccessible() {}
33 ////////////////////////////////////////////////////////////////////////////////
34 // XULTreeGridAccessible: Table
36 uint32_t XULTreeGridAccessible::ColCount() const {
37 return nsCoreUtils::GetSensibleColumnCount(mTree
);
40 uint32_t XULTreeGridAccessible::RowCount() {
41 if (!mTreeView
) return 0;
44 mTreeView
->GetRowCount(&rowCount
);
45 return rowCount
>= 0 ? rowCount
: 0;
48 uint32_t XULTreeGridAccessible::SelectedCellCount() {
49 return SelectedRowCount() * ColCount();
52 uint32_t XULTreeGridAccessible::SelectedColCount() {
53 // If all the row has been selected, then all the columns are selected,
54 // because we can't select a column alone.
56 uint32_t selectedRowCount
= SelectedItemCount();
57 return selectedRowCount
> 0 && selectedRowCount
== RowCount() ? ColCount()
61 uint32_t XULTreeGridAccessible::SelectedRowCount() {
62 return SelectedItemCount();
65 void XULTreeGridAccessible::SelectedCells(nsTArray
<Accessible
*>* aCells
) {
66 uint32_t colCount
= ColCount(), rowCount
= RowCount();
68 for (uint32_t rowIdx
= 0; rowIdx
< rowCount
; rowIdx
++) {
69 if (IsRowSelected(rowIdx
)) {
70 for (uint32_t colIdx
= 0; colIdx
< colCount
; colIdx
++) {
71 LocalAccessible
* cell
= CellAt(rowIdx
, colIdx
);
72 aCells
->AppendElement(cell
);
78 void XULTreeGridAccessible::SelectedCellIndices(nsTArray
<uint32_t>* aCells
) {
79 uint32_t colCount
= ColCount(), rowCount
= RowCount();
81 for (uint32_t rowIdx
= 0; rowIdx
< rowCount
; rowIdx
++) {
82 if (IsRowSelected(rowIdx
)) {
83 for (uint32_t colIdx
= 0; colIdx
< colCount
; colIdx
++) {
84 aCells
->AppendElement(rowIdx
* colCount
+ colIdx
);
90 void XULTreeGridAccessible::SelectedColIndices(nsTArray
<uint32_t>* aCols
) {
91 if (RowCount() != SelectedRowCount()) return;
93 uint32_t colCount
= ColCount();
94 aCols
->SetCapacity(colCount
);
95 for (uint32_t colIdx
= 0; colIdx
< colCount
; colIdx
++) {
96 aCols
->AppendElement(colIdx
);
100 void XULTreeGridAccessible::SelectedRowIndices(nsTArray
<uint32_t>* aRows
) {
101 uint32_t rowCount
= RowCount();
102 for (uint32_t rowIdx
= 0; rowIdx
< rowCount
; rowIdx
++) {
103 if (IsRowSelected(rowIdx
)) aRows
->AppendElement(rowIdx
);
107 LocalAccessible
* XULTreeGridAccessible::CellAt(uint32_t aRowIndex
,
108 uint32_t aColumnIndex
) {
109 LocalAccessible
* row
= GetTreeItemAccessible(aRowIndex
);
110 if (!row
) return nullptr;
112 RefPtr
<nsTreeColumn
> column
=
113 nsCoreUtils::GetSensibleColumnAt(mTree
, aColumnIndex
);
114 if (!column
) return nullptr;
116 RefPtr
<XULTreeItemAccessibleBase
> rowAcc
= do_QueryObject(row
);
117 if (!rowAcc
) return nullptr;
119 return rowAcc
->GetCellAccessible(column
);
122 void XULTreeGridAccessible::ColDescription(uint32_t aColIdx
,
123 nsString
& aDescription
) {
124 aDescription
.Truncate();
126 LocalAccessible
* treeColumns
= LocalAccessible::LocalChildAt(0);
128 LocalAccessible
* treeColumnItem
= treeColumns
->LocalChildAt(aColIdx
);
129 if (treeColumnItem
) treeColumnItem
->Name(aDescription
);
133 bool XULTreeGridAccessible::IsColSelected(uint32_t aColIdx
) {
134 // If all the row has been selected, then all the columns are selected.
135 // Because we can't select a column alone.
136 return SelectedItemCount() == RowCount();
139 bool XULTreeGridAccessible::IsRowSelected(uint32_t aRowIdx
) {
140 if (!mTreeView
) return false;
142 nsCOMPtr
<nsITreeSelection
> selection
;
143 nsresult rv
= mTreeView
->GetSelection(getter_AddRefs(selection
));
144 NS_ENSURE_SUCCESS(rv
, false);
146 bool isSelected
= false;
147 selection
->IsSelected(aRowIdx
, &isSelected
);
151 bool XULTreeGridAccessible::IsCellSelected(uint32_t aRowIdx
, uint32_t aColIdx
) {
152 return IsRowSelected(aRowIdx
);
155 void XULTreeGridAccessible::SelectRow(uint32_t aRowIdx
) {
156 if (!mTreeView
) return;
158 nsCOMPtr
<nsITreeSelection
> selection
;
159 mTreeView
->GetSelection(getter_AddRefs(selection
));
160 NS_ASSERTION(selection
, "GetSelection() Shouldn't fail!");
162 selection
->Select(aRowIdx
);
165 void XULTreeGridAccessible::UnselectRow(uint32_t aRowIdx
) {
166 if (!mTreeView
) return;
168 nsCOMPtr
<nsITreeSelection
> selection
;
169 mTreeView
->GetSelection(getter_AddRefs(selection
));
171 if (selection
) selection
->ClearRange(aRowIdx
, aRowIdx
);
174 ////////////////////////////////////////////////////////////////////////////////
175 // XULTreeGridAccessible: LocalAccessible implementation
177 role
XULTreeGridAccessible::NativeRole() const {
178 RefPtr
<nsTreeColumns
> treeColumns
= mTree
->GetColumns(FlushType::None
);
180 NS_ERROR("No treecolumns object for tree!");
181 return roles::NOTHING
;
184 nsTreeColumn
* primaryColumn
= treeColumns
->GetPrimaryColumn();
186 return primaryColumn
? roles::TREE_TABLE
: roles::TABLE
;
189 ////////////////////////////////////////////////////////////////////////////////
190 // XULTreeGridAccessible: XULTreeAccessible implementation
192 already_AddRefed
<LocalAccessible
>
193 XULTreeGridAccessible::CreateTreeItemAccessible(int32_t aRow
) const {
194 RefPtr
<LocalAccessible
> accessible
= new XULTreeGridRowAccessible(
195 mContent
, mDoc
, const_cast<XULTreeGridAccessible
*>(this), mTree
,
198 return accessible
.forget();
201 ////////////////////////////////////////////////////////////////////////////////
202 // XULTreeGridRowAccessible
203 ////////////////////////////////////////////////////////////////////////////////
205 XULTreeGridRowAccessible::XULTreeGridRowAccessible(
206 nsIContent
* aContent
, DocAccessible
* aDoc
, LocalAccessible
* aTreeAcc
,
207 dom::XULTreeElement
* aTree
, nsITreeView
* aTreeView
, int32_t aRow
)
208 : XULTreeItemAccessibleBase(aContent
, aDoc
, aTreeAcc
, aTree
, aTreeView
,
210 mAccessibleCache(kDefaultTreeCacheLength
) {
211 mGenericTypes
|= eTableRow
;
212 mStateFlags
|= eNoKidsFromDOM
;
215 XULTreeGridRowAccessible::~XULTreeGridRowAccessible() {}
217 ////////////////////////////////////////////////////////////////////////////////
218 // XULTreeGridRowAccessible: nsISupports and cycle collection implementation
220 NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridRowAccessible
,
221 XULTreeItemAccessibleBase
, mAccessibleCache
)
223 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeGridRowAccessible
)
224 NS_INTERFACE_MAP_END_INHERITING(XULTreeItemAccessibleBase
)
226 NS_IMPL_ADDREF_INHERITED(XULTreeGridRowAccessible
, XULTreeItemAccessibleBase
)
227 NS_IMPL_RELEASE_INHERITED(XULTreeGridRowAccessible
, XULTreeItemAccessibleBase
)
229 ////////////////////////////////////////////////////////////////////////////////
230 // XULTreeGridRowAccessible: LocalAccessible implementation
232 void XULTreeGridRowAccessible::Shutdown() {
233 if (mDoc
&& !mDoc
->IsDefunct()) {
234 UnbindCacheEntriesFromDocument(mAccessibleCache
);
237 XULTreeItemAccessibleBase::Shutdown();
240 role
XULTreeGridRowAccessible::NativeRole() const { return roles::ROW
; }
242 ENameValueFlag
XULTreeGridRowAccessible::Name(nsString
& aName
) const {
245 // XXX: the row name sholdn't be a concatenation of cell names (bug 664384).
246 RefPtr
<nsTreeColumn
> column
= nsCoreUtils::GetFirstSensibleColumn(mTree
);
248 if (!aName
.IsEmpty()) aName
.Append(' ');
250 nsAutoString cellName
;
251 GetCellName(column
, cellName
);
252 aName
.Append(cellName
);
254 column
= nsCoreUtils::GetNextSensibleColumn(column
);
260 LocalAccessible
* XULTreeGridRowAccessible::LocalChildAtPoint(
261 int32_t aX
, int32_t aY
, EWhichChildAtPoint aWhichChild
) {
262 nsIFrame
* frame
= GetFrame();
263 if (!frame
) return nullptr;
265 nsPresContext
* presContext
= frame
->PresContext();
266 PresShell
* presShell
= presContext
->PresShell();
268 nsIFrame
* rootFrame
= presShell
->GetRootFrame();
269 NS_ENSURE_TRUE(rootFrame
, nullptr);
271 CSSIntRect rootRect
= rootFrame
->GetScreenRect();
273 int32_t clientX
= presContext
->DevPixelsToIntCSSPixels(aX
) - rootRect
.X();
274 int32_t clientY
= presContext
->DevPixelsToIntCSSPixels(aY
) - rootRect
.Y();
277 dom::TreeCellInfo cellInfo
;
278 mTree
->GetCellAt(clientX
, clientY
, cellInfo
, rv
);
280 // Return if we failed to find tree cell in the row for the given point.
281 if (cellInfo
.mRow
!= mRow
|| !cellInfo
.mCol
) return nullptr;
283 return GetCellAccessible(cellInfo
.mCol
);
286 LocalAccessible
* XULTreeGridRowAccessible::LocalChildAt(uint32_t aIndex
) const {
287 if (IsDefunct()) return nullptr;
289 RefPtr
<nsTreeColumn
> column
= nsCoreUtils::GetSensibleColumnAt(mTree
, aIndex
);
290 if (!column
) return nullptr;
292 return GetCellAccessible(column
);
295 uint32_t XULTreeGridRowAccessible::ChildCount() const {
296 return nsCoreUtils::GetSensibleColumnCount(mTree
);
299 ////////////////////////////////////////////////////////////////////////////////
300 // XULTreeGridRowAccessible: XULTreeItemAccessibleBase implementation
302 XULTreeGridCellAccessible
* XULTreeGridRowAccessible::GetCellAccessible(
303 nsTreeColumn
* aColumn
) const {
304 MOZ_ASSERT(aColumn
, "No tree column!");
306 void* key
= static_cast<void*>(aColumn
);
307 XULTreeGridCellAccessible
* cachedCell
= mAccessibleCache
.GetWeak(key
);
308 if (cachedCell
) return cachedCell
;
310 RefPtr
<XULTreeGridCellAccessible
> cell
= new XULTreeGridCellAccessible(
311 mContent
, mDoc
, const_cast<XULTreeGridRowAccessible
*>(this), mTree
,
312 mTreeView
, mRow
, aColumn
);
313 mAccessibleCache
.InsertOrUpdate(key
, RefPtr
{cell
});
314 Document()->BindToDocument(cell
, nullptr);
318 void XULTreeGridRowAccessible::RowInvalidated(int32_t aStartColIdx
,
319 int32_t aEndColIdx
) {
320 RefPtr
<nsTreeColumns
> treeColumns
= mTree
->GetColumns(FlushType::None
);
321 if (!treeColumns
) return;
323 bool nameChanged
= false;
324 for (int32_t colIdx
= aStartColIdx
; colIdx
<= aEndColIdx
; ++colIdx
) {
325 nsTreeColumn
* column
= treeColumns
->GetColumnAt(colIdx
);
326 if (column
&& !nsCoreUtils::IsColumnHidden(column
)) {
327 XULTreeGridCellAccessible
* cell
= GetCellAccessible(column
);
328 if (cell
) nameChanged
|= cell
->CellInvalidated();
333 nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE
, this);
337 ////////////////////////////////////////////////////////////////////////////////
338 // XULTreeGridCellAccessible
339 ////////////////////////////////////////////////////////////////////////////////
341 XULTreeGridCellAccessible::XULTreeGridCellAccessible(
342 nsIContent
* aContent
, DocAccessible
* aDoc
,
343 XULTreeGridRowAccessible
* aRowAcc
, dom::XULTreeElement
* aTree
,
344 nsITreeView
* aTreeView
, int32_t aRow
, nsTreeColumn
* aColumn
)
345 : LeafAccessible(aContent
, aDoc
),
347 mTreeView(aTreeView
),
351 mStateFlags
|= eSharedNode
;
352 mGenericTypes
|= eTableCell
;
354 NS_ASSERTION(mTreeView
, "mTreeView is null");
356 if (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
) {
357 mTreeView
->GetCellValue(mRow
, mColumn
, mCachedTextEquiv
);
359 mTreeView
->GetCellText(mRow
, mColumn
, mCachedTextEquiv
);
363 XULTreeGridCellAccessible::~XULTreeGridCellAccessible() {}
365 ////////////////////////////////////////////////////////////////////////////////
366 // XULTreeGridCellAccessible: nsISupports implementation
368 NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridCellAccessible
, LeafAccessible
,
371 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeGridCellAccessible
)
372 NS_INTERFACE_MAP_END_INHERITING(LeafAccessible
)
373 NS_IMPL_ADDREF_INHERITED(XULTreeGridCellAccessible
, LeafAccessible
)
374 NS_IMPL_RELEASE_INHERITED(XULTreeGridCellAccessible
, LeafAccessible
)
376 ////////////////////////////////////////////////////////////////////////////////
377 // XULTreeGridCellAccessible: LocalAccessible
379 void XULTreeGridCellAccessible::Shutdown() {
384 mParent
= nullptr; // null-out to prevent base class's shutdown ops
386 LeafAccessible::Shutdown();
389 Accessible
* XULTreeGridCellAccessible::FocusedChild() { return nullptr; }
391 ENameValueFlag
XULTreeGridCellAccessible::Name(nsString
& aName
) const {
394 if (!mTreeView
) return eNameOK
;
396 mTreeView
->GetCellText(mRow
, mColumn
, aName
);
398 // If there is still no name try the cell value:
399 // This is for graphical cells. We need tree/table view implementors to
400 // implement FooView::GetCellValue to return a meaningful string for cases
401 // where there is something shown in the cell (non-text) such as a star icon;
402 // in which case GetCellValue for that cell would return "starred" or
403 // "flagged" for example.
404 if (aName
.IsEmpty()) mTreeView
->GetCellValue(mRow
, mColumn
, aName
);
409 nsIntRect
XULTreeGridCellAccessible::BoundsInCSSPixels() const {
410 // Get bounds for tree cell and add x and y of treechildren element to
411 // x and y of the cell.
413 nsIntRect rect
= mTree
->GetCoordsForCellItem(mRow
, mColumn
, u
"cell"_ns
, rv
);
418 RefPtr
<dom::Element
> bodyElement
= mTree
->GetTreeBody();
419 if (!bodyElement
|| !bodyElement
->IsXULElement()) {
423 nsIFrame
* bodyFrame
= bodyElement
->GetPrimaryFrame();
428 CSSIntRect screenRect
= bodyFrame
->GetScreenRect();
429 rect
.x
+= screenRect
.x
;
430 rect
.y
+= screenRect
.y
;
434 nsRect
XULTreeGridCellAccessible::BoundsInAppUnits() const {
435 nsIntRect bounds
= BoundsInCSSPixels();
436 nsPresContext
* presContext
= mDoc
->PresContext();
437 return nsRect(presContext
->CSSPixelsToAppUnits(bounds
.X()),
438 presContext
->CSSPixelsToAppUnits(bounds
.Y()),
439 presContext
->CSSPixelsToAppUnits(bounds
.Width()),
440 presContext
->CSSPixelsToAppUnits(bounds
.Height()));
443 bool XULTreeGridCellAccessible::HasPrimaryAction() const {
444 return mColumn
->Cycler() ||
445 (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
&&
449 void XULTreeGridCellAccessible::ActionNameAt(uint8_t aIndex
, nsAString
& aName
) {
452 if (aIndex
!= eAction_Click
|| !mTreeView
) return;
454 if (mColumn
->Cycler()) {
455 aName
.AssignLiteral("cycle");
459 if (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
&&
462 mTreeView
->GetCellValue(mRow
, mColumn
, value
);
463 if (value
.EqualsLiteral("true")) {
464 aName
.AssignLiteral("uncheck");
466 aName
.AssignLiteral("check");
471 ////////////////////////////////////////////////////////////////////////////////
472 // XULTreeGridCellAccessible: TableCell
474 TableAccessible
* XULTreeGridCellAccessible::Table() const {
475 LocalAccessible
* grandParent
= mParent
->LocalParent();
476 if (grandParent
) return grandParent
->AsTable();
481 uint32_t XULTreeGridCellAccessible::ColIdx() const {
483 RefPtr
<nsTreeColumn
> column
= mColumn
;
484 while ((column
= nsCoreUtils::GetPreviousSensibleColumn(column
))) colIdx
++;
489 uint32_t XULTreeGridCellAccessible::RowIdx() const { return mRow
; }
491 void XULTreeGridCellAccessible::ColHeaderCells(
492 nsTArray
<Accessible
*>* aHeaderCells
) {
493 dom::Element
* columnElm
= mColumn
->Element();
495 LocalAccessible
* headerCell
= mDoc
->GetAccessible(columnElm
);
496 if (headerCell
) aHeaderCells
->AppendElement(headerCell
);
499 bool XULTreeGridCellAccessible::Selected() {
500 nsCOMPtr
<nsITreeSelection
> selection
;
501 nsresult rv
= mTreeView
->GetSelection(getter_AddRefs(selection
));
502 NS_ENSURE_SUCCESS(rv
, false);
504 bool selected
= false;
505 selection
->IsSelected(mRow
, &selected
);
509 ////////////////////////////////////////////////////////////////////////////////
510 // XULTreeGridCellAccessible: LocalAccessible public implementation
512 already_AddRefed
<AccAttributes
> XULTreeGridCellAccessible::NativeAttributes() {
513 RefPtr
<AccAttributes
> attributes
= new AccAttributes();
515 // "table-cell-index" attribute
516 TableAccessible
* table
= Table();
517 if (!table
) return attributes
.forget();
519 attributes
->SetAttribute(nsGkAtoms::tableCellIndex
,
520 table
->CellIndexAt(mRow
, ColIdx()));
522 // "cycles" attribute
523 if (mColumn
->Cycler()) {
524 attributes
->SetAttribute(nsGkAtoms::cycles
, true);
527 return attributes
.forget();
530 role
XULTreeGridCellAccessible::NativeRole() const { return roles::GRID_CELL
; }
532 uint64_t XULTreeGridCellAccessible::NativeState() const {
533 if (!mTreeView
) return states::DEFUNCT
;
535 // selectable/selected state
537 states::SELECTABLE
; // keep in sync with NativeInteractiveState
539 nsCOMPtr
<nsITreeSelection
> selection
;
540 mTreeView
->GetSelection(getter_AddRefs(selection
));
542 bool isSelected
= false;
543 selection
->IsSelected(mRow
, &isSelected
);
544 if (isSelected
) states
|= states::SELECTED
;
548 if (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
) {
549 states
|= states::CHECKABLE
;
550 nsAutoString checked
;
551 mTreeView
->GetCellValue(mRow
, mColumn
, checked
);
552 if (checked
.EqualsIgnoreCase("true")) states
|= states::CHECKED
;
558 uint64_t XULTreeGridCellAccessible::NativeInteractiveState() const {
559 return states::SELECTABLE
;
562 int32_t XULTreeGridCellAccessible::IndexInParent() const { return ColIdx(); }
564 Relation
XULTreeGridCellAccessible::RelationByType(RelationType aType
) const {
568 ////////////////////////////////////////////////////////////////////////////////
569 // XULTreeGridCellAccessible: public implementation
571 bool XULTreeGridCellAccessible::CellInvalidated() {
572 nsAutoString textEquiv
;
574 if (mColumn
->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX
) {
575 mTreeView
->GetCellValue(mRow
, mColumn
, textEquiv
);
576 if (mCachedTextEquiv
!= textEquiv
) {
577 bool isEnabled
= textEquiv
.EqualsLiteral("true");
578 RefPtr
<AccEvent
> accEvent
=
579 new AccStateChangeEvent(this, states::CHECKED
, isEnabled
);
580 nsEventShell::FireEvent(accEvent
);
582 mCachedTextEquiv
= textEquiv
;
589 mTreeView
->GetCellText(mRow
, mColumn
, textEquiv
);
590 if (mCachedTextEquiv
!= textEquiv
) {
591 nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE
, this);
592 mCachedTextEquiv
= textEquiv
;
599 ////////////////////////////////////////////////////////////////////////////////
600 // XULTreeGridCellAccessible: LocalAccessible protected implementation
602 LocalAccessible
* XULTreeGridCellAccessible::GetSiblingAtOffset(
603 int32_t aOffset
, nsresult
* aError
) const {
604 if (aError
) *aError
= NS_OK
; // fail peacefully
606 RefPtr
<nsTreeColumn
> columnAtOffset(mColumn
), column
;
608 for (int32_t index
= aOffset
; index
< 0 && columnAtOffset
; index
++) {
609 column
= nsCoreUtils::GetPreviousSensibleColumn(columnAtOffset
);
610 column
.swap(columnAtOffset
);
613 for (int32_t index
= aOffset
; index
> 0 && columnAtOffset
; index
--) {
614 column
= nsCoreUtils::GetNextSensibleColumn(columnAtOffset
);
615 column
.swap(columnAtOffset
);
619 if (!columnAtOffset
) return nullptr;
621 RefPtr
<XULTreeItemAccessibleBase
> rowAcc
= do_QueryObject(LocalParent());
622 return rowAcc
->GetCellAccessible(columnAtOffset
);
625 void XULTreeGridCellAccessible::DispatchClickEvent(
626 nsIContent
* aContent
, uint32_t aActionIndex
) const {
627 if (IsDefunct()) return;
629 RefPtr
<dom::XULTreeElement
> tree
= mTree
;
630 RefPtr
<nsTreeColumn
> column
= mColumn
;
631 nsCoreUtils::DispatchClickEvent(tree
, mRow
, column
);
634 ////////////////////////////////////////////////////////////////////////////////
635 // XULTreeGridCellAccessible: protected implementation
637 bool XULTreeGridCellAccessible::IsEditable() const {
638 // XXX: logic corresponds to tree.xml, it's preferable to have interface
639 // method to check it.
640 bool isEditable
= false;
641 nsresult rv
= mTreeView
->IsEditable(mRow
, mColumn
, &isEditable
);
642 if (NS_FAILED(rv
) || !isEditable
) return false;
644 dom::Element
* columnElm
= mColumn
->Element();
646 if (!columnElm
->AttrValueIs(kNameSpaceID_None
, nsGkAtoms::editable
,
647 nsGkAtoms::_true
, eCaseMatters
)) {
651 return mContent
->AsElement()->AttrValueIs(
652 kNameSpaceID_None
, nsGkAtoms::editable
, nsGkAtoms::_true
, eCaseMatters
);