Accessible* nsAccessiblePivot::AdjustStartPosition(Accessible* aAccessible, RuleCache& aCache, uint16_t* aFilterResult, nsresult* aResult) { Accessible* matched = aAccessible; *aResult = aCache.ApplyFilter(aAccessible, aFilterResult); if (aAccessible != mRoot && aAccessible != mModalRoot) { for (Accessible* temp = aAccessible->Parent(); temp && temp != mRoot && temp != mModalRoot; temp = temp->Parent()) { uint16_t filtered = nsIAccessibleTraversalRule::FILTER_IGNORE; *aResult = aCache.ApplyFilter(temp, &filtered); NS_ENSURE_SUCCESS(*aResult, nullptr); if (filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) { *aFilterResult = filtered; matched = temp; } } } if (aAccessible == mPosition && mStartOffset != -1 && mEndOffset != -1) { HyperTextAccessible* text = aAccessible->AsHyperText(); if (text) { matched = text->GetChildAtOffset(mStartOffset); } } return matched; }
static gchar* getTextAtOffsetCB(AtkText *aText, gint aOffset, AtkTextBoundary aBoundaryType, gint *aStartOffset, gint *aEndOffset) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (!accWrap) return nullptr; HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) return nullptr; nsAutoString autoStr; int32_t startOffset = 0, endOffset = 0; nsresult rv = text->GetTextAtOffset(aOffset, aBoundaryType, &startOffset, &endOffset, autoStr); *aStartOffset = startOffset; *aEndOffset = endOffset; NS_ENSURE_SUCCESS(rv, nullptr); ConvertTexttoAsterisks(accWrap, autoStr); NS_ConvertUTF16toUTF8 cautoStr(autoStr); return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; }
void EventQueue::CreateTextChangeEventFor(AccMutationEvent* aEvent) { Accessible* container = aEvent->mAccessible->Parent(); if (!container) return; HyperTextAccessible* textAccessible = container->AsHyperText(); if (!textAccessible) return; // Don't fire event for the first html:br in an editor. if (aEvent->mAccessible->Role() == roles::WHITESPACE) { nsCOMPtr<nsIEditor> editor = textAccessible->GetEditor(); if (editor) { bool isEmpty = false; editor->GetDocumentIsEmpty(&isEmpty); if (isEmpty) return; } } int32_t offset = textAccessible->GetChildOffset(aEvent->mAccessible); nsAutoString text; aEvent->mAccessible->AppendTextTo(text); if (text.IsEmpty()) return; aEvent->mTextChangeEvent = new AccTextChangeEvent(textAccessible, offset, text, aEvent->IsShow(), aEvent->mIsFromUserInput ? eFromUserInput : eNoUserInput); }
static void getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset, AtkCoordType aCoords, AtkTextRectangle *aRect) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if(!accWrap || !aRect) return; HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) return; int32_t extY = 0, extX = 0; int32_t extWidth = 0, extHeight = 0; uint32_t geckoCoordType; if (aCoords == ATK_XY_SCREEN) geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; else geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; #ifdef DEBUG nsresult rv = #endif text->GetRangeExtents(aStartOffset, aEndOffset, &extX, &extY, &extWidth, &extHeight, geckoCoordType); aRect->x = extX; aRect->y = extY; aRect->width = extWidth; aRect->height = extHeight; NS_ASSERTION(NS_SUCCEEDED(rv), "MaiInterfaceText::GetRangeExtents, failed\n"); }
static gchar* getTextSelectionCB(AtkText *aText, gint aSelectionNum, gint *aStartOffset, gint *aEndOffset) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); int32_t startOffset = 0, endOffset = 0; if (accWrap) { HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) { return nullptr; } text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset); *aStartOffset = startOffset; *aEndOffset = endOffset; return getTextCB(aText, *aStartOffset, *aEndOffset); } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { nsString data; proxy->SelectionBoundsAt(aSelectionNum, data, &startOffset, &endOffset); *aStartOffset = startOffset; *aEndOffset = endOffset; NS_ConvertUTF16toUTF8 dataAsUTF8(data); return (dataAsUTF8.get()) ? g_strdup(dataAsUTF8.get()) : nullptr; } return nullptr; }
static AtkAttributeSet* getRunAttributesCB(AtkText *aText, gint aOffset, gint *aStartOffset, gint *aEndOffset) { *aStartOffset = -1; *aEndOffset = -1; AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (!accWrap) return nullptr; HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) return nullptr; nsCOMPtr<nsIPersistentProperties> attributes; int32_t startOffset = 0, endOffset = 0; nsresult rv = text->GetTextAttributes(false, aOffset, &startOffset, &endOffset, getter_AddRefs(attributes)); NS_ENSURE_SUCCESS(rv, nullptr); *aStartOffset = startOffset; *aEndOffset = endOffset; return ConvertToAtkAttributeSet(attributes); }
static void getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset, AtkCoordType aCoords, AtkTextRectangle *aRect) { if (!aRect) { return; } nsIntRect rect; uint32_t geckoCoordType; if (aCoords == ATK_XY_SCREEN) { geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; } else { geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; } AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if(accWrap) { HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) { return; } rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType); } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { rect = proxy->TextBounds(aStartOffset, aEndOffset, geckoCoordType); } else { return; } aRect->x = rect.x; aRect->y = rect.y; aRect->width = rect.width; aRect->height = rect.height; }
static gint getOffsetAtPointCB(AtkText *aText, gint aX, gint aY, AtkCoordType aCoords) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (accWrap) { HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) { return -1; } return static_cast<gint>( text->OffsetAtPoint(aX, aY, (aCoords == ATK_XY_SCREEN ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE))); } if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { return static_cast<gint>( proxy->OffsetAtPoint(aX, aY, (aCoords == ATK_XY_SCREEN ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE))); } return -1; }
static gchar* getTextBeforeOffsetCB(AtkText *aText, gint aOffset, AtkTextBoundary aBoundaryType, gint *aStartOffset, gint *aEndOffset) { nsAutoString autoStr; int32_t startOffset = 0, endOffset = 0; AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (accWrap) { HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) return nullptr; text->TextBeforeOffset(aOffset, aBoundaryType, &startOffset, &endOffset, autoStr); ConvertTexttoAsterisks(accWrap, autoStr); } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { proxy->GetTextBeforeOffset(aOffset, aBoundaryType, autoStr, &startOffset, &endOffset); } *aStartOffset = startOffset; *aEndOffset = endOffset; NS_ConvertUTF16toUTF8 cautoStr(autoStr); return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; }
void SelectionManager::NormalSelectionChanged(nsISelection* aSelection) { mLastUsedSelection = do_GetWeakReference(aSelection); int32_t rangeCount = 0; aSelection->GetRangeCount(&rangeCount); if (rangeCount == 0) { mLastTextAccessible = nullptr; return; // No selection } HyperTextAccessible* textAcc = nsAccUtils::GetTextAccessibleFromSelection(aSelection); if (!textAcc) return; int32_t caretOffset = -1; nsresult rv = textAcc->GetCaretOffset(&caretOffset); if (NS_FAILED(rv)) return; if (textAcc == mLastTextAccessible && caretOffset == mLastCaretOffset) { int32_t selectionCount = 0; textAcc->GetSelectionCount(&selectionCount); // Don't swallow similar events when selecting text if (!selectionCount) return; // Swallow duplicate caret event } mLastCaretOffset = caretOffset; mLastTextAccessible = textAcc; nsRefPtr<AccEvent> event = new AccCaretMoveEvent(mLastTextAccessible); mLastTextAccessible->Document()->FireDelayedEvent(event); }
void SelectionManager::ProcessSelectionChanged(nsISelection* aSelection) { Selection* selection = static_cast<Selection*>(aSelection); const nsRange* range = selection->GetAnchorFocusRange(); nsINode* cntrNode = nullptr; if (range) cntrNode = range->GetCommonAncestor(); if (!cntrNode) { cntrNode = selection->GetFrameSelection()->GetAncestorLimiter(); if (!cntrNode) { cntrNode = selection->GetPresShell()->GetDocument(); NS_ASSERTION(selection->GetPresShell()->ConstFrameSelection() == selection->GetFrameSelection(), "Wrong selection container was used!"); } } HyperTextAccessible* text = nsAccUtils::GetTextContainer(cntrNode); if (!text) { NS_NOTREACHED("We must reach document accessible implementing text interface!"); return; } if (selection->GetType() == nsISelectionController::SELECTION_NORMAL) { nsRefPtr<AccEvent> event = new AccTextSelChangeEvent(text, aSelection); text->Document()->FireDelayedEvent(event); } else if (selection->GetType() == nsISelectionController::SELECTION_SPELLCHECK) { // XXX: fire an event for container accessible of the focus/anchor range // of the spelcheck selection. text->Document()->FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED, text); } }
void SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent) { AccTextSelChangeEvent* event = downcast_accEvent(aEvent); Selection* sel = static_cast<Selection*>(event->mSel.get()); // Fire selection change event if it's not pure caret-move selection change. if (sel->GetRangeCount() != 1 || !sel->IsCollapsed()) nsEventShell::FireEvent(aEvent); // Fire caret move event if there's a caret in the selection. nsINode* caretCntrNode = nsCoreUtils::GetDOMNodeFromDOMPoint(sel->GetFocusNode(), sel->GetFocusOffset()); if (!caretCntrNode) return; HyperTextAccessible* caretCntr = nsAccUtils::GetTextContainer(caretCntrNode); NS_ASSERTION(caretCntr, "No text container for focus while there's one for common ancestor?!"); if (!caretCntr) return; int32_t caretOffset = -1; if (NS_SUCCEEDED(caretCntr->GetCaretOffset(&caretOffset)) && caretOffset != -1) { nsRefPtr<AccCaretMoveEvent> caretMoveEvent = new AccCaretMoveEvent(caretCntr, caretOffset, aEvent->FromUserInput()); nsEventShell::FireEvent(caretMoveEvent); } }
void SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent) { // Fire selection change event if it's not pure caret-move selection change, // i.e. the accessible has or had not collapsed selection. AccTextSelChangeEvent* event = downcast_accEvent(aEvent); if (!event->IsCaretMoveOnly()) nsEventShell::FireEvent(aEvent); // Fire caret move event if there's a caret in the selection. nsINode* caretCntrNode = nsCoreUtils::GetDOMNodeFromDOMPoint( event->mSel->GetFocusNode(), event->mSel->FocusOffset()); if (!caretCntrNode) return; HyperTextAccessible* caretCntr = nsAccUtils::GetTextContainer(caretCntrNode); NS_ASSERTION( caretCntr, "No text container for focus while there's one for common ancestor?!"); if (!caretCntr) return; Selection* selection = caretCntr->DOMSelection(); // XXX Sometimes we can't get a selection for caretCntr, in that case assume // event->mSel is correct. if (!selection) selection = event->mSel; mCaretOffset = caretCntr->DOMPointToOffset(selection->GetFocusNode(), selection->FocusOffset()); mAccWithCaret = caretCntr; if (mCaretOffset != -1) { RefPtr<AccCaretMoveEvent> caretMoveEvent = new AccCaretMoveEvent(caretCntr, mCaretOffset, aEvent->FromUserInput()); nsEventShell::FireEvent(caretMoveEvent); } }
/* private */ PRUint16 AccessibleWrap::CreateMaiInterfaces(void) { PRUint16 interfacesBits = 0; // The Component interface is supported by all accessibles. interfacesBits |= 1 << MAI_INTERFACE_COMPONENT; // Add Action interface if the action count is more than zero. if (ActionCount() > 0) interfacesBits |= 1 << MAI_INTERFACE_ACTION; // Text, Editabletext, and Hypertext interface. HyperTextAccessible* hyperText = AsHyperText(); if (hyperText && hyperText->IsTextRole()) { interfacesBits |= 1 << MAI_INTERFACE_TEXT; interfacesBits |= 1 << MAI_INTERFACE_EDITABLE_TEXT; if (!nsAccUtils::MustPrune(this)) interfacesBits |= 1 << MAI_INTERFACE_HYPERTEXT; } // Value interface. nsCOMPtr<nsIAccessibleValue> accessInterfaceValue; QueryInterface(NS_GET_IID(nsIAccessibleValue), getter_AddRefs(accessInterfaceValue)); if (accessInterfaceValue) { interfacesBits |= 1 << MAI_INTERFACE_VALUE; } // Document interface. if (IsDoc()) interfacesBits |= 1 << MAI_INTERFACE_DOCUMENT; if (IsImage()) interfacesBits |= 1 << MAI_INTERFACE_IMAGE; // HyperLink interface. if (IsLink()) interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL; if (!nsAccUtils::MustPrune(this)) { // These interfaces require children // Table interface. nsCOMPtr<nsIAccessibleTable> accessInterfaceTable; QueryInterface(NS_GET_IID(nsIAccessibleTable), getter_AddRefs(accessInterfaceTable)); if (accessInterfaceTable) { interfacesBits |= 1 << MAI_INTERFACE_TABLE; } // Selection interface. if (IsSelect()) { interfacesBits |= 1 << MAI_INTERFACE_SELECTION; } } return interfacesBits; }
NS_IMETHODIMP xpcAccessibleHyperText::AddSelection(int32_t aStartOffset, int32_t aEndOffset) { HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; text->AddToSelection(aStartOffset, aEndOffset); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::SetTextContents(const nsAString& aText) { HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; text->ReplaceText(aText); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::ScriptablePasteText(int32_t aOffset) { HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; text->PasteText(aOffset); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::RemoveSelection(int32_t aSelectionNum) { HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; text->RemoveFromSelection(aSelectionNum); return NS_OK; }
NS_IMETHODIMP nsAccessiblePivot::MovePreviousByText(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 (mStartOffset == -1) mStartOffset = text != oldPosition ? text->GetChildOffset(oldPosition) : 0; if (mStartOffset == 0) 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->GetTextBeforeOffset(mStartOffset, startBoundary, &newStart, &newEnd, unusedText); if (newStart < mStartOffset) mStartOffset = newEnd == mStartOffset ? newStart : newEnd; else // XXX: In certain odd cases newStart is equal to mStartOffset text->GetTextBeforeOffset(mStartOffset - 1, startBoundary, &newStart, &mStartOffset, unusedText); text->GetTextAtOffset(mStartOffset, endBoundary, &newStart, &mEndOffset, unusedText); *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) return 0; HyperTextAccessible* textAcc = accWrap->AsHyperText(); return textAcc->IsDefunct() ? 0 : static_cast<gint>(textAcc->CharacterCount()); }
NS_IMETHODIMP xpcAccessibleHyperText::ScriptableCutText(int32_t aStartOffset, int32_t aEndOffset) { HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; text->CutText(aStartOffset, aEndOffset); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::ScriptableInsertText(const nsAString& aText, int32_t aOffset) { HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; text->InsertText(aText, aOffset); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::ScriptableScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset, uint32_t aScrollType) { HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; text->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::GetText(int32_t aStartOffset, int32_t aEndOffset, nsAString& aText) { aText.Truncate(); HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; text->TextSubstring(aStartOffset, aEndOffset, aText); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::GetLinkCount(int32_t* aLinkCount) { NS_ENSURE_ARG_POINTER(aLinkCount); *aLinkCount = 0; HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; *aLinkCount = text->LinkCount(); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::GetScriptableCaretOffset(int32_t* aCaretOffset) { NS_ENSURE_ARG_POINTER(aCaretOffset); *aCaretOffset = -1; HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; *aCaretOffset = text->CaretOffset(); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::GetDefaultTextAttributes(nsIPersistentProperties** aAttributes) { NS_ENSURE_ARG_POINTER(aAttributes); *aAttributes = nullptr; HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; nsCOMPtr<nsIPersistentProperties> attrs = text->DefaultTextAttributes(); attrs.swap(*aAttributes); return NS_OK; }
NS_IMETHODIMP xpcAccessibleHyperText::GetOffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType, int32_t* aOffset) { NS_ENSURE_ARG_POINTER(aOffset); *aOffset = -1; HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; *aOffset = text->OffsetAtPoint(aX, aY, aCoordType); return NS_OK; }
STDMETHODIMP ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset) { A11Y_TRYBLOCK_BEGIN HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; return textAcc->AddToSelection(aStartOffset, aEndOffset) ? S_OK : E_INVALIDARG; A11Y_TRYBLOCK_END }
NS_IMETHODIMP xpcAccessibleHyperText::GetLinkIndexAtOffset(int32_t aOffset, int32_t* aLinkIndex) { NS_ENSURE_ARG_POINTER(aLinkIndex); *aLinkIndex = -1; // API says this magic value means 'not found' HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this); if (text->IsDefunct()) return NS_ERROR_FAILURE; *aLinkIndex = text->LinkIndexAtOffset(aOffset); return NS_OK; }