diff --git a/accessible/windows/ia2/ia2Accessible.cpp b/accessible/windows/ia2/ia2Accessible.cpp index a557d142bf49..ec17b47e222d 100644 --- a/accessible/windows/ia2/ia2Accessible.cpp +++ b/accessible/windows/ia2/ia2Accessible.cpp @@ -73,7 +73,14 @@ ia2Accessible::get_nRelations(long* aNRelations) if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!acc->IsProxy()); + if (acc->IsProxy()) { + // XXX evaluate performance of collecting all relation targets. + nsTArray types; + nsTArray> targetSets; + acc->Proxy()->Relations(&types, &targetSets); + *aNRelations = types.Length(); + return S_OK; + } for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) { if (sRelationTypePairs[idx].second == IA2_RELATION_NULL) @@ -102,7 +109,33 @@ ia2Accessible::get_relation(long aRelationIndex, if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!acc->IsProxy()); + if (acc->IsProxy()) { + nsTArray types; + nsTArray> targetSets; + acc->Proxy()->Relations(&types, &targetSets); + + size_t targetSetCount = targetSets.Length(); + for (size_t i = 0; i < targetSetCount; i++) { + uint32_t relTypeIdx = static_cast(types[i]); + MOZ_ASSERT(sRelationTypePairs[relTypeIdx].first == types[i]); + if (sRelationTypePairs[relTypeIdx].second == IA2_RELATION_NULL) + continue; + + if (static_cast(aRelationIndex) == i) { + nsTArray> targets; + size_t targetCount = targetSets[i].Length(); + for (size_t j = 0; j < targetCount; j++) + targets.AppendElement(WrapperFor(targetSets[i][j])); + + RefPtr rel = + new ia2AccessibleRelation(types[i], Move(targets)); + rel.forget(aRelation); + return S_OK; + } + } + + return E_INVALIDARG; + } long relIdx = 0; for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) { @@ -143,7 +176,33 @@ ia2Accessible::get_relations(long aMaxRelations, if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!acc->IsProxy()); + if (acc->IsProxy()) { + nsTArray types; + nsTArray> targetSets; + acc->Proxy()->Relations(&types, &targetSets); + + size_t count = std::min(targetSets.Length(), + static_cast(aMaxRelations)); + size_t i = 0; + while (i < count) { + uint32_t relTypeIdx = static_cast(types[i]); + if (sRelationTypePairs[relTypeIdx].second == IA2_RELATION_NULL) + continue; + + size_t targetCount = targetSets[i].Length(); + nsTArray> targets(targetCount); + for (size_t j = 0; j < targetCount; j++) + targets.AppendElement(WrapperFor(targetSets[i][j])); + + RefPtr rel = + new ia2AccessibleRelation(types[i], Move(targets)); + rel.forget(aRelation + i); + i++; + } + + *aNRelations = i; + return S_OK; + } for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs) && *aNRelations < aMaxRelations; idx++) { @@ -184,8 +243,10 @@ ia2Accessible::role(long* aRole) break; a11y::role geckoRole; - MOZ_ASSERT(!acc->IsProxy()); - geckoRole = acc->Role(); + if (acc->IsProxy()) + geckoRole = acc->Proxy()->Role(); + else + geckoRole = acc->Role(); switch (geckoRole) { #include "RoleMap.h" default: @@ -196,11 +257,16 @@ ia2Accessible::role(long* aRole) // Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call // the IA2 role a ROLE_OUTLINEITEM. - MOZ_ASSERT(!acc->IsProxy()); - if (geckoRole == roles::ROW) { - Accessible* xpParent = acc->Parent(); - if (xpParent && xpParent->Role() == roles::TREE_TABLE) + if (acc->IsProxy()) { + if (geckoRole == roles::ROW && acc->Proxy()->Parent() && + acc->Proxy()->Parent()->Role() == roles::TREE_TABLE) *aRole = ROLE_SYSTEM_OUTLINEITEM; + } else { + if (geckoRole == roles::ROW) { + Accessible* xpParent = acc->Parent(); + if (xpParent && xpParent->Role() == roles::TREE_TABLE) + *aRole = ROLE_SYSTEM_OUTLINEITEM; + } } return S_OK; @@ -217,9 +283,12 @@ ia2Accessible::scrollTo(enum IA2ScrollType aScrollType) if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!acc->IsProxy()); - nsCoreUtils::ScrollTo(acc->Document()->PresShell(), acc->GetContent(), - aScrollType); + if (acc->IsProxy()) { + acc->Proxy()->ScrollTo(aScrollType); + } else { + nsCoreUtils::ScrollTo(acc->Document()->PresShell(), acc->GetContent(), + aScrollType); + } return S_OK; @@ -240,8 +309,11 @@ ia2Accessible::scrollToPoint(enum IA2CoordinateType aCoordType, nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; - MOZ_ASSERT(!acc->IsProxy()); - acc->ScrollToPoint(geckoCoordType, aX, aY); + if (acc->IsProxy()) { + acc->Proxy()->ScrollToPoint(geckoCoordType, aX, aY); + } else { + acc->ScrollToPoint(geckoCoordType, aX, aY); + } return S_OK; @@ -301,8 +373,10 @@ ia2Accessible::get_states(AccessibleStates* aStates) } uint64_t state; - MOZ_ASSERT(!acc->IsProxy()); - state = acc->State(); + if (acc->IsProxy()) + state = acc->Proxy()->State(); + else + state = acc->State(); if (state & states::INVALID) *aStates |= IA2_STATE_INVALID_ENTRY; @@ -474,8 +548,10 @@ ia2Accessible::get_indexInParent(long* aIndexInParent) if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!acc->IsProxy()); - *aIndexInParent = acc->IndexInParent(); + if (acc->IsProxy()) + *aIndexInParent = acc->Proxy()->IndexInParent(); + else + *aIndexInParent = acc->IndexInParent(); if (*aIndexInParent == -1) return S_FALSE; @@ -556,8 +632,9 @@ ia2Accessible::get_attributes(BSTR* aAttributes) return ConvertToIA2Attributes(attributes, aAttributes); } - MOZ_ASSERT(!acc->IsProxy()); - return E_UNEXPECTED; + nsTArray attrs; + acc->Proxy()->Attributes(&attrs); + return ConvertToIA2Attributes(&attrs, aAttributes); A11Y_TRYBLOCK_END } @@ -642,12 +719,21 @@ ia2Accessible::get_relationTargetsOfType(BSTR aType, return CO_E_OBJNOTCONNECTED; nsTArray targets; - MOZ_ASSERT(!acc->IsProxy()); - Relation rel = acc->RelationByType(*relationType); - Accessible* target = nullptr; - while ((target = rel.Next()) && - static_cast(targets.Length()) <= aMaxTargets) { - targets.AppendElement(target); + if (acc->IsProxy()) { + nsTArray targetProxies = + acc->Proxy()->RelationByType(*relationType); + + size_t targetCount = aMaxTargets; + if (targetProxies.Length() < targetCount) + targetCount = targetProxies.Length(); + for (size_t i = 0; i < targetCount; i++) + targets.AppendElement(WrapperFor(targetProxies[i])); + } else { + Relation rel = acc->RelationByType(*relationType); + Accessible* target = nullptr; + while ((target = rel.Next()) && + static_cast(targets.Length()) <= aMaxTargets) + targets.AppendElement(target); } *aNTargets = targets.Length(); diff --git a/accessible/windows/ia2/ia2AccessibleEditableText.cpp b/accessible/windows/ia2/ia2AccessibleEditableText.cpp index 361d6a13060f..4685a2df9756 100644 --- a/accessible/windows/ia2/ia2AccessibleEditableText.cpp +++ b/accessible/windows/ia2/ia2AccessibleEditableText.cpp @@ -24,7 +24,9 @@ ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset) { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + return proxy->CopyText(aStartOffset, aEndOffset) ? S_OK : E_INVALIDARG; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -44,7 +46,9 @@ ia2AccessibleEditableText::deleteText(long aStartOffset, long aEndOffset) { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + return proxy->DeleteText(aStartOffset, aEndOffset) ? S_OK : E_INVALIDARG; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -66,7 +70,9 @@ ia2AccessibleEditableText::insertText(long aOffset, BSTR *aText) uint32_t length = ::SysStringLen(*aText); nsAutoString text(*aText, length); - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + return proxy->InsertText(text, aOffset) ? S_OK : E_INVALIDARG; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -86,7 +92,9 @@ ia2AccessibleEditableText::cutText(long aStartOffset, long aEndOffset) { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + return proxy->CutText(aStartOffset, aEndOffset) ? S_OK : E_INVALIDARG; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -106,7 +114,9 @@ ia2AccessibleEditableText::pasteText(long aOffset) { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + return proxy->PasteText(aOffset) ? S_OK : E_INVALIDARG; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) diff --git a/accessible/windows/ia2/ia2AccessibleHyperlink.cpp b/accessible/windows/ia2/ia2AccessibleHyperlink.cpp index d1c577f1df9a..2b829e019579 100644 --- a/accessible/windows/ia2/ia2AccessibleHyperlink.cpp +++ b/accessible/windows/ia2/ia2AccessibleHyperlink.cpp @@ -53,7 +53,17 @@ ia2AccessibleHyperlink::get_anchor(long aIndex, VARIANT* aAnchor) VariantInit(aAnchor); Accessible* thisObj = static_cast(this); - MOZ_ASSERT(!thisObj->IsProxy()); + if (thisObj->IsProxy()) { + ProxyAccessible* anchor = thisObj->Proxy()->AnchorAt(aIndex); + if (!anchor) + return S_FALSE; + + IUnknown* tmp = static_cast(WrapperFor(anchor)); + tmp->AddRef(); + aAnchor->punkVal = tmp; + aAnchor->vt = VT_UNKNOWN; + return S_OK; + } if (thisObj->IsDefunct()) return CO_E_OBJNOTCONNECTED; @@ -87,35 +97,36 @@ ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget) { A11Y_TRYBLOCK_BEGIN - if (!aAnchorTarget) { + if (!aAnchorTarget) return E_INVALIDARG; - } VariantInit(aAnchorTarget); Accessible* thisObj = static_cast(this); nsAutoCString uriStr; - MOZ_ASSERT(!thisObj->IsProxy()); - if (thisObj->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (thisObj->IsProxy()) { + bool ok; + thisObj->Proxy()->AnchorURIAt(aIndex, uriStr, &ok); + if (!ok) + return S_FALSE; - if (aIndex < 0 || aIndex >= static_cast(thisObj->AnchorCount())) { - return E_INVALIDARG; - } + } else { + if (thisObj->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - if (!thisObj->IsLink()) { - return S_FALSE; - } + if (aIndex < 0 || aIndex >= static_cast(thisObj->AnchorCount())) + return E_INVALIDARG; - nsCOMPtr uri = thisObj->AnchorURIAt(aIndex); - if (!uri) { - return S_FALSE; - } + if (!thisObj->IsLink()) + return S_FALSE; - nsresult rv = uri->GetSpec(uriStr); - if (NS_FAILED(rv)) { - return GetHRESULT(rv); + nsCOMPtr uri = thisObj->AnchorURIAt(aIndex); + if (!uri) + return S_FALSE; + + nsresult rv = uri->GetSpec(uriStr); + if (NS_FAILED(rv)) + return GetHRESULT(rv); } nsAutoString stringURI; @@ -139,7 +150,11 @@ ia2AccessibleHyperlink::get_startIndex(long* aIndex) *aIndex = 0; - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + bool valid; + *aIndex = proxy->StartOffset(&valid); + return valid ? S_OK : S_FALSE; + } Accessible* thisObj = static_cast(this); if (thisObj->IsDefunct()) @@ -164,7 +179,11 @@ ia2AccessibleHyperlink::get_endIndex(long* aIndex) *aIndex = 0; - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + bool valid; + *aIndex = proxy->EndOffset(&valid); + return valid ? S_OK : S_FALSE; + } Accessible* thisObj = static_cast(this); if (thisObj->IsDefunct()) @@ -189,7 +208,10 @@ ia2AccessibleHyperlink::get_valid(boolean* aValid) *aValid = false; - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + *aValid = proxy->IsLinkValid(); + return S_OK; + } Accessible* thisObj = static_cast(this); if (thisObj->IsDefunct()) diff --git a/accessible/windows/ia2/ia2AccessibleHypertext.cpp b/accessible/windows/ia2/ia2AccessibleHypertext.cpp index f4b3bdaf25a6..906b76d4e796 100644 --- a/accessible/windows/ia2/ia2AccessibleHypertext.cpp +++ b/accessible/windows/ia2/ia2AccessibleHypertext.cpp @@ -26,7 +26,10 @@ ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount) *aHyperlinkCount = 0; - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + *aHyperlinkCount = proxy->LinkCount(); + return S_OK; + } HyperTextAccessibleWrap* hyperText = static_cast(this); if (hyperText->IsDefunct()) @@ -50,13 +53,19 @@ ia2AccessibleHypertext::get_hyperlink(long aLinkIndex, *aHyperlink = nullptr; AccessibleWrap* hyperLink; - MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessibleWrap* hyperText = static_cast(this); - if (hyperText->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + ProxyAccessible* link = proxy->LinkAt(aLinkIndex); + if (!link) + return E_FAIL; - hyperLink = static_cast(hyperText->LinkAt(aLinkIndex)); + hyperLink = WrapperFor(link); + } else { + HyperTextAccessibleWrap* hyperText = static_cast(this); + if (hyperText->IsDefunct()) + return CO_E_OBJNOTCONNECTED; + + hyperLink = static_cast(hyperText->LinkAt(aLinkIndex)); + } if (!hyperLink) return E_FAIL; @@ -79,7 +88,10 @@ ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long* aHyperlinkInde *aHyperlinkIndex = 0; - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + *aHyperlinkIndex = proxy->LinkIndexAtOffset(aCharIndex); + return S_OK; + } HyperTextAccessibleWrap* hyperAcc = static_cast(this); if (hyperAcc->IsDefunct()) diff --git a/accessible/windows/ia2/ia2AccessibleText.cpp b/accessible/windows/ia2/ia2AccessibleText.cpp index 7ac766f300ba..7f79b110cc4e 100644 --- a/accessible/windows/ia2/ia2AccessibleText.cpp +++ b/accessible/windows/ia2/ia2AccessibleText.cpp @@ -30,7 +30,10 @@ ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset) { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + return proxy->AddToSelection(aStartOffset, aEndOffset) ? + S_OK : E_INVALIDARG; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -57,16 +60,21 @@ ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset, int32_t startOffset = 0, endOffset = 0; HRESULT hr; - MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessible* textAcc = static_cast(this); - if (textAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + AutoTArray attrs; + proxy->TextAttributes(true, aOffset, &attrs, &startOffset, &endOffset); + hr = AccessibleWrap::ConvertToIA2Attributes(&attrs, aTextAttributes); + } else { + HyperTextAccessible* textAcc = static_cast(this); + if (textAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; + + nsCOMPtr attributes = + textAcc->TextAttributes(true, aOffset, &startOffset, &endOffset); + + hr = AccessibleWrap::ConvertToIA2Attributes(attributes, aTextAttributes); } - nsCOMPtr attributes = - textAcc->TextAttributes(true, aOffset, &startOffset, &endOffset); - - hr = AccessibleWrap::ConvertToIA2Attributes(attributes, aTextAttributes); if (FAILED(hr)) return hr; @@ -88,13 +96,15 @@ ia2AccessibleText::get_caretOffset(long *aOffset) *aOffset = -1; - MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessible* textAcc = static_cast(this); - if (textAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + *aOffset = proxy->CaretOffset(); + } else { + HyperTextAccessible* textAcc = static_cast(this); + if (textAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - *aOffset = textAcc->CaretOffset(); + *aOffset = textAcc->CaretOffset(); + } return *aOffset != -1 ? S_OK : S_FALSE; @@ -117,12 +127,15 @@ ia2AccessibleText::get_characterExtents(long aOffset, nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; nsIntRect rect; - MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessible* textAcc = static_cast(this); - if (textAcc->IsDefunct()) - return CO_E_OBJNOTCONNECTED; + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + rect = proxy->CharBounds(aOffset, geckoCoordType); + } else { + HyperTextAccessible* textAcc = static_cast(this); + if (textAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - rect = textAcc->CharBounds(aOffset, geckoCoordType); + rect = textAcc->CharBounds(aOffset, geckoCoordType); + } *aX = rect.x; *aY = rect.y; @@ -142,13 +155,15 @@ ia2AccessibleText::get_nSelections(long* aNSelections) return E_INVALIDARG; *aNSelections = 0; - MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessible* textAcc = static_cast(this); - if (textAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + *aNSelections = proxy->SelectionCount(); + } else { + HyperTextAccessible* textAcc = static_cast(this); + if (textAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - *aNSelections = textAcc->SelectionCount(); + *aNSelections = textAcc->SelectionCount(); + } return S_OK; @@ -170,13 +185,15 @@ ia2AccessibleText::get_offsetAtPoint(long aX, long aY, nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; - MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessible* textAcc = static_cast(this); - if (textAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + *aOffset = proxy->OffsetAtPoint(aX, aY, geckoCoordType); + } else { + HyperTextAccessible* textAcc = static_cast(this); + if (textAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - *aOffset = textAcc->OffsetAtPoint(aX, aY, geckoCoordType); + *aOffset = textAcc->OffsetAtPoint(aX, aY, geckoCoordType); + } return *aOffset == -1 ? S_FALSE : S_OK; @@ -194,14 +211,18 @@ ia2AccessibleText::get_selection(long aSelectionIndex, long* aStartOffset, *aStartOffset = *aEndOffset = 0; int32_t startOffset = 0, endOffset = 0; - MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessible* textAcc = static_cast(this); - if (textAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + nsString unused; + if (!proxy->SelectionBoundsAt(aSelectionIndex, unused, &startOffset, + &endOffset)) + return E_INVALIDARG; + } else { + HyperTextAccessible* textAcc = static_cast(this); + if (textAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - if (!textAcc->SelectionBoundsAt(aSelectionIndex, &startOffset, &endOffset)) { - return E_INVALIDARG; + if (!textAcc->SelectionBoundsAt(aSelectionIndex, &startOffset, &endOffset)) + return E_INVALIDARG; } *aStartOffset = startOffset; @@ -222,17 +243,20 @@ ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR* aText) *aText = nullptr; nsAutoString text; - MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessible* textAcc = static_cast(this); - if (textAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + if (!proxy->TextSubstring(aStartOffset, aEndOffset, text)) { + return E_INVALIDARG; + } + } else { + HyperTextAccessible* textAcc = static_cast(this); + if (textAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) { - return E_INVALIDARG; - } + if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) + return E_INVALIDARG; - textAcc->TextSubstring(aStartOffset, aEndOffset, text); + textAcc->TextSubstring(aStartOffset, aEndOffset, text); + } if (text.IsEmpty()) return S_FALSE; @@ -390,7 +414,9 @@ ia2AccessibleText::removeSelection(long aSelectionIndex) { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + return proxy->RemoveFromSelection(aSelectionIndex) ? S_OK : E_INVALIDARG; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -407,7 +433,10 @@ ia2AccessibleText::setCaretOffset(long aOffset) { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + proxy->SetCaretOffset(aOffset); + return S_OK; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -428,7 +457,10 @@ ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset, { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + return proxy->SetSelectionBoundsAt(aSelectionIndex, aStartOffset, + aEndOffset) ? S_OK : E_INVALIDARG; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -449,7 +481,10 @@ ia2AccessibleText::get_nCharacters(long* aNCharacters) return E_INVALIDARG; *aNCharacters = 0; - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + *aNCharacters = proxy->CharacterCount(); + return S_OK; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -467,7 +502,10 @@ ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex, { A11Y_TRYBLOCK_BEGIN - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + proxy->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType); + return S_OK; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -493,7 +531,11 @@ ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex, nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; - MOZ_ASSERT(!HyperTextProxyFor(this)); + if (ProxyAccessible* proxy = HyperTextProxyFor(this)) { + proxy->ScrollSubstringToPoint(aStartIndex, aEndIndex, geckoCoordType, aX, + aY); + return S_OK; + } HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) diff --git a/accessible/windows/ia2/ia2AccessibleValue.cpp b/accessible/windows/ia2/ia2AccessibleValue.cpp index e33442295651..b78d206bc07f 100644 --- a/accessible/windows/ia2/ia2AccessibleValue.cpp +++ b/accessible/windows/ia2/ia2AccessibleValue.cpp @@ -55,12 +55,14 @@ ia2AccessibleValue::get_currentValue(VARIANT* aCurrentValue) AccessibleWrap* valueAcc = static_cast(this); double currentValue; - MOZ_ASSERT(!valueAcc->IsProxy()); - if (valueAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (valueAcc->IsProxy()) { + currentValue = valueAcc->Proxy()->CurValue(); + } else { + if (valueAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - currentValue = valueAcc->CurValue(); + currentValue = valueAcc->CurValue(); + } if (IsNaN(currentValue)) return S_FALSE; @@ -81,7 +83,8 @@ ia2AccessibleValue::setCurrentValue(VARIANT aValue) return E_INVALIDARG; AccessibleWrap* valueAcc = static_cast(this); - MOZ_ASSERT(!valueAcc->IsProxy()); + if (valueAcc->IsProxy()) + return valueAcc->Proxy()->SetCurValue(aValue.dblVal) ? S_OK : E_FAIL; if (valueAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; @@ -103,12 +106,14 @@ ia2AccessibleValue::get_maximumValue(VARIANT* aMaximumValue) AccessibleWrap* valueAcc = static_cast(this); double maximumValue; - MOZ_ASSERT(!valueAcc->IsProxy()); - if (valueAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (valueAcc->IsProxy()) { + maximumValue = valueAcc->Proxy()->MaxValue(); + } else { + if (valueAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - maximumValue = valueAcc->MaxValue(); + maximumValue = valueAcc->MaxValue(); + } if (IsNaN(maximumValue)) return S_FALSE; @@ -132,12 +137,14 @@ ia2AccessibleValue::get_minimumValue(VARIANT* aMinimumValue) AccessibleWrap* valueAcc = static_cast(this); double minimumValue; - MOZ_ASSERT(!valueAcc->IsProxy()); - if (valueAcc->IsDefunct()) { - return CO_E_OBJNOTCONNECTED; - } + if (valueAcc->IsProxy()) { + minimumValue = valueAcc->Proxy()->MinValue(); + } else { + if (valueAcc->IsDefunct()) + return CO_E_OBJNOTCONNECTED; - minimumValue = valueAcc->MinValue(); + minimumValue = valueAcc->MinValue(); + } if (IsNaN(minimumValue)) return S_FALSE; diff --git a/accessible/windows/msaa/AccessibleWrap.cpp b/accessible/windows/msaa/AccessibleWrap.cpp index ad23d1a56838..064eef0ac6fb 100644 --- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -187,6 +187,16 @@ AccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent) if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + if (IsProxy()) { + ProxyAccessible* proxy = Proxy(); + ProxyAccessible* parent = proxy->Parent(); + if (!parent) + return S_FALSE; + + *ppdispParent = NativeAccessible(WrapperFor(parent)); + return S_OK; + } + DocAccessible* doc = AsDoc(); if (doc) { // Return window system accessible object for root document and tab document @@ -226,6 +236,15 @@ AccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren) if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + if (IsProxy()) { + ProxyAccessible* proxy = Proxy(); + if (proxy->MustPruneChildren()) + return S_OK; + + *pcountChildren = proxy->ChildrenCount(); + return S_OK; + } + if (nsAccUtils::MustPrune(this)) return S_OK; @@ -290,7 +309,10 @@ AccessibleWrap::get_accName( return CO_E_OBJNOTCONNECTED; nsAutoString name; - xpAccessible->Name(name); + if (xpAccessible->IsProxy()) + xpAccessible->Proxy()->Name(name); + else + xpAccessible->Name(name); // The name was not provided, e.g. no alt attribute for an image. A screen // reader may choose to invent its own accessible name, e.g. from an image src @@ -329,6 +351,10 @@ AccessibleWrap::get_accValue( if (xpAccessible->IsDefunct()) return CO_E_OBJNOTCONNECTED; + // TODO make this work with proxies. + if (IsProxy()) + return E_NOTIMPL; + nsAutoString value; xpAccessible->Value(value); @@ -368,7 +394,10 @@ AccessibleWrap::get_accDescription(VARIANT varChild, return CO_E_OBJNOTCONNECTED; nsAutoString description; - xpAccessible->Description(description); + if (IsProxy()) + xpAccessible->Proxy()->Description(description); + else + xpAccessible->Description(description); *pszDescription = ::SysAllocStringLen(description.get(), description.Length()); @@ -400,12 +429,16 @@ AccessibleWrap::get_accRole( return CO_E_OBJNOTCONNECTED; a11y::role geckoRole; + if (xpAccessible->IsProxy()) { + geckoRole = xpAccessible->Proxy()->Role(); + } else { #ifdef DEBUG - NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(xpAccessible), - "Does not support Text when it should"); + NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(xpAccessible), + "Does not support Text when it should"); #endif - geckoRole = xpAccessible->Role(); + geckoRole = xpAccessible->Role(); + } uint32_t msaaRole = 0; @@ -426,12 +459,18 @@ AccessibleWrap::get_accRole( // Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call the MSAA role // a ROLE_OUTLINEITEM for consistency and compatibility. // We need this because ARIA has a role of "row" for both grid and treegrid - if (geckoRole == roles::ROW) { - Accessible* xpParent = Parent(); - if (xpParent && xpParent->Role() == roles::TREE_TABLE) - msaaRole = ROLE_SYSTEM_OUTLINEITEM; + if (xpAccessible->IsProxy()) { + if (geckoRole == roles::ROW + && xpAccessible->Proxy()->Parent()->Role() == roles::TREE_TABLE) + msaaRole = ROLE_SYSTEM_OUTLINEITEM; + } else { + if (geckoRole == roles::ROW) { + Accessible* xpParent = Parent(); + if (xpParent && xpParent->Role() == roles::TREE_TABLE) + msaaRole = ROLE_SYSTEM_OUTLINEITEM; + } } - + // -- Try enumerated role if (msaaRole != USE_ROLE_STRING) { pvarRole->vt = VT_I4; @@ -439,6 +478,10 @@ AccessibleWrap::get_accRole( return S_OK; } + // XXX bug 798492 make this work with proxies? + if (IsProxy()) + return E_FAIL; + // -- Try BSTR role // Could not map to known enumerated MSAA role like ROLE_BUTTON // Use BSTR role to expose role attribute or tag name + namespace @@ -509,7 +552,11 @@ AccessibleWrap::get_accState( // INVALID -> ALERT_HIGH // CHECKABLE -> MARQUEED - uint64_t state = State(); + uint64_t state; + if (xpAccessible->IsProxy()) + state = xpAccessible->Proxy()->State(); + else + state = State(); uint32_t msaaState = 0; nsAccUtils::To32States(state, &msaaState, nullptr); @@ -575,6 +622,10 @@ AccessibleWrap::get_accKeyboardShortcut( if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; + // TODO make this work with proxies. + if (acc->IsProxy()) + return E_NOTIMPL; + KeyBinding keyBinding = acc->AccessKey(); if (keyBinding.IsEmpty()) keyBinding = acc->KeyboardShortcut(); @@ -610,7 +661,13 @@ AccessibleWrap::get_accFocus( return CO_E_OBJNOTCONNECTED; // Return the current IAccessible child that has focus - Accessible* focusedAccessible = FocusedChild(); + Accessible* focusedAccessible; + if (IsProxy()) { + ProxyAccessible* proxy = Proxy()->FocusedChild(); + focusedAccessible = proxy ? WrapperFor(proxy) : nullptr; + } else { + focusedAccessible = FocusedChild(); + } if (focusedAccessible == this) { pvarChild->vt = VT_I4; @@ -772,9 +829,23 @@ AccessibleWrap::get_accSelection(VARIANT __RPC_FAR *pvarChildren) if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + // TODO make this work with proxies. + if (IsProxy()) + return E_NOTIMPL; + if (IsSelect()) { AutoTArray selectedItems; - SelectedItems(&selectedItems); + if (IsProxy()) { + nsTArray proxies; + Proxy()->SelectedItems(&proxies); + + uint32_t selectedCount = proxies.Length(); + for (uint32_t i = 0; i < selectedCount; i++) { + selectedItems.AppendElement(WrapperFor(proxies[i])); + } + } else { + SelectedItems(&selectedItems); + } // 1) Create and initialize the enumeration RefPtr pEnum = new AccessibleEnumerator(selectedItems); @@ -809,7 +880,11 @@ AccessibleWrap::get_accDefaultAction( return CO_E_OBJNOTCONNECTED; nsAutoString defaultAction; - xpAccessible->ActionNameAt(0, defaultAction); + if (xpAccessible->IsProxy()) { + xpAccessible->Proxy()->ActionNameAt(0, defaultAction); + } else { + xpAccessible->ActionNameAt(0, defaultAction); + } *pszDefaultAction = ::SysAllocStringLen(defaultAction.get(), defaultAction.Length()); @@ -837,22 +912,42 @@ AccessibleWrap::accSelect( return CO_E_OBJNOTCONNECTED; if (flagsSelect & SELFLAG_TAKEFOCUS) { - xpAccessible->TakeFocus(); + if (xpAccessible->IsProxy()) { + xpAccessible->Proxy()->TakeFocus(); + } else { + xpAccessible->TakeFocus(); + } + return S_OK; } if (flagsSelect & SELFLAG_TAKESELECTION) { - xpAccessible->TakeSelection(); + if (xpAccessible->IsProxy()) { + xpAccessible->Proxy()->TakeSelection(); + } else { + xpAccessible->TakeSelection(); + } + return S_OK; } if (flagsSelect & SELFLAG_ADDSELECTION) { - xpAccessible->SetSelected(true); + if (xpAccessible->IsProxy()) { + xpAccessible->Proxy()->SetSelected(true); + } else { + xpAccessible->SetSelected(true); + } + return S_OK; } if (flagsSelect & SELFLAG_REMOVESELECTION) { - xpAccessible->SetSelected(false); + if (xpAccessible->IsProxy()) { + xpAccessible->Proxy()->SetSelected(false); + } else { + xpAccessible->SetSelected(false); + } + return S_OK; } @@ -889,7 +984,12 @@ AccessibleWrap::accLocation( if (xpAccessible->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsIntRect rect = xpAccessible->Bounds(); + nsIntRect rect; + if (xpAccessible->IsProxy()) { + rect = xpAccessible->Proxy()->Bounds(); + } else { + rect = xpAccessible->Bounds(); + } *pxLeft = rect.x; *pyTop = rect.y; @@ -923,22 +1023,6 @@ AccessibleWrap::accNavigate( if (accessible->IsDefunct()) return CO_E_OBJNOTCONNECTED; - // Make sure that varStart != CHILDID_SELF so we don't infinitely recurse - if (accessible->IsProxy() && varStart.vt == VT_I4 && - varStart.lVal != CHILDID_SELF) { - // Now that we have the starting object, delegate this request to that - // object as a self-relative request... - RefPtr comProxy; - accessible->GetNativeInterface((void**) getter_AddRefs(comProxy)); - if (!comProxy) { - return E_UNEXPECTED; - } - VARIANT selfChildId; - selfChildId.vt = VT_I4; - selfChildId.lVal = CHILDID_SELF; - return comProxy->accNavigate(navDir, selfChildId, pvarEndUpAt); - } - Accessible* navAccessible = nullptr; Maybe xpRelation; @@ -996,8 +1080,16 @@ AccessibleWrap::accNavigate( pvarEndUpAt->vt = VT_EMPTY; if (xpRelation) { - Relation rel = RelationByType(*xpRelation); - navAccessible = rel.Next(); + if (accessible->IsProxy()) { + nsTArray targets = + accessible->Proxy()->RelationByType(*xpRelation); + if (targets.Length()) { + navAccessible = WrapperFor(targets[0]); + } + } else { + Relation rel = RelationByType(*xpRelation); + navAccessible = rel.Next(); + } } if (!navAccessible) @@ -1026,7 +1118,15 @@ AccessibleWrap::accHitTest( if (IsDefunct()) return CO_E_OBJNOTCONNECTED; - Accessible* accessible = ChildAtPoint(xLeft, yTop, eDirectChild); + Accessible* accessible = nullptr; + if (IsProxy()) { + ProxyAccessible* proxy = Proxy()->ChildAtPoint(xLeft, yTop, eDirectChild); + if (proxy) { + accessible = WrapperFor(proxy); + } + } else { + accessible = ChildAtPoint(xLeft, yTop, eDirectChild); + } // if we got a child if (accessible) { @@ -1064,6 +1164,10 @@ AccessibleWrap::accDoDefaultAction( if (xpAccessible->IsDefunct()) return CO_E_OBJNOTCONNECTED; + // TODO make this work with proxies. + if (xpAccessible->IsProxy()) + return xpAccessible->Proxy()->DoAction(0) ? S_OK : E_INVALIDARG; + return xpAccessible->DoAction(0) ? S_OK : E_INVALIDARG; A11Y_TRYBLOCK_END