Bug 1833114 - Simplify marking code now |stack| represents the mark stack for the...
[gecko.git] / accessible / xul / XULTreeGridAccessible.cpp
bloba2a0341f1c7fa1aa182aa1128b3e2ff13d43bec8
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"
15 #include "Relation.h"
16 #include "Role.h"
17 #include "States.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;
43 int32_t rowCount = 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()
58 : 0;
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 XULTreeItemAccessibleBase* rowAcc = GetTreeItemAccessible(aRowIndex);
110 if (!rowAcc) return nullptr;
112 RefPtr<nsTreeColumn> column =
113 nsCoreUtils::GetSensibleColumnAt(mTree, aColumnIndex);
114 if (!column) return nullptr;
116 return rowAcc->GetCellAccessible(column);
119 void XULTreeGridAccessible::ColDescription(uint32_t aColIdx,
120 nsString& aDescription) {
121 aDescription.Truncate();
123 LocalAccessible* treeColumns = LocalAccessible::LocalChildAt(0);
124 if (treeColumns) {
125 LocalAccessible* treeColumnItem = treeColumns->LocalChildAt(aColIdx);
126 if (treeColumnItem) treeColumnItem->Name(aDescription);
130 bool XULTreeGridAccessible::IsColSelected(uint32_t aColIdx) {
131 // If all the row has been selected, then all the columns are selected.
132 // Because we can't select a column alone.
133 return SelectedItemCount() == RowCount();
136 bool XULTreeGridAccessible::IsRowSelected(uint32_t aRowIdx) {
137 if (!mTreeView) return false;
139 nsCOMPtr<nsITreeSelection> selection;
140 nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
141 NS_ENSURE_SUCCESS(rv, false);
143 bool isSelected = false;
144 selection->IsSelected(aRowIdx, &isSelected);
145 return isSelected;
148 bool XULTreeGridAccessible::IsCellSelected(uint32_t aRowIdx, uint32_t aColIdx) {
149 return IsRowSelected(aRowIdx);
152 void XULTreeGridAccessible::SelectRow(uint32_t aRowIdx) {
153 if (!mTreeView) return;
155 nsCOMPtr<nsITreeSelection> selection;
156 mTreeView->GetSelection(getter_AddRefs(selection));
157 NS_ASSERTION(selection, "GetSelection() Shouldn't fail!");
159 selection->Select(aRowIdx);
162 void XULTreeGridAccessible::UnselectRow(uint32_t aRowIdx) {
163 if (!mTreeView) return;
165 nsCOMPtr<nsITreeSelection> selection;
166 mTreeView->GetSelection(getter_AddRefs(selection));
168 if (selection) selection->ClearRange(aRowIdx, aRowIdx);
171 ////////////////////////////////////////////////////////////////////////////////
172 // XULTreeGridAccessible: LocalAccessible implementation
174 role XULTreeGridAccessible::NativeRole() const {
175 RefPtr<nsTreeColumns> treeColumns = mTree->GetColumns(FlushType::None);
176 if (!treeColumns) {
177 NS_ERROR("No treecolumns object for tree!");
178 return roles::NOTHING;
181 nsTreeColumn* primaryColumn = treeColumns->GetPrimaryColumn();
183 return primaryColumn ? roles::TREE_TABLE : roles::TABLE;
186 ////////////////////////////////////////////////////////////////////////////////
187 // XULTreeGridAccessible: XULTreeAccessible implementation
189 already_AddRefed<XULTreeItemAccessibleBase>
190 XULTreeGridAccessible::CreateTreeItemAccessible(int32_t aRow) const {
191 RefPtr<XULTreeItemAccessibleBase> accessible = new XULTreeGridRowAccessible(
192 mContent, mDoc, const_cast<XULTreeGridAccessible*>(this), mTree,
193 mTreeView, aRow);
195 return accessible.forget();
198 ////////////////////////////////////////////////////////////////////////////////
199 // XULTreeGridRowAccessible
200 ////////////////////////////////////////////////////////////////////////////////
202 XULTreeGridRowAccessible::XULTreeGridRowAccessible(
203 nsIContent* aContent, DocAccessible* aDoc, LocalAccessible* aTreeAcc,
204 dom::XULTreeElement* aTree, nsITreeView* aTreeView, int32_t aRow)
205 : XULTreeItemAccessibleBase(aContent, aDoc, aTreeAcc, aTree, aTreeView,
206 aRow),
207 mAccessibleCache(kDefaultTreeCacheLength) {
208 mGenericTypes |= eTableRow;
209 mStateFlags |= eNoKidsFromDOM;
212 XULTreeGridRowAccessible::~XULTreeGridRowAccessible() {}
214 ////////////////////////////////////////////////////////////////////////////////
215 // XULTreeGridRowAccessible: nsISupports and cycle collection implementation
217 NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridRowAccessible,
218 XULTreeItemAccessibleBase, mAccessibleCache)
220 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeGridRowAccessible)
221 NS_INTERFACE_MAP_END_INHERITING(XULTreeItemAccessibleBase)
223 NS_IMPL_ADDREF_INHERITED(XULTreeGridRowAccessible, XULTreeItemAccessibleBase)
224 NS_IMPL_RELEASE_INHERITED(XULTreeGridRowAccessible, XULTreeItemAccessibleBase)
226 ////////////////////////////////////////////////////////////////////////////////
227 // XULTreeGridRowAccessible: LocalAccessible implementation
229 void XULTreeGridRowAccessible::Shutdown() {
230 if (mDoc && !mDoc->IsDefunct()) {
231 UnbindCacheEntriesFromDocument(mAccessibleCache);
234 XULTreeItemAccessibleBase::Shutdown();
237 role XULTreeGridRowAccessible::NativeRole() const { return roles::ROW; }
239 ENameValueFlag XULTreeGridRowAccessible::Name(nsString& aName) const {
240 aName.Truncate();
242 // XXX: the row name sholdn't be a concatenation of cell names (bug 664384).
243 RefPtr<nsTreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree);
244 while (column) {
245 if (!aName.IsEmpty()) aName.Append(' ');
247 nsAutoString cellName;
248 GetCellName(column, cellName);
249 aName.Append(cellName);
251 column = nsCoreUtils::GetNextSensibleColumn(column);
254 return eNameOK;
257 LocalAccessible* XULTreeGridRowAccessible::LocalChildAtPoint(
258 int32_t aX, int32_t aY, EWhichChildAtPoint aWhichChild) {
259 nsIFrame* frame = GetFrame();
260 if (!frame) return nullptr;
262 nsPresContext* presContext = frame->PresContext();
263 PresShell* presShell = presContext->PresShell();
265 nsIFrame* rootFrame = presShell->GetRootFrame();
266 NS_ENSURE_TRUE(rootFrame, nullptr);
268 CSSIntRect rootRect = rootFrame->GetScreenRect();
270 int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X();
271 int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y();
273 ErrorResult rv;
274 dom::TreeCellInfo cellInfo;
275 mTree->GetCellAt(clientX, clientY, cellInfo, rv);
277 // Return if we failed to find tree cell in the row for the given point.
278 if (cellInfo.mRow != mRow || !cellInfo.mCol) return nullptr;
280 return GetCellAccessible(cellInfo.mCol);
283 LocalAccessible* XULTreeGridRowAccessible::LocalChildAt(uint32_t aIndex) const {
284 if (IsDefunct()) return nullptr;
286 RefPtr<nsTreeColumn> column = nsCoreUtils::GetSensibleColumnAt(mTree, aIndex);
287 if (!column) return nullptr;
289 return GetCellAccessible(column);
292 uint32_t XULTreeGridRowAccessible::ChildCount() const {
293 return nsCoreUtils::GetSensibleColumnCount(mTree);
296 ////////////////////////////////////////////////////////////////////////////////
297 // XULTreeGridRowAccessible: XULTreeItemAccessibleBase implementation
299 XULTreeGridCellAccessible* XULTreeGridRowAccessible::GetCellAccessible(
300 nsTreeColumn* aColumn) const {
301 MOZ_ASSERT(aColumn, "No tree column!");
303 void* key = static_cast<void*>(aColumn);
304 XULTreeGridCellAccessible* cachedCell = mAccessibleCache.GetWeak(key);
305 if (cachedCell) return cachedCell;
307 RefPtr<XULTreeGridCellAccessible> cell = new XULTreeGridCellAccessible(
308 mContent, mDoc, const_cast<XULTreeGridRowAccessible*>(this), mTree,
309 mTreeView, mRow, aColumn);
310 mAccessibleCache.InsertOrUpdate(key, RefPtr{cell});
311 Document()->BindToDocument(cell, nullptr);
312 return cell;
315 void XULTreeGridRowAccessible::RowInvalidated(int32_t aStartColIdx,
316 int32_t aEndColIdx) {
317 RefPtr<nsTreeColumns> treeColumns = mTree->GetColumns(FlushType::None);
318 if (!treeColumns) return;
320 bool nameChanged = false;
321 for (int32_t colIdx = aStartColIdx; colIdx <= aEndColIdx; ++colIdx) {
322 nsTreeColumn* column = treeColumns->GetColumnAt(colIdx);
323 if (column && !nsCoreUtils::IsColumnHidden(column)) {
324 XULTreeGridCellAccessible* cell = GetCellAccessible(column);
325 if (cell) nameChanged |= cell->CellInvalidated();
329 if (nameChanged) {
330 nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
334 ////////////////////////////////////////////////////////////////////////////////
335 // XULTreeGridCellAccessible
336 ////////////////////////////////////////////////////////////////////////////////
338 XULTreeGridCellAccessible::XULTreeGridCellAccessible(
339 nsIContent* aContent, DocAccessible* aDoc,
340 XULTreeGridRowAccessible* aRowAcc, dom::XULTreeElement* aTree,
341 nsITreeView* aTreeView, int32_t aRow, nsTreeColumn* aColumn)
342 : LeafAccessible(aContent, aDoc),
343 mTree(aTree),
344 mTreeView(aTreeView),
345 mRow(aRow),
346 mColumn(aColumn) {
347 mParent = aRowAcc;
348 mStateFlags |= eSharedNode;
349 mGenericTypes |= eTableCell;
351 NS_ASSERTION(mTreeView, "mTreeView is null");
353 if (mColumn->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX) {
354 mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv);
355 } else {
356 mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv);
360 XULTreeGridCellAccessible::~XULTreeGridCellAccessible() {}
362 ////////////////////////////////////////////////////////////////////////////////
363 // XULTreeGridCellAccessible: nsISupports implementation
365 NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridCellAccessible, LeafAccessible,
366 mTree, mColumn)
368 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeGridCellAccessible)
369 NS_INTERFACE_MAP_END_INHERITING(LeafAccessible)
370 NS_IMPL_ADDREF_INHERITED(XULTreeGridCellAccessible, LeafAccessible)
371 NS_IMPL_RELEASE_INHERITED(XULTreeGridCellAccessible, LeafAccessible)
373 ////////////////////////////////////////////////////////////////////////////////
374 // XULTreeGridCellAccessible: LocalAccessible
376 void XULTreeGridCellAccessible::Shutdown() {
377 mTree = nullptr;
378 mTreeView = nullptr;
379 mRow = -1;
380 mColumn = nullptr;
381 mParent = nullptr; // null-out to prevent base class's shutdown ops
383 LeafAccessible::Shutdown();
386 Accessible* XULTreeGridCellAccessible::FocusedChild() { return nullptr; }
388 ENameValueFlag XULTreeGridCellAccessible::Name(nsString& aName) const {
389 aName.Truncate();
391 if (!mTreeView) return eNameOK;
393 mTreeView->GetCellText(mRow, mColumn, aName);
395 // If there is still no name try the cell value:
396 // This is for graphical cells. We need tree/table view implementors to
397 // implement FooView::GetCellValue to return a meaningful string for cases
398 // where there is something shown in the cell (non-text) such as a star icon;
399 // in which case GetCellValue for that cell would return "starred" or
400 // "flagged" for example.
401 if (aName.IsEmpty()) mTreeView->GetCellValue(mRow, mColumn, aName);
403 return eNameOK;
406 nsIntRect XULTreeGridCellAccessible::BoundsInCSSPixels() const {
407 // Get bounds for tree cell and add x and y of treechildren element to
408 // x and y of the cell.
409 nsresult rv;
410 nsIntRect rect = mTree->GetCoordsForCellItem(mRow, mColumn, u"cell"_ns, rv);
411 if (NS_FAILED(rv)) {
412 return nsIntRect();
415 RefPtr<dom::Element> bodyElement = mTree->GetTreeBody();
416 if (!bodyElement || !bodyElement->IsXULElement()) {
417 return nsIntRect();
420 nsIFrame* bodyFrame = bodyElement->GetPrimaryFrame();
421 if (!bodyFrame) {
422 return nsIntRect();
425 CSSIntRect screenRect = bodyFrame->GetScreenRect();
426 rect.x += screenRect.x;
427 rect.y += screenRect.y;
428 return rect;
431 nsRect XULTreeGridCellAccessible::BoundsInAppUnits() const {
432 nsIntRect bounds = BoundsInCSSPixels();
433 nsPresContext* presContext = mDoc->PresContext();
434 return nsRect(presContext->CSSPixelsToAppUnits(bounds.X()),
435 presContext->CSSPixelsToAppUnits(bounds.Y()),
436 presContext->CSSPixelsToAppUnits(bounds.Width()),
437 presContext->CSSPixelsToAppUnits(bounds.Height()));
440 bool XULTreeGridCellAccessible::HasPrimaryAction() const {
441 return mColumn->Cycler() ||
442 (mColumn->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX &&
443 IsEditable());
446 void XULTreeGridCellAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
447 aName.Truncate();
449 if (aIndex != eAction_Click || !mTreeView) return;
451 if (mColumn->Cycler()) {
452 aName.AssignLiteral("cycle");
453 return;
456 if (mColumn->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX &&
457 IsEditable()) {
458 nsAutoString value;
459 mTreeView->GetCellValue(mRow, mColumn, value);
460 if (value.EqualsLiteral("true")) {
461 aName.AssignLiteral("uncheck");
462 } else {
463 aName.AssignLiteral("check");
468 ////////////////////////////////////////////////////////////////////////////////
469 // XULTreeGridCellAccessible: TableCell
471 TableAccessible* XULTreeGridCellAccessible::Table() const {
472 LocalAccessible* grandParent = mParent->LocalParent();
473 if (grandParent) return grandParent->AsTable();
475 return nullptr;
478 uint32_t XULTreeGridCellAccessible::ColIdx() const {
479 uint32_t colIdx = 0;
480 RefPtr<nsTreeColumn> column = mColumn;
481 while ((column = nsCoreUtils::GetPreviousSensibleColumn(column))) colIdx++;
483 return colIdx;
486 uint32_t XULTreeGridCellAccessible::RowIdx() const { return mRow; }
488 void XULTreeGridCellAccessible::ColHeaderCells(
489 nsTArray<Accessible*>* aHeaderCells) {
490 dom::Element* columnElm = mColumn->Element();
492 LocalAccessible* headerCell = mDoc->GetAccessible(columnElm);
493 if (headerCell) aHeaderCells->AppendElement(headerCell);
496 bool XULTreeGridCellAccessible::Selected() {
497 nsCOMPtr<nsITreeSelection> selection;
498 nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
499 NS_ENSURE_SUCCESS(rv, false);
501 bool selected = false;
502 selection->IsSelected(mRow, &selected);
503 return selected;
506 ////////////////////////////////////////////////////////////////////////////////
507 // XULTreeGridCellAccessible: LocalAccessible public implementation
509 already_AddRefed<AccAttributes> XULTreeGridCellAccessible::NativeAttributes() {
510 RefPtr<AccAttributes> attributes = new AccAttributes();
512 // "table-cell-index" attribute
513 TableAccessible* table = Table();
514 if (!table) return attributes.forget();
516 attributes->SetAttribute(nsGkAtoms::tableCellIndex,
517 table->CellIndexAt(mRow, ColIdx()));
519 // "cycles" attribute
520 if (mColumn->Cycler()) {
521 attributes->SetAttribute(nsGkAtoms::cycles, true);
524 return attributes.forget();
527 role XULTreeGridCellAccessible::NativeRole() const { return roles::GRID_CELL; }
529 uint64_t XULTreeGridCellAccessible::NativeState() const {
530 if (!mTreeView) return states::DEFUNCT;
532 // selectable/selected state
533 uint64_t states =
534 states::SELECTABLE; // keep in sync with NativeInteractiveState
536 nsCOMPtr<nsITreeSelection> selection;
537 mTreeView->GetSelection(getter_AddRefs(selection));
538 if (selection) {
539 bool isSelected = false;
540 selection->IsSelected(mRow, &isSelected);
541 if (isSelected) states |= states::SELECTED;
544 // checked state
545 if (mColumn->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX) {
546 states |= states::CHECKABLE;
547 nsAutoString checked;
548 mTreeView->GetCellValue(mRow, mColumn, checked);
549 if (checked.EqualsIgnoreCase("true")) states |= states::CHECKED;
552 return states;
555 uint64_t XULTreeGridCellAccessible::NativeInteractiveState() const {
556 return states::SELECTABLE;
559 int32_t XULTreeGridCellAccessible::IndexInParent() const { return ColIdx(); }
561 Relation XULTreeGridCellAccessible::RelationByType(RelationType aType) const {
562 return Relation();
565 ////////////////////////////////////////////////////////////////////////////////
566 // XULTreeGridCellAccessible: public implementation
568 bool XULTreeGridCellAccessible::CellInvalidated() {
569 nsAutoString textEquiv;
571 if (mColumn->Type() == dom::TreeColumn_Binding::TYPE_CHECKBOX) {
572 mTreeView->GetCellValue(mRow, mColumn, textEquiv);
573 if (mCachedTextEquiv != textEquiv) {
574 bool isEnabled = textEquiv.EqualsLiteral("true");
575 RefPtr<AccEvent> accEvent =
576 new AccStateChangeEvent(this, states::CHECKED, isEnabled);
577 nsEventShell::FireEvent(accEvent);
579 mCachedTextEquiv = textEquiv;
580 return true;
583 return false;
586 mTreeView->GetCellText(mRow, mColumn, textEquiv);
587 if (mCachedTextEquiv != textEquiv) {
588 nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
589 mCachedTextEquiv = textEquiv;
590 return true;
593 return false;
596 ////////////////////////////////////////////////////////////////////////////////
597 // XULTreeGridCellAccessible: LocalAccessible protected implementation
599 LocalAccessible* XULTreeGridCellAccessible::GetSiblingAtOffset(
600 int32_t aOffset, nsresult* aError) const {
601 if (aError) *aError = NS_OK; // fail peacefully
603 RefPtr<nsTreeColumn> columnAtOffset(mColumn), column;
604 if (aOffset < 0) {
605 for (int32_t index = aOffset; index < 0 && columnAtOffset; index++) {
606 column = nsCoreUtils::GetPreviousSensibleColumn(columnAtOffset);
607 column.swap(columnAtOffset);
609 } else {
610 for (int32_t index = aOffset; index > 0 && columnAtOffset; index--) {
611 column = nsCoreUtils::GetNextSensibleColumn(columnAtOffset);
612 column.swap(columnAtOffset);
616 if (!columnAtOffset) return nullptr;
618 XULTreeItemAccessibleBase* rowAcc =
619 static_cast<XULTreeItemAccessibleBase*>(LocalParent());
620 return rowAcc->GetCellAccessible(columnAtOffset);
623 void XULTreeGridCellAccessible::DispatchClickEvent(
624 nsIContent* aContent, uint32_t aActionIndex) const {
625 if (IsDefunct()) return;
627 RefPtr<dom::XULTreeElement> tree = mTree;
628 RefPtr<nsTreeColumn> column = mColumn;
629 nsCoreUtils::DispatchClickEvent(tree, mRow, column);
632 ////////////////////////////////////////////////////////////////////////////////
633 // XULTreeGridCellAccessible: protected implementation
635 bool XULTreeGridCellAccessible::IsEditable() const {
636 // XXX: logic corresponds to tree.xml, it's preferable to have interface
637 // method to check it.
638 bool isEditable = false;
639 nsresult rv = mTreeView->IsEditable(mRow, mColumn, &isEditable);
640 if (NS_FAILED(rv) || !isEditable) return false;
642 dom::Element* columnElm = mColumn->Element();
644 if (!columnElm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
645 nsGkAtoms::_true, eCaseMatters)) {
646 return false;
649 return mContent->AsElement()->AttrValueIs(
650 kNameSpaceID_None, nsGkAtoms::editable, nsGkAtoms::_true, eCaseMatters);