/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "DocAccessibleChild.h" #include "AccAttributes.h" #include "nsAccessibilityService.h" #include "LocalAccessible-inl.h" #include "RemoteAccessible.h" #include "Relation.h" #include "HyperTextAccessible-inl.h" #include "TextLeafAccessible.h" #include "ImageAccessible.h" #include "TableAccessible.h" #include "TableCellAccessible.h" #include "nsAccUtils.h" #ifdef MOZ_ACCESSIBILITY_ATK # include "AccessibleWrap.h" #endif #include "AccAttributes.h" #include "mozilla/PresShell.h" #include "mozilla/a11y/DocAccessiblePlatformExtChild.h" namespace mozilla { namespace a11y { LocalAccessible* DocAccessibleChild::IdToAccessibleLink( const uint64_t& aID) const { LocalAccessible* acc = IdToAccessible(aID); return acc && acc->IsLink() ? acc : nullptr; } LocalAccessible* DocAccessibleChild::IdToAccessibleSelect( const uint64_t& aID) const { LocalAccessible* acc = IdToAccessible(aID); return acc && acc->IsSelect() ? acc : nullptr; } TextLeafAccessible* DocAccessibleChild::IdToTextLeafAccessible( const uint64_t& aID) const { LocalAccessible* acc = IdToAccessible(aID); return acc && acc->IsTextLeaf() ? acc->AsTextLeaf() : nullptr; } ImageAccessible* DocAccessibleChild::IdToImageAccessible( const uint64_t& aID) const { LocalAccessible* acc = IdToAccessible(aID); return (acc && acc->IsImage()) ? acc->AsImage() : nullptr; } TableCellAccessible* DocAccessibleChild::IdToTableCellAccessible( const uint64_t& aID) const { LocalAccessible* acc = IdToAccessible(aID); return (acc && acc->IsTableCell()) ? acc->AsTableCell() : nullptr; } TableAccessible* DocAccessibleChild::IdToTableAccessible( const uint64_t& aID) const { LocalAccessible* acc = IdToAccessible(aID); return (acc && acc->IsTable()) ? acc->AsTable() : nullptr; } mozilla::ipc::IPCResult DocAccessibleChild::RecvState(const uint64_t& aID, uint64_t* aState) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) { *aState = states::DEFUNCT; return IPC_OK(); } *aState = acc->State(); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvNativeState(const uint64_t& aID, uint64_t* aState) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) { *aState = states::DEFUNCT; return IPC_OK(); } *aState = acc->NativeState(); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvName(const uint64_t& aID, nsString* aName, uint32_t* aFlag) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) return IPC_OK(); *aFlag = acc->Name(*aName); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvValue(const uint64_t& aID, nsString* aValue) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) { return IPC_OK(); } acc->Value(*aValue); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvHelp(const uint64_t& aID, nsString* aHelp) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) { return IPC_OK(); } acc->Help(*aHelp); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvDescription(const uint64_t& aID, nsString* aDesc) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) return IPC_OK(); acc->Description(*aDesc); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAttributes( const uint64_t& aID, RefPtr* aAttributes) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) return IPC_OK(); *aAttributes = acc->Attributes(); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvRelationByType( const uint64_t& aID, const uint32_t& aType, nsTArray* aTargets) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) return IPC_OK(); auto type = static_cast(aType); Relation rel = acc->RelationByType(type); while (LocalAccessible* target = rel.LocalNext()) { aTargets->AppendElement(reinterpret_cast(target->UniqueID())); } return IPC_OK(); } static void AddRelation(LocalAccessible* aAcc, RelationType aType, nsTArray* aTargets) { Relation rel = aAcc->RelationByType(aType); nsTArray targets; while (LocalAccessible* target = rel.LocalNext()) { targets.AppendElement(reinterpret_cast(target->UniqueID())); } if (!targets.IsEmpty()) { RelationTargets* newRelation = aTargets->AppendElement( RelationTargets(static_cast(aType), nsTArray())); newRelation->Targets() = std::move(targets); } } mozilla::ipc::IPCResult DocAccessibleChild::RecvRelations( const uint64_t& aID, nsTArray* aRelations) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) return IPC_OK(); #define RELATIONTYPE(gecko, s, a, m, i) \ AddRelation(acc, RelationType::gecko, aRelations); #include "RelationTypeMap.h" #undef RELATIONTYPE return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvIsSearchbox(const uint64_t& aID, bool* aRetVal) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) return IPC_OK(); *aRetVal = acc->IsSearchbox(); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvLandmarkRole( const uint64_t& aID, nsString* aLandmark) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) { return IPC_OK(); } if (nsAtom* roleAtom = acc->LandmarkRole()) { roleAtom->ToString(*aLandmark); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvGroupPosition( const uint64_t& aID, int32_t* aLevel, int32_t* aSimilarItemsInGroup, int32_t* aPositionInGroup) { LocalAccessible* acc = IdToAccessible(aID); if (acc) { GroupPos groupPos = acc->GroupPosition(); *aLevel = groupPos.level; *aSimilarItemsInGroup = groupPos.setSize; *aPositionInGroup = groupPos.posInSet; } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvScrollToPoint( const uint64_t& aID, const uint32_t& aScrollType, const int32_t& aX, const int32_t& aY) { LocalAccessible* acc = IdToAccessible(aID); if (acc) { acc->ScrollToPoint(aScrollType, aX, aY); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAnnounce( const uint64_t& aID, const nsAString& aAnnouncement, const uint16_t& aPriority) { LocalAccessible* acc = IdToAccessible(aID); if (acc) { acc->Announce(aAnnouncement, aPriority); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvCaretLineNumber( const uint64_t& aID, int32_t* aLineNumber) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); *aLineNumber = acc && acc->IsTextRole() ? acc->CaretLineNumber() : 0; return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvCaretOffset(const uint64_t& aID, int32_t* aOffset) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); *aOffset = acc && acc->IsTextRole() ? acc->CaretOffset() : 0; return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvCharacterCount( const uint64_t& aID, int32_t* aCount) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); *aCount = acc ? acc->CharacterCount() : 0; return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvSelectionCount( const uint64_t& aID, int32_t* aCount) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); *aCount = acc ? acc->SelectionCount() : 0; return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTextSubstring( const uint64_t& aID, const int32_t& aStartOffset, const int32_t& aEndOffset, nsString* aText, bool* aValid) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) { return IPC_OK(); } TextLeafAccessible* leaf = acc->AsTextLeaf(); if (leaf) { if (aStartOffset != 0 || aEndOffset != -1) { // We don't support fetching partial text from a leaf. *aValid = false; return IPC_OK(); } *aValid = true; *aText = leaf->Text(); return IPC_OK(); } HyperTextAccessible* hyper = acc->AsHyperText(); if (!hyper) { return IPC_OK(); } *aValid = hyper->IsValidRange(aStartOffset, aEndOffset); hyper->TextSubstring(aStartOffset, aEndOffset, *aText); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvGetTextAfterOffset( const uint64_t& aID, const int32_t& aOffset, const int32_t& aBoundaryType, nsString* aText, int32_t* aStartOffset, int32_t* aEndOffset) { *aStartOffset = 0; *aEndOffset = 0; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc) { acc->TextAfterOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, *aText); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvGetTextAtOffset( const uint64_t& aID, const int32_t& aOffset, const int32_t& aBoundaryType, nsString* aText, int32_t* aStartOffset, int32_t* aEndOffset) { *aStartOffset = 0; *aEndOffset = 0; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc) { acc->TextAtOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, *aText); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvGetTextBeforeOffset( const uint64_t& aID, const int32_t& aOffset, const int32_t& aBoundaryType, nsString* aText, int32_t* aStartOffset, int32_t* aEndOffset) { *aStartOffset = 0; *aEndOffset = 0; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc) { acc->TextBeforeOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, *aText); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvCharAt(const uint64_t& aID, const int32_t& aOffset, uint16_t* aChar) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); *aChar = acc && acc->IsTextRole() ? static_cast(acc->CharAt(aOffset)) : 0; return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTextAttributes( const uint64_t& aID, const bool& aIncludeDefAttrs, const int32_t& aOffset, RefPtr* aAttributes, int32_t* aStartOffset, int32_t* aEndOffset) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (!acc || !acc->IsTextRole()) { return IPC_OK(); } *aAttributes = acc->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvDefaultTextAttributes( const uint64_t& aID, RefPtr* aAttributes) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (!acc || !acc->IsTextRole()) { return IPC_OK(); } *aAttributes = acc->DefaultTextAttributes(); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTextBounds( const uint64_t& aID, const int32_t& aStartOffset, const int32_t& aEndOffset, const uint32_t& aCoordType, LayoutDeviceIntRect* aRetVal) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aRetVal = acc->TextBounds(aStartOffset, aEndOffset, aCoordType); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvCharBounds( const uint64_t& aID, const int32_t& aOffset, const uint32_t& aCoordType, LayoutDeviceIntRect* aRetVal) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aRetVal = acc->CharBounds(aOffset, aCoordType); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvOffsetAtPoint( const uint64_t& aID, const int32_t& aX, const int32_t& aY, const uint32_t& aCoordType, int32_t* aRetVal) { *aRetVal = -1; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aRetVal = acc->OffsetAtPoint(aX, aY, aCoordType); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvSelectionBoundsAt( const uint64_t& aID, const int32_t& aSelectionNum, bool* aSucceeded, nsString* aData, int32_t* aStartOffset, int32_t* aEndOffset) { *aSucceeded = false; *aStartOffset = 0; *aEndOffset = 0; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aSucceeded = acc->SelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset); if (*aSucceeded) { acc->TextSubstring(*aStartOffset, *aEndOffset, *aData); } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvSetSelectionBoundsAt( const uint64_t& aID, const int32_t& aSelectionNum, const int32_t& aStartOffset, const int32_t& aEndOffset, bool* aSucceeded) { *aSucceeded = false; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aSucceeded = acc->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAddToSelection( const uint64_t& aID, const int32_t& aStartOffset, const int32_t& aEndOffset, bool* aSucceeded) { *aSucceeded = false; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aSucceeded = acc->AddToSelection(aStartOffset, aEndOffset); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvRemoveFromSelection( const uint64_t& aID, const int32_t& aSelectionNum, bool* aSucceeded) { *aSucceeded = false; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aSucceeded = acc->RemoveFromSelection(aSelectionNum); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvScrollSubstringTo( const uint64_t& aID, const int32_t& aStartOffset, const int32_t& aEndOffset, const uint32_t& aScrollType) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc) { acc->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvScrollSubstringToPoint( const uint64_t& aID, const int32_t& aStartOffset, const int32_t& aEndOffset, const uint32_t& aCoordinateType, const int32_t& aX, const int32_t& aY) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc) { acc->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType, aX, aY); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvText(const uint64_t& aID, nsString* aText) { TextLeafAccessible* acc = IdToTextLeafAccessible(aID); if (acc) { *aText = acc->Text(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvReplaceText( const uint64_t& aID, const nsAString& aText) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { acc->ReplaceText(aText); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvInsertText( const uint64_t& aID, const nsAString& aText, const int32_t& aPosition, bool* aValid) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aValid = acc->IsValidOffset(aPosition); acc->InsertText(aText, aPosition); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvCopyText( const uint64_t& aID, const int32_t& aStartPos, const int32_t& aEndPos, bool* aValid) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { acc->CopyText(aStartPos, aEndPos); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvCutText( const uint64_t& aID, const int32_t& aStartPos, const int32_t& aEndPos, bool* aValid) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aValid = acc->IsValidRange(aStartPos, aEndPos); acc->CutText(aStartPos, aEndPos); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvDeleteText( const uint64_t& aID, const int32_t& aStartPos, const int32_t& aEndPos, bool* aValid) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aValid = acc->IsValidRange(aStartPos, aEndPos); acc->DeleteText(aStartPos, aEndPos); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvPasteText( const uint64_t& aID, const int32_t& aPosition, bool* aValid) { RefPtr acc = IdToHyperTextAccessible(aID); if (acc && acc->IsTextRole()) { *aValid = acc->IsValidOffset(aPosition); acc->PasteText(aPosition); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvImagePosition( const uint64_t& aID, const uint32_t& aCoordType, LayoutDeviceIntPoint* aRetVal) { ImageAccessible* acc = IdToImageAccessible(aID); if (acc) { *aRetVal = acc->Position(aCoordType); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvImageSize( const uint64_t& aID, LayoutDeviceIntSize* aRetVal) { ImageAccessible* acc = IdToImageAccessible(aID); if (acc) { *aRetVal = acc->Size(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvStartOffset(const uint64_t& aID, uint32_t* aRetVal, bool* aOk) { LocalAccessible* acc = IdToAccessibleLink(aID); if (acc) { *aRetVal = acc->StartOffset(); *aOk = true; } else { *aRetVal = 0; *aOk = false; } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvEndOffset(const uint64_t& aID, uint32_t* aRetVal, bool* aOk) { LocalAccessible* acc = IdToAccessibleLink(aID); if (acc) { *aRetVal = acc->EndOffset(); *aOk = true; } else { *aRetVal = 0; *aOk = false; } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvIsLinkValid(const uint64_t& aID, bool* aRetVal) { LocalAccessible* acc = IdToAccessibleLink(aID); if (acc) { *aRetVal = acc->IsLinkValid(); } else { *aRetVal = false; } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAnchorCount(const uint64_t& aID, uint32_t* aRetVal, bool* aOk) { LocalAccessible* acc = IdToAccessibleLink(aID); if (acc) { *aRetVal = acc->AnchorCount(); *aOk = true; } else { *aRetVal = 0; *aOk = false; } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAnchorURIAt( const uint64_t& aID, const uint32_t& aIndex, nsCString* aURI, bool* aOk) { LocalAccessible* acc = IdToAccessibleLink(aID); *aOk = false; if (acc) { nsCOMPtr uri = acc->AnchorURIAt(aIndex); if (uri) { uri->GetSpec(*aURI); *aOk = true; } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAnchorAt(const uint64_t& aID, const uint32_t& aIndex, uint64_t* aIDOfAnchor, bool* aOk) { *aIDOfAnchor = 0; *aOk = false; LocalAccessible* acc = IdToAccessibleLink(aID); if (acc) { LocalAccessible* anchor = acc->AnchorAt(aIndex); if (anchor) { *aIDOfAnchor = reinterpret_cast(anchor->UniqueID()); *aOk = true; } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvLinkCount(const uint64_t& aID, uint32_t* aCount) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); *aCount = acc ? acc->LinkCount() : 0; return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvLinkAt(const uint64_t& aID, const uint32_t& aIndex, uint64_t* aIDOfLink, bool* aOk) { *aIDOfLink = 0; *aOk = false; HyperTextAccessible* acc = IdToHyperTextAccessible(aID); if (acc) { LocalAccessible* link = acc->LinkAt(aIndex); if (link) { *aIDOfLink = reinterpret_cast(link->UniqueID()); *aOk = true; } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvLinkIndexAtOffset( const uint64_t& aID, const uint32_t& aOffset, int32_t* aIndex) { HyperTextAccessible* acc = IdToHyperTextAccessible(aID); *aIndex = acc ? acc->LinkIndexAtOffset(aOffset) : -1; return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableOfACell( const uint64_t& aID, uint64_t* aTableID, bool* aOk) { *aTableID = 0; *aOk = false; TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { TableAccessible* table = acc->Table(); if (table) { *aTableID = reinterpret_cast(table->AsAccessible()->UniqueID()); *aOk = true; } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvColIdx(const uint64_t& aID, uint32_t* aIndex) { *aIndex = 0; TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { *aIndex = acc->ColIdx(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvRowIdx(const uint64_t& aID, uint32_t* aIndex) { *aIndex = 0; TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { *aIndex = acc->RowIdx(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvGetPosition(const uint64_t& aID, uint32_t* aRowIdx, uint32_t* aColIdx) { *aColIdx = 0; *aRowIdx = 0; TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { *aColIdx = acc->ColIdx(); *aRowIdx = acc->RowIdx(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvGetColRowExtents( const uint64_t& aID, uint32_t* aColIdx, uint32_t* aRowIdx, uint32_t* aColExtent, uint32_t* aRowExtent) { *aColIdx = 0; *aRowIdx = 0; *aColExtent = 0; *aRowExtent = 0; TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { *aColIdx = acc->ColIdx(); *aRowIdx = acc->RowIdx(); *aColExtent = acc->ColExtent(); *aRowExtent = acc->RowExtent(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvColExtent(const uint64_t& aID, uint32_t* aExtent) { *aExtent = 0; TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { *aExtent = acc->ColExtent(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvRowExtent(const uint64_t& aID, uint32_t* aExtent) { *aExtent = 0; TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { *aExtent = acc->RowExtent(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvColHeaderCells( const uint64_t& aID, nsTArray* aCells) { TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { AutoTArray headerCells; acc->ColHeaderCells(&headerCells); aCells->SetCapacity(headerCells.Length()); for (Accessible* header : headerCells) { aCells->AppendElement(header->ID()); } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvRowHeaderCells( const uint64_t& aID, nsTArray* aCells) { TableCellAccessible* acc = IdToTableCellAccessible(aID); if (acc) { AutoTArray headerCells; acc->RowHeaderCells(&headerCells); aCells->SetCapacity(headerCells.Length()); for (Accessible* header : headerCells) { aCells->AppendElement(header->ID()); } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvIsCellSelected( const uint64_t& aID, bool* aSelected) { TableCellAccessible* acc = IdToTableCellAccessible(aID); *aSelected = acc && acc->Selected(); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableCaption( const uint64_t& aID, uint64_t* aCaptionID, bool* aOk) { *aCaptionID = 0; *aOk = false; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { LocalAccessible* caption = acc->Caption(); if (caption) { *aCaptionID = reinterpret_cast(caption->UniqueID()); *aOk = true; } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSummary( const uint64_t& aID, nsString* aSummary) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->Summary(*aSummary); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableColumnCount( const uint64_t& aID, uint32_t* aColCount) { *aColCount = 0; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aColCount = acc->ColCount(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableRowCount( const uint64_t& aID, uint32_t* aRowCount) { *aRowCount = 0; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aRowCount = acc->RowCount(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableCellAt( const uint64_t& aID, const uint32_t& aRow, const uint32_t& aCol, uint64_t* aCellID, bool* aOk) { *aCellID = 0; *aOk = false; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { LocalAccessible* cell = acc->CellAt(aRow, aCol); if (cell) { *aCellID = reinterpret_cast(cell->UniqueID()); *aOk = true; } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableCellIndexAt( const uint64_t& aID, const uint32_t& aRow, const uint32_t& aCol, int32_t* aIndex) { *aIndex = -1; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aIndex = acc->CellIndexAt(aRow, aCol); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableColumnIndexAt( const uint64_t& aID, const uint32_t& aCellIndex, int32_t* aCol) { *aCol = -1; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aCol = acc->ColIndexAt(aCellIndex); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableRowIndexAt( const uint64_t& aID, const uint32_t& aCellIndex, int32_t* aRow) { *aRow = -1; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aRow = acc->RowIndexAt(aCellIndex); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableRowAndColumnIndicesAt( const uint64_t& aID, const uint32_t& aCellIndex, int32_t* aRow, int32_t* aCol) { *aRow = -1; *aCol = -1; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->RowAndColIndicesAt(aCellIndex, aRow, aCol); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableColumnExtentAt( const uint64_t& aID, const uint32_t& aRow, const uint32_t& aCol, uint32_t* aExtent) { *aExtent = 0; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aExtent = acc->ColExtentAt(aRow, aCol); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableRowExtentAt( const uint64_t& aID, const uint32_t& aRow, const uint32_t& aCol, uint32_t* aExtent) { *aExtent = 0; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aExtent = acc->RowExtentAt(aRow, aCol); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableColumnDescription( const uint64_t& aID, const uint32_t& aCol, nsString* aDescription) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->ColDescription(aCol, *aDescription); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableRowDescription( const uint64_t& aID, const uint32_t& aRow, nsString* aDescription) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->RowDescription(aRow, *aDescription); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableColumnSelected( const uint64_t& aID, const uint32_t& aCol, bool* aSelected) { *aSelected = false; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aSelected = acc->IsColSelected(aCol); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableRowSelected( const uint64_t& aID, const uint32_t& aRow, bool* aSelected) { *aSelected = false; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aSelected = acc->IsRowSelected(aRow); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableCellSelected( const uint64_t& aID, const uint32_t& aRow, const uint32_t& aCol, bool* aSelected) { *aSelected = false; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aSelected = acc->IsCellSelected(aRow, aCol); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectedCellCount( const uint64_t& aID, uint32_t* aSelectedCells) { *aSelectedCells = 0; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aSelectedCells = acc->SelectedCellCount(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectedColumnCount( const uint64_t& aID, uint32_t* aSelectedColumns) { *aSelectedColumns = 0; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aSelectedColumns = acc->SelectedColCount(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectedRowCount( const uint64_t& aID, uint32_t* aSelectedRows) { *aSelectedRows = 0; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aSelectedRows = acc->SelectedRowCount(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectedCells( const uint64_t& aID, nsTArray* aCellIDs) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { AutoTArray cells; acc->SelectedCells(&cells); aCellIDs->SetCapacity(cells.Length()); for (Accessible* cell : cells) { aCellIDs->AppendElement(cell->ID()); } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectedCellIndices( const uint64_t& aID, nsTArray* aCellIndices) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->SelectedCellIndices(aCellIndices); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectedColumnIndices( const uint64_t& aID, nsTArray* aColumnIndices) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->SelectedColIndices(aColumnIndices); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectedRowIndices( const uint64_t& aID, nsTArray* aRowIndices) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->SelectedRowIndices(aRowIndices); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectColumn( const uint64_t& aID, const uint32_t& aCol) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->SelectCol(aCol); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableSelectRow( const uint64_t& aID, const uint32_t& aRow) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->SelectRow(aRow); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableUnselectColumn( const uint64_t& aID, const uint32_t& aCol) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->UnselectCol(aCol); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableUnselectRow( const uint64_t& aID, const uint32_t& aRow) { TableAccessible* acc = IdToTableAccessible(aID); if (acc) { acc->UnselectRow(aRow); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTableIsProbablyForLayout( const uint64_t& aID, bool* aForLayout) { *aForLayout = false; TableAccessible* acc = IdToTableAccessible(aID); if (acc) { *aForLayout = acc->IsProbablyLayoutTable(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAtkTableColumnHeader( const uint64_t& aID, const int32_t& aCol, uint64_t* aHeader, bool* aOk) { *aHeader = 0; *aOk = false; #ifdef MOZ_ACCESSIBILITY_ATK TableAccessible* acc = IdToTableAccessible(aID); if (acc) { Accessible* header = AccessibleWrap::GetColumnHeader(acc, aCol); if (header) { *aHeader = header->ID(); *aOk = true; } } #endif return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAtkTableRowHeader( const uint64_t& aID, const int32_t& aRow, uint64_t* aHeader, bool* aOk) { *aHeader = 0; *aOk = false; #ifdef MOZ_ACCESSIBILITY_ATK TableAccessible* acc = IdToTableAccessible(aID); if (acc) { Accessible* header = AccessibleWrap::GetRowHeader(acc, aRow); if (header) { *aHeader = header->ID(); *aOk = true; } } #endif return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvSelectedItems( const uint64_t& aID, nsTArray* aSelectedItemIDs) { LocalAccessible* acc = IdToAccessibleSelect(aID); if (acc) { AutoTArray selectedItems; acc->SelectedItems(&selectedItems); aSelectedItemIDs->SetCapacity(selectedItems.Length()); for (Accessible* item : selectedItems) { aSelectedItemIDs->AppendElement( reinterpret_cast(item->AsLocal()->UniqueID())); } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvSelectedItemCount( const uint64_t& aID, uint32_t* aCount) { *aCount = 0; LocalAccessible* acc = IdToAccessibleSelect(aID); if (acc) { *aCount = acc->SelectedItemCount(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvGetSelectedItem( const uint64_t& aID, const uint32_t& aIndex, uint64_t* aSelected, bool* aOk) { LocalAccessible* acc = IdToAccessibleSelect(aID); if (acc) { Accessible* selected = acc->GetSelectedItem(aIndex); *aSelected = reinterpret_cast(selected->AsLocal()->UniqueID()); } *aOk = !!acc; return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvIsItemSelected( const uint64_t& aID, const uint32_t& aIndex, bool* aSelected) { *aSelected = false; LocalAccessible* acc = IdToAccessibleSelect(aID); if (acc) { *aSelected = acc->IsItemSelected(aIndex); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAddItemToSelection( const uint64_t& aID, const uint32_t& aIndex, bool* aSuccess) { *aSuccess = false; LocalAccessible* acc = IdToAccessibleSelect(aID); if (acc) { *aSuccess = acc->AddItemToSelection(aIndex); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvRemoveItemFromSelection( const uint64_t& aID, const uint32_t& aIndex, bool* aSuccess) { *aSuccess = false; LocalAccessible* acc = IdToAccessibleSelect(aID); if (acc) { *aSuccess = acc->RemoveItemFromSelection(aIndex); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvSelectAll(const uint64_t& aID, bool* aSuccess) { *aSuccess = false; LocalAccessible* acc = IdToAccessibleSelect(aID); if (acc) { *aSuccess = acc->SelectAll(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvUnselectAll(const uint64_t& aID, bool* aSuccess) { *aSuccess = false; LocalAccessible* acc = IdToAccessibleSelect(aID); if (acc) { *aSuccess = acc->UnselectAll(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvDoAction(const uint64_t& aID, const uint8_t& aIndex, bool* aSuccess) { *aSuccess = false; LocalAccessible* acc = IdToAccessible(aID); if (acc) { *aSuccess = acc->DoAction(aIndex); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvActionCount(const uint64_t& aID, uint8_t* aCount) { *aCount = 0; LocalAccessible* acc = IdToAccessible(aID); if (acc) { *aCount = acc->ActionCount(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvActionNameAt( const uint64_t& aID, const uint8_t& aIndex, nsString* aName) { LocalAccessible* acc = IdToAccessible(aID); if (acc) { acc->ActionNameAt(aIndex, *aName); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAccessKey( const uint64_t& aID, uint32_t* aKey, uint32_t* aModifierMask) { *aKey = 0; *aModifierMask = 0; LocalAccessible* acc = IdToAccessible(aID); if (acc) { KeyBinding kb = acc->AccessKey(); *aKey = kb.Key(); *aModifierMask = kb.ModifierMask(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvAtkKeyBinding( const uint64_t& aID, nsString* aResult) { #ifdef MOZ_ACCESSIBILITY_ATK LocalAccessible* acc = IdToAccessible(aID); if (acc) { AccessibleWrap::GetKeyBinding(acc, *aResult); } #endif return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvCurValue(const uint64_t& aID, double* aValue) { *aValue = UnspecifiedNaN(); LocalAccessible* acc = IdToAccessible(aID); if (acc) { *aValue = acc->CurValue(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvSetCurValue( const uint64_t& aID, const double& aValue, bool* aRetVal) { *aRetVal = false; LocalAccessible* acc = IdToAccessible(aID); if (acc) { *aRetVal = acc->SetCurValue(aValue); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvMinValue(const uint64_t& aID, double* aValue) { *aValue = UnspecifiedNaN(); LocalAccessible* acc = IdToAccessible(aID); if (acc) { *aValue = acc->MinValue(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvMaxValue(const uint64_t& aID, double* aValue) { *aValue = UnspecifiedNaN(); LocalAccessible* acc = IdToAccessible(aID); if (acc) { *aValue = acc->MaxValue(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvStep(const uint64_t& aID, double* aStep) { *aStep = UnspecifiedNaN(); LocalAccessible* acc = IdToAccessible(aID); if (acc) { *aStep = acc->Step(); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvLanguage(const uint64_t& aID, nsString* aLocale) { LocalAccessible* acc = IdToAccessible(aID); if (acc) { acc->Language(*aLocale); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvDocType(const uint64_t& aID, nsString* aType) { LocalAccessible* acc = IdToAccessible(aID); if (acc && acc->IsDoc()) { acc->AsDoc()->DocType(*aType); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvTitle(const uint64_t& aID, nsString* aTitle) { LocalAccessible* acc = IdToAccessible(aID); if (acc) { mozilla::ErrorResult rv; acc->GetContent()->GetTextContent(*aTitle, rv); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvMimeType(const uint64_t& aID, nsString* aMime) { LocalAccessible* acc = IdToAccessible(aID); if (acc && acc->IsDoc()) { acc->AsDoc()->MimeType(*aMime); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvURLDocTypeMimeType( const uint64_t& aID, nsString* aURL, nsString* aDocType, nsString* aMimeType) { LocalAccessible* acc = IdToAccessible(aID); if (acc && acc->IsDoc()) { DocAccessible* doc = acc->AsDoc(); doc->URL(*aURL); doc->DocType(*aDocType); doc->MimeType(*aMimeType); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvChildAtPoint( const uint64_t& aID, const int32_t& aX, const int32_t& aY, const uint32_t& aWhich, PDocAccessibleChild** aResultDoc, uint64_t* aResultID) { *aResultDoc = nullptr; *aResultID = 0; LocalAccessible* acc = IdToAccessible(aID); if (acc && !acc->IsDefunct()) { int32_t x = aX; int32_t y = aY; LocalAccessible* result = acc->LocalChildAtPoint( x, y, static_cast(aWhich)); if (result) { // LocalAccessible::ChildAtPoint can return a LocalAccessible from a // descendant document. DocAccessibleChild* resultDoc = result->Document()->IPCDoc(); // We've sent the constructor for this document to the parent process. // However, because the constructor is async, the parent process might // get the result of this (sync) method before it runs the constructor. // If we send this document in this case, the parent process will crash. // Therefore, we only do this if the parent process has explicitly told // us that the document has been constructed there. if (resultDoc && resultDoc->IsConstructedInParentProcess()) { *aResultDoc = resultDoc; *aResultID = result->IsDoc() ? 0 : reinterpret_cast(result->UniqueID()); } } } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvExtents( const uint64_t& aID, const bool& aNeedsScreenCoords, int32_t* aX, int32_t* aY, int32_t* aWidth, int32_t* aHeight) { *aX = 0; *aY = 0; *aWidth = 0; *aHeight = 0; LocalAccessible* acc = IdToAccessible(aID); if (acc && !acc->IsDefunct()) { LayoutDeviceIntRect screenRect = acc->Bounds(); if (!screenRect.IsEmpty()) { if (aNeedsScreenCoords) { LayoutDeviceIntPoint winCoords = nsAccUtils::GetScreenCoordsForWindow(acc); screenRect.x -= winCoords.x; screenRect.y -= winCoords.y; } *aWidth = screenRect.width; *aHeight = screenRect.height; } // We should always report the position of our acc, even if // the returned screenRect is empty. *aX = screenRect.x; *aY = screenRect.y; } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvExtentsInCSSPixels( const uint64_t& aID, int32_t* aX, int32_t* aY, int32_t* aWidth, int32_t* aHeight) { *aX = 0; *aY = 0; *aWidth = 0; *aHeight = 0; LocalAccessible* acc = IdToAccessible(aID); if (acc && !acc->IsDefunct()) { nsIntRect screenRect = acc->BoundsInCSSPixels(); if (!screenRect.IsEmpty()) { *aWidth = screenRect.width; *aHeight = screenRect.height; } // We should always report the position of our acc, even if // the returned screenRect is empty. *aX = screenRect.x; *aY = screenRect.y; } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvDOMNodeID( const uint64_t& aID, nsString* aDOMNodeID) { LocalAccessible* acc = IdToAccessible(aID); if (!acc) { return IPC_OK(); } nsIContent* content = acc->GetContent(); if (!content) { return IPC_OK(); } nsAtom* id = content->GetID(); if (id) { id->ToString(*aDOMNodeID); } return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvConstructedInParentProcess() { SetConstructedInParentProcess(); return IPC_OK(); } mozilla::ipc::IPCResult DocAccessibleChild::RecvRestoreFocus() { FocusMgr()->ForceFocusEvent(); return IPC_OK(); } bool DocAccessibleChild::DeallocPDocAccessiblePlatformExtChild( PDocAccessiblePlatformExtChild* aActor) { delete aActor; return true; } PDocAccessiblePlatformExtChild* DocAccessibleChild::AllocPDocAccessiblePlatformExtChild() { return new DocAccessiblePlatformExtChild(); } DocAccessiblePlatformExtChild* DocAccessibleChild::GetPlatformExtension() { return static_cast( SingleManagedOrNull(ManagedPDocAccessiblePlatformExtChild())); } } // namespace a11y } // namespace mozilla