NS_IMETHODIMP nsAccessiblePivot::MoveLast(nsIAccessibleTraversalRule* aRule, bool* aResult) { NS_ENSURE_ARG(aResult); NS_ENSURE_ARG(aRule); Accessible* root = GetActiveRoot(); NS_ENSURE_TRUE(root && !root->IsDefunct(), NS_ERROR_NOT_IN_TREE); *aResult = false; nsresult rv = NS_OK; Accessible* lastAccessible = root; Accessible* accessible = nullptr; // First go to the last accessible in pre-order while (lastAccessible->HasChildren()) lastAccessible = lastAccessible->LastChild(); // Search backwards from last accessible and find the last occurrence in the doc accessible = SearchBackward(lastAccessible, aRule, true, &rv); NS_ENSURE_SUCCESS(rv, rv); if (accessible) *aResult = MovePivotInternal(accessible, nsAccessiblePivot::REASON_LAST); return NS_OK; }
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; }
HyperTextAccessible* nsAccessiblePivot::SearchForText(Accessible* aAccessible, bool aBackward) { Accessible* root = GetActiveRoot(); Accessible* accessible = aAccessible; while (true) { Accessible* child = nullptr; while ((child = (aBackward ? accessible->LastChild() : accessible->FirstChild()))) { accessible = child; if (child->IsHyperText()) return child->AsHyperText(); } Accessible* sibling = nullptr; Accessible* temp = accessible; do { if (temp == root) break; if (temp != aAccessible && temp->IsHyperText()) return temp->AsHyperText(); sibling = aBackward ? temp->PrevSibling() : temp->NextSibling(); if (sibling) break; } while ((temp = temp->Parent())); if (!sibling) break; accessible = sibling; if (accessible->IsHyperText()) return accessible->AsHyperText(); } return nullptr; }