1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/xul/XULTreeAccessible.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1218 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "XULTreeAccessible.h" 1.11 + 1.12 +#include "Accessible-inl.h" 1.13 +#include "DocAccessible-inl.h" 1.14 +#include "nsAccCache.h" 1.15 +#include "nsAccUtils.h" 1.16 +#include "nsCoreUtils.h" 1.17 +#include "nsEventShell.h" 1.18 +#include "DocAccessible.h" 1.19 +#include "Relation.h" 1.20 +#include "Role.h" 1.21 +#include "States.h" 1.22 + 1.23 +#include "nsComponentManagerUtils.h" 1.24 +#include "nsIAccessibleRelation.h" 1.25 +#include "nsIAutoCompleteInput.h" 1.26 +#include "nsIAutoCompletePopup.h" 1.27 +#include "nsIBoxObject.h" 1.28 +#include "nsIDOMXULElement.h" 1.29 +#include "nsIDOMXULMenuListElement.h" 1.30 +#include "nsIDOMXULMultSelectCntrlEl.h" 1.31 +#include "nsIDOMXULTreeElement.h" 1.32 +#include "nsITreeSelection.h" 1.33 +#include "nsIMutableArray.h" 1.34 +#include "nsTreeBodyFrame.h" 1.35 +#include "nsTreeColumns.h" 1.36 +#include "nsTreeUtils.h" 1.37 + 1.38 +using namespace mozilla::a11y; 1.39 + 1.40 +//////////////////////////////////////////////////////////////////////////////// 1.41 +// XULTreeAccessible 1.42 +//////////////////////////////////////////////////////////////////////////////// 1.43 + 1.44 +XULTreeAccessible:: 1.45 + XULTreeAccessible(nsIContent* aContent, DocAccessible* aDoc, 1.46 + nsTreeBodyFrame* aTreeFrame) : 1.47 + AccessibleWrap(aContent, aDoc), 1.48 + mAccessibleCache(kDefaultTreeCacheSize) 1.49 +{ 1.50 + mType = eXULTreeType; 1.51 + mGenericTypes |= eSelect; 1.52 + 1.53 + nsCOMPtr<nsITreeView> view = aTreeFrame->GetExistingView(); 1.54 + mTreeView = view; 1.55 + 1.56 + mTree = nsCoreUtils::GetTreeBoxObject(aContent); 1.57 + NS_ASSERTION(mTree, "Can't get mTree!\n"); 1.58 + 1.59 + nsIContent* parentContent = mContent->GetParent(); 1.60 + if (parentContent) { 1.61 + nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm = 1.62 + do_QueryInterface(parentContent); 1.63 + if (autoCompletePopupElm) 1.64 + mGenericTypes |= eAutoCompletePopup; 1.65 + } 1.66 +} 1.67 + 1.68 +//////////////////////////////////////////////////////////////////////////////// 1.69 +// XULTreeAccessible: nsISupports and cycle collection implementation 1.70 + 1.71 +NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeAccessible, Accessible, 1.72 + mTree, mAccessibleCache) 1.73 + 1.74 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(XULTreeAccessible) 1.75 +NS_INTERFACE_MAP_END_INHERITING(Accessible) 1.76 + 1.77 +NS_IMPL_ADDREF_INHERITED(XULTreeAccessible, Accessible) 1.78 +NS_IMPL_RELEASE_INHERITED(XULTreeAccessible, Accessible) 1.79 + 1.80 +//////////////////////////////////////////////////////////////////////////////// 1.81 +// XULTreeAccessible: Accessible implementation 1.82 + 1.83 +uint64_t 1.84 +XULTreeAccessible::NativeState() 1.85 +{ 1.86 + // Get focus status from base class. 1.87 + uint64_t state = Accessible::NativeState(); 1.88 + 1.89 + // readonly state 1.90 + state |= states::READONLY; 1.91 + 1.92 + // multiselectable state. 1.93 + if (!mTreeView) 1.94 + return state; 1.95 + 1.96 + nsCOMPtr<nsITreeSelection> selection; 1.97 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.98 + NS_ENSURE_TRUE(selection, state); 1.99 + 1.100 + bool isSingle = false; 1.101 + nsresult rv = selection->GetSingle(&isSingle); 1.102 + NS_ENSURE_SUCCESS(rv, state); 1.103 + 1.104 + if (!isSingle) 1.105 + state |= states::MULTISELECTABLE; 1.106 + 1.107 + return state; 1.108 +} 1.109 + 1.110 +void 1.111 +XULTreeAccessible::Value(nsString& aValue) 1.112 +{ 1.113 + aValue.Truncate(); 1.114 + if (!mTreeView) 1.115 + return; 1.116 + 1.117 + // Return the value is the first selected child. 1.118 + nsCOMPtr<nsITreeSelection> selection; 1.119 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.120 + if (!selection) 1.121 + return; 1.122 + 1.123 + int32_t currentIndex; 1.124 + nsCOMPtr<nsIDOMElement> selectItem; 1.125 + selection->GetCurrentIndex(¤tIndex); 1.126 + if (currentIndex >= 0) { 1.127 + nsCOMPtr<nsITreeColumn> keyCol; 1.128 + 1.129 + nsCOMPtr<nsITreeColumns> cols; 1.130 + mTree->GetColumns(getter_AddRefs(cols)); 1.131 + if (cols) 1.132 + cols->GetKeyColumn(getter_AddRefs(keyCol)); 1.133 + 1.134 + mTreeView->GetCellText(currentIndex, keyCol, aValue); 1.135 + } 1.136 + 1.137 +} 1.138 + 1.139 +//////////////////////////////////////////////////////////////////////////////// 1.140 +// XULTreeAccessible: Accessible implementation 1.141 + 1.142 +void 1.143 +XULTreeAccessible::Shutdown() 1.144 +{ 1.145 + // XXX: we don't remove accessible from document cache if shutdown wasn't 1.146 + // initiated by document destroying. Note, we can't remove accessible from 1.147 + // document cache here while document is going to be shutdown. Note, this is 1.148 + // not unique place where we have similar problem. 1.149 + ClearCache(mAccessibleCache); 1.150 + 1.151 + mTree = nullptr; 1.152 + mTreeView = nullptr; 1.153 + 1.154 + AccessibleWrap::Shutdown(); 1.155 +} 1.156 + 1.157 +role 1.158 +XULTreeAccessible::NativeRole() 1.159 +{ 1.160 + // No primary column means we're in a list. In fact, history and mail turn off 1.161 + // the primary flag when switching to a flat view. 1.162 + 1.163 + nsIContent* child = nsTreeUtils::GetDescendantChild(mContent, nsGkAtoms::treechildren); 1.164 + NS_ASSERTION(child, "tree without treechildren!"); 1.165 + nsTreeBodyFrame* treeFrame = do_QueryFrame(child->GetPrimaryFrame()); 1.166 + NS_ASSERTION(treeFrame, "xul tree accessible for tree without a frame!"); 1.167 + if (!treeFrame) 1.168 + return roles::LIST; 1.169 + 1.170 + nsRefPtr<nsTreeColumns> cols = treeFrame->Columns(); 1.171 + nsCOMPtr<nsITreeColumn> primaryCol; 1.172 + cols->GetPrimaryColumn(getter_AddRefs(primaryCol)); 1.173 + 1.174 + return primaryCol ? roles::OUTLINE : roles::LIST; 1.175 +} 1.176 + 1.177 +//////////////////////////////////////////////////////////////////////////////// 1.178 +// XULTreeAccessible: Accessible implementation (DON'T put methods here) 1.179 + 1.180 +Accessible* 1.181 +XULTreeAccessible::ChildAtPoint(int32_t aX, int32_t aY, 1.182 + EWhichChildAtPoint aWhichChild) 1.183 +{ 1.184 + nsIFrame *frame = GetFrame(); 1.185 + if (!frame) 1.186 + return nullptr; 1.187 + 1.188 + nsPresContext *presContext = frame->PresContext(); 1.189 + nsIPresShell* presShell = presContext->PresShell(); 1.190 + 1.191 + nsIFrame *rootFrame = presShell->GetRootFrame(); 1.192 + NS_ENSURE_TRUE(rootFrame, nullptr); 1.193 + 1.194 + nsIntRect rootRect = rootFrame->GetScreenRect(); 1.195 + 1.196 + int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.x; 1.197 + int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.y; 1.198 + 1.199 + int32_t row = -1; 1.200 + nsCOMPtr<nsITreeColumn> column; 1.201 + nsAutoCString childEltUnused; 1.202 + mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column), 1.203 + childEltUnused); 1.204 + 1.205 + // If we failed to find tree cell for the given point then it might be 1.206 + // tree columns. 1.207 + if (row == -1 || !column) 1.208 + return AccessibleWrap::ChildAtPoint(aX, aY, aWhichChild); 1.209 + 1.210 + Accessible* child = GetTreeItemAccessible(row); 1.211 + if (aWhichChild == eDeepestChild && child) { 1.212 + // Look for accessible cell for the found item accessible. 1.213 + nsRefPtr<XULTreeItemAccessibleBase> treeitem = do_QueryObject(child); 1.214 + 1.215 + Accessible* cell = treeitem->GetCellAccessible(column); 1.216 + if (cell) 1.217 + child = cell; 1.218 + } 1.219 + 1.220 + return child; 1.221 +} 1.222 + 1.223 +//////////////////////////////////////////////////////////////////////////////// 1.224 +// XULTreeAccessible: SelectAccessible 1.225 + 1.226 +Accessible* 1.227 +XULTreeAccessible::CurrentItem() 1.228 +{ 1.229 + if (!mTreeView) 1.230 + return nullptr; 1.231 + 1.232 + nsCOMPtr<nsITreeSelection> selection; 1.233 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.234 + if (selection) { 1.235 + int32_t currentIndex = -1; 1.236 + selection->GetCurrentIndex(¤tIndex); 1.237 + if (currentIndex >= 0) 1.238 + return GetTreeItemAccessible(currentIndex); 1.239 + } 1.240 + 1.241 + return nullptr; 1.242 +} 1.243 + 1.244 +void 1.245 +XULTreeAccessible::SetCurrentItem(Accessible* aItem) 1.246 +{ 1.247 + NS_ERROR("XULTreeAccessible::SetCurrentItem not implemented"); 1.248 +} 1.249 + 1.250 +already_AddRefed<nsIArray> 1.251 +XULTreeAccessible::SelectedItems() 1.252 +{ 1.253 + if (!mTreeView) 1.254 + return nullptr; 1.255 + 1.256 + nsCOMPtr<nsITreeSelection> selection; 1.257 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.258 + if (!selection) 1.259 + return nullptr; 1.260 + 1.261 + nsCOMPtr<nsIMutableArray> selectedItems = 1.262 + do_CreateInstance(NS_ARRAY_CONTRACTID); 1.263 + if (!selectedItems) 1.264 + return nullptr; 1.265 + 1.266 + int32_t rangeCount = 0; 1.267 + selection->GetRangeCount(&rangeCount); 1.268 + for (int32_t rangeIdx = 0; rangeIdx < rangeCount; rangeIdx++) { 1.269 + int32_t firstIdx = 0, lastIdx = -1; 1.270 + selection->GetRangeAt(rangeIdx, &firstIdx, &lastIdx); 1.271 + for (int32_t rowIdx = firstIdx; rowIdx <= lastIdx; rowIdx++) { 1.272 + nsIAccessible* item = GetTreeItemAccessible(rowIdx); 1.273 + if (item) 1.274 + selectedItems->AppendElement(item, false); 1.275 + } 1.276 + } 1.277 + 1.278 + return selectedItems.forget(); 1.279 +} 1.280 + 1.281 +uint32_t 1.282 +XULTreeAccessible::SelectedItemCount() 1.283 +{ 1.284 + if (!mTreeView) 1.285 + return 0; 1.286 + 1.287 + nsCOMPtr<nsITreeSelection> selection; 1.288 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.289 + if (selection) { 1.290 + int32_t count = 0; 1.291 + selection->GetCount(&count); 1.292 + return count; 1.293 + } 1.294 + 1.295 + return 0; 1.296 +} 1.297 + 1.298 +bool 1.299 +XULTreeAccessible::AddItemToSelection(uint32_t aIndex) 1.300 +{ 1.301 + if (!mTreeView) 1.302 + return false; 1.303 + 1.304 + nsCOMPtr<nsITreeSelection> selection; 1.305 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.306 + if (selection) { 1.307 + bool isSelected = false; 1.308 + selection->IsSelected(aIndex, &isSelected); 1.309 + if (!isSelected) 1.310 + selection->ToggleSelect(aIndex); 1.311 + 1.312 + return true; 1.313 + } 1.314 + return false; 1.315 +} 1.316 + 1.317 +bool 1.318 +XULTreeAccessible::RemoveItemFromSelection(uint32_t aIndex) 1.319 +{ 1.320 + if (!mTreeView) 1.321 + return false; 1.322 + 1.323 + nsCOMPtr<nsITreeSelection> selection; 1.324 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.325 + if (selection) { 1.326 + bool isSelected = false; 1.327 + selection->IsSelected(aIndex, &isSelected); 1.328 + if (isSelected) 1.329 + selection->ToggleSelect(aIndex); 1.330 + 1.331 + return true; 1.332 + } 1.333 + return false; 1.334 +} 1.335 + 1.336 +bool 1.337 +XULTreeAccessible::IsItemSelected(uint32_t aIndex) 1.338 +{ 1.339 + if (!mTreeView) 1.340 + return false; 1.341 + 1.342 + nsCOMPtr<nsITreeSelection> selection; 1.343 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.344 + if (selection) { 1.345 + bool isSelected = false; 1.346 + selection->IsSelected(aIndex, &isSelected); 1.347 + return isSelected; 1.348 + } 1.349 + return false; 1.350 +} 1.351 + 1.352 +bool 1.353 +XULTreeAccessible::UnselectAll() 1.354 +{ 1.355 + if (!mTreeView) 1.356 + return false; 1.357 + 1.358 + nsCOMPtr<nsITreeSelection> selection; 1.359 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.360 + if (!selection) 1.361 + return false; 1.362 + 1.363 + selection->ClearSelection(); 1.364 + return true; 1.365 +} 1.366 + 1.367 +Accessible* 1.368 +XULTreeAccessible::GetSelectedItem(uint32_t aIndex) 1.369 +{ 1.370 + if (!mTreeView) 1.371 + return nullptr; 1.372 + 1.373 + nsCOMPtr<nsITreeSelection> selection; 1.374 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.375 + if (!selection) 1.376 + return nullptr; 1.377 + 1.378 + uint32_t selCount = 0; 1.379 + int32_t rangeCount = 0; 1.380 + selection->GetRangeCount(&rangeCount); 1.381 + for (int32_t rangeIdx = 0; rangeIdx < rangeCount; rangeIdx++) { 1.382 + int32_t firstIdx = 0, lastIdx = -1; 1.383 + selection->GetRangeAt(rangeIdx, &firstIdx, &lastIdx); 1.384 + for (int32_t rowIdx = firstIdx; rowIdx <= lastIdx; rowIdx++) { 1.385 + if (selCount == aIndex) 1.386 + return GetTreeItemAccessible(rowIdx); 1.387 + 1.388 + selCount++; 1.389 + } 1.390 + } 1.391 + 1.392 + return nullptr; 1.393 +} 1.394 + 1.395 +bool 1.396 +XULTreeAccessible::SelectAll() 1.397 +{ 1.398 + // see if we are multiple select if so set ourselves as such 1.399 + if (!mTreeView) 1.400 + return false; 1.401 + 1.402 + nsCOMPtr<nsITreeSelection> selection; 1.403 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.404 + if (selection) { 1.405 + bool single = false; 1.406 + selection->GetSingle(&single); 1.407 + if (!single) { 1.408 + selection->SelectAll(); 1.409 + return true; 1.410 + } 1.411 + } 1.412 + 1.413 + return false; 1.414 +} 1.415 + 1.416 +//////////////////////////////////////////////////////////////////////////////// 1.417 +// XULTreeAccessible: Accessible implementation 1.418 + 1.419 +Accessible* 1.420 +XULTreeAccessible::GetChildAt(uint32_t aIndex) const 1.421 +{ 1.422 + uint32_t childCount = Accessible::ChildCount(); 1.423 + if (aIndex < childCount) 1.424 + return Accessible::GetChildAt(aIndex); 1.425 + 1.426 + return GetTreeItemAccessible(aIndex - childCount); 1.427 +} 1.428 + 1.429 +uint32_t 1.430 +XULTreeAccessible::ChildCount() const 1.431 +{ 1.432 + // Tree's children count is row count + treecols count. 1.433 + uint32_t childCount = Accessible::ChildCount(); 1.434 + if (!mTreeView) 1.435 + return childCount; 1.436 + 1.437 + int32_t rowCount = 0; 1.438 + mTreeView->GetRowCount(&rowCount); 1.439 + childCount += rowCount; 1.440 + 1.441 + return childCount; 1.442 +} 1.443 + 1.444 +Relation 1.445 +XULTreeAccessible::RelationByType(RelationType aType) 1.446 +{ 1.447 + if (aType == RelationType::NODE_PARENT_OF) { 1.448 + if (mTreeView) 1.449 + return Relation(new XULTreeItemIterator(this, mTreeView, -1)); 1.450 + 1.451 + return Relation(); 1.452 + } 1.453 + 1.454 + return Accessible::RelationByType(aType); 1.455 +} 1.456 + 1.457 +//////////////////////////////////////////////////////////////////////////////// 1.458 +// XULTreeAccessible: Widgets 1.459 + 1.460 +bool 1.461 +XULTreeAccessible::IsWidget() const 1.462 +{ 1.463 + return true; 1.464 +} 1.465 + 1.466 +bool 1.467 +XULTreeAccessible::IsActiveWidget() const 1.468 +{ 1.469 + if (IsAutoCompletePopup()) { 1.470 + nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm = 1.471 + do_QueryInterface(mContent->GetParent()); 1.472 + 1.473 + if (autoCompletePopupElm) { 1.474 + bool isOpen = false; 1.475 + autoCompletePopupElm->GetPopupOpen(&isOpen); 1.476 + return isOpen; 1.477 + } 1.478 + } 1.479 + return FocusMgr()->HasDOMFocus(mContent); 1.480 +} 1.481 + 1.482 +bool 1.483 +XULTreeAccessible::AreItemsOperable() const 1.484 +{ 1.485 + if (IsAutoCompletePopup()) { 1.486 + nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm = 1.487 + do_QueryInterface(mContent->GetParent()); 1.488 + 1.489 + if (autoCompletePopupElm) { 1.490 + bool isOpen = false; 1.491 + autoCompletePopupElm->GetPopupOpen(&isOpen); 1.492 + return isOpen; 1.493 + } 1.494 + } 1.495 + return true; 1.496 +} 1.497 + 1.498 +Accessible* 1.499 +XULTreeAccessible::ContainerWidget() const 1.500 +{ 1.501 + if (IsAutoCompletePopup()) { 1.502 + // This works for XUL autocompletes. It doesn't work for HTML forms 1.503 + // autocomplete because of potential crossprocess calls (when autocomplete 1.504 + // lives in content process while popup lives in chrome process). If that's 1.505 + // a problem then rethink Widgets interface. 1.506 + nsCOMPtr<nsIDOMXULMenuListElement> menuListElm = 1.507 + do_QueryInterface(mContent->GetParent()); 1.508 + if (menuListElm) { 1.509 + nsCOMPtr<nsIDOMNode> inputElm; 1.510 + menuListElm->GetInputField(getter_AddRefs(inputElm)); 1.511 + if (inputElm) { 1.512 + nsCOMPtr<nsINode> inputNode = do_QueryInterface(inputElm); 1.513 + if (inputNode) { 1.514 + Accessible* input = 1.515 + mDoc->GetAccessible(inputNode); 1.516 + return input ? input->ContainerWidget() : nullptr; 1.517 + } 1.518 + } 1.519 + } 1.520 + } 1.521 + return nullptr; 1.522 +} 1.523 + 1.524 +//////////////////////////////////////////////////////////////////////////////// 1.525 +// XULTreeAccessible: public implementation 1.526 + 1.527 +Accessible* 1.528 +XULTreeAccessible::GetTreeItemAccessible(int32_t aRow) const 1.529 +{ 1.530 + if (aRow < 0 || IsDefunct() || !mTreeView) 1.531 + return nullptr; 1.532 + 1.533 + int32_t rowCount = 0; 1.534 + nsresult rv = mTreeView->GetRowCount(&rowCount); 1.535 + if (NS_FAILED(rv) || aRow >= rowCount) 1.536 + return nullptr; 1.537 + 1.538 + void *key = reinterpret_cast<void*>(aRow); 1.539 + Accessible* cachedTreeItem = mAccessibleCache.GetWeak(key); 1.540 + if (cachedTreeItem) 1.541 + return cachedTreeItem; 1.542 + 1.543 + nsRefPtr<Accessible> treeItem = CreateTreeItemAccessible(aRow); 1.544 + if (treeItem) { 1.545 + mAccessibleCache.Put(key, treeItem); 1.546 + Document()->BindToDocument(treeItem, nullptr); 1.547 + return treeItem; 1.548 + } 1.549 + 1.550 + return nullptr; 1.551 +} 1.552 + 1.553 +void 1.554 +XULTreeAccessible::InvalidateCache(int32_t aRow, int32_t aCount) 1.555 +{ 1.556 + if (IsDefunct()) 1.557 + return; 1.558 + 1.559 + if (!mTreeView) { 1.560 + ClearCache(mAccessibleCache); 1.561 + return; 1.562 + } 1.563 + 1.564 + // Do not invalidate the cache if rows have been inserted. 1.565 + if (aCount > 0) 1.566 + return; 1.567 + 1.568 + DocAccessible* document = Document(); 1.569 + 1.570 + // Fire destroy event for removed tree items and delete them from caches. 1.571 + for (int32_t rowIdx = aRow; rowIdx < aRow - aCount; rowIdx++) { 1.572 + 1.573 + void* key = reinterpret_cast<void*>(rowIdx); 1.574 + Accessible* treeItem = mAccessibleCache.GetWeak(key); 1.575 + 1.576 + if (treeItem) { 1.577 + nsRefPtr<AccEvent> event = 1.578 + new AccEvent(nsIAccessibleEvent::EVENT_HIDE, treeItem); 1.579 + nsEventShell::FireEvent(event); 1.580 + 1.581 + // Unbind from document, shutdown and remove from tree cache. 1.582 + document->UnbindFromDocument(treeItem); 1.583 + mAccessibleCache.Remove(key); 1.584 + } 1.585 + } 1.586 + 1.587 + // We dealt with removed tree items already however we may keep tree items 1.588 + // having row indexes greater than row count. We should remove these dead tree 1.589 + // items silently from caches. 1.590 + int32_t newRowCount = 0; 1.591 + nsresult rv = mTreeView->GetRowCount(&newRowCount); 1.592 + if (NS_FAILED(rv)) 1.593 + return; 1.594 + 1.595 + int32_t oldRowCount = newRowCount - aCount; 1.596 + 1.597 + for (int32_t rowIdx = newRowCount; rowIdx < oldRowCount; ++rowIdx) { 1.598 + 1.599 + void *key = reinterpret_cast<void*>(rowIdx); 1.600 + Accessible* treeItem = mAccessibleCache.GetWeak(key); 1.601 + 1.602 + if (treeItem) { 1.603 + // Unbind from document, shutdown and remove from tree cache. 1.604 + document->UnbindFromDocument(treeItem); 1.605 + mAccessibleCache.Remove(key); 1.606 + } 1.607 + } 1.608 +} 1.609 + 1.610 +void 1.611 +XULTreeAccessible::TreeViewInvalidated(int32_t aStartRow, int32_t aEndRow, 1.612 + int32_t aStartCol, int32_t aEndCol) 1.613 +{ 1.614 + if (IsDefunct()) 1.615 + return; 1.616 + 1.617 + if (!mTreeView) { 1.618 + ClearCache(mAccessibleCache); 1.619 + return; 1.620 + } 1.621 + 1.622 + int32_t endRow = aEndRow; 1.623 + 1.624 + nsresult rv; 1.625 + if (endRow == -1) { 1.626 + int32_t rowCount = 0; 1.627 + rv = mTreeView->GetRowCount(&rowCount); 1.628 + if (NS_FAILED(rv)) 1.629 + return; 1.630 + 1.631 + endRow = rowCount - 1; 1.632 + } 1.633 + 1.634 + nsCOMPtr<nsITreeColumns> treeColumns; 1.635 + mTree->GetColumns(getter_AddRefs(treeColumns)); 1.636 + if (!treeColumns) 1.637 + return; 1.638 + 1.639 + int32_t endCol = aEndCol; 1.640 + 1.641 + if (endCol == -1) { 1.642 + int32_t colCount = 0; 1.643 + rv = treeColumns->GetCount(&colCount); 1.644 + if (NS_FAILED(rv)) 1.645 + return; 1.646 + 1.647 + endCol = colCount - 1; 1.648 + } 1.649 + 1.650 + for (int32_t rowIdx = aStartRow; rowIdx <= endRow; ++rowIdx) { 1.651 + 1.652 + void *key = reinterpret_cast<void*>(rowIdx); 1.653 + Accessible* accessible = mAccessibleCache.GetWeak(key); 1.654 + 1.655 + if (accessible) { 1.656 + nsRefPtr<XULTreeItemAccessibleBase> treeitemAcc = do_QueryObject(accessible); 1.657 + NS_ASSERTION(treeitemAcc, "Wrong accessible at the given key!"); 1.658 + 1.659 + treeitemAcc->RowInvalidated(aStartCol, endCol); 1.660 + } 1.661 + } 1.662 +} 1.663 + 1.664 +void 1.665 +XULTreeAccessible::TreeViewChanged(nsITreeView* aView) 1.666 +{ 1.667 + if (IsDefunct()) 1.668 + return; 1.669 + 1.670 + // Fire reorder event on tree accessible on accessible tree (do not fire 1.671 + // show/hide events on tree items because it can be expensive to fire them for 1.672 + // each tree item. 1.673 + nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this); 1.674 + Document()->FireDelayedEvent(reorderEvent); 1.675 + 1.676 + // Clear cache. 1.677 + ClearCache(mAccessibleCache); 1.678 + mTreeView = aView; 1.679 +} 1.680 + 1.681 +//////////////////////////////////////////////////////////////////////////////// 1.682 +// XULTreeAccessible: protected implementation 1.683 + 1.684 +already_AddRefed<Accessible> 1.685 +XULTreeAccessible::CreateTreeItemAccessible(int32_t aRow) const 1.686 +{ 1.687 + nsRefPtr<Accessible> accessible = 1.688 + new XULTreeItemAccessible(mContent, mDoc, const_cast<XULTreeAccessible*>(this), 1.689 + mTree, mTreeView, aRow); 1.690 + 1.691 + return accessible.forget(); 1.692 +} 1.693 + 1.694 +//////////////////////////////////////////////////////////////////////////////// 1.695 +// XULTreeItemAccessibleBase 1.696 +//////////////////////////////////////////////////////////////////////////////// 1.697 + 1.698 +XULTreeItemAccessibleBase:: 1.699 + XULTreeItemAccessibleBase(nsIContent* aContent, DocAccessible* aDoc, 1.700 + Accessible* aParent, nsITreeBoxObject* aTree, 1.701 + nsITreeView* aTreeView, int32_t aRow) : 1.702 + AccessibleWrap(aContent, aDoc), 1.703 + mTree(aTree), mTreeView(aTreeView), mRow(aRow) 1.704 +{ 1.705 + mParent = aParent; 1.706 + mStateFlags |= eSharedNode; 1.707 +} 1.708 + 1.709 +//////////////////////////////////////////////////////////////////////////////// 1.710 +// XULTreeItemAccessibleBase: nsISupports implementation 1.711 + 1.712 +NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessibleBase, Accessible, 1.713 + mTree) 1.714 + 1.715 +NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessibleBase) 1.716 + NS_INTERFACE_TABLE_INHERITED(XULTreeItemAccessibleBase, 1.717 + XULTreeItemAccessibleBase) 1.718 +NS_INTERFACE_TABLE_TAIL_INHERITING(Accessible) 1.719 +NS_IMPL_ADDREF_INHERITED(XULTreeItemAccessibleBase, Accessible) 1.720 +NS_IMPL_RELEASE_INHERITED(XULTreeItemAccessibleBase, Accessible) 1.721 + 1.722 +//////////////////////////////////////////////////////////////////////////////// 1.723 +// XULTreeItemAccessibleBase: nsIAccessible implementation 1.724 + 1.725 +Accessible* 1.726 +XULTreeItemAccessibleBase::FocusedChild() 1.727 +{ 1.728 + return FocusMgr()->FocusedAccessible() == this ? this : nullptr; 1.729 +} 1.730 + 1.731 +NS_IMETHODIMP 1.732 +XULTreeItemAccessibleBase::GetBounds(int32_t* aX, int32_t* aY, 1.733 + int32_t* aWidth, int32_t* aHeight) 1.734 +{ 1.735 + NS_ENSURE_ARG_POINTER(aX); 1.736 + *aX = 0; 1.737 + NS_ENSURE_ARG_POINTER(aY); 1.738 + *aY = 0; 1.739 + NS_ENSURE_ARG_POINTER(aWidth); 1.740 + *aWidth = 0; 1.741 + NS_ENSURE_ARG_POINTER(aHeight); 1.742 + *aHeight = 0; 1.743 + 1.744 + if (IsDefunct()) 1.745 + return NS_ERROR_FAILURE; 1.746 + 1.747 + // Get x coordinate and width from treechildren element, get y coordinate and 1.748 + // height from tree cell. 1.749 + 1.750 + nsCOMPtr<nsIBoxObject> boxObj = nsCoreUtils::GetTreeBodyBoxObject(mTree); 1.751 + NS_ENSURE_STATE(boxObj); 1.752 + 1.753 + nsCOMPtr<nsITreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree); 1.754 + 1.755 + int32_t x = 0, y = 0, width = 0, height = 0; 1.756 + nsresult rv = mTree->GetCoordsForCellItem(mRow, column, EmptyCString(), 1.757 + &x, &y, &width, &height); 1.758 + NS_ENSURE_SUCCESS(rv, rv); 1.759 + 1.760 + boxObj->GetWidth(&width); 1.761 + 1.762 + int32_t tcX = 0, tcY = 0; 1.763 + boxObj->GetScreenX(&tcX); 1.764 + boxObj->GetScreenY(&tcY); 1.765 + 1.766 + x = tcX; 1.767 + y += tcY; 1.768 + 1.769 + nsPresContext* presContext = mDoc->PresContext(); 1.770 + *aX = presContext->CSSPixelsToDevPixels(x); 1.771 + *aY = presContext->CSSPixelsToDevPixels(y); 1.772 + *aWidth = presContext->CSSPixelsToDevPixels(width); 1.773 + *aHeight = presContext->CSSPixelsToDevPixels(height); 1.774 + 1.775 + return NS_OK; 1.776 +} 1.777 + 1.778 +NS_IMETHODIMP 1.779 +XULTreeItemAccessibleBase::SetSelected(bool aSelect) 1.780 +{ 1.781 + if (IsDefunct()) 1.782 + return NS_ERROR_FAILURE; 1.783 + 1.784 + nsCOMPtr<nsITreeSelection> selection; 1.785 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.786 + if (selection) { 1.787 + bool isSelected; 1.788 + selection->IsSelected(mRow, &isSelected); 1.789 + if (isSelected != aSelect) 1.790 + selection->ToggleSelect(mRow); 1.791 + } 1.792 + 1.793 + return NS_OK; 1.794 +} 1.795 + 1.796 +NS_IMETHODIMP 1.797 +XULTreeItemAccessibleBase::TakeFocus() 1.798 +{ 1.799 + if (IsDefunct()) 1.800 + return NS_ERROR_FAILURE; 1.801 + 1.802 + nsCOMPtr<nsITreeSelection> selection; 1.803 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.804 + if (selection) 1.805 + selection->SetCurrentIndex(mRow); 1.806 + 1.807 + // focus event will be fired here 1.808 + return Accessible::TakeFocus(); 1.809 +} 1.810 + 1.811 +Relation 1.812 +XULTreeItemAccessibleBase::RelationByType(RelationType aType) 1.813 +{ 1.814 + 1.815 + switch (aType) { 1.816 + case RelationType::NODE_CHILD_OF: { 1.817 + int32_t parentIndex = -1; 1.818 + if (!NS_SUCCEEDED(mTreeView->GetParentIndex(mRow, &parentIndex))) 1.819 + return Relation(); 1.820 + 1.821 + if (parentIndex == -1) 1.822 + return Relation(mParent); 1.823 + 1.824 + XULTreeAccessible* treeAcc = mParent->AsXULTree(); 1.825 + return Relation(treeAcc->GetTreeItemAccessible(parentIndex)); 1.826 + } 1.827 + 1.828 + case RelationType::NODE_PARENT_OF: { 1.829 + bool isTrue = false; 1.830 + if (NS_FAILED(mTreeView->IsContainerEmpty(mRow, &isTrue)) || isTrue) 1.831 + return Relation(); 1.832 + 1.833 + if (NS_FAILED(mTreeView->IsContainerOpen(mRow, &isTrue)) || !isTrue) 1.834 + return Relation(); 1.835 + 1.836 + XULTreeAccessible* tree = mParent->AsXULTree(); 1.837 + return Relation(new XULTreeItemIterator(tree, mTreeView, mRow)); 1.838 + } 1.839 + 1.840 + default: 1.841 + return Relation(); 1.842 + } 1.843 +} 1.844 + 1.845 +uint8_t 1.846 +XULTreeItemAccessibleBase::ActionCount() 1.847 +{ 1.848 + // "activate" action is available for all treeitems, "expand/collapse" action 1.849 + // is avaible for treeitem which is container. 1.850 + return IsExpandable() ? 2 : 1; 1.851 +} 1.852 + 1.853 +NS_IMETHODIMP 1.854 +XULTreeItemAccessibleBase::GetActionName(uint8_t aIndex, nsAString& aName) 1.855 +{ 1.856 + if (IsDefunct()) 1.857 + return NS_ERROR_FAILURE; 1.858 + 1.859 + if (aIndex == eAction_Click) { 1.860 + aName.AssignLiteral("activate"); 1.861 + return NS_OK; 1.862 + } 1.863 + 1.864 + if (aIndex == eAction_Expand && IsExpandable()) { 1.865 + bool isContainerOpen; 1.866 + mTreeView->IsContainerOpen(mRow, &isContainerOpen); 1.867 + if (isContainerOpen) 1.868 + aName.AssignLiteral("collapse"); 1.869 + else 1.870 + aName.AssignLiteral("expand"); 1.871 + 1.872 + return NS_OK; 1.873 + } 1.874 + 1.875 + return NS_ERROR_INVALID_ARG; 1.876 +} 1.877 + 1.878 +NS_IMETHODIMP 1.879 +XULTreeItemAccessibleBase::DoAction(uint8_t aIndex) 1.880 +{ 1.881 + if (IsDefunct()) 1.882 + return NS_ERROR_FAILURE; 1.883 + 1.884 + if (aIndex != eAction_Click && 1.885 + (aIndex != eAction_Expand || !IsExpandable())) 1.886 + return NS_ERROR_INVALID_ARG; 1.887 + 1.888 + DoCommand(nullptr, aIndex); 1.889 + return NS_OK; 1.890 +} 1.891 + 1.892 +//////////////////////////////////////////////////////////////////////////////// 1.893 +// XULTreeItemAccessibleBase: Accessible implementation 1.894 + 1.895 +void 1.896 +XULTreeItemAccessibleBase::Shutdown() 1.897 +{ 1.898 + mTree = nullptr; 1.899 + mTreeView = nullptr; 1.900 + mRow = -1; 1.901 + 1.902 + AccessibleWrap::Shutdown(); 1.903 +} 1.904 + 1.905 +GroupPos 1.906 +XULTreeItemAccessibleBase::GroupPosition() 1.907 +{ 1.908 + GroupPos groupPos; 1.909 + 1.910 + int32_t level; 1.911 + nsresult rv = mTreeView->GetLevel(mRow, &level); 1.912 + NS_ENSURE_SUCCESS(rv, groupPos); 1.913 + 1.914 + int32_t topCount = 1; 1.915 + for (int32_t index = mRow - 1; index >= 0; index--) { 1.916 + int32_t lvl = -1; 1.917 + if (NS_SUCCEEDED(mTreeView->GetLevel(index, &lvl))) { 1.918 + if (lvl < level) 1.919 + break; 1.920 + 1.921 + if (lvl == level) 1.922 + topCount++; 1.923 + } 1.924 + } 1.925 + 1.926 + int32_t rowCount = 0; 1.927 + rv = mTreeView->GetRowCount(&rowCount); 1.928 + NS_ENSURE_SUCCESS(rv, groupPos); 1.929 + 1.930 + int32_t bottomCount = 0; 1.931 + for (int32_t index = mRow + 1; index < rowCount; index++) { 1.932 + int32_t lvl = -1; 1.933 + if (NS_SUCCEEDED(mTreeView->GetLevel(index, &lvl))) { 1.934 + if (lvl < level) 1.935 + break; 1.936 + 1.937 + if (lvl == level) 1.938 + bottomCount++; 1.939 + } 1.940 + } 1.941 + 1.942 + groupPos.level = level + 1; 1.943 + groupPos.setSize = topCount + bottomCount; 1.944 + groupPos.posInSet = topCount; 1.945 + 1.946 + return groupPos; 1.947 +} 1.948 + 1.949 +uint64_t 1.950 +XULTreeItemAccessibleBase::NativeState() 1.951 +{ 1.952 + 1.953 + // focusable and selectable states 1.954 + uint64_t state = NativeInteractiveState(); 1.955 + 1.956 + // expanded/collapsed state 1.957 + if (IsExpandable()) { 1.958 + bool isContainerOpen; 1.959 + mTreeView->IsContainerOpen(mRow, &isContainerOpen); 1.960 + state |= isContainerOpen ? states::EXPANDED : states::COLLAPSED; 1.961 + } 1.962 + 1.963 + // selected state 1.964 + nsCOMPtr<nsITreeSelection> selection; 1.965 + mTreeView->GetSelection(getter_AddRefs(selection)); 1.966 + if (selection) { 1.967 + bool isSelected; 1.968 + selection->IsSelected(mRow, &isSelected); 1.969 + if (isSelected) 1.970 + state |= states::SELECTED; 1.971 + } 1.972 + 1.973 + // focused state 1.974 + if (FocusMgr()->IsFocused(this)) 1.975 + state |= states::FOCUSED; 1.976 + 1.977 + // invisible state 1.978 + int32_t firstVisibleRow, lastVisibleRow; 1.979 + mTree->GetFirstVisibleRow(&firstVisibleRow); 1.980 + mTree->GetLastVisibleRow(&lastVisibleRow); 1.981 + if (mRow < firstVisibleRow || mRow > lastVisibleRow) 1.982 + state |= states::INVISIBLE; 1.983 + 1.984 + return state; 1.985 +} 1.986 + 1.987 +uint64_t 1.988 +XULTreeItemAccessibleBase::NativeInteractiveState() const 1.989 +{ 1.990 + return states::FOCUSABLE | states::SELECTABLE; 1.991 +} 1.992 + 1.993 +int32_t 1.994 +XULTreeItemAccessibleBase::IndexInParent() const 1.995 +{ 1.996 + return mParent ? mParent->ContentChildCount() + mRow : -1; 1.997 +} 1.998 + 1.999 +//////////////////////////////////////////////////////////////////////////////// 1.1000 +// XULTreeItemAccessibleBase: Widgets 1.1001 + 1.1002 +Accessible* 1.1003 +XULTreeItemAccessibleBase::ContainerWidget() const 1.1004 +{ 1.1005 + return mParent; 1.1006 +} 1.1007 + 1.1008 +//////////////////////////////////////////////////////////////////////////////// 1.1009 +// XULTreeItemAccessibleBase: Accessible protected methods 1.1010 + 1.1011 +void 1.1012 +XULTreeItemAccessibleBase::DispatchClickEvent(nsIContent* aContent, 1.1013 + uint32_t aActionIndex) 1.1014 +{ 1.1015 + if (IsDefunct()) 1.1016 + return; 1.1017 + 1.1018 + nsCOMPtr<nsITreeColumns> columns; 1.1019 + mTree->GetColumns(getter_AddRefs(columns)); 1.1020 + if (!columns) 1.1021 + return; 1.1022 + 1.1023 + // Get column and pseudo element. 1.1024 + nsCOMPtr<nsITreeColumn> column; 1.1025 + nsAutoCString pseudoElm; 1.1026 + 1.1027 + if (aActionIndex == eAction_Click) { 1.1028 + // Key column is visible and clickable. 1.1029 + columns->GetKeyColumn(getter_AddRefs(column)); 1.1030 + } else { 1.1031 + // Primary column contains a twisty we should click on. 1.1032 + columns->GetPrimaryColumn(getter_AddRefs(column)); 1.1033 + pseudoElm = NS_LITERAL_CSTRING("twisty"); 1.1034 + } 1.1035 + 1.1036 + if (column) 1.1037 + nsCoreUtils::DispatchClickEvent(mTree, mRow, column, pseudoElm); 1.1038 +} 1.1039 + 1.1040 +Accessible* 1.1041 +XULTreeItemAccessibleBase::GetSiblingAtOffset(int32_t aOffset, 1.1042 + nsresult* aError) const 1.1043 +{ 1.1044 + if (aError) 1.1045 + *aError = NS_OK; // fail peacefully 1.1046 + 1.1047 + return mParent->GetChildAt(IndexInParent() + aOffset); 1.1048 +} 1.1049 + 1.1050 +//////////////////////////////////////////////////////////////////////////////// 1.1051 +// XULTreeItemAccessibleBase: protected implementation 1.1052 + 1.1053 +bool 1.1054 +XULTreeItemAccessibleBase::IsExpandable() 1.1055 +{ 1.1056 + 1.1057 + bool isContainer = false; 1.1058 + mTreeView->IsContainer(mRow, &isContainer); 1.1059 + if (isContainer) { 1.1060 + bool isEmpty = false; 1.1061 + mTreeView->IsContainerEmpty(mRow, &isEmpty); 1.1062 + if (!isEmpty) { 1.1063 + nsCOMPtr<nsITreeColumns> columns; 1.1064 + mTree->GetColumns(getter_AddRefs(columns)); 1.1065 + nsCOMPtr<nsITreeColumn> primaryColumn; 1.1066 + if (columns) { 1.1067 + columns->GetPrimaryColumn(getter_AddRefs(primaryColumn)); 1.1068 + if (primaryColumn && 1.1069 + !nsCoreUtils::IsColumnHidden(primaryColumn)) 1.1070 + return true; 1.1071 + } 1.1072 + } 1.1073 + } 1.1074 + 1.1075 + return false; 1.1076 +} 1.1077 + 1.1078 +void 1.1079 +XULTreeItemAccessibleBase::GetCellName(nsITreeColumn* aColumn, nsAString& aName) 1.1080 +{ 1.1081 + 1.1082 + mTreeView->GetCellText(mRow, aColumn, aName); 1.1083 + 1.1084 + // If there is still no name try the cell value: 1.1085 + // This is for graphical cells. We need tree/table view implementors to 1.1086 + // implement FooView::GetCellValue to return a meaningful string for cases 1.1087 + // where there is something shown in the cell (non-text) such as a star icon; 1.1088 + // in which case GetCellValue for that cell would return "starred" or 1.1089 + // "flagged" for example. 1.1090 + if (aName.IsEmpty()) 1.1091 + mTreeView->GetCellValue(mRow, aColumn, aName); 1.1092 +} 1.1093 + 1.1094 + 1.1095 +//////////////////////////////////////////////////////////////////////////////// 1.1096 +// XULTreeItemAccessible 1.1097 +//////////////////////////////////////////////////////////////////////////////// 1.1098 + 1.1099 +XULTreeItemAccessible:: 1.1100 + XULTreeItemAccessible(nsIContent* aContent, DocAccessible* aDoc, 1.1101 + Accessible* aParent, nsITreeBoxObject* aTree, 1.1102 + nsITreeView* aTreeView, int32_t aRow) : 1.1103 + XULTreeItemAccessibleBase(aContent, aDoc, aParent, aTree, aTreeView, aRow) 1.1104 +{ 1.1105 + mColumn = nsCoreUtils::GetFirstSensibleColumn(mTree); 1.1106 + GetCellName(mColumn, mCachedName); 1.1107 +} 1.1108 + 1.1109 +//////////////////////////////////////////////////////////////////////////////// 1.1110 +// XULTreeItemAccessible: nsISupports implementation 1.1111 + 1.1112 +NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessible, 1.1113 + XULTreeItemAccessibleBase, 1.1114 + mColumn) 1.1115 + 1.1116 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessible) 1.1117 +NS_INTERFACE_MAP_END_INHERITING(XULTreeItemAccessibleBase) 1.1118 +NS_IMPL_ADDREF_INHERITED(XULTreeItemAccessible, XULTreeItemAccessibleBase) 1.1119 +NS_IMPL_RELEASE_INHERITED(XULTreeItemAccessible, XULTreeItemAccessibleBase) 1.1120 + 1.1121 +//////////////////////////////////////////////////////////////////////////////// 1.1122 +// XULTreeItemAccessible: nsIAccessible implementation 1.1123 + 1.1124 +ENameValueFlag 1.1125 +XULTreeItemAccessible::Name(nsString& aName) 1.1126 +{ 1.1127 + aName.Truncate(); 1.1128 + 1.1129 + GetCellName(mColumn, aName); 1.1130 + return eNameOK; 1.1131 +} 1.1132 + 1.1133 +//////////////////////////////////////////////////////////////////////////////// 1.1134 +// XULTreeItemAccessible: Accessible implementation 1.1135 + 1.1136 +void 1.1137 +XULTreeItemAccessible::Shutdown() 1.1138 +{ 1.1139 + mColumn = nullptr; 1.1140 + XULTreeItemAccessibleBase::Shutdown(); 1.1141 +} 1.1142 + 1.1143 +role 1.1144 +XULTreeItemAccessible::NativeRole() 1.1145 +{ 1.1146 + nsCOMPtr<nsITreeColumns> columns; 1.1147 + mTree->GetColumns(getter_AddRefs(columns)); 1.1148 + if (!columns) { 1.1149 + NS_ERROR("No tree columns object in the tree!"); 1.1150 + return roles::NOTHING; 1.1151 + } 1.1152 + 1.1153 + nsCOMPtr<nsITreeColumn> primaryColumn; 1.1154 + columns->GetPrimaryColumn(getter_AddRefs(primaryColumn)); 1.1155 + 1.1156 + return primaryColumn ? roles::OUTLINEITEM : roles::LISTITEM; 1.1157 +} 1.1158 + 1.1159 +//////////////////////////////////////////////////////////////////////////////// 1.1160 +// XULTreeItemAccessible: XULTreeItemAccessibleBase implementation 1.1161 + 1.1162 +void 1.1163 +XULTreeItemAccessible::RowInvalidated(int32_t aStartColIdx, int32_t aEndColIdx) 1.1164 +{ 1.1165 + nsAutoString name; 1.1166 + Name(name); 1.1167 + 1.1168 + if (name != mCachedName) { 1.1169 + nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this); 1.1170 + mCachedName = name; 1.1171 + } 1.1172 +} 1.1173 + 1.1174 +//////////////////////////////////////////////////////////////////////////////// 1.1175 +// XULTreeItemAccessible: Accessible protected implementation 1.1176 + 1.1177 +void 1.1178 +XULTreeItemAccessible::CacheChildren() 1.1179 +{ 1.1180 +} 1.1181 + 1.1182 + 1.1183 +//////////////////////////////////////////////////////////////////////////////// 1.1184 +// XULTreeColumAccessible 1.1185 +//////////////////////////////////////////////////////////////////////////////// 1.1186 + 1.1187 +XULTreeColumAccessible:: 1.1188 + XULTreeColumAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.1189 + XULColumAccessible(aContent, aDoc) 1.1190 +{ 1.1191 +} 1.1192 + 1.1193 +Accessible* 1.1194 +XULTreeColumAccessible::GetSiblingAtOffset(int32_t aOffset, 1.1195 + nsresult* aError) const 1.1196 +{ 1.1197 + if (aOffset < 0) 1.1198 + return XULColumAccessible::GetSiblingAtOffset(aOffset, aError); 1.1199 + 1.1200 + if (aError) 1.1201 + *aError = NS_OK; // fail peacefully 1.1202 + 1.1203 + nsCOMPtr<nsITreeBoxObject> tree = nsCoreUtils::GetTreeBoxObject(mContent); 1.1204 + if (tree) { 1.1205 + nsCOMPtr<nsITreeView> treeView; 1.1206 + tree->GetView(getter_AddRefs(treeView)); 1.1207 + if (treeView) { 1.1208 + int32_t rowCount = 0; 1.1209 + treeView->GetRowCount(&rowCount); 1.1210 + if (rowCount > 0 && aOffset <= rowCount) { 1.1211 + XULTreeAccessible* treeAcc = Parent()->AsXULTree(); 1.1212 + 1.1213 + if (treeAcc) 1.1214 + return treeAcc->GetTreeItemAccessible(aOffset - 1); 1.1215 + } 1.1216 + } 1.1217 + } 1.1218 + 1.1219 + return nullptr; 1.1220 +} 1.1221 +