Accessible* nsAccessiblePivot::SearchBackward(Accessible* aAccessible, nsIAccessibleTraversalRule* aRule, bool aSearchCurrent, nsresult* aResult) { *aResult = NS_OK; // Initial position could be unset, in that case return null. if (!aAccessible) return nullptr; RuleCache cache(aRule); uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE; Accessible* accessible = AdjustStartPosition(aAccessible, cache, &filtered, aResult); NS_ENSURE_SUCCESS(*aResult, nullptr); if (aSearchCurrent && (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)) { return accessible; } Accessible* root = GetActiveRoot(); while (accessible != root) { Accessible* parent = accessible->Parent(); int32_t idxInParent = accessible->IndexInParent(); while (idxInParent > 0) { if (!(accessible = parent->GetChildAt(--idxInParent))) continue; *aResult = cache.ApplyFilter(accessible, &filtered); NS_ENSURE_SUCCESS(*aResult, nullptr); Accessible* lastChild = nullptr; while (!(filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) && (lastChild = accessible->LastChild())) { parent = accessible; accessible = lastChild; idxInParent = accessible->IndexInParent(); *aResult = cache.ApplyFilter(accessible, &filtered); NS_ENSURE_SUCCESS(*aResult, nullptr); } if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH) return accessible; } if (!(accessible = parent)) break; *aResult = cache.ApplyFilter(accessible, &filtered); NS_ENSURE_SUCCESS(*aResult, nullptr); if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH) return accessible; } return nullptr; }
void TextRange::EmbeddedChildren(nsTArray<Accessible*>* aChildren) const { if (mStartContainer == mEndContainer) { int32_t startIdx = mStartContainer->GetChildIndexAtOffset(mStartOffset); int32_t endIdx = mStartContainer->GetChildIndexAtOffset(mEndOffset); for (int32_t idx = startIdx; idx <= endIdx; idx++) { Accessible* child = mStartContainer->GetChildAt(idx); if (nsAccUtils::IsEmbeddedObject(child)) aChildren->AppendElement(child); } return; } Accessible* p1 = mStartContainer->GetChildAtOffset(mStartOffset); Accessible* p2 = mEndContainer->GetChildAtOffset(mEndOffset); uint32_t pos1 = 0, pos2 = 0; AutoTArray<Accessible*, 30> parents1, parents2; Accessible* container = CommonParent(p1, p2, &parents1, &pos1, &parents2, &pos2); // Traverse the tree up to the container and collect embedded objects. for (uint32_t idx = 0; idx < pos1 - 1; idx++) { Accessible* parent = parents1[idx + 1]; Accessible* child = parents1[idx]; uint32_t childCount = parent->ChildCount(); for (uint32_t childIdx = child->IndexInParent(); childIdx < childCount; childIdx++) { Accessible* next = parent->GetChildAt(childIdx); if (nsAccUtils::IsEmbeddedObject(next)) aChildren->AppendElement(next); } } // Traverse through direct children in the container. int32_t endIdx = parents2[pos2 - 1]->IndexInParent(); int32_t childIdx = parents1[pos1 - 1]->IndexInParent() + 1; for (; childIdx < endIdx; childIdx++) { Accessible* next = container->GetChildAt(childIdx); if (nsAccUtils::IsEmbeddedObject(next)) aChildren->AppendElement(next); } // Traverse down from the container to end point. for (int32_t idx = pos2 - 2; idx > 0; idx--) { Accessible* parent = parents2[idx]; Accessible* child = parents2[idx - 1]; int32_t endIdx = child->IndexInParent(); for (int32_t childIdx = 0; childIdx < endIdx; childIdx++) { Accessible* next = parent->GetChildAt(childIdx); if (nsAccUtils::IsEmbeddedObject(next)) aChildren->AppendElement(next); } } }
NS_IMETHODIMP ARIAGridCellAccessible::GetRowIndex(int32_t* aRowIndex) { NS_ENSURE_ARG_POINTER(aRowIndex); *aRowIndex = -1; if (IsDefunct()) return NS_ERROR_FAILURE; Accessible* row = Parent(); if (!row) return NS_OK; Accessible* table = row->Parent(); if (!table) return NS_OK; *aRowIndex = 0; int32_t indexInTable = row->IndexInParent(); for (int32_t idx = 0; idx < indexInTable; idx++) { row = table->GetChildAt(idx); if (row->Role() == roles::ROW) (*aRowIndex)++; } return NS_OK; }
uint32_t XULListCellAccessible::RowIdx() const { Accessible* row = Parent(); if (!row) return 0; Accessible* table = row->Parent(); if (!table) return 0; int32_t indexInTable = row->IndexInParent(); uint32_t rowIdx = 0; for (int32_t idx = 0; idx < indexInTable; idx++) { row = table->GetChildAt(idx); if (row->Role() == roles::ROW) rowIdx++; } return rowIdx; }
bool TextRange::Crop(Accessible* aContainer) { uint32_t boundaryPos = 0, containerPos = 0; AutoTArray<Accessible*, 30> boundaryParents, containerParents; // Crop the start boundary. Accessible* container = nullptr; Accessible* boundary = mStartContainer->GetChildAtOffset(mStartOffset); if (boundary != aContainer) { CommonParent(boundary, aContainer, &boundaryParents, &boundaryPos, &containerParents, &containerPos); if (boundaryPos == 0) { if (containerPos != 0) { // The container is contained by the start boundary, reduce the range to // the point starting at the container. aContainer->ToTextPoint(mStartContainer.StartAssignment(), &mStartOffset); static_cast<Accessible*>(mStartContainer)->AddRef(); } else { // The start boundary and the container are siblings. container = aContainer; } } else if (containerPos != 0) { // The container does not contain the start boundary. boundary = boundaryParents[boundaryPos]; container = containerParents[containerPos]; } if (container) { // If the range start is after the container, then make the range invalid. if (boundary->IndexInParent() > container->IndexInParent()) { return !!(mRoot = nullptr); } // If the range starts before the container, then reduce the range to // the point starting at the container. if (boundary->IndexInParent() < container->IndexInParent()) { container->ToTextPoint(mStartContainer.StartAssignment(), &mStartOffset); mStartContainer.get()->AddRef(); } } boundaryParents.SetLengthAndRetainStorage(0); containerParents.SetLengthAndRetainStorage(0); } boundary = mEndContainer->GetChildAtOffset(mEndOffset); if (boundary == aContainer) { return true; } // Crop the end boundary. container = nullptr; CommonParent(boundary, aContainer, &boundaryParents, &boundaryPos, &containerParents, &containerPos); if (boundaryPos == 0) { if (containerPos != 0) { aContainer->ToTextPoint(mEndContainer.StartAssignment(), &mEndOffset, false); static_cast<Accessible*>(mEndContainer)->AddRef(); } else { container = aContainer; } } else if (containerPos != 0) { boundary = boundaryParents[boundaryPos]; container = containerParents[containerPos]; } if (!container) { return true; } if (boundary->IndexInParent() < container->IndexInParent()) { return !!(mRoot = nullptr); } if (boundary->IndexInParent() > container->IndexInParent()) { container->ToTextPoint(mEndContainer.StartAssignment(), &mEndOffset, false); static_cast<Accessible*>(mEndContainer)->AddRef(); } return true; }