static gint getCharacterCountCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (!accWrap) return 0; HyperTextAccessible* textAcc = accWrap->AsHyperText(); return textAcc->IsDefunct() ? 0 : static_cast<gint>(textAcc->CharacterCount()); }
NS_IMETHODIMP xpcAccessibleHyperText::GetCharacterCount(int32_t* aCharacterCount) { NS_ENSURE_ARG_POINTER(aCharacterCount); *aCharacterCount = 0; HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; *aCharacterCount = text->CharacterCount(); return NS_OK; }
NS_IMETHODIMP nsAccessiblePivot::MoveNextByText(TextBoundaryType aBoundary, bool* aResult) { NS_ENSURE_ARG(aResult); *aResult = false; int32_t oldStart = mStartOffset, oldEnd = mEndOffset; HyperTextAccessible* text = mPosition->AsHyperText(); Accessible* oldPosition = mPosition; while (!text) { oldPosition = mPosition; mPosition = mPosition->Parent(); text = mPosition->AsHyperText(); } if (mEndOffset == -1) mEndOffset = text != oldPosition ? text->GetChildOffset(oldPosition) : 0; if (mEndOffset == text->CharacterCount()) return NS_OK; AccessibleTextBoundary startBoundary, endBoundary; switch (aBoundary) { case CHAR_BOUNDARY: startBoundary = nsIAccessibleText::BOUNDARY_CHAR; endBoundary = nsIAccessibleText::BOUNDARY_CHAR; break; case WORD_BOUNDARY: startBoundary = nsIAccessibleText::BOUNDARY_WORD_START; endBoundary = nsIAccessibleText::BOUNDARY_WORD_END; break; default: return NS_ERROR_INVALID_ARG; } nsAutoString unusedText; int32_t newStart = 0, newEnd = 0; text->GetTextAtOffset(mEndOffset, endBoundary, &newStart, &mEndOffset, unusedText); text->GetTextBeforeOffset(mEndOffset, startBoundary, &newStart, &newEnd, unusedText); mStartOffset = newEnd == mEndOffset ? newStart : newEnd; *aResult = true; NotifyOfPivotChange(mPosition, oldStart, oldEnd, nsIAccessiblePivot::REASON_TEXT); return NS_OK; }
static gint getCharacterCountCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (accWrap) { HyperTextAccessible* textAcc = accWrap->AsHyperText(); return textAcc->IsDefunct() ? 0 : static_cast<gint>(textAcc->CharacterCount()); } if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { return proxy->CharacterCount(); } return 0; }
NS_IMETHODIMP nsAccessiblePivot::SetTextRange(nsIAccessibleText* aTextAccessible, int32_t aStartOffset, int32_t aEndOffset, bool aIsFromUserInput, uint8_t aArgc) { NS_ENSURE_ARG(aTextAccessible); // Check that start offset is smaller than end offset, and that if a value is // smaller than 0, both should be -1. NS_ENSURE_TRUE(aStartOffset <= aEndOffset && (aStartOffset >= 0 || (aStartOffset != -1 && aEndOffset != -1)), NS_ERROR_INVALID_ARG); nsRefPtr<Accessible> acc(do_QueryObject(aTextAccessible)); if (!acc) return NS_ERROR_INVALID_ARG; HyperTextAccessible* newPosition = acc->AsHyperText(); if (!newPosition || !IsDescendantOf(newPosition, GetActiveRoot())) return NS_ERROR_INVALID_ARG; // Make sure the given offsets don't exceed the character count. int32_t charCount = newPosition->CharacterCount(); if (aEndOffset > charCount) return NS_ERROR_FAILURE; int32_t oldStart = mStartOffset, oldEnd = mEndOffset; mStartOffset = aStartOffset; mEndOffset = aEndOffset; nsRefPtr<Accessible> oldPosition = mPosition.forget(); mPosition = newPosition; NotifyOfPivotChange(oldPosition, oldStart, oldEnd, nsIAccessiblePivot::REASON_TEXT, (aArgc > 0) ? aIsFromUserInput : true); return NS_OK; }
NS_IMETHODIMP nsAccessiblePivot::SetTextRange(nsIAccessibleText* aTextAccessible, int32_t aStartOffset, int32_t aEndOffset, bool aIsFromUserInput, uint8_t aArgc) { NS_ENSURE_ARG(aTextAccessible); // Check that start offset is smaller than end offset, and that if a value is // smaller than 0, both should be -1. NS_ENSURE_TRUE(aStartOffset <= aEndOffset && (aStartOffset >= 0 || (aStartOffset != -1 && aEndOffset != -1)), NS_ERROR_INVALID_ARG); nsCOMPtr<nsIAccessible> xpcAcc = do_QueryInterface(aTextAccessible); NS_ENSURE_ARG(xpcAcc); RefPtr<Accessible> acc = xpcAcc->ToInternalAccessible(); NS_ENSURE_ARG(acc); HyperTextAccessible* position = acc->AsHyperText(); if (!position || !IsDescendantOf(position, GetActiveRoot())) return NS_ERROR_INVALID_ARG; // Make sure the given offsets don't exceed the character count. if (aEndOffset > static_cast<int32_t>(position->CharacterCount())) return NS_ERROR_FAILURE; int32_t oldStart = mStartOffset, oldEnd = mEndOffset; mStartOffset = aStartOffset; mEndOffset = aEndOffset; mPosition.swap(acc); NotifyOfPivotChange(acc, oldStart, oldEnd, nsIAccessiblePivot::REASON_TEXT, (aArgc > 0) ? aIsFromUserInput : true); return NS_OK; }
NS_IMETHODIMP nsAccessiblePivot::MovePreviousByText(TextBoundaryType aBoundary, bool* aResult) { NS_ENSURE_ARG(aResult); *aResult = false; int32_t tempStart = mStartOffset, tempEnd = mEndOffset; Accessible* tempPosition = mPosition; Accessible* root = GetActiveRoot(); while (true) { Accessible* curPosition = tempPosition; HyperTextAccessible* text; // Find the nearest text node using a reverse preorder traversal starting // from the current node. if (!(text = tempPosition->AsHyperText())) { text = SearchForText(tempPosition, true); if (!text) return NS_OK; if (text != curPosition) tempStart = tempEnd = -1; tempPosition = text; } // If the search led to the parent of the node we started on (e.g. when // starting on a text leaf), start the text movement from the end of that // node, otherwise we just default to 0. if (tempStart == -1) { if (tempPosition != curPosition) tempStart = text == curPosition->Parent() ? text->GetChildOffset(curPosition) : text->CharacterCount(); else tempStart = 0; } // If there's no more text on the current node, try to find the previous // text node; if there isn't one, bail out. if (tempStart == 0) { if (tempPosition == root) return NS_OK; // If we're currently sitting on a link, try move to either the previous // sibling or the parent, whichever is closer to the current end // offset. Otherwise, do a forward search for the next node to land on // (we don't do this in the first case because we don't want to go to the // subtree). Accessible* sibling = tempPosition->PrevSibling(); if (tempPosition->IsLink()) { if (sibling && sibling->IsLink()) { HyperTextAccessible* siblingText = sibling->AsHyperText(); tempStart = tempEnd = siblingText ? siblingText->CharacterCount() : -1; tempPosition = sibling; } else { tempStart = tempPosition->StartOffset(); tempEnd = tempPosition->EndOffset(); tempPosition = tempPosition->Parent(); } } else { HyperTextAccessible* tempText = SearchForText(tempPosition, true); if (!tempText) return NS_OK; tempPosition = tempText; tempStart = tempEnd = tempText->CharacterCount(); } continue; } AccessibleTextBoundary startBoundary, endBoundary; switch (aBoundary) { case CHAR_BOUNDARY: startBoundary = nsIAccessibleText::BOUNDARY_CHAR; endBoundary = nsIAccessibleText::BOUNDARY_CHAR; break; case WORD_BOUNDARY: startBoundary = nsIAccessibleText::BOUNDARY_WORD_START; endBoundary = nsIAccessibleText::BOUNDARY_WORD_END; break; default: return NS_ERROR_INVALID_ARG; } nsAutoString unusedText; int32_t newStart = 0, newEnd = 0, currentStart = tempStart, potentialEnd = 0; text->TextBeforeOffset(tempStart, startBoundary, &newStart, &newEnd, unusedText); if (newStart < tempStart) tempStart = newEnd >= currentStart ? newStart : newEnd; else // XXX: In certain odd cases newStart is equal to tempStart text->TextBeforeOffset(tempStart - 1, startBoundary, &newStart, &tempStart, unusedText); text->TextAtOffset(tempStart, endBoundary, &newStart, &potentialEnd, unusedText); tempEnd = potentialEnd < tempEnd ? potentialEnd : currentStart; // The offset range we've obtained might have embedded characters in it, // limit the range to the start of the last occurrence of an embedded // character. Accessible* childAtOffset = nullptr; for (int32_t i = tempEnd - 1; i >= tempStart; i--) { childAtOffset = text->GetChildAtOffset(i); if (childAtOffset && nsAccUtils::IsEmbeddedObject(childAtOffset)) { tempStart = childAtOffset->EndOffset(); break; } } // If there's an embedded character at the very end of the range, we // instead want to traverse into it. So restart the movement with // the child as the starting point. if (childAtOffset && nsAccUtils::IsEmbeddedObject(childAtOffset) && tempEnd == static_cast<int32_t>(childAtOffset->EndOffset())) { tempPosition = childAtOffset; tempStart = tempEnd = childAtOffset->AsHyperText()->CharacterCount(); continue; } *aResult = true; Accessible* startPosition = mPosition; int32_t oldStart = mStartOffset, oldEnd = mEndOffset; mPosition = tempPosition; mStartOffset = tempStart; mEndOffset = tempEnd; NotifyOfPivotChange(startPosition, oldStart, oldEnd, nsIAccessiblePivot::REASON_TEXT); return NS_OK; } }