author | Sebastian Hengst <archaeopteryx@coole-files.de> |
Thu, 29 Apr 2021 14:29:25 +0200 | |
changeset 577939 | d9e30da70def144c22f40e7debc5b190a31eb1f1 |
parent 577938 | 36de91ab59b93fecadebd915220833ba0de4ddaa |
child 577972 | abe0d75ef0ee47c22fcddb8d273c35128c446535 |
push id | 38418 |
push user | archaeopteryx@coole-files.de |
push date | Thu, 29 Apr 2021 12:29:50 +0000 |
treeherder | mozilla-central@d9e30da70def [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | backout |
bugs | 1694865 |
milestone | 90.0a1 |
backs out | 53ed762843ec9fbb7c622f498c5ffa494fcd7e09 309f737d3bc3479d0fe4d82d13519f0d78205eae 461b46e1a2cbcbdfa8306a4a007972894aef0bae acafc5835608eeda617d7e2cb9118d8b667c6287 40c7e0bcfcfd65160b8e15123bae95b84f457718 7dfb88fc34a1631546768dfd23305ba2f14eb88b |
first release with | nightly win32
d9e30da70def
/
90.0a1
/
20210429122950
/
files
nightly win64
d9e30da70def
/
90.0a1
/
20210429122950
/
files
nightly linux32
nightly linux64
nightly mac
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly win32
90.0a1
/
20210429122950
/
pushlog to previous
nightly win64
90.0a1
/
20210429122950
/
pushlog to previous
|
--- a/accessible/generic/LocalAccessible-inl.h +++ b/accessible/generic/LocalAccessible-inl.h @@ -67,17 +67,17 @@ inline bool LocalAccessible::ARIAHasNume } inline bool LocalAccessible::HasNumericValue() const { return NativeHasNumericValue() || ARIAHasNumericValue(); } inline bool LocalAccessible::IsDefunct() const { MOZ_ASSERT(mStateFlags & eIsDefunct || IsApplication() || IsDoc() || - IsProxy() || mStateFlags & eSharedNode || mContent, + mStateFlags & eSharedNode || mContent, "No content"); return mStateFlags & eIsDefunct; } inline void LocalAccessible::ScrollTo(uint32_t aHow) const { if (mContent) { RefPtr<PresShell> presShell = mDoc->PresShellPtr(); nsCOMPtr<nsIContent> content = mContent;
--- a/accessible/windows/ia2/ia2Accessible.cpp +++ b/accessible/windows/ia2/ia2Accessible.cpp @@ -56,30 +56,26 @@ ia2Accessible::QueryInterface(REFIID iid if (*ppv) { (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); return S_OK; } return E_NOINTERFACE; } -AccessibleWrap* ia2Accessible::LocalAcc() { - return static_cast<MsaaAccessible*>(this)->LocalAcc(); -} - //////////////////////////////////////////////////////////////////////////////// // IAccessible2 STDMETHODIMP ia2Accessible::get_nRelations(long* aNRelations) { if (!aNRelations) return E_INVALIDARG; *aNRelations = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; MOZ_ASSERT(!acc->IsProxy()); for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) { if (sRelationTypePairs[idx].second == IA2_RELATION_NULL) continue; Relation rel = acc->RelationByType(sRelationTypePairs[idx].first); if (rel.Next()) (*aNRelations)++; @@ -88,33 +84,32 @@ ia2Accessible::get_nRelations(long* aNRe } STDMETHODIMP ia2Accessible::get_relation(long aRelationIndex, IAccessibleRelation** aRelation) { if (!aRelation || aRelationIndex < 0) return E_INVALIDARG; *aRelation = nullptr; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; MOZ_ASSERT(!acc->IsProxy()); long relIdx = 0; for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) { if (sRelationTypePairs[idx].second == IA2_RELATION_NULL) continue; RelationType relationType = sRelationTypePairs[idx].first; Relation rel = acc->RelationByType(relationType); RefPtr<ia2AccessibleRelation> ia2Relation = new ia2AccessibleRelation(relationType, &rel); if (ia2Relation->HasTargets()) { if (relIdx == aRelationIndex) { - MsaaAccessible* msaa = static_cast<MsaaAccessible*>(this); - msaa->AssociateCOMObjectForDisconnection(ia2Relation); + acc->AssociateCOMObjectForDisconnection(ia2Relation); ia2Relation.forget(aRelation); return S_OK; } relIdx++; } } @@ -123,47 +118,46 @@ ia2Accessible::get_relation(long aRelati STDMETHODIMP ia2Accessible::get_relations(long aMaxRelations, IAccessibleRelation** aRelation, long* aNRelations) { if (!aRelation || !aNRelations || aMaxRelations <= 0) return E_INVALIDARG; *aNRelations = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; MOZ_ASSERT(!acc->IsProxy()); for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs) && *aNRelations < aMaxRelations; idx++) { if (sRelationTypePairs[idx].second == IA2_RELATION_NULL) continue; RelationType relationType = sRelationTypePairs[idx].first; Relation rel = acc->RelationByType(relationType); RefPtr<ia2AccessibleRelation> ia2Rel = new ia2AccessibleRelation(relationType, &rel); if (ia2Rel->HasTargets()) { - MsaaAccessible* msaa = static_cast<MsaaAccessible*>(this); - msaa->AssociateCOMObjectForDisconnection(ia2Rel); + acc->AssociateCOMObjectForDisconnection(ia2Rel); ia2Rel.forget(aRelation + (*aNRelations)); (*aNRelations)++; } } return S_OK; } STDMETHODIMP ia2Accessible::role(long* aRole) { if (!aRole) return E_INVALIDARG; *aRole = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; #define ROLE(_geckoRole, stringRole, atkRole, macRole, macSubrole, msaaRole, \ ia2Role, androidClass, nameRule) \ case roles::_geckoRole: \ *aRole = ia2Role; \ break; a11y::role geckoRole; @@ -187,32 +181,32 @@ ia2Accessible::role(long* aRole) { } return S_OK; } // XXX Use MOZ_CAN_RUN_SCRIPT_BOUNDARY for now due to bug 1543294. MOZ_CAN_RUN_SCRIPT_BOUNDARY STDMETHODIMP ia2Accessible::scrollTo(enum IA2ScrollType aScrollType) { - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; MOZ_ASSERT(!acc->IsProxy()); RefPtr<PresShell> presShell = acc->Document()->PresShellPtr(); nsCOMPtr<nsIContent> content = acc->GetContent(); nsCoreUtils::ScrollTo(presShell, content, aScrollType); return S_OK; } STDMETHODIMP ia2Accessible::scrollToPoint(enum IA2CoordinateType aCoordType, long aX, long aY) { - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; MOZ_ASSERT(!acc->IsProxy()); acc->ScrollToPoint(geckoCoordType, aX, aY); @@ -225,18 +219,18 @@ ia2Accessible::get_groupPosition(long* a long* aPositionInGroup) { if (!aGroupLevel || !aSimilarItemsInGroup || !aPositionInGroup) return E_INVALIDARG; *aGroupLevel = 0; *aSimilarItemsInGroup = 0; *aPositionInGroup = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; GroupPos groupPos = acc->GroupPosition(); // Group information for accessibles having level only (like html headings // elements) isn't exposed by this method. AT should look for 'level' object // attribute. if (!groupPos.setSize && !groupPos.posInSet) return S_FALSE; @@ -249,18 +243,18 @@ ia2Accessible::get_groupPosition(long* a STDMETHODIMP ia2Accessible::get_states(AccessibleStates* aStates) { if (!aStates) return E_INVALIDARG; *aStates = 0; // XXX: bug 344674 should come with better approach that we have here. - AccessibleWrap* acc = LocalAcc(); - if (!acc) { + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) { *aStates = IA2_STATE_DEFUNCT; return S_OK; } uint64_t state; MOZ_ASSERT(!acc->IsProxy()); state = acc->State(); @@ -339,40 +333,40 @@ ia2Accessible::get_localizedExtendedStat *aNLocalizedExtendedStates = 0; return E_NOTIMPL; } STDMETHODIMP ia2Accessible::get_uniqueID(long* aUniqueID) { if (!aUniqueID) return E_INVALIDARG; - AccessibleWrap* acc = LocalAcc(); + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); *aUniqueID = MsaaAccessible::GetChildIDFor(acc); return S_OK; } STDMETHODIMP ia2Accessible::get_windowHandle(HWND* aWindowHandle) { if (!aWindowHandle) return E_INVALIDARG; *aWindowHandle = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - *aWindowHandle = MsaaAccessible::GetHWNDFor(acc); + *aWindowHandle = AccessibleWrap::GetHWNDFor(acc); return S_OK; } STDMETHODIMP ia2Accessible::get_indexInParent(long* aIndexInParent) { if (!aIndexInParent) return E_INVALIDARG; *aIndexInParent = -1; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; MOZ_ASSERT(!acc->IsProxy()); *aIndexInParent = acc->IndexInParent(); if (*aIndexInParent == -1) return S_FALSE; return S_OK; } @@ -381,18 +375,18 @@ STDMETHODIMP ia2Accessible::get_locale(IA2Locale* aLocale) { if (!aLocale) return E_INVALIDARG; // Language codes consist of a primary code and a possibly empty series of // subcodes: language-code = primary-code ( "-" subcode )* // Two-letter primary codes are reserved for [ISO639] language abbreviations. // Any two-letter subcode is understood to be a [ISO3166] country code. - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsAutoString lang; acc->Language(lang); // If primary code consists from two letters then expose it as language. int32_t offset = lang.FindChar('-', 0); if (offset == -1) { if (lang.Length() == 2) { @@ -421,18 +415,18 @@ ia2Accessible::get_locale(IA2Locale* aLo return S_OK; } STDMETHODIMP ia2Accessible::get_attributes(BSTR* aAttributes) { if (!aAttributes) return E_INVALIDARG; *aAttributes = nullptr; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; // The format is name:value;name:value; with \ for escaping these // characters ":;=,\". if (!acc->IsProxy()) { nsCOMPtr<nsIPersistentProperties> attributes = acc->Attributes(); return ConvertToIA2Attributes(attributes, aAttributes); } @@ -453,33 +447,33 @@ ia2Accessible::get_attribute(BSTR name, STDMETHODIMP ia2Accessible::get_accessibleWithCaret(IUnknown** aAccessible, long* aCaretOffset) { if (!aAccessible || !aCaretOffset) return E_INVALIDARG; *aAccessible = nullptr; *aCaretOffset = -1; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; int32_t caretOffset = -1; LocalAccessible* accWithCaret = SelectionMgr()->AccessibleWithCaret(&caretOffset); if (!accWithCaret || acc->Document() != accWithCaret->Document()) return S_FALSE; LocalAccessible* child = accWithCaret; while (!child->IsDoc() && child != acc) child = child->LocalParent(); if (child != acc) return S_FALSE; - RefPtr<IAccessible2> ia2WithCaret; - accWithCaret->GetNativeInterface(getter_AddRefs(ia2WithCaret)); - ia2WithCaret.forget(aAccessible); + *aAccessible = + static_cast<IAccessible2*>(static_cast<AccessibleWrap*>(accWithCaret)); + (*aAccessible)->AddRef(); *aCaretOffset = caretOffset; return S_OK; } STDMETHODIMP ia2Accessible::get_relationTargetsOfType(BSTR aType, long aMaxTargets, IUnknown*** aTargets, long* aNTargets) { @@ -490,18 +484,18 @@ ia2Accessible::get_relationTargetsOfType for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) { if (wcscmp(aType, sRelationTypePairs[idx].second) == 0) { relationType.emplace(sRelationTypePairs[idx].first); break; } } if (!relationType) return E_INVALIDARG; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsTArray<LocalAccessible*> targets; MOZ_ASSERT(!acc->IsProxy()); Relation rel = acc->RelationByType(*relationType); LocalAccessible* target = nullptr; while ( (target = rel.Next()) && (aMaxTargets == 0 || static_cast<long>(targets.Length()) < aMaxTargets)) { @@ -509,52 +503,54 @@ ia2Accessible::get_relationTargetsOfType } *aNTargets = targets.Length(); *aTargets = static_cast<IUnknown**>(::CoTaskMemAlloc(sizeof(IUnknown*) * *aNTargets)); if (!*aTargets) return E_OUTOFMEMORY; for (int32_t i = 0; i < *aNTargets; i++) { - RefPtr<IAccessible2> target; - targets[i]->GetNativeInterface(getter_AddRefs(target)); - target.forget(&(*aTargets)[i]); + AccessibleWrap* target = static_cast<AccessibleWrap*>(targets[i]); + (*aTargets)[i] = static_cast<IAccessible2*>(target); + (*aTargets)[i]->AddRef(); } return S_OK; } STDMETHODIMP ia2Accessible::get_selectionRanges(IA2Range** aRanges, long* aNRanges) { if (!aRanges || !aNRanges) return E_INVALIDARG; *aNRanges = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; AutoTArray<TextRange, 1> ranges; acc->Document()->SelectionRanges(&ranges); ranges.RemoveElementsBy([acc](auto& range) { return !range.Crop(acc); }); *aNRanges = ranges.Length(); *aRanges = static_cast<IA2Range*>(::CoTaskMemAlloc(sizeof(IA2Range) * *aNRanges)); if (!*aRanges) return E_OUTOFMEMORY; for (uint32_t idx = 0; idx < static_cast<uint32_t>(*aNRanges); idx++) { - RefPtr<IAccessible2> anchor; - ranges[idx].StartContainer()->GetNativeInterface(getter_AddRefs(anchor)); - anchor.forget(&(*aRanges)[idx].anchor); + AccessibleWrap* anchor = + static_cast<AccessibleWrap*>(ranges[idx].StartContainer()); + (*aRanges)[idx].anchor = static_cast<IAccessible2*>(anchor); + anchor->AddRef(); (*aRanges)[idx].anchorOffset = ranges[idx].StartOffset(); - RefPtr<IAccessible2> active; - ranges[idx].EndContainer()->GetNativeInterface(getter_AddRefs(active)); - active.forget(&(*aRanges)[idx].active); + AccessibleWrap* active = + static_cast<AccessibleWrap*>(ranges[idx].EndContainer()); + (*aRanges)[idx].active = static_cast<IAccessible2*>(active); + active->AddRef(); (*aRanges)[idx].activeOffset = ranges[idx].EndOffset(); } return S_OK; } ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/windows/ia2/ia2Accessible.h +++ b/accessible/windows/ia2/ia2Accessible.h @@ -12,17 +12,16 @@ #include "Accessible2_3.h" class nsIPersistentProperties; namespace mozilla { namespace a11y { class Attribute; -class AccessibleWrap; class ia2Accessible : public IAccessible2_3 { public: // IUnknown STDMETHODIMP QueryInterface(REFIID, void**); // IAccessible2 virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_nRelations( @@ -111,17 +110,14 @@ class ia2Accessible : public IAccessible /* [out, size_is(,*nRanges)] */ IA2Range** ranges, /* [out, retval] */ long* nRanges); // Helper method static HRESULT ConvertToIA2Attributes(nsIPersistentProperties* aAttributes, BSTR* aIA2Attributes); static HRESULT ConvertToIA2Attributes(nsTArray<Attribute>* aAttributes, BSTR* aIA2Attributes); - - private: - AccessibleWrap* LocalAcc(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/ia2/ia2AccessibleAction.cpp +++ b/accessible/windows/ia2/ia2AccessibleAction.cpp @@ -9,68 +9,65 @@ #include "AccessibleAction_i.c" #include "AccessibleWrap.h" #include "IUnknownImpl.h" using namespace mozilla::a11y; -AccessibleWrap* ia2AccessibleAction::LocalAcc() { - return static_cast<MsaaAccessible*>(this)->LocalAcc(); -} - // IUnknown STDMETHODIMP ia2AccessibleAction::QueryInterface(REFIID iid, void** ppv) { if (!ppv) return E_INVALIDARG; *ppv = nullptr; - if (IID_IAccessibleAction == iid && LocalAcc() && !LocalAcc()->IsProxy()) { + if (IID_IAccessibleAction == iid && + !static_cast<AccessibleWrap*>(this)->IsProxy()) { *ppv = static_cast<IAccessibleAction*>(this); (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); return S_OK; } return E_NOINTERFACE; } // IAccessibleAction STDMETHODIMP ia2AccessibleAction::nActions(long* aActionCount) { if (!aActionCount) return E_INVALIDARG; *aActionCount = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; *aActionCount = acc->ActionCount(); return S_OK; } STDMETHODIMP ia2AccessibleAction::doAction(long aActionIndex) { - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; uint8_t index = static_cast<uint8_t>(aActionIndex); return acc->DoAction(index) ? S_OK : E_INVALIDARG; } STDMETHODIMP ia2AccessibleAction::get_description(long aActionIndex, BSTR* aDescription) { if (!aDescription) return E_INVALIDARG; *aDescription = nullptr; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsAutoString description; uint8_t index = static_cast<uint8_t>(aActionIndex); acc->ActionDescriptionAt(index, description); if (description.IsEmpty()) return S_FALSE; *aDescription = ::SysAllocStringLen(description.get(), description.Length()); return *aDescription ? S_OK : E_OUTOFMEMORY; @@ -82,18 +79,18 @@ ia2AccessibleAction::get_keyBinding(long if (!aKeyBinding) return E_INVALIDARG; *aKeyBinding = nullptr; if (!aNumBinding) return E_INVALIDARG; *aNumBinding = 0; if (aActionIndex != 0 || aNumMaxBinding < 1) return E_INVALIDARG; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; // Expose keyboard shortcut if it's not exposed via MSAA keyboard shortcut. KeyBinding keyBinding = acc->AccessKey(); if (keyBinding.IsEmpty()) return S_FALSE; keyBinding = acc->KeyboardShortcut(); if (keyBinding.IsEmpty()) return S_FALSE; @@ -114,18 +111,18 @@ ia2AccessibleAction::get_keyBinding(long } STDMETHODIMP ia2AccessibleAction::get_name(long aActionIndex, BSTR* aName) { if (!aName) return E_INVALIDARG; *aName = nullptr; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsAutoString name; uint8_t index = static_cast<uint8_t>(aActionIndex); acc->ActionNameAt(index, name); if (name.IsEmpty()) return E_INVALIDARG; *aName = ::SysAllocStringLen(name.get(), name.Length()); return *aName ? S_OK : E_OUTOFMEMORY;
--- a/accessible/windows/ia2/ia2AccessibleAction.h +++ b/accessible/windows/ia2/ia2AccessibleAction.h @@ -9,17 +9,16 @@ #define _ACCESSIBLE_ACTION_H #include "nsISupports.h" #include "AccessibleAction.h" namespace mozilla { namespace a11y { -class AccessibleWrap; class ia2AccessibleAction : public IAccessibleAction { public: // IUnknown STDMETHODIMP QueryInterface(REFIID, void**); // IAccessibleAction virtual HRESULT STDMETHODCALLTYPE nActions( @@ -40,19 +39,16 @@ class ia2AccessibleAction : public IAcce virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_name( /* [in] */ long actionIndex, /* [retval][out] */ BSTR* name); virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_localizedName( /* [in] */ long actionIndex, /* [retval][out] */ BSTR* localizedName); - - private: - AccessibleWrap* LocalAcc(); }; } // namespace a11y } // namespace mozilla #define FORWARD_IACCESSIBLEACTION(Class) \ virtual HRESULT STDMETHODCALLTYPE nActions(long* nActions) { \ return Class::nActions(nActions); \
--- a/accessible/windows/ia2/ia2AccessibleComponent.cpp +++ b/accessible/windows/ia2/ia2AccessibleComponent.cpp @@ -12,20 +12,16 @@ #include "AccessibleWrap.h" #include "States.h" #include "IUnknownImpl.h" #include "nsIFrame.h" using namespace mozilla::a11y; -AccessibleWrap* ia2AccessibleComponent::LocalAcc() { - return static_cast<MsaaAccessible*>(this)->LocalAcc(); -} - // IUnknown STDMETHODIMP ia2AccessibleComponent::QueryInterface(REFIID iid, void** ppv) { if (!ppv) return E_INVALIDARG; *ppv = nullptr; @@ -42,18 +38,18 @@ ia2AccessibleComponent::QueryInterface(R STDMETHODIMP ia2AccessibleComponent::get_locationInParent(long* aX, long* aY) { if (!aX || !aY) return E_INVALIDARG; *aX = 0; *aY = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; // If the object is not on any screen the returned position is (0,0). uint64_t state = acc->State(); if (state & states::INVISIBLE) return S_OK; nsIntRect rect = acc->Bounds(); // The coordinates of the returned position are relative to this object's @@ -74,33 +70,33 @@ ia2AccessibleComponent::get_locationInPa } STDMETHODIMP ia2AccessibleComponent::get_foreground(IA2Color* aForeground) { if (!aForeground) return E_INVALIDARG; *aForeground = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsIFrame* frame = acc->GetFrame(); if (frame) *aForeground = frame->StyleText()->mColor.ToColor(); return S_OK; } STDMETHODIMP ia2AccessibleComponent::get_background(IA2Color* aBackground) { if (!aBackground) return E_INVALIDARG; *aBackground = 0; - AccessibleWrap* acc = LocalAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsIFrame* frame = acc->GetFrame(); if (frame) { *aBackground = frame->StyleBackground()->BackgroundColor(frame); } return S_OK; }
--- a/accessible/windows/ia2/ia2AccessibleComponent.h +++ b/accessible/windows/ia2/ia2AccessibleComponent.h @@ -7,34 +7,30 @@ #ifndef IA2_ACCESSIBLE_COMPONENT_H_ #define IA2_ACCESSIBLE_COMPONENT_H_ #include "AccessibleComponent.h" namespace mozilla { namespace a11y { -class AccessibleWrap; class ia2AccessibleComponent : public IAccessibleComponent { public: // IUnknown STDMETHODIMP QueryInterface(REFIID, void**); // IAccessibleComponent virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_locationInParent( /* [out] */ long* x, /* [retval][out] */ long* y); virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_foreground( /* [retval][out] */ IA2Color* foreground); virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_background( /* [retval][out] */ IA2Color* background); - - private: - AccessibleWrap* LocalAcc(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/ia2/ia2AccessibleEditableText.cpp +++ b/accessible/windows/ia2/ia2AccessibleEditableText.cpp @@ -12,94 +12,91 @@ #include "HyperTextAccessibleWrap.h" #include "ProxyWrappers.h" #include "nsCOMPtr.h" #include "nsString.h" using namespace mozilla::a11y; -HyperTextAccessibleWrap* ia2AccessibleEditableText::TextAcc() { - // XXX This first static_cast is a necessary hack until we get rid of the - // inheritance of HyperTextAccessibleWrap. - auto wrap = static_cast<HyperTextAccessibleWrap*>(this); - AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc(); - return static_cast<HyperTextAccessibleWrap*>(acc); -} - // IAccessibleEditableText STDMETHODIMP ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) return E_INVALIDARG; textAcc->CopyText(aStartOffset, aEndOffset); return S_OK; } STDMETHODIMP ia2AccessibleEditableText::deleteText(long aStartOffset, long aEndOffset) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) return E_INVALIDARG; textAcc->DeleteText(aStartOffset, aEndOffset); return S_OK; } STDMETHODIMP ia2AccessibleEditableText::insertText(long aOffset, BSTR* aText) { uint32_t length = ::SysStringLen(*aText); nsAutoString text(*aText, length); + MOZ_ASSERT(!HyperTextProxyFor(this)); - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidOffset(aOffset)) return E_INVALIDARG; textAcc->InsertText(text, aOffset); return S_OK; } STDMETHODIMP ia2AccessibleEditableText::cutText(long aStartOffset, long aEndOffset) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) return E_INVALIDARG; textAcc->CutText(aStartOffset, aEndOffset); return S_OK; } STDMETHODIMP ia2AccessibleEditableText::pasteText(long aOffset) { - RefPtr<HyperTextAccessible> textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + RefPtr<HyperTextAccessible> textAcc = + static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidOffset(aOffset)) return E_INVALIDARG; textAcc->PasteText(aOffset); return S_OK; } STDMETHODIMP ia2AccessibleEditableText::replaceText(long aStartOffset, long aEndOffset, BSTR* aText) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) return E_INVALIDARG; textAcc->DeleteText(aStartOffset, aEndOffset); uint32_t length = ::SysStringLen(*aText); nsAutoString text(*aText, length); textAcc->InsertText(text, aStartOffset);
--- a/accessible/windows/ia2/ia2AccessibleEditableText.h +++ b/accessible/windows/ia2/ia2AccessibleEditableText.h @@ -9,17 +9,16 @@ #define _ACCESSIBLE_EDITABLETEXT_H #include "nsISupports.h" #include "AccessibleEditableText.h" namespace mozilla { namespace a11y { -class HyperTextAccessibleWrap; class ia2AccessibleEditableText : public IAccessibleEditableText { public: // IAccessibleEditableText virtual HRESULT STDMETHODCALLTYPE copyText( /* [in] */ long startOffset, /* [in] */ long endOffset); @@ -43,17 +42,14 @@ class ia2AccessibleEditableText : public /* [in] */ long startOffset, /* [in] */ long endOffset, /* [in] */ BSTR* text); virtual HRESULT STDMETHODCALLTYPE setAttributes( /* [in] */ long startOffset, /* [in] */ long endOffset, /* [in] */ BSTR* attributes); - - private: - HyperTextAccessibleWrap* TextAcc(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/ia2/ia2AccessibleHyperlink.cpp +++ b/accessible/windows/ia2/ia2AccessibleHyperlink.cpp @@ -9,34 +9,28 @@ #include "AccessibleHyperlink_i.c" #include "AccessibleWrap.h" #include "IUnknownImpl.h" #include "nsIURI.h" using namespace mozilla::a11y; -AccessibleWrap* ia2AccessibleHyperlink::LocalAcc() { - return static_cast<MsaaAccessible*>(this)->LocalAcc(); -} - // IUnknown STDMETHODIMP ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv) { if (!ppv) return E_INVALIDARG; *ppv = nullptr; if (IID_IAccessibleHyperlink == iid) { - auto accWrap = LocalAcc(); - if (!accWrap || accWrap->IsProxy() ? !accWrap->Proxy()->IsLink() - : !accWrap->IsLink()) { + auto accWrap = static_cast<AccessibleWrap*>(this); + if (accWrap->IsProxy() ? !accWrap->Proxy()->IsLink() : !accWrap->IsLink()) return E_NOINTERFACE; - } *ppv = static_cast<IAccessibleHyperlink*>(this); (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); return S_OK; } return ia2AccessibleAction::QueryInterface(iid, ppv); } @@ -44,52 +38,53 @@ ia2AccessibleHyperlink::QueryInterface(R // IAccessibleHyperlink STDMETHODIMP ia2AccessibleHyperlink::get_anchor(long aIndex, VARIANT* aAnchor) { if (!aAnchor) return E_INVALIDARG; VariantInit(aAnchor); - LocalAccessible* thisObj = LocalAcc(); - if (!thisObj) { - return CO_E_OBJNOTCONNECTED; - } + LocalAccessible* thisObj = static_cast<AccessibleWrap*>(this); MOZ_ASSERT(!thisObj->IsProxy()); + if (thisObj->IsDefunct()) return CO_E_OBJNOTCONNECTED; + if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount())) return E_INVALIDARG; if (!thisObj->IsLink()) return S_FALSE; AccessibleWrap* anchor = static_cast<AccessibleWrap*>(thisObj->AnchorAt(aIndex)); if (!anchor) return S_FALSE; - RefPtr<IAccessible> result; - anchor->GetNativeInterface(getter_AddRefs(result)); - result.forget(&aAnchor->punkVal); + void* instancePtr = nullptr; + HRESULT result = anchor->QueryInterface(IID_IUnknown, &instancePtr); + if (FAILED(result)) return result; + + aAnchor->punkVal = static_cast<IUnknown*>(instancePtr); aAnchor->vt = VT_UNKNOWN; return S_OK; } STDMETHODIMP ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget) { if (!aAnchorTarget) { return E_INVALIDARG; } VariantInit(aAnchorTarget); - LocalAccessible* thisObj = LocalAcc(); - if (!thisObj) { + LocalAccessible* thisObj = static_cast<AccessibleWrap*>(this); + nsAutoCString uriStr; + MOZ_ASSERT(!thisObj->IsProxy()); + if (thisObj->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - nsAutoCString uriStr; - MOZ_ASSERT(!thisObj->IsProxy()); if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount())) { return E_INVALIDARG; } if (!thisObj->IsLink()) { return S_FALSE; } @@ -114,55 +109,52 @@ ia2AccessibleHyperlink::get_anchorTarget } STDMETHODIMP ia2AccessibleHyperlink::get_startIndex(long* aIndex) { if (!aIndex) return E_INVALIDARG; *aIndex = 0; - LocalAccessible* thisObj = LocalAcc(); - if (!thisObj) { - return CO_E_OBJNOTCONNECTED; - } - MOZ_ASSERT(!thisObj->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + LocalAccessible* thisObj = static_cast<AccessibleWrap*>(this); + if (thisObj->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!thisObj->IsLink()) return S_FALSE; *aIndex = thisObj->StartOffset(); return S_OK; } STDMETHODIMP ia2AccessibleHyperlink::get_endIndex(long* aIndex) { if (!aIndex) return E_INVALIDARG; *aIndex = 0; - LocalAccessible* thisObj = LocalAcc(); - if (!thisObj) { - return CO_E_OBJNOTCONNECTED; - } - MOZ_ASSERT(!thisObj->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + LocalAccessible* thisObj = static_cast<AccessibleWrap*>(this); + if (thisObj->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!thisObj->IsLink()) return S_FALSE; *aIndex = thisObj->EndOffset(); return S_OK; } STDMETHODIMP ia2AccessibleHyperlink::get_valid(boolean* aValid) { if (!aValid) return E_INVALIDARG; *aValid = false; - LocalAccessible* thisObj = LocalAcc(); - if (!thisObj) { - return CO_E_OBJNOTCONNECTED; - } - MOZ_ASSERT(!thisObj->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + LocalAccessible* thisObj = static_cast<AccessibleWrap*>(this); + if (thisObj->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!thisObj->IsLink()) return S_FALSE; *aValid = thisObj->IsLinkValid(); return S_OK; }
--- a/accessible/windows/ia2/ia2AccessibleHyperlink.h +++ b/accessible/windows/ia2/ia2AccessibleHyperlink.h @@ -10,17 +10,16 @@ #include "nsISupports.h" #include "ia2AccessibleAction.h" #include "AccessibleHyperlink.h" namespace mozilla { namespace a11y { -class AccessibleWrap; class ia2AccessibleHyperlink : public ia2AccessibleAction, public IAccessibleHyperlink { public: // IUnknown STDMETHODIMP QueryInterface(REFIID, void**); // IAccessibleAction @@ -37,17 +36,14 @@ class ia2AccessibleHyperlink : public ia virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_startIndex( /* [retval][out] */ long* index); virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_endIndex( /* [retval][out] */ long* index); virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_valid( /* [retval][out] */ boolean* valid); - - private: - AccessibleWrap* LocalAcc(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/ia2/ia2AccessibleHypertext.cpp +++ b/accessible/windows/ia2/ia2AccessibleHypertext.cpp @@ -9,94 +9,92 @@ #include "AccessibleHypertext_i.c" #include "HyperTextAccessibleWrap.h" #include "IUnknownImpl.h" using namespace mozilla::a11y; -HyperTextAccessibleWrap* ia2AccessibleHypertext::TextAcc() { - // XXX This first static_cast is a necessary hack until we get rid of the - // inheritance of HyperTextAccessibleWrap. - auto wrap = static_cast<HyperTextAccessibleWrap*>(this); - AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc(); - return static_cast<HyperTextAccessibleWrap*>(acc); -} - // IAccessibleHypertext STDMETHODIMP ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount) { if (!aHyperlinkCount) return E_INVALIDARG; *aHyperlinkCount = 0; - HyperTextAccessibleWrap* hyperText = TextAcc(); - if (!hyperText) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!hyperText->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessibleWrap* hyperText = + static_cast<HyperTextAccessibleWrap*>(this); + if (hyperText->IsDefunct()) return CO_E_OBJNOTCONNECTED; *aHyperlinkCount = hyperText->LinkCount(); return S_OK; } STDMETHODIMP ia2AccessibleHypertext::get_hyperlink(long aLinkIndex, IAccessibleHyperlink** aHyperlink) { if (!aHyperlink) return E_INVALIDARG; *aHyperlink = nullptr; AccessibleWrap* hyperLink; - HyperTextAccessibleWrap* hyperText = TextAcc(); - if (!hyperText) { + MOZ_ASSERT(!HyperTextProxyFor(this)); + HyperTextAccessibleWrap* hyperText = + static_cast<HyperTextAccessibleWrap*>(this); + if (hyperText->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - MOZ_ASSERT(!hyperText->IsProxy()); hyperLink = static_cast<AccessibleWrap*>(hyperText->LinkAt(aLinkIndex)); if (!hyperLink) return E_FAIL; - RefPtr<IAccessibleHyperlink> result; - hyperLink->GetNativeInterface(getter_AddRefs(result)); - result.forget(aHyperlink); + *aHyperlink = static_cast<IAccessibleHyperlink*>(hyperLink); + (*aHyperlink)->AddRef(); return S_OK; } STDMETHODIMP ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long* aHyperlinkIndex) { if (!aHyperlinkIndex) return E_INVALIDARG; *aHyperlinkIndex = 0; - HyperTextAccessibleWrap* hyperAcc = TextAcc(); - if (!hyperAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!hyperAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessibleWrap* hyperAcc = + static_cast<HyperTextAccessibleWrap*>(this); + if (hyperAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; *aHyperlinkIndex = hyperAcc->LinkIndexAtOffset(aCharIndex); return S_OK; } STDMETHODIMP ia2AccessibleHypertext::get_hyperlinks(IAccessibleHyperlink*** aHyperlinks, long* aNHyperlinks) { if (!aHyperlinks || !aNHyperlinks) { return E_INVALIDARG; } *aHyperlinks = nullptr; *aNHyperlinks = 0; - HyperTextAccessibleWrap* hyperText = TextAcc(); - if (!hyperText) { + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessibleWrap* hyperText = + static_cast<HyperTextAccessibleWrap*>(this); + if (hyperText->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - MOZ_ASSERT(!hyperText->IsProxy()); uint32_t count = hyperText->LinkCount(); *aNHyperlinks = count; if (count == 0) { *aHyperlinks = nullptr; return S_FALSE; } @@ -106,15 +104,14 @@ ia2AccessibleHypertext::get_hyperlinks(I if (!*aHyperlinks) { return E_OUTOFMEMORY; } for (uint32_t i = 0; i < count; ++i) { AccessibleWrap* hyperLink = static_cast<AccessibleWrap*>(hyperText->LinkAt(i)); MOZ_ASSERT(hyperLink); - RefPtr<IAccessibleHyperlink> iaHyper; - hyperLink->GetNativeInterface(getter_AddRefs(iaHyper)); - iaHyper.forget(&(*aHyperlinks)[i]); + (*aHyperlinks)[i] = static_cast<IAccessibleHyperlink*>(hyperLink); + (*aHyperlinks)[i]->AddRef(); } return S_OK; }
--- a/accessible/windows/ia2/ia2AccessibleHypertext.h +++ b/accessible/windows/ia2/ia2AccessibleHypertext.h @@ -10,17 +10,16 @@ #include "nsISupports.h" #include "ia2AccessibleText.h" #include "AccessibleHypertext2.h" namespace mozilla { namespace a11y { -class HyperTextAccessibleWrap; class ia2AccessibleHypertext : public ia2AccessibleText, public IAccessibleHypertext2 { public: // IAccessibleText FORWARD_IACCESSIBLETEXT(ia2AccessibleText) // IAccessibleHypertext @@ -34,17 +33,14 @@ class ia2AccessibleHypertext : public ia virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_hyperlinkIndex( /* [in] */ long charIndex, /* [retval][out] */ long* hyperlinkIndex); // IAccessibleHypertext2 virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_hyperlinks( /* [out, size_is(,*nHyperlinks)] */ IAccessibleHyperlink*** hyperlinks, /* [out, retval] */ long* nHyperlinks); - - private: - HyperTextAccessibleWrap* TextAcc(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/ia2/ia2AccessibleImage.cpp +++ b/accessible/windows/ia2/ia2AccessibleImage.cpp @@ -13,24 +13,16 @@ #include "IUnknownImpl.h" #include "nsIAccessibleTypes.h" #include "nsString.h" using namespace mozilla; using namespace mozilla::a11y; -ImageAccessible* ia2AccessibleImage::ImageAcc() { - // XXX This first static_cast is a necessary hack until we get rid of the - // inheritance of ImageAccessibleWrap. - auto wrap = static_cast<ImageAccessibleWrap*>(this); - AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc(); - return static_cast<ImageAccessible*>(acc); -} - // IUnknown STDMETHODIMP ia2AccessibleImage::QueryInterface(REFIID iid, void** ppv) { if (!ppv) return E_INVALIDARG; *ppv = nullptr; @@ -46,18 +38,18 @@ ia2AccessibleImage::QueryInterface(REFII // IAccessibleImage STDMETHODIMP ia2AccessibleImage::get_description(BSTR* aDescription) { if (!aDescription) return E_INVALIDARG; *aDescription = nullptr; - ImageAccessible* acc = ImageAcc(); - if (!acc) return CO_E_OBJNOTCONNECTED; + ImageAccessibleWrap* acc = static_cast<ImageAccessibleWrap*>(this); + if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsAutoString description; acc->Name(description); if (description.IsEmpty()) return S_FALSE; *aDescription = ::SysAllocStringLen(description.get(), description.Length()); return *aDescription ? S_OK : E_OUTOFMEMORY; } @@ -65,18 +57,18 @@ ia2AccessibleImage::get_description(BSTR STDMETHODIMP ia2AccessibleImage::get_imagePosition(enum IA2CoordinateType aCoordType, long* aX, long* aY) { if (!aX || !aY) return E_INVALIDARG; *aX = 0; *aY = 0; - ImageAccessible* imageAcc = ImageAcc(); - if (!imageAcc) return CO_E_OBJNOTCONNECTED; + ImageAccessibleWrap* imageAcc = static_cast<ImageAccessibleWrap*>(this); + if (imageAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; nsIntPoint pos = imageAcc->Position(geckoCoordType); *aX = pos.x; @@ -86,16 +78,16 @@ ia2AccessibleImage::get_imagePosition(en STDMETHODIMP ia2AccessibleImage::get_imageSize(long* aHeight, long* aWidth) { if (!aHeight || !aWidth) return E_INVALIDARG; *aHeight = 0; *aWidth = 0; - ImageAccessible* imageAcc = ImageAcc(); - if (!imageAcc) return CO_E_OBJNOTCONNECTED; + ImageAccessibleWrap* imageAcc = static_cast<ImageAccessibleWrap*>(this); + if (imageAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsIntSize size = imageAcc->Size(); *aHeight = size.width; *aWidth = size.height; return S_OK; }
--- a/accessible/windows/ia2/ia2AccessibleImage.h +++ b/accessible/windows/ia2/ia2AccessibleImage.h @@ -7,17 +7,16 @@ #ifndef _ACCESSIBLE_IMAGE_H #define _ACCESSIBLE_IMAGE_H #include "AccessibleImage.h" namespace mozilla { namespace a11y { -class ImageAccessible; class ia2AccessibleImage : public IAccessibleImage { public: // IUnknown STDMETHODIMP QueryInterface(REFIID, void**); // IAccessibleImage virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_description( @@ -26,17 +25,14 @@ class ia2AccessibleImage : public IAcces virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_imagePosition( /* [in] */ enum IA2CoordinateType coordinateType, /* [out] */ long* x, /* [retval][out] */ long* y); virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_imageSize( /* [out] */ long* height, /* [retval][out] */ long* width); - - private: - ImageAccessible* ImageAcc(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/ia2/ia2AccessibleRelation.cpp +++ b/accessible/windows/ia2/ia2AccessibleRelation.cpp @@ -64,19 +64,20 @@ ia2AccessibleRelation::get_nTargets(long } STDMETHODIMP ia2AccessibleRelation::get_target(long aTargetIndex, IUnknown** aTarget) { if (aTargetIndex < 0 || (uint32_t)aTargetIndex >= mTargets.Length() || !aTarget) return E_INVALIDARG; - RefPtr<IAccessible> target; - mTargets[aTargetIndex]->GetNativeInterface(getter_AddRefs(target)); - target.forget(aTarget); + AccessibleWrap* target = + static_cast<AccessibleWrap*>(mTargets[aTargetIndex].get()); + *aTarget = static_cast<IAccessible*>(target); + (*aTarget)->AddRef(); return S_OK; } STDMETHODIMP ia2AccessibleRelation::get_targets(long aMaxTargets, IUnknown** aTargets, long* aNTargets) { if (!aNTargets || !aTargets) return E_INVALIDARG;
--- a/accessible/windows/ia2/ia2AccessibleTable.cpp +++ b/accessible/windows/ia2/ia2AccessibleTable.cpp @@ -54,80 +54,74 @@ ia2AccessibleTable::get_accessibleAt(lon return get_cellAt(aRowIdx, aColIdx, aAccessible); } STDMETHODIMP ia2AccessibleTable::get_caption(IUnknown** aAccessible) { if (!aAccessible) return E_INVALIDARG; *aAccessible = nullptr; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - AccessibleWrap* caption = static_cast<AccessibleWrap*>(table->Caption()); + AccessibleWrap* caption = static_cast<AccessibleWrap*>(mTable->Caption()); if (!caption) return S_FALSE; - RefPtr<IAccessible> result; - caption->GetNativeInterface(getter_AddRefs(result)); - result.forget(aAccessible); + (*aAccessible = static_cast<IAccessible*>(caption))->AddRef(); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_childIndex(long aRowIdx, long aColIdx, long* aChildIdx) { if (!aChildIdx) return E_INVALIDARG; *aChildIdx = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; if (aRowIdx < 0 || aColIdx < 0 || - static_cast<uint32_t>(aRowIdx) >= table->RowCount() || - static_cast<uint32_t>(aColIdx) >= table->ColCount()) + static_cast<uint32_t>(aRowIdx) >= mTable->RowCount() || + static_cast<uint32_t>(aColIdx) >= mTable->ColCount()) return E_INVALIDARG; - *aChildIdx = table->CellIndexAt(aRowIdx, aColIdx); + *aChildIdx = mTable->CellIndexAt(aRowIdx, aColIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_columnDescription(long aColIdx, BSTR* aDescription) { if (!aDescription) return E_INVALIDARG; *aDescription = nullptr; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= table->ColCount()) + if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount()) return E_INVALIDARG; nsAutoString descr; - table->ColDescription(aColIdx, descr); + mTable->ColDescription(aColIdx, descr); if (descr.IsEmpty()) return S_FALSE; *aDescription = ::SysAllocStringLen(descr.get(), descr.Length()); return *aDescription ? S_OK : E_OUTOFMEMORY; } STDMETHODIMP ia2AccessibleTable::get_columnExtentAt(long aRowIdx, long aColIdx, long* aSpan) { if (!aSpan) return E_INVALIDARG; *aSpan = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; if (aRowIdx < 0 || aColIdx < 0 || - static_cast<uint32_t>(aRowIdx) >= table->RowCount() || - static_cast<uint32_t>(aColIdx) >= table->ColCount()) + static_cast<uint32_t>(aRowIdx) >= mTable->RowCount() || + static_cast<uint32_t>(aColIdx) >= mTable->ColCount()) return E_INVALIDARG; - *aSpan = table->ColExtentAt(aRowIdx, aColIdx); + *aSpan = mTable->ColExtentAt(aRowIdx, aColIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_columnHeader(IAccessibleTable** aAccessibleTable, long* aStartingRowIndex) { if (!aAccessibleTable || !aStartingRowIndex) return E_INVALIDARG; @@ -136,119 +130,112 @@ ia2AccessibleTable::get_columnHeader(IAc return E_NOTIMPL; } STDMETHODIMP ia2AccessibleTable::get_columnIndex(long aCellIdx, long* aColIdx) { if (!aColIdx) return E_INVALIDARG; *aColIdx = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; if (aCellIdx < 0) { return E_INVALIDARG; } - long colIdx = table->ColIndexAt(aCellIdx); + long colIdx = mTable->ColIndexAt(aCellIdx); if (colIdx == -1) { // Indicates an error. return E_INVALIDARG; } *aColIdx = colIdx; return S_OK; } STDMETHODIMP ia2AccessibleTable::get_nColumns(long* aColCount) { if (!aColCount) return E_INVALIDARG; *aColCount = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - *aColCount = table->ColCount(); + *aColCount = mTable->ColCount(); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_nRows(long* aRowCount) { if (!aRowCount) return E_INVALIDARG; *aRowCount = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - *aRowCount = table->RowCount(); + *aRowCount = mTable->RowCount(); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_nSelectedChildren(long* aChildCount) { return get_nSelectedCells(aChildCount); } STDMETHODIMP ia2AccessibleTable::get_nSelectedColumns(long* aColCount) { if (!aColCount) return E_INVALIDARG; *aColCount = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - *aColCount = table->SelectedColCount(); + *aColCount = mTable->SelectedColCount(); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_nSelectedRows(long* aRowCount) { if (!aRowCount) return E_INVALIDARG; *aRowCount = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - *aRowCount = table->SelectedRowCount(); + *aRowCount = mTable->SelectedRowCount(); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_rowDescription(long aRowIdx, BSTR* aDescription) { if (!aDescription) return E_INVALIDARG; *aDescription = nullptr; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= table->RowCount()) + if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount()) return E_INVALIDARG; nsAutoString descr; - table->RowDescription(aRowIdx, descr); + mTable->RowDescription(aRowIdx, descr); if (descr.IsEmpty()) return S_FALSE; *aDescription = ::SysAllocStringLen(descr.get(), descr.Length()); return *aDescription ? S_OK : E_OUTOFMEMORY; } STDMETHODIMP ia2AccessibleTable::get_rowExtentAt(long aRowIdx, long aColIdx, long* aSpan) { if (!aSpan) return E_INVALIDARG; *aSpan = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; if (aRowIdx < 0 || aColIdx < 0 || - static_cast<uint32_t>(aRowIdx) >= table->RowCount() || - static_cast<uint32_t>(aColIdx) >= table->ColCount()) + static_cast<uint32_t>(aRowIdx) >= mTable->RowCount() || + static_cast<uint32_t>(aColIdx) >= mTable->ColCount()) return E_INVALIDARG; - *aSpan = table->RowExtentAt(aRowIdx, aColIdx); + *aSpan = mTable->RowExtentAt(aRowIdx, aColIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_rowHeader(IAccessibleTable** aAccessibleTable, long* aStartingColumnIndex) { if (!aAccessibleTable || !aStartingColumnIndex) return E_INVALIDARG; @@ -257,44 +244,42 @@ ia2AccessibleTable::get_rowHeader(IAcces return E_NOTIMPL; } STDMETHODIMP ia2AccessibleTable::get_rowIndex(long aCellIdx, long* aRowIdx) { if (!aRowIdx) return E_INVALIDARG; *aRowIdx = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; if (aCellIdx < 0) { return E_INVALIDARG; } - long rowIdx = table->RowIndexAt(aCellIdx); + long rowIdx = mTable->RowIndexAt(aCellIdx); if (rowIdx == -1) { // Indicates an error. return E_INVALIDARG; } *aRowIdx = rowIdx; return S_OK; } STDMETHODIMP ia2AccessibleTable::get_selectedChildren(long aMaxChildren, long** aChildren, long* aNChildren) { if (!aChildren || !aNChildren) return E_INVALIDARG; *aChildren = nullptr; *aNChildren = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; AutoTArray<uint32_t, 30> cellIndices; - table->SelectedCellIndices(&cellIndices); + mTable->SelectedCellIndices(&cellIndices); uint32_t maxCells = cellIndices.Length(); if (maxCells == 0) return S_FALSE; *aChildren = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxCells)); *aNChildren = maxCells; for (uint32_t i = 0; i < maxCells; i++) (*aChildren)[i] = cellIndices[i]; @@ -326,104 +311,97 @@ ia2AccessibleTable::get_summary(IUnknown return S_FALSE; } STDMETHODIMP ia2AccessibleTable::get_isColumnSelected(long aColIdx, boolean* aIsSelected) { if (!aIsSelected) return E_INVALIDARG; *aIsSelected = false; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= table->ColCount()) + if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount()) return E_INVALIDARG; - *aIsSelected = table->IsColSelected(aColIdx); + *aIsSelected = mTable->IsColSelected(aColIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_isRowSelected(long aRowIdx, boolean* aIsSelected) { if (!aIsSelected) return E_INVALIDARG; *aIsSelected = false; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= table->RowCount()) + if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount()) return E_INVALIDARG; - *aIsSelected = table->IsRowSelected(aRowIdx); + *aIsSelected = mTable->IsRowSelected(aRowIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_isSelected(long aRowIdx, long aColIdx, boolean* aIsSelected) { if (!aIsSelected) return E_INVALIDARG; *aIsSelected = false; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; if (aRowIdx < 0 || aColIdx < 0 || - static_cast<uint32_t>(aColIdx) >= table->ColCount() || - static_cast<uint32_t>(aRowIdx) >= table->RowCount()) + static_cast<uint32_t>(aColIdx) >= mTable->ColCount() || + static_cast<uint32_t>(aRowIdx) >= mTable->RowCount()) return E_INVALIDARG; - *aIsSelected = table->IsCellSelected(aRowIdx, aColIdx); + *aIsSelected = mTable->IsCellSelected(aRowIdx, aColIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::selectRow(long aRowIdx) { - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= table->RowCount()) + if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount()) return E_INVALIDARG; - table->SelectRow(aRowIdx); + mTable->SelectRow(aRowIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::selectColumn(long aColIdx) { - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= table->ColCount()) + if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount()) return E_INVALIDARG; - table->SelectCol(aColIdx); + mTable->SelectCol(aColIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::unselectRow(long aRowIdx) { - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= table->RowCount()) + if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount()) return E_INVALIDARG; - table->UnselectRow(aRowIdx); + mTable->UnselectRow(aRowIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::unselectColumn(long aColIdx) { - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= table->ColCount()) + if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount()) return E_INVALIDARG; - table->UnselectCol(aColIdx); + mTable->UnselectCol(aColIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_rowColumnExtentsAtIndex(long aCellIdx, long* aRowIdx, long* aColIdx, long* aRowExtents, long* aColExtents, @@ -431,34 +409,33 @@ ia2AccessibleTable::get_rowColumnExtents if (!aRowIdx || !aColIdx || !aRowExtents || !aColExtents || !aIsSelected) return E_INVALIDARG; *aRowIdx = 0; *aColIdx = 0; *aRowExtents = 0; *aColExtents = 0; *aIsSelected = false; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; if (aCellIdx < 0) { return E_INVALIDARG; } int32_t colIdx = 0, rowIdx = 0; - table->RowAndColIndicesAt(aCellIdx, &rowIdx, &colIdx); + mTable->RowAndColIndicesAt(aCellIdx, &rowIdx, &colIdx); if (rowIdx == -1 || colIdx == -1) { // Indicates an error. return E_INVALIDARG; } *aRowIdx = rowIdx; *aColIdx = colIdx; - *aRowExtents = table->RowExtentAt(rowIdx, colIdx); - *aColExtents = table->ColExtentAt(rowIdx, colIdx); - *aIsSelected = table->IsCellSelected(rowIdx, colIdx); + *aRowExtents = mTable->RowExtentAt(rowIdx, colIdx); + *aColExtents = mTable->ColExtentAt(rowIdx, colIdx); + *aIsSelected = mTable->IsCellSelected(rowIdx, colIdx); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_modelChange(IA2TableModelChange* aModelChange) { return E_NOTIMPL; } @@ -467,80 +444,74 @@ ia2AccessibleTable::get_modelChange(IA2T // IAccessibleTable2 STDMETHODIMP ia2AccessibleTable::get_cellAt(long aRowIdx, long aColIdx, IUnknown** aCell) { if (!aCell) return E_INVALIDARG; *aCell = nullptr; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; AccessibleWrap* cell = - static_cast<AccessibleWrap*>(table->CellAt(aRowIdx, aColIdx)); + static_cast<AccessibleWrap*>(mTable->CellAt(aRowIdx, aColIdx)); if (!cell) return E_INVALIDARG; - RefPtr<IAccessible> result; - cell->GetNativeInterface(getter_AddRefs(result)); - result.forget(aCell); + (*aCell = static_cast<IAccessible*>(cell))->AddRef(); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_nSelectedCells(long* aCellCount) { if (!aCellCount) return E_INVALIDARG; *aCellCount = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; - *aCellCount = table->SelectedCellCount(); + *aCellCount = mTable->SelectedCellCount(); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_selectedCells(IUnknown*** aCells, long* aNSelectedCells) { if (!aCells || !aNSelectedCells) return E_INVALIDARG; *aCells = nullptr; *aNSelectedCells = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; AutoTArray<LocalAccessible*, 30> cells; - table->SelectedCells(&cells); + mTable->SelectedCells(&cells); if (cells.IsEmpty()) return S_FALSE; *aCells = static_cast<IUnknown**>( ::CoTaskMemAlloc(sizeof(IUnknown*) * cells.Length())); if (!*aCells) return E_OUTOFMEMORY; for (uint32_t i = 0; i < cells.Length(); i++) { - RefPtr<IAccessible> cell; - cells[i]->GetNativeInterface(getter_AddRefs(cell)); - cell.forget(&(*aCells)[i]); + (*aCells)[i] = + static_cast<IAccessible*>(static_cast<AccessibleWrap*>(cells[i])); + ((*aCells)[i])->AddRef(); } *aNSelectedCells = cells.Length(); return S_OK; } STDMETHODIMP ia2AccessibleTable::get_selectedColumns(long** aColumns, long* aNColumns) { if (!aColumns || !aNColumns) return E_INVALIDARG; *aColumns = nullptr; *aNColumns = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; AutoTArray<uint32_t, 30> colIndices; - table->SelectedColIndices(&colIndices); + mTable->SelectedColIndices(&colIndices); uint32_t maxCols = colIndices.Length(); if (maxCols == 0) return S_FALSE; *aColumns = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxCols)); *aNColumns = maxCols; for (uint32_t i = 0; i < maxCols; i++) (*aColumns)[i] = colIndices[i]; @@ -548,21 +519,20 @@ ia2AccessibleTable::get_selectedColumns( } STDMETHODIMP ia2AccessibleTable::get_selectedRows(long** aRows, long* aNRows) { if (!aRows || !aNRows) return E_INVALIDARG; *aRows = nullptr; *aNRows = 0; - TableAccessible* table = TableAcc(); - if (!table) return CO_E_OBJNOTCONNECTED; + if (!mTable) return CO_E_OBJNOTCONNECTED; AutoTArray<uint32_t, 30> rowIndices; - table->SelectedRowIndices(&rowIndices); + mTable->SelectedRowIndices(&rowIndices); uint32_t maxRows = rowIndices.Length(); if (maxRows == 0) return S_FALSE; *aRows = static_cast<LONG*>(moz_xmalloc(sizeof(LONG) * maxRows)); *aNRows = maxRows; for (uint32_t i = 0; i < maxRows; i++) (*aRows)[i] = rowIndices[i];
--- a/accessible/windows/ia2/ia2AccessibleTable.h +++ b/accessible/windows/ia2/ia2AccessibleTable.h @@ -159,17 +159,14 @@ class ia2AccessibleTable : public IAcces virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_selectedRows( /* [out, size_is(,*nRows)] */ long** selectedRows, /* [out, retval] */ long* nRows); protected: ia2AccessibleTable(TableAccessible* aTable) : mTable(aTable) {} TableAccessible* mTable; - - private: - TableAccessible* TableAcc() { return mTable; } }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/ia2/ia2AccessibleTableCell.cpp +++ b/accessible/windows/ia2/ia2AccessibleTableCell.cpp @@ -40,160 +40,148 @@ ia2AccessibleTableCell::QueryInterface(R //////////////////////////////////////////////////////////////////////////////// // IAccessibleTableCell STDMETHODIMP ia2AccessibleTableCell::get_table(IUnknown** aTable) { if (!aTable) return E_INVALIDARG; *aTable = nullptr; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; - TableAccessible* table = tableCell->Table(); + TableAccessible* table = mTableCell->Table(); if (!table) return E_FAIL; AccessibleWrap* wrap = static_cast<AccessibleWrap*>(table->AsAccessible()); - RefPtr<IAccessibleTable> result; - wrap->GetNativeInterface(getter_AddRefs(result)); - result.forget(aTable); + *aTable = static_cast<IAccessible*>(wrap); + (*aTable)->AddRef(); return S_OK; } STDMETHODIMP ia2AccessibleTableCell::get_columnExtent(long* aSpan) { if (!aSpan) return E_INVALIDARG; *aSpan = 0; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; - *aSpan = tableCell->ColExtent(); + *aSpan = mTableCell->ColExtent(); return S_OK; } STDMETHODIMP ia2AccessibleTableCell::get_columnHeaderCells(IUnknown*** aCellAccessibles, long* aNColumnHeaderCells) { if (!aCellAccessibles || !aNColumnHeaderCells) return E_INVALIDARG; *aCellAccessibles = nullptr; *aNColumnHeaderCells = 0; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; AutoTArray<LocalAccessible*, 10> cells; - tableCell->ColHeaderCells(&cells); + mTableCell->ColHeaderCells(&cells); *aNColumnHeaderCells = cells.Length(); *aCellAccessibles = static_cast<IUnknown**>( ::CoTaskMemAlloc(sizeof(IUnknown*) * cells.Length())); if (!*aCellAccessibles) return E_OUTOFMEMORY; for (uint32_t i = 0; i < cells.Length(); i++) { AccessibleWrap* cell = static_cast<AccessibleWrap*>(cells[i]); - RefPtr<IAccessible> iaCell; - cell->GetNativeInterface(getter_AddRefs(iaCell)); - iaCell.forget(&(*aCellAccessibles)[i]); + (*aCellAccessibles)[i] = static_cast<IAccessible*>(cell); + (*aCellAccessibles)[i]->AddRef(); } return S_OK; } STDMETHODIMP ia2AccessibleTableCell::get_columnIndex(long* aColIdx) { if (!aColIdx) return E_INVALIDARG; *aColIdx = -1; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; - *aColIdx = tableCell->ColIdx(); + *aColIdx = mTableCell->ColIdx(); return S_OK; } STDMETHODIMP ia2AccessibleTableCell::get_rowExtent(long* aSpan) { if (!aSpan) return E_INVALIDARG; *aSpan = 0; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; - *aSpan = tableCell->RowExtent(); + *aSpan = mTableCell->RowExtent(); return S_OK; } STDMETHODIMP ia2AccessibleTableCell::get_rowHeaderCells(IUnknown*** aCellAccessibles, long* aNRowHeaderCells) { if (!aCellAccessibles || !aNRowHeaderCells) return E_INVALIDARG; *aCellAccessibles = nullptr; *aNRowHeaderCells = 0; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; AutoTArray<LocalAccessible*, 10> cells; - tableCell->RowHeaderCells(&cells); + mTableCell->RowHeaderCells(&cells); *aNRowHeaderCells = cells.Length(); *aCellAccessibles = static_cast<IUnknown**>( ::CoTaskMemAlloc(sizeof(IUnknown*) * cells.Length())); if (!*aCellAccessibles) return E_OUTOFMEMORY; for (uint32_t i = 0; i < cells.Length(); i++) { AccessibleWrap* cell = static_cast<AccessibleWrap*>(cells[i]); - RefPtr<IAccessible> iaCell; - cell->GetNativeInterface(getter_AddRefs(iaCell)); - iaCell.forget(&(*aCellAccessibles)[i]); + (*aCellAccessibles)[i] = static_cast<IAccessible*>(cell); + (*aCellAccessibles)[i]->AddRef(); } return S_OK; } STDMETHODIMP ia2AccessibleTableCell::get_rowIndex(long* aRowIdx) { if (!aRowIdx) return E_INVALIDARG; *aRowIdx = -1; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; - *aRowIdx = tableCell->RowIdx(); + *aRowIdx = mTableCell->RowIdx(); return S_OK; } STDMETHODIMP ia2AccessibleTableCell::get_rowColumnExtents(long* aRowIdx, long* aColIdx, long* aRowExtents, long* aColExtents, boolean* aIsSelected) { if (!aRowIdx || !aColIdx || !aRowExtents || !aColExtents || !aIsSelected) return E_INVALIDARG; *aRowIdx = *aColIdx = *aRowExtents = *aColExtents = 0; *aIsSelected = false; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; - *aRowIdx = tableCell->RowIdx(); - *aColIdx = tableCell->ColIdx(); - *aRowExtents = tableCell->RowExtent(); - *aColExtents = tableCell->ColExtent(); - *aIsSelected = tableCell->Selected(); + *aRowIdx = mTableCell->RowIdx(); + *aColIdx = mTableCell->ColIdx(); + *aRowExtents = mTableCell->RowExtent(); + *aColExtents = mTableCell->ColExtent(); + *aIsSelected = mTableCell->Selected(); return S_OK; } STDMETHODIMP ia2AccessibleTableCell::get_isSelected(boolean* aIsSelected) { if (!aIsSelected) return E_INVALIDARG; *aIsSelected = false; - TableCellAccessible* tableCell = CellAcc(); - if (!tableCell) return CO_E_OBJNOTCONNECTED; + if (!mTableCell) return CO_E_OBJNOTCONNECTED; - *aIsSelected = tableCell->Selected(); + *aIsSelected = mTableCell->Selected(); return S_OK; }
--- a/accessible/windows/ia2/ia2AccessibleTableCell.h +++ b/accessible/windows/ia2/ia2AccessibleTableCell.h @@ -54,17 +54,14 @@ class ia2AccessibleTableCell : public IA virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_isSelected( /* [out, retval] */ boolean* isSelected); protected: ia2AccessibleTableCell(TableCellAccessible* aTableCell) : mTableCell(aTableCell) {} TableCellAccessible* mTableCell; - - private: - TableCellAccessible* CellAcc() { return mTableCell; } }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/ia2/ia2AccessibleText.cpp +++ b/accessible/windows/ia2/ia2AccessibleText.cpp @@ -1,16 +1,15 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:expandtab:shiftwidth=2:tabstop=2: */ /* 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 "ia2Accessible.h" #include "ia2AccessibleText.h" #include "AccessibleText_i.c" #include "HyperTextAccessibleWrap.h" #include "HyperTextAccessible-inl.h" #include "ProxyWrappers.h" #include "mozilla/ClearOnShutdown.h" @@ -18,76 +17,69 @@ using namespace mozilla::a11y; StaticRefPtr<HyperTextAccessibleWrap> ia2AccessibleText::sLastTextChangeAcc; StaticAutoPtr<nsString> ia2AccessibleText::sLastTextChangeString; uint32_t ia2AccessibleText::sLastTextChangeStart = 0; uint32_t ia2AccessibleText::sLastTextChangeEnd = 0; bool ia2AccessibleText::sLastTextChangeWasInsert = false; -HyperTextAccessibleWrap* ia2AccessibleText::TextAcc() { - // XXX This first static_cast is a necessary hack until we get rid of the - // inheritance of HyperTextAccessibleWrap. - auto wrap = static_cast<HyperTextAccessibleWrap*>(this); - AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc(); - return static_cast<HyperTextAccessibleWrap*>(acc); -} - // IAccessibleText STDMETHODIMP ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; return textAcc->AddToSelection(aStartOffset, aEndOffset) ? S_OK : E_INVALIDARG; } STDMETHODIMP ia2AccessibleText::get_attributes(long aOffset, long* aStartOffset, long* aEndOffset, BSTR* aTextAttributes) { if (!aStartOffset || !aEndOffset || !aTextAttributes) return E_INVALIDARG; *aStartOffset = 0; *aEndOffset = 0; *aTextAttributes = nullptr; int32_t startOffset = 0, endOffset = 0; HRESULT hr; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) { + MOZ_ASSERT(!HyperTextProxyFor(this)); + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - MOZ_ASSERT(!textAcc->IsProxy()); nsCOMPtr<nsIPersistentProperties> attributes = textAcc->TextAttributes(true, aOffset, &startOffset, &endOffset); - hr = ia2Accessible::ConvertToIA2Attributes(attributes, aTextAttributes); + hr = AccessibleWrap::ConvertToIA2Attributes(attributes, aTextAttributes); if (FAILED(hr)) return hr; *aStartOffset = startOffset; *aEndOffset = endOffset; return S_OK; } STDMETHODIMP ia2AccessibleText::get_caretOffset(long* aOffset) { if (!aOffset) return E_INVALIDARG; *aOffset = -1; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) { + MOZ_ASSERT(!HyperTextProxyFor(this)); + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - MOZ_ASSERT(!textAcc->IsProxy()); *aOffset = textAcc->CaretOffset(); return *aOffset != -1 ? S_OK : S_FALSE; } STDMETHODIMP ia2AccessibleText::get_characterExtents(long aOffset, @@ -97,40 +89,40 @@ ia2AccessibleText::get_characterExtents( if (!aX || !aY || !aWidth || !aHeight) return E_INVALIDARG; *aX = *aY = *aWidth = *aHeight = 0; uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; nsIntRect rect; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; rect = textAcc->CharBounds(aOffset, geckoCoordType); // Can't use GetRect() because of long vs. int32_t mismatch *aX = rect.X(); *aY = rect.Y(); *aWidth = rect.Width(); *aHeight = rect.Height(); return S_OK; } STDMETHODIMP ia2AccessibleText::get_nSelections(long* aNSelections) { if (!aNSelections) return E_INVALIDARG; *aNSelections = 0; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) { + MOZ_ASSERT(!HyperTextProxyFor(this)); + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - MOZ_ASSERT(!textAcc->IsProxy()); *aNSelections = textAcc->SelectionCount(); return S_OK; } STDMETHODIMP ia2AccessibleText::get_offsetAtPoint(long aX, long aY, @@ -139,39 +131,39 @@ ia2AccessibleText::get_offsetAtPoint(lon if (!aOffset) return E_INVALIDARG; *aOffset = 0; uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) { + MOZ_ASSERT(!HyperTextProxyFor(this)); + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - MOZ_ASSERT(!textAcc->IsProxy()); *aOffset = textAcc->OffsetAtPoint(aX, aY, geckoCoordType); return *aOffset == -1 ? S_FALSE : S_OK; } STDMETHODIMP ia2AccessibleText::get_selection(long aSelectionIndex, long* aStartOffset, long* aEndOffset) { if (!aStartOffset || !aEndOffset) return E_INVALIDARG; *aStartOffset = *aEndOffset = 0; int32_t startOffset = 0, endOffset = 0; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) { + MOZ_ASSERT(!HyperTextProxyFor(this)); + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - MOZ_ASSERT(!textAcc->IsProxy()); if (!textAcc->SelectionBoundsAt(aSelectionIndex, &startOffset, &endOffset)) { return E_INVALIDARG; } *aStartOffset = startOffset; *aEndOffset = endOffset; return S_OK; @@ -179,21 +171,21 @@ ia2AccessibleText::get_selection(long aS STDMETHODIMP ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR* aText) { if (!aText) return E_INVALIDARG; *aText = nullptr; nsAutoString text; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) { + MOZ_ASSERT(!HyperTextProxyFor(this)); + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - MOZ_ASSERT(!textAcc->IsProxy()); if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) { return E_INVALIDARG; } textAcc->TextSubstring(aStartOffset, aEndOffset, text); if (text.IsEmpty()) return S_FALSE; @@ -207,18 +199,18 @@ ia2AccessibleText::get_textBeforeOffset( enum IA2TextBoundaryType aBoundaryType, long* aStartOffset, long* aEndOffset, BSTR* aText) { if (!aStartOffset || !aEndOffset || !aText) return E_INVALIDARG; *aStartOffset = *aEndOffset = 0; *aText = nullptr; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidOffset(aOffset)) return E_INVALIDARG; nsAutoString text; int32_t startOffset = 0, endOffset = 0; if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) { startOffset = 0; @@ -247,18 +239,18 @@ ia2AccessibleText::get_textAfterOffset(l long* aStartOffset, long* aEndOffset, BSTR* aText) { if (!aStartOffset || !aEndOffset || !aText) return E_INVALIDARG; *aStartOffset = 0; *aEndOffset = 0; *aText = nullptr; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidOffset(aOffset)) return E_INVALIDARG; nsAutoString text; int32_t startOffset = 0, endOffset = 0; if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) { startOffset = 0; @@ -285,18 +277,18 @@ ia2AccessibleText::get_textAtOffset(long enum IA2TextBoundaryType aBoundaryType, long* aStartOffset, long* aEndOffset, BSTR* aText) { if (!aStartOffset || !aEndOffset || !aText) return E_INVALIDARG; *aStartOffset = *aEndOffset = 0; *aText = nullptr; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidOffset(aOffset)) return E_INVALIDARG; nsAutoString text; int32_t startOffset = 0, endOffset = 0; if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) { startOffset = 0; endOffset = textAcc->CharacterCount(); @@ -314,86 +306,92 @@ ia2AccessibleText::get_textAtOffset(long if (text.IsEmpty()) return S_FALSE; *aText = ::SysAllocStringLen(text.get(), text.Length()); return *aText ? S_OK : E_OUTOFMEMORY; } STDMETHODIMP ia2AccessibleText::removeSelection(long aSelectionIndex) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; return textAcc->RemoveFromSelection(aSelectionIndex) ? S_OK : E_INVALIDARG; } STDMETHODIMP ia2AccessibleText::setCaretOffset(long aOffset) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidOffset(aOffset)) return E_INVALIDARG; textAcc->SetCaretOffset(aOffset); return S_OK; } STDMETHODIMP ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset, long aEndOffset) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; return textAcc->SetSelectionBoundsAt(aSelectionIndex, aStartOffset, aEndOffset) ? S_OK : E_INVALIDARG; } STDMETHODIMP ia2AccessibleText::get_nCharacters(long* aNCharacters) { if (!aNCharacters) return E_INVALIDARG; *aNCharacters = 0; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; *aNCharacters = textAcc->CharacterCount(); return S_OK; } STDMETHODIMP ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex, enum IA2ScrollType aScrollType) { - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidRange(aStartIndex, aEndIndex)) return E_INVALIDARG; textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType); return S_OK; } STDMETHODIMP ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex, enum IA2CoordinateType aCoordType, long aX, long aY) { uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; - HyperTextAccessible* textAcc = TextAcc(); - if (!textAcc) return CO_E_OBJNOTCONNECTED; - MOZ_ASSERT(!textAcc->IsProxy()); + MOZ_ASSERT(!HyperTextProxyFor(this)); + + HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this); + if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (!textAcc->IsValidRange(aStartIndex, aEndIndex)) return E_INVALIDARG; textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex, geckoCoordType, aX, aY); return S_OK; } @@ -413,17 +411,17 @@ HRESULT ia2AccessibleText::GetModifiedText(bool aGetInsertedText, IA2TextSegment* aText) { if (!aText) return E_INVALIDARG; if (!sLastTextChangeAcc) return S_OK; if (aGetInsertedText != sLastTextChangeWasInsert) return S_OK; - if (sLastTextChangeAcc != TextAcc()) return S_OK; + if (sLastTextChangeAcc != this) return S_OK; aText->start = sLastTextChangeStart; aText->end = sLastTextChangeEnd; if (sLastTextChangeString->IsEmpty()) return S_FALSE; aText->text = ::SysAllocStringLen(sLastTextChangeString->get(), sLastTextChangeString->Length());
--- a/accessible/windows/ia2/ia2AccessibleText.h +++ b/accessible/windows/ia2/ia2AccessibleText.h @@ -121,17 +121,16 @@ class ia2AccessibleText : public IAccess static bool sLastTextChangeWasInsert; static uint32_t sLastTextChangeStart; static uint32_t sLastTextChangeEnd; private: HRESULT GetModifiedText(bool aGetInsertedText, IA2TextSegment* aNewText); AccessibleTextBoundary GetGeckoTextBoundary( enum IA2TextBoundaryType coordinateType); - HyperTextAccessibleWrap* TextAcc(); }; } // namespace a11y } // namespace mozilla #define FORWARD_IACCESSIBLETEXT(Class) \ virtual HRESULT STDMETHODCALLTYPE addSelection(long startOffset, \ long endOffset) { \
--- a/accessible/windows/ia2/ia2AccessibleValue.cpp +++ b/accessible/windows/ia2/ia2AccessibleValue.cpp @@ -12,33 +12,29 @@ #include "AccessibleWrap.h" #include "LocalAccessible-inl.h" #include "IUnknownImpl.h" #include "mozilla/FloatingPoint.h" using namespace mozilla::a11y; -AccessibleWrap* ia2AccessibleValue::LocalAcc() { - return static_cast<MsaaAccessible*>(this)->LocalAcc(); -} - // IUnknown STDMETHODIMP ia2AccessibleValue::QueryInterface(REFIID iid, void** ppv) { if (!ppv) return E_INVALIDARG; *ppv = nullptr; if (IID_IAccessibleValue == iid) { - AccessibleWrap* valueAcc = LocalAcc(); - if (valueAcc && valueAcc->HasNumericValue()) { - RefPtr<IAccessibleValue> result = this; - result.forget(ppv); + AccessibleWrap* valueAcc = static_cast<AccessibleWrap*>(this); + if (valueAcc->HasNumericValue()) { + *ppv = static_cast<IAccessibleValue*>(this); + valueAcc->AddRef(); return S_OK; } return E_NOINTERFACE; } return E_NOINTERFACE; } @@ -46,79 +42,78 @@ ia2AccessibleValue::QueryInterface(REFII // IAccessibleValue STDMETHODIMP ia2AccessibleValue::get_currentValue(VARIANT* aCurrentValue) { if (!aCurrentValue) return E_INVALIDARG; VariantInit(aCurrentValue); - AccessibleWrap* valueAcc = LocalAcc(); - if (!valueAcc) { + AccessibleWrap* valueAcc = static_cast<AccessibleWrap*>(this); + double currentValue; + MOZ_ASSERT(!valueAcc->IsProxy()); + if (valueAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - double currentValue; - MOZ_ASSERT(!valueAcc->IsProxy()); currentValue = valueAcc->CurValue(); if (IsNaN(currentValue)) return S_FALSE; aCurrentValue->vt = VT_R8; aCurrentValue->dblVal = currentValue; return S_OK; } STDMETHODIMP ia2AccessibleValue::setCurrentValue(VARIANT aValue) { if (aValue.vt != VT_R8) return E_INVALIDARG; - AccessibleWrap* valueAcc = LocalAcc(); - if (!valueAcc) { - return CO_E_OBJNOTCONNECTED; - } + AccessibleWrap* valueAcc = static_cast<AccessibleWrap*>(this); MOZ_ASSERT(!valueAcc->IsProxy()); + if (valueAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; + return valueAcc->SetCurValue(aValue.dblVal) ? S_OK : E_FAIL; } STDMETHODIMP ia2AccessibleValue::get_maximumValue(VARIANT* aMaximumValue) { if (!aMaximumValue) return E_INVALIDARG; VariantInit(aMaximumValue); - AccessibleWrap* valueAcc = LocalAcc(); - if (!valueAcc) { + AccessibleWrap* valueAcc = static_cast<AccessibleWrap*>(this); + double maximumValue; + MOZ_ASSERT(!valueAcc->IsProxy()); + if (valueAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - double maximumValue; - MOZ_ASSERT(!valueAcc->IsProxy()); maximumValue = valueAcc->MaxValue(); if (IsNaN(maximumValue)) return S_FALSE; aMaximumValue->vt = VT_R8; aMaximumValue->dblVal = maximumValue; return S_OK; } STDMETHODIMP ia2AccessibleValue::get_minimumValue(VARIANT* aMinimumValue) { if (!aMinimumValue) return E_INVALIDARG; VariantInit(aMinimumValue); - AccessibleWrap* valueAcc = LocalAcc(); - if (!valueAcc) { + AccessibleWrap* valueAcc = static_cast<AccessibleWrap*>(this); + double minimumValue; + MOZ_ASSERT(!valueAcc->IsProxy()); + if (valueAcc->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } - double minimumValue; - MOZ_ASSERT(!valueAcc->IsProxy()); minimumValue = valueAcc->MinValue(); if (IsNaN(minimumValue)) return S_FALSE; aMinimumValue->vt = VT_R8; aMinimumValue->dblVal = minimumValue; return S_OK;
--- a/accessible/windows/ia2/ia2AccessibleValue.h +++ b/accessible/windows/ia2/ia2AccessibleValue.h @@ -7,17 +7,16 @@ #ifndef _ACCESSIBLE_VALUE_H #define _ACCESSIBLE_VALUE_H #include "AccessibleValue.h" namespace mozilla { namespace a11y { -class AccessibleWrap; class ia2AccessibleValue : public IAccessibleValue { public: // IUnknown STDMETHODIMP QueryInterface(REFIID, void**); // IAccessibleValue virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_currentValue( @@ -26,17 +25,14 @@ class ia2AccessibleValue : public IAcces virtual HRESULT STDMETHODCALLTYPE setCurrentValue( /* [in] */ VARIANT value); virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_maximumValue( /* [retval][out] */ VARIANT* maximumValue); virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_minimumValue( /* [retval][out] */ VARIANT* minimumValue); - - private: - AccessibleWrap* LocalAcc(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -1,47 +1,86 @@ /* -*- 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 "AccessibleWrap.h" +#include "LocalAccessible-inl.h" +#include "Compatibility.h" +#include "DocAccessible-inl.h" #include "mozilla/a11y/DocAccessibleParent.h" -#include "AccEvent.h" #include "EnumVariant.h" #include "GeckoCustom.h" #include "nsAccUtils.h" +#include "nsCoreUtils.h" #include "nsIAccessibleEvent.h" -#include "nsIWidget.h" #include "nsWindowsHelpers.h" +#include "nsWinUtils.h" #include "mozilla/a11y/RemoteAccessible.h" #include "ProxyWrappers.h" #include "ServiceProvider.h" +#include "Relation.h" +#include "Role.h" +#include "RootAccessible.h" #include "sdnAccessible.h" +#include "States.h" + +#ifdef A11Y_LOG +# include "Logging.h" +#endif +#include "nsIFrame.h" +#include "nsIScrollableFrame.h" +#include "mozilla/PresShell.h" +#include "mozilla/dom/NodeInfo.h" +#include "mozilla/dom/BrowserParent.h" +#include "nsNameSpaceManager.h" +#include "nsTextFormatter.h" +#include "nsView.h" +#include "nsViewManager.h" +#include "nsArrayUtils.h" +#include "mozilla/Preferences.h" +#include "mozilla/ReverseIterator.h" #include "mozilla/mscom/AsyncInvoker.h" +#include "oleacc.h" + using namespace mozilla; using namespace mozilla::a11y; +const uint32_t USE_ROLE_STRING = 0; + /* For documentation of the accessibility architecture, * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html */ +//#define DEBUG_LEAKS + +#ifdef DEBUG_LEAKS +static gAccessibles = 0; +#endif + StaticAutoPtr<nsTArray<AccessibleWrap::HandlerControllerData>> AccessibleWrap::sHandlerControllers; +static const VARIANT kVarChildIdSelf = {{{VT_I4}}}; + +static const int32_t kIEnumVariantDisconnected = -1; + //////////////////////////////////////////////////////////////////////////////// // AccessibleWrap //////////////////////////////////////////////////////////////////////////////// AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) : LocalAccessible(aContent, aDoc) {} +ITypeInfo* AccessibleWrap::gTypeInfo = nullptr; + NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, LocalAccessible) void AccessibleWrap::Shutdown() { MsaaShutdown(); LocalAccessible::Shutdown(); } //----------------------------------------------------- @@ -107,16 +146,841 @@ AccessibleWrap::QueryInterface(REFIID ii } if (nullptr == *ppv) return E_NOINTERFACE; (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); return S_OK; } +//----------------------------------------------------- +// IAccessible methods +//----------------------------------------------------- + +STDMETHODIMP +AccessibleWrap::get_accParent(IDispatch __RPC_FAR* __RPC_FAR* ppdispParent) { + if (!ppdispParent) return E_INVALIDARG; + + *ppdispParent = nullptr; + + if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + + LocalAccessible* xpParentAcc = LocalParent(); + if (!xpParentAcc) return S_FALSE; + + *ppdispParent = NativeAccessible(xpParentAcc); + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::get_accChildCount(long __RPC_FAR* pcountChildren) { + if (!pcountChildren) return E_INVALIDARG; + + *pcountChildren = 0; + + if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + + if (nsAccUtils::MustPrune(this)) return S_OK; + + *pcountChildren = ChildCount(); + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::get_accChild( + /* [in] */ VARIANT varChild, + /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispChild) { + if (!ppdispChild) return E_INVALIDARG; + + *ppdispChild = nullptr; + if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + + // IAccessible::accChild is used to return this accessible or child accessible + // at the given index or to get an accessible by child ID in the case of + // document accessible. + // The getting an accessible by child ID is used by + // AccessibleObjectFromEvent() called by AT when AT handles our MSAA event. + bool isDefunct = false; + RefPtr<IAccessible> child = GetIAccessibleFor(varChild, &isDefunct); + if (!child) { + return E_INVALIDARG; + } + + if (isDefunct) { + return CO_E_OBJNOTCONNECTED; + } + + child.forget(ppdispChild); + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::get_accName( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszName) { + if (!pszName || varChild.vt != VT_I4) return E_INVALIDARG; + + *pszName = nullptr; + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->get_accName(kVarChildIdSelf, pszName); + } + + nsAutoString name; + 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 + // attribute. Refer to eNoNameOnPurpose return value. + if (name.IsVoid()) return S_FALSE; + + *pszName = ::SysAllocStringLen(name.get(), name.Length()); + if (!*pszName) return E_OUTOFMEMORY; + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::get_accValue( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszValue) { + if (!pszValue) return E_INVALIDARG; + + *pszValue = nullptr; + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->get_accValue(kVarChildIdSelf, pszValue); + } + + nsAutoString value; + Value(value); + + // See bug 438784: need to expose URL on doc's value attribute. For this, + // reverting part of fix for bug 425693 to make this MSAA method behave + // IAccessible2-style. + if (value.IsEmpty()) return S_FALSE; + + *pszValue = ::SysAllocStringLen(value.get(), value.Length()); + if (!*pszValue) return E_OUTOFMEMORY; + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::get_accDescription(VARIANT varChild, + BSTR __RPC_FAR* pszDescription) { + if (!pszDescription) return E_INVALIDARG; + + *pszDescription = nullptr; + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->get_accDescription(kVarChildIdSelf, pszDescription); + } + + nsAutoString description; + Description(description); + + *pszDescription = + ::SysAllocStringLen(description.get(), description.Length()); + return *pszDescription ? S_OK : E_OUTOFMEMORY; +} + +STDMETHODIMP +AccessibleWrap::get_accRole( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ VARIANT __RPC_FAR* pvarRole) { + if (!pvarRole) return E_INVALIDARG; + + VariantInit(pvarRole); + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->get_accRole(kVarChildIdSelf, pvarRole); + } + + a11y::role geckoRole; +#ifdef DEBUG + NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(this), + "Does not support Text when it should"); +#endif + + geckoRole = Role(); + + uint32_t msaaRole = 0; + +#define ROLE(_geckoRole, stringRole, atkRole, macRole, macSubrole, _msaaRole, \ + ia2Role, androidClass, nameRule) \ + case roles::_geckoRole: \ + msaaRole = _msaaRole; \ + break; + + switch (geckoRole) { +#include "RoleMap.h" + default: + MOZ_CRASH("Unknown role."); + } + +#undef ROLE + + // 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) { + LocalAccessible* xpParent = LocalParent(); + if (xpParent && xpParent->Role() == roles::TREE_TABLE) + msaaRole = ROLE_SYSTEM_OUTLINEITEM; + } + + // -- Try enumerated role + if (msaaRole != USE_ROLE_STRING) { + pvarRole->vt = VT_I4; + pvarRole->lVal = msaaRole; // Normal enumerated role + return S_OK; + } + + // -- 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 + nsIContent* content = GetContent(); + if (!content) return E_FAIL; + + if (content->IsElement()) { + nsAutoString roleString; + // Try the role attribute. + content->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::role, + roleString); + + if (roleString.IsEmpty()) { + // No role attribute (or it is an empty string). + // Use the tag name. + dom::Document* document = content->GetUncomposedDoc(); + if (!document) return E_FAIL; + + dom::NodeInfo* nodeInfo = content->NodeInfo(); + nodeInfo->GetName(roleString); + + // Only append name space if different from that of current document. + if (!nodeInfo->NamespaceEquals(document->GetDefaultNamespaceID())) { + nsAutoString nameSpaceURI; + nodeInfo->GetNamespaceURI(nameSpaceURI); + roleString += u", "_ns + nameSpaceURI; + } + } + + if (!roleString.IsEmpty()) { + pvarRole->vt = VT_BSTR; + pvarRole->bstrVal = ::SysAllocString(roleString.get()); + return S_OK; + } + } + + return E_FAIL; +} + +STDMETHODIMP +AccessibleWrap::get_accState( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ VARIANT __RPC_FAR* pvarState) { + if (!pvarState) return E_INVALIDARG; + + VariantInit(pvarState); + pvarState->vt = VT_I4; + pvarState->lVal = 0; + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->get_accState(kVarChildIdSelf, pvarState); + } + + // MSAA only has 31 states and the lowest 31 bits of our state bit mask + // are the same states as MSAA. + // Note: we map the following Gecko states to different MSAA states: + // REQUIRED -> ALERT_LOW + // ALERT -> ALERT_MEDIUM + // INVALID -> ALERT_HIGH + // CHECKABLE -> MARQUEED + + uint64_t state = State(); + + uint32_t msaaState = 0; + nsAccUtils::To32States(state, &msaaState, nullptr); + pvarState->lVal = msaaState; + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::get_accHelp( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszHelp) { + if (!pszHelp) return E_INVALIDARG; + + *pszHelp = nullptr; + return S_FALSE; +} + +STDMETHODIMP +AccessibleWrap::get_accHelpTopic( + /* [out] */ BSTR __RPC_FAR* pszHelpFile, + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ long __RPC_FAR* pidTopic) { + if (!pszHelpFile || !pidTopic) return E_INVALIDARG; + + *pszHelpFile = nullptr; + *pidTopic = 0; + return S_FALSE; +} + +STDMETHODIMP +AccessibleWrap::get_accKeyboardShortcut( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszKeyboardShortcut) { + if (!pszKeyboardShortcut) return E_INVALIDARG; + *pszKeyboardShortcut = nullptr; + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->get_accKeyboardShortcut(kVarChildIdSelf, + pszKeyboardShortcut); + } + + KeyBinding keyBinding = AccessKey(); + if (keyBinding.IsEmpty()) keyBinding = KeyboardShortcut(); + + nsAutoString shortcut; + keyBinding.ToString(shortcut); + + *pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(), shortcut.Length()); + return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY; +} + +STDMETHODIMP +AccessibleWrap::get_accFocus( + /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) { + if (!pvarChild) return E_INVALIDARG; + + VariantInit(pvarChild); + + // clang-format off + // VT_EMPTY: None. This object does not have the keyboard focus itself + // and does not contain a child that has the keyboard focus. + // VT_I4: lVal is CHILDID_SELF. The object itself has the keyboard focus. + // VT_I4: lVal contains the child ID of the child element with the keyboard focus. + // VT_DISPATCH: pdispVal member is the address of the IDispatch interface + // for the child object with the keyboard focus. + // clang-format on + if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + + // Return the current IAccessible child that has focus + LocalAccessible* focusedAccessible = FocusedChild(); + + if (focusedAccessible == this) { + pvarChild->vt = VT_I4; + pvarChild->lVal = CHILDID_SELF; + } else if (focusedAccessible) { + pvarChild->vt = VT_DISPATCH; + pvarChild->pdispVal = NativeAccessible(focusedAccessible); + } else { + pvarChild->vt = VT_EMPTY; // No focus or focus is not a child + } + + return S_OK; +} + +/** + * This helper class implements IEnumVARIANT for a nsTArray containing + * accessible objects. + */ +class AccessibleEnumerator final : public IEnumVARIANT { + public: + explicit AccessibleEnumerator(const nsTArray<LocalAccessible*>& aArray) + : mArray(aArray.Clone()), mCurIndex(0) {} + AccessibleEnumerator(const AccessibleEnumerator& toCopy) + : mArray(toCopy.mArray.Clone()), mCurIndex(toCopy.mCurIndex) {} + ~AccessibleEnumerator() {} + + // IUnknown + DECL_IUNKNOWN + + // IEnumVARIANT + STDMETHODIMP Next(unsigned long celt, VARIANT FAR* rgvar, + unsigned long FAR* pceltFetched); + STDMETHODIMP Skip(unsigned long celt); + STDMETHODIMP Reset() { + mCurIndex = 0; + return S_OK; + } + STDMETHODIMP Clone(IEnumVARIANT FAR* FAR* ppenum); + + private: + nsTArray<LocalAccessible*> mArray; + uint32_t mCurIndex; +}; + +STDMETHODIMP +AccessibleEnumerator::QueryInterface(REFIID iid, void** ppvObject) { + if (iid == IID_IEnumVARIANT) { + *ppvObject = static_cast<IEnumVARIANT*>(this); + AddRef(); + return S_OK; + } + if (iid == IID_IUnknown) { + *ppvObject = static_cast<IUnknown*>(this); + AddRef(); + return S_OK; + } + + *ppvObject = nullptr; + return E_NOINTERFACE; +} + +STDMETHODIMP +AccessibleEnumerator::Next(unsigned long celt, VARIANT FAR* rgvar, + unsigned long FAR* pceltFetched) { + uint32_t length = mArray.Length(); + HRESULT hr = S_OK; + + // Can't get more elements than there are... + if (celt > length - mCurIndex) { + hr = S_FALSE; + celt = length - mCurIndex; + } + + // Copy the elements of the array into rgvar. + for (uint32_t i = 0; i < celt; ++i, ++mCurIndex) { + rgvar[i].vt = VT_DISPATCH; + rgvar[i].pdispVal = AccessibleWrap::NativeAccessible(mArray[mCurIndex]); + } + + if (pceltFetched) *pceltFetched = celt; + + return hr; +} + +STDMETHODIMP +AccessibleEnumerator::Clone(IEnumVARIANT FAR* FAR* ppenum) { + *ppenum = new AccessibleEnumerator(*this); + NS_ADDREF(*ppenum); + return S_OK; +} + +STDMETHODIMP +AccessibleEnumerator::Skip(unsigned long celt) { + uint32_t length = mArray.Length(); + // Check if we can skip the requested number of elements + if (celt > length - mCurIndex) { + mCurIndex = length; + return S_FALSE; + } + mCurIndex += celt; + return S_OK; +} + +/** + * This method is called when a client wants to know which children of a node + * are selected. Note that this method can only find selected children for + * accessible object which implement SelectAccessible. + * + * The VARIANT return value arguement is expected to either contain a single + * IAccessible or an IEnumVARIANT of IAccessibles. We return the IEnumVARIANT + * regardless of the number of children selected, unless there are none selected + * in which case we return an empty VARIANT. + * + * We get the selected options from the select's accessible object and wrap + * those in an AccessibleEnumerator which we then put in the return VARIANT. + * + * returns a VT_EMPTY VARIANT if: + * - there are no selected children for this object + * - the object is not the type that can have children selected + */ +STDMETHODIMP +AccessibleWrap::get_accSelection(VARIANT __RPC_FAR* pvarChildren) { + if (!pvarChildren) return E_INVALIDARG; + + VariantInit(pvarChildren); + pvarChildren->vt = VT_EMPTY; + + if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + + if (!IsSelect()) { + return S_OK; + } + + AutoTArray<LocalAccessible*, 10> selectedItems; + SelectedItems(&selectedItems); + uint32_t count = selectedItems.Length(); + if (count == 1) { + pvarChildren->vt = VT_DISPATCH; + pvarChildren->pdispVal = NativeAccessible(selectedItems[0]); + } else if (count > 1) { + RefPtr<AccessibleEnumerator> pEnum = + new AccessibleEnumerator(selectedItems); + AssociateCOMObjectForDisconnection(pEnum); + pvarChildren->vt = + VT_UNKNOWN; // this must be VT_UNKNOWN for an IEnumVARIANT + NS_ADDREF(pvarChildren->punkVal = pEnum); + } + // If count == 0, vt is already VT_EMPTY, so there's nothing else to do. + + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::get_accDefaultAction( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszDefaultAction) { + if (!pszDefaultAction) return E_INVALIDARG; + + *pszDefaultAction = nullptr; + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->get_accDefaultAction(kVarChildIdSelf, pszDefaultAction); + } + + nsAutoString defaultAction; + ActionNameAt(0, defaultAction); + + *pszDefaultAction = + ::SysAllocStringLen(defaultAction.get(), defaultAction.Length()); + return *pszDefaultAction ? S_OK : E_OUTOFMEMORY; +} + +STDMETHODIMP +AccessibleWrap::accSelect( + /* [in] */ long flagsSelect, + /* [optional][in] */ VARIANT varChild) { + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->accSelect(flagsSelect, kVarChildIdSelf); + } + + if (flagsSelect & SELFLAG_TAKEFOCUS) { + if (XRE_IsContentProcess()) { + // In this case we might have been invoked while the IPC MessageChannel is + // waiting on a sync reply. We cannot dispatch additional IPC while that + // is happening, so we dispatch TakeFocus from the main thread to + // guarantee that we are outside any IPC. + nsCOMPtr<nsIRunnable> runnable = mozilla::NewRunnableMethod( + "LocalAccessible::TakeFocus", this, &LocalAccessible::TakeFocus); + NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL); + return S_OK; + } + TakeFocus(); + return S_OK; + } + + if (flagsSelect & SELFLAG_TAKESELECTION) { + TakeSelection(); + return S_OK; + } + + if (flagsSelect & SELFLAG_ADDSELECTION) { + SetSelected(true); + return S_OK; + } + + if (flagsSelect & SELFLAG_REMOVESELECTION) { + SetSelected(false); + return S_OK; + } + + return E_FAIL; +} + +STDMETHODIMP +AccessibleWrap::accLocation( + /* [out] */ long __RPC_FAR* pxLeft, + /* [out] */ long __RPC_FAR* pyTop, + /* [out] */ long __RPC_FAR* pcxWidth, + /* [out] */ long __RPC_FAR* pcyHeight, + /* [optional][in] */ VARIANT varChild) { + if (!pxLeft || !pyTop || !pcxWidth || !pcyHeight) return E_INVALIDARG; + + *pxLeft = 0; + *pyTop = 0; + *pcxWidth = 0; + *pcyHeight = 0; + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, + kVarChildIdSelf); + } + + if (IsDefunct()) { + return CO_E_OBJNOTCONNECTED; + } + + nsIntRect rect = Bounds(); + + *pxLeft = rect.X(); + *pyTop = rect.Y(); + *pcxWidth = rect.Width(); + *pcyHeight = rect.Height(); + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::accNavigate( + /* [in] */ long navDir, + /* [optional][in] */ VARIANT varStart, + /* [retval][out] */ VARIANT __RPC_FAR* pvarEndUpAt) { + if (!pvarEndUpAt) return E_INVALIDARG; + + VariantInit(pvarEndUpAt); + + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varStart, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->accNavigate(navDir, kVarChildIdSelf, pvarEndUpAt); + } + + LocalAccessible* navAccessible = nullptr; + Maybe<RelationType> xpRelation; + +#define RELATIONTYPE(geckoType, stringType, atkType, msaaType, ia2Type) \ + case msaaType: \ + xpRelation.emplace(RelationType::geckoType); \ + break; + + switch (navDir) { + case NAVDIR_FIRSTCHILD: + if (IsProxy()) { + if (!nsAccUtils::MustPrune(Proxy())) { + navAccessible = WrapperFor(Proxy()->RemoteFirstChild()); + } + } else { + if (!nsAccUtils::MustPrune(this)) navAccessible = LocalFirstChild(); + } + break; + case NAVDIR_LASTCHILD: + if (IsProxy()) { + if (!nsAccUtils::MustPrune(Proxy())) { + navAccessible = WrapperFor(Proxy()->RemoteLastChild()); + } + } else { + if (!nsAccUtils::MustPrune(this)) navAccessible = LocalLastChild(); + } + break; + case NAVDIR_NEXT: + navAccessible = IsProxy() ? WrapperFor(Proxy()->RemoteNextSibling()) + : LocalNextSibling(); + break; + case NAVDIR_PREVIOUS: + navAccessible = IsProxy() ? WrapperFor(Proxy()->RemotePrevSibling()) + : LocalPrevSibling(); + break; + case NAVDIR_DOWN: + case NAVDIR_LEFT: + case NAVDIR_RIGHT: + case NAVDIR_UP: + return E_NOTIMPL; + + // MSAA relationship extensions to accNavigate +#include "RelationTypeMap.h" + + default: + return E_INVALIDARG; + } + +#undef RELATIONTYPE + + pvarEndUpAt->vt = VT_EMPTY; + + if (xpRelation) { + Relation rel = RelationByType(*xpRelation); + navAccessible = rel.Next(); + } + + if (!navAccessible) return E_FAIL; + + pvarEndUpAt->pdispVal = NativeAccessible(navAccessible); + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::accHitTest( + /* [in] */ long xLeft, + /* [in] */ long yTop, + /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) { + if (!pvarChild) return E_INVALIDARG; + + VariantInit(pvarChild); + + if (IsDefunct()) return CO_E_OBJNOTCONNECTED; + + LocalAccessible* accessible = LocalChildAtPoint( + xLeft, yTop, Accessible::EWhichChildAtPoint::DirectChild); + + // if we got a child + if (accessible) { + // if the child is us + if (accessible == this) { + pvarChild->vt = VT_I4; + pvarChild->lVal = CHILDID_SELF; + } else { // its not create a LocalAccessible for it. + pvarChild->vt = VT_DISPATCH; + pvarChild->pdispVal = NativeAccessible(accessible); + } + } else { + // no child at that point + pvarChild->vt = VT_EMPTY; + return S_FALSE; + } + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::accDoDefaultAction( + /* [optional][in] */ VARIANT varChild) { + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->accDoDefaultAction(kVarChildIdSelf); + } + + return DoAction(0) ? S_OK : E_INVALIDARG; +} + +STDMETHODIMP +AccessibleWrap::put_accName( + /* [optional][in] */ VARIANT varChild, + /* [in] */ BSTR szName) { + return E_NOTIMPL; +} + +STDMETHODIMP +AccessibleWrap::put_accValue( + /* [optional][in] */ VARIANT varChild, + /* [in] */ BSTR szValue) { + RefPtr<IAccessible> accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->put_accValue(kVarChildIdSelf, szValue); + } + + HyperTextAccessible* ht = AsHyperText(); + if (!ht) { + return E_NOTIMPL; + } + + uint32_t length = ::SysStringLen(szValue); + nsAutoString text(szValue, length); + ht->ReplaceText(text); + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// IDispatch + +STDMETHODIMP +AccessibleWrap::GetTypeInfoCount(UINT* pctinfo) { + if (!pctinfo) return E_INVALIDARG; + + *pctinfo = 1; + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { + if (!ppTInfo) return E_INVALIDARG; + + *ppTInfo = nullptr; + + if (iTInfo != 0) return DISP_E_BADINDEX; + + ITypeInfo* typeInfo = GetTI(lcid); + if (!typeInfo) return E_FAIL; + + typeInfo->AddRef(); + *ppTInfo = typeInfo; + + return S_OK; +} + +STDMETHODIMP +AccessibleWrap::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, + LCID lcid, DISPID* rgDispId) { + ITypeInfo* typeInfo = GetTI(lcid); + if (!typeInfo) return E_FAIL; + + HRESULT hr = DispGetIDsOfNames(typeInfo, rgszNames, cNames, rgDispId); + return hr; +} + +STDMETHODIMP +AccessibleWrap::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS* pDispParams, VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, UINT* puArgErr) { + ITypeInfo* typeInfo = GetTI(lcid); + if (!typeInfo) return E_FAIL; + + return typeInfo->Invoke(static_cast<IAccessible*>(this), dispIdMember, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + void AccessibleWrap::GetNativeInterface(void** aOutAccessible) { *aOutAccessible = static_cast<IAccessible*>(this); NS_ADDREF_THIS(); } //////////////////////////////////////////////////////////////////////////////// // LocalAccessible @@ -141,21 +1005,46 @@ nsresult AccessibleWrap::HandleAccEvent( UpdateSystemCaretFor(accessible); } MsaaAccessible::FireWinEvent(accessible, eventType); return NS_OK; } +DocRemoteAccessibleWrap* AccessibleWrap::DocProxyWrapper() const { + MOZ_ASSERT(IsProxy()); + + RemoteAccessible* proxy = Proxy(); + if (!proxy) { + return nullptr; + } + + AccessibleWrap* acc = WrapperFor(proxy->Document()); + MOZ_ASSERT(acc->IsDoc()); + + return static_cast<DocRemoteAccessibleWrap*>(acc); +} + //////////////////////////////////////////////////////////////////////////////// // AccessibleWrap //------- Helper methods --------- +IDispatch* AccessibleWrap::NativeAccessible(LocalAccessible* aAccessible) { + if (!aAccessible) { + NS_WARNING("Not passing in an aAccessible"); + return nullptr; + } + + IAccessible* msaaAccessible = nullptr; + aAccessible->GetNativeInterface(reinterpret_cast<void**>(&msaaAccessible)); + return static_cast<IDispatch*>(msaaAccessible); +} + bool AccessibleWrap::IsRootForHWND() { if (IsRoot()) { return true; } HWND thisHwnd = MsaaAccessible::GetHWNDFor(this); AccessibleWrap* parent = static_cast<AccessibleWrap*>(LocalParent()); MOZ_ASSERT(parent); HWND parentHwnd = MsaaAccessible::GetHWNDFor(parent); @@ -208,16 +1097,31 @@ void AccessibleWrap::UpdateSystemCaretFo ::ShowCaret(aCaretWnd); RECT windowRect; ::GetWindowRect(aCaretWnd, &windowRect); ::SetCaretPos(aCaretRect.X() - windowRect.left, aCaretRect.Y() - windowRect.top); } } +ITypeInfo* AccessibleWrap::GetTI(LCID lcid) { + if (gTypeInfo) return gTypeInfo; + + ITypeLib* typeLib = nullptr; + HRESULT hr = LoadRegTypeLib(LIBID_Accessibility, 1, 0, lcid, &typeLib); + if (FAILED(hr)) return nullptr; + + hr = typeLib->GetTypeInfoOfGuid(IID_IAccessible, &gTypeInfo); + typeLib->Release(); + + if (FAILED(hr)) return nullptr; + + return gTypeInfo; +} + /* static */ void AccessibleWrap::SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl) { MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread()); if (!sHandlerControllers) { sHandlerControllers = new nsTArray<HandlerControllerData>(); ClearOnShutdown(&sHandlerControllers);
--- a/accessible/windows/msaa/AccessibleWrap.h +++ b/accessible/windows/msaa/AccessibleWrap.h @@ -34,16 +34,124 @@ class AccessibleWrap : public LocalAcces AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc); // nsISupports NS_DECL_ISUPPORTS_INHERITED public: // IUnknown methods - see iunknown.h for documentation STDMETHODIMP QueryInterface(REFIID, void**) override; + // Return the registered OLE class ID of this object's CfDataObj. + CLSID GetClassID() const; + + public: // COM interface IAccessible + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent( + /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispParent) + override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChildCount( + /* [retval][out] */ long __RPC_FAR* pcountChildren) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChild( + /* [in] */ VARIANT varChild, + /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispChild) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accName( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszName) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accValue( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszValue) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accDescription( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszDescription) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accRole( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ VARIANT __RPC_FAR* pvarRole) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accState( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ VARIANT __RPC_FAR* pvarState) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accHelp( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszHelp) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accHelpTopic( + /* [out] */ BSTR __RPC_FAR* pszHelpFile, + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ long __RPC_FAR* pidTopic) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszKeyboardShortcut) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accFocus( + /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accSelection( + /* [retval][out] */ VARIANT __RPC_FAR* pvarChildren) override; + + virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accDefaultAction( + /* [optional][in] */ VARIANT varChild, + /* [retval][out] */ BSTR __RPC_FAR* pszDefaultAction) override; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE accSelect( + /* [in] */ long flagsSelect, + /* [optional][in] */ VARIANT varChild) override; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE accLocation( + /* [out] */ long __RPC_FAR* pxLeft, + /* [out] */ long __RPC_FAR* pyTop, + /* [out] */ long __RPC_FAR* pcxWidth, + /* [out] */ long __RPC_FAR* pcyHeight, + /* [optional][in] */ VARIANT varChild) override; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE accNavigate( + /* [in] */ long navDir, + /* [optional][in] */ VARIANT varStart, + /* [retval][out] */ VARIANT __RPC_FAR* pvarEndUpAt) override; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE accHitTest( + /* [in] */ long xLeft, + /* [in] */ long yTop, + /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) override; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE accDoDefaultAction( + /* [optional][in] */ VARIANT varChild) override; + + virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_accName( + /* [optional][in] */ VARIANT varChild, + /* [in] */ BSTR szName) override; + + virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_accValue( + /* [optional][in] */ VARIANT varChild, + /* [in] */ BSTR szValue) override; + + // IDispatch (support of scripting languages like VB) + virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override; + + virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, + ITypeInfo** ppTInfo) override; + + virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, LCID lcid, + DISPID* rgDispId) override; + + virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) override; + // LocalAccessible virtual nsresult HandleAccEvent(AccEvent* aEvent) override; virtual void Shutdown() override; // Helper methods /** * System caret support: update the Windows caret position. * The system caret works more universally than the MSAA caret @@ -62,26 +170,68 @@ class AccessibleWrap : public LocalAcces public: /** * Determine whether this is the root accessible for its HWND. */ bool IsRootForHWND(); virtual void GetNativeInterface(void** aOutAccessible) override; + static IDispatch* NativeAccessible(LocalAccessible* aAccessible); + static void SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl); static void InvalidateHandlers(); bool DispatchTextChangeToHandler(bool aIsInsert, const nsString& aText, int32_t aStart, uint32_t aLen); protected: virtual ~AccessibleWrap() = default; + /** + * Return the wrapper for the document's proxy. + */ + DocRemoteAccessibleWrap* DocProxyWrapper() const; + + /** + * Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it. + */ + static ITypeInfo* GetTI(LCID lcid); + + static ITypeInfo* gTypeInfo; + + enum navRelations { + NAVRELATION_CONTROLLED_BY = 0x1000, + NAVRELATION_CONTROLLER_FOR = 0x1001, + NAVRELATION_LABEL_FOR = 0x1002, + NAVRELATION_LABELLED_BY = 0x1003, + NAVRELATION_MEMBER_OF = 0x1004, + NAVRELATION_NODE_CHILD_OF = 0x1005, + NAVRELATION_FLOWS_TO = 0x1006, + NAVRELATION_FLOWS_FROM = 0x1007, + NAVRELATION_SUBWINDOW_OF = 0x1008, + NAVRELATION_EMBEDS = 0x1009, + NAVRELATION_EMBEDDED_BY = 0x100a, + NAVRELATION_POPUP_FOR = 0x100b, + NAVRELATION_PARENT_WINDOW_OF = 0x100c, + NAVRELATION_DEFAULT_BUTTON = 0x100d, + NAVRELATION_DESCRIBED_BY = 0x100e, + NAVRELATION_DESCRIPTION_FOR = 0x100f, + NAVRELATION_NODE_PARENT_OF = 0x1010, + NAVRELATION_CONTAINING_DOCUMENT = 0x1011, + NAVRELATION_CONTAINING_TAB_PANE = 0x1012, + NAVRELATION_CONTAINING_WINDOW = 0x1013, + NAVRELATION_CONTAINING_APPLICATION = 0x1014, + NAVRELATION_DETAILS = 0x1015, + NAVRELATION_DETAILS_FOR = 0x1016, + NAVRELATION_ERROR = 0x1017, + NAVRELATION_ERROR_FOR = 0x1018 + }; + struct HandlerControllerData final { HandlerControllerData(DWORD aPid, RefPtr<IHandlerControl>&& aCtrl) : mPid(aPid), mCtrl(std::move(aCtrl)) { mIsProxy = mozilla::mscom::IsProxy(mCtrl); } HandlerControllerData(HandlerControllerData&& aOther) : mPid(aOther.mPid),
--- a/accessible/windows/msaa/CompatibilityUIA.cpp +++ b/accessible/windows/msaa/CompatibilityUIA.cpp @@ -5,17 +5,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "Compatibility.h" #include "mozilla/ScopeExit.h" #include "mozilla/Telemetry.h" #include "mozilla/UniquePtrExtensions.h" #include "mozilla/WindowsVersion.h" -#include "nspr/prenv.h" #include "nsTHashMap.h" #include "nsTHashSet.h" #include "nsPrintfCString.h" #include "nsReadableUtils.h" #include "nsString.h" #include "nsTHashtable.h" #include "nsUnicharUtils.h"
--- a/accessible/windows/msaa/DocAccessibleWrap.cpp +++ b/accessible/windows/msaa/DocAccessibleWrap.cpp @@ -4,17 +4,16 @@ * 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 "DocAccessibleWrap.h" #include "Compatibility.h" #include "mozilla/PresShell.h" #include "mozilla/dom/BrowserChild.h" -#include "mozilla/dom/Document.h" #include "DocAccessibleChild.h" #include "nsWinUtils.h" #include "Role.h" #include "RootAccessible.h" #include "sdnDocAccessible.h" #include "Statistics.h" #include "nsIDocShell.h"
--- a/accessible/windows/msaa/EnumVariant.cpp +++ b/accessible/windows/msaa/EnumVariant.cpp @@ -26,17 +26,17 @@ ChildrenEnumVariant::Next(ULONG aCount, if (mAnchorAcc->IsDefunct() || mAnchorAcc->LocalChildAt(mCurIndex) != mCurAcc) return CO_E_OBJNOTCONNECTED; ULONG countFetched = 0; while (mCurAcc && countFetched < aCount) { VariantInit(aItems + countFetched); - IDispatch* accNative = MsaaAccessible::NativeAccessible(mCurAcc); + IDispatch* accNative = AccessibleWrap::NativeAccessible(mCurAcc); ++mCurIndex; mCurAcc = mAnchorAcc->LocalChildAt(mCurIndex); // Don't output the accessible and count it as having been fetched unless // it is non-null MOZ_ASSERT(accNative); if (!accNative) {
--- a/accessible/windows/msaa/MsaaAccessible.cpp +++ b/accessible/windows/msaa/MsaaAccessible.cpp @@ -1,51 +1,38 @@ /* -*- 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 "MsaaAccessible.h" -#include "mozilla/a11y/AccessibleWrap.h" -#include "mozilla/a11y/DocAccessibleParent.h" #include "mozilla/dom/BrowserBridgeParent.h" #include "mozilla/dom/BrowserParent.h" #include "mozilla/mscom/Interceptor.h" #include "nsEventMap.h" -#include "nsViewManager.h" #include "nsWinUtils.h" -#include "Relation.h" #include "sdnAccessible.h" using namespace mozilla; using namespace mozilla::a11y; -const uint32_t USE_ROLE_STRING = 0; -static const VARIANT kVarChildIdSelf = {{{VT_I4}}}; - MsaaIdGenerator MsaaAccessible::sIDGen; -ITypeInfo* MsaaAccessible::gTypeInfo = nullptr; MsaaAccessible::MsaaAccessible() : mID(kNoID) {} MsaaAccessible::~MsaaAccessible() { if (mID != kNoID) { sIDGen.ReleaseID(WrapNotNull(this)); } } void MsaaAccessible::MsaaShutdown() { if (mID != kNoID) { - // Don't use LocalAcc() here because it requires that the Accessible is - // not defunct. When shutting down, the Accessible might already be - // marked defunct. It's safe for us to call LocalAccessible::Document() here - // regardless. - auto localAcc = static_cast<AccessibleWrap*>(this); - auto doc = static_cast<DocAccessibleWrap*>(localAcc->Document()); + auto doc = static_cast<DocAccessibleWrap*>(LocalAcc()->Document()); // Accessibles can be shut down twice in some cases. When this happens, // doc will be null. if (doc) { doc->RemoveID(mID); } } if (XRE_IsContentProcess()) { @@ -246,18 +233,17 @@ void MsaaAccessible::FireWinEvent(LocalA AccessibleWrap::InvalidateHandlers(); } // Fire MSAA event for client area window. ::NotifyWinEvent(winEvent, hwnd, OBJID_CLIENT, childID); } AccessibleWrap* MsaaAccessible::LocalAcc() { - auto acc = static_cast<AccessibleWrap*>(this); - return acc->IsDefunct() ? nullptr : acc; + return static_cast<AccessibleWrap*>(this); } /** * This function is a helper for implementing IAccessible methods that accept * a Child ID as a parameter. If the child ID is CHILDID_SELF, the function * returns S_OK but a null *aOutInterface. Otherwise, *aOutInterface points * to the resolved IAccessible. * @@ -284,17 +270,17 @@ MsaaAccessible::ResolveChild(const VARIA IAccessible** aOutInterface) { MOZ_ASSERT(aOutInterface); *aOutInterface = nullptr; if (aVarChild.vt != VT_I4) { return E_INVALIDARG; } - if (!LocalAcc()) { + if (LocalAcc()->IsDefunct()) { return CO_E_OBJNOTCONNECTED; } if (aVarChild.lVal == CHILDID_SELF) { return S_OK; } bool isDefunct = false; @@ -376,22 +362,21 @@ already_AddRefed<IAccessible> MsaaAccess VARIANT varChild = aVarChild; MOZ_ASSERT(aIsDefunct); *aIsDefunct = false; RefPtr<IAccessible> result; AccessibleWrap* localAcc = LocalAcc(); - if (!localAcc) { - *aIsDefunct = true; - return nullptr; - } - if (varChild.lVal == CHILDID_SELF) { + *aIsDefunct = localAcc->IsDefunct(); + if (*aIsDefunct) { + return nullptr; + } localAcc->GetNativeInterface(getter_AddRefs(result)); if (result) { return result.forget(); } // If we're not a proxy, there's nothing more we can do to attempt to // resolve the IAccessible, so we just fail. if (!localAcc->IsProxy()) { return nullptr; @@ -586,869 +571,8 @@ already_AddRefed<IAccessible> MsaaAccess // QI can fail on rare occasions if the LocalAccessible dies after we // fetched disp but before we QI. NS_WARNING_ASSERTION(SUCCEEDED(hr), "QI failed on remote IDispatch"); return result.forget(); } return nullptr; } - -IDispatch* MsaaAccessible::NativeAccessible(LocalAccessible* aAccessible) { - if (!aAccessible) { - NS_WARNING("Not passing in an aAccessible"); - return nullptr; - } - - IAccessible* msaaAccessible = nullptr; - aAccessible->GetNativeInterface(reinterpret_cast<void**>(&msaaAccessible)); - return static_cast<IDispatch*>(msaaAccessible); -} - -ITypeInfo* MsaaAccessible::GetTI(LCID lcid) { - if (gTypeInfo) return gTypeInfo; - - ITypeLib* typeLib = nullptr; - HRESULT hr = LoadRegTypeLib(LIBID_Accessibility, 1, 0, lcid, &typeLib); - if (FAILED(hr)) return nullptr; - - hr = typeLib->GetTypeInfoOfGuid(IID_IAccessible, &gTypeInfo); - typeLib->Release(); - - if (FAILED(hr)) return nullptr; - - return gTypeInfo; -} - -// IAccessible methods - -STDMETHODIMP -MsaaAccessible::get_accParent(IDispatch __RPC_FAR* __RPC_FAR* ppdispParent) { - if (!ppdispParent) return E_INVALIDARG; - - *ppdispParent = nullptr; - - LocalAccessible* localAcc = LocalAcc(); - if (!localAcc) return CO_E_OBJNOTCONNECTED; - - LocalAccessible* xpParentAcc = localAcc->LocalParent(); - if (!xpParentAcc) return S_FALSE; - - *ppdispParent = NativeAccessible(xpParentAcc); - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::get_accChildCount(long __RPC_FAR* pcountChildren) { - if (!pcountChildren) return E_INVALIDARG; - - *pcountChildren = 0; - - LocalAccessible* localAcc = LocalAcc(); - if (!localAcc) return CO_E_OBJNOTCONNECTED; - - if (nsAccUtils::MustPrune(localAcc)) return S_OK; - - *pcountChildren = localAcc->ChildCount(); - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::get_accChild( - /* [in] */ VARIANT varChild, - /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispChild) { - if (!ppdispChild) return E_INVALIDARG; - - *ppdispChild = nullptr; - if (!LocalAcc()) return CO_E_OBJNOTCONNECTED; - - // IAccessible::accChild is used to return this accessible or child accessible - // at the given index or to get an accessible by child ID in the case of - // document accessible. - // The getting an accessible by child ID is used by - // AccessibleObjectFromEvent() called by AT when AT handles our MSAA event. - bool isDefunct = false; - RefPtr<IAccessible> child = GetIAccessibleFor(varChild, &isDefunct); - if (!child) { - return E_INVALIDARG; - } - - if (isDefunct) { - return CO_E_OBJNOTCONNECTED; - } - - child.forget(ppdispChild); - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::get_accName( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszName) { - if (!pszName || varChild.vt != VT_I4) return E_INVALIDARG; - - *pszName = nullptr; - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->get_accName(kVarChildIdSelf, pszName); - } - - nsAutoString name; - LocalAcc()->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 - // attribute. Refer to eNoNameOnPurpose return value. - if (name.IsVoid()) return S_FALSE; - - *pszName = ::SysAllocStringLen(name.get(), name.Length()); - if (!*pszName) return E_OUTOFMEMORY; - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::get_accValue( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszValue) { - if (!pszValue) return E_INVALIDARG; - - *pszValue = nullptr; - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->get_accValue(kVarChildIdSelf, pszValue); - } - - nsAutoString value; - LocalAcc()->Value(value); - - // See bug 438784: need to expose URL on doc's value attribute. For this, - // reverting part of fix for bug 425693 to make this MSAA method behave - // IAccessible2-style. - if (value.IsEmpty()) return S_FALSE; - - *pszValue = ::SysAllocStringLen(value.get(), value.Length()); - if (!*pszValue) return E_OUTOFMEMORY; - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::get_accDescription(VARIANT varChild, - BSTR __RPC_FAR* pszDescription) { - if (!pszDescription) return E_INVALIDARG; - - *pszDescription = nullptr; - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->get_accDescription(kVarChildIdSelf, pszDescription); - } - - nsAutoString description; - LocalAcc()->Description(description); - - *pszDescription = - ::SysAllocStringLen(description.get(), description.Length()); - return *pszDescription ? S_OK : E_OUTOFMEMORY; -} - -STDMETHODIMP -MsaaAccessible::get_accRole( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ VARIANT __RPC_FAR* pvarRole) { - if (!pvarRole) return E_INVALIDARG; - - VariantInit(pvarRole); - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->get_accRole(kVarChildIdSelf, pvarRole); - } - - a11y::role geckoRole; - LocalAccessible* localAcc = LocalAcc(); -#ifdef DEBUG - NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(localAcc), - "Does not support Text when it should"); -#endif - geckoRole = localAcc->Role(); - - uint32_t msaaRole = 0; - -#define ROLE(_geckoRole, stringRole, atkRole, macRole, macSubrole, _msaaRole, \ - ia2Role, androidClass, nameRule) \ - case roles::_geckoRole: \ - msaaRole = _msaaRole; \ - break; - - switch (geckoRole) { -#include "RoleMap.h" - default: - MOZ_CRASH("Unknown role."); - } - -#undef ROLE - - // 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) { - LocalAccessible* xpParent = localAcc->LocalParent(); - if (xpParent && xpParent->Role() == roles::TREE_TABLE) - msaaRole = ROLE_SYSTEM_OUTLINEITEM; - } - - // -- Try enumerated role - if (msaaRole != USE_ROLE_STRING) { - pvarRole->vt = VT_I4; - pvarRole->lVal = msaaRole; // Normal enumerated role - return S_OK; - } - - // -- 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 - nsIContent* content = localAcc->GetContent(); - if (!content) return E_FAIL; - - if (content->IsElement()) { - nsAutoString roleString; - // Try the role attribute. - content->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::role, - roleString); - - if (roleString.IsEmpty()) { - // No role attribute (or it is an empty string). - // Use the tag name. - dom::Document* document = content->GetUncomposedDoc(); - if (!document) return E_FAIL; - - dom::NodeInfo* nodeInfo = content->NodeInfo(); - nodeInfo->GetName(roleString); - - // Only append name space if different from that of current document. - if (!nodeInfo->NamespaceEquals(document->GetDefaultNamespaceID())) { - nsAutoString nameSpaceURI; - nodeInfo->GetNamespaceURI(nameSpaceURI); - roleString += u", "_ns + nameSpaceURI; - } - } - - if (!roleString.IsEmpty()) { - pvarRole->vt = VT_BSTR; - pvarRole->bstrVal = ::SysAllocString(roleString.get()); - return S_OK; - } - } - - return E_FAIL; -} - -STDMETHODIMP -MsaaAccessible::get_accState( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ VARIANT __RPC_FAR* pvarState) { - if (!pvarState) return E_INVALIDARG; - - VariantInit(pvarState); - pvarState->vt = VT_I4; - pvarState->lVal = 0; - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->get_accState(kVarChildIdSelf, pvarState); - } - - // MSAA only has 31 states and the lowest 31 bits of our state bit mask - // are the same states as MSAA. - // Note: we map the following Gecko states to different MSAA states: - // REQUIRED -> ALERT_LOW - // ALERT -> ALERT_MEDIUM - // INVALID -> ALERT_HIGH - // CHECKABLE -> MARQUEED - - uint64_t state = LocalAcc()->State(); - - uint32_t msaaState = 0; - nsAccUtils::To32States(state, &msaaState, nullptr); - pvarState->lVal = msaaState; - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::get_accHelp( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszHelp) { - if (!pszHelp) return E_INVALIDARG; - - *pszHelp = nullptr; - return S_FALSE; -} - -STDMETHODIMP -MsaaAccessible::get_accHelpTopic( - /* [out] */ BSTR __RPC_FAR* pszHelpFile, - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ long __RPC_FAR* pidTopic) { - if (!pszHelpFile || !pidTopic) return E_INVALIDARG; - - *pszHelpFile = nullptr; - *pidTopic = 0; - return S_FALSE; -} - -STDMETHODIMP -MsaaAccessible::get_accKeyboardShortcut( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszKeyboardShortcut) { - if (!pszKeyboardShortcut) return E_INVALIDARG; - *pszKeyboardShortcut = nullptr; - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->get_accKeyboardShortcut(kVarChildIdSelf, - pszKeyboardShortcut); - } - - LocalAccessible* localAcc = LocalAcc(); - KeyBinding keyBinding = localAcc->AccessKey(); - if (keyBinding.IsEmpty()) keyBinding = localAcc->KeyboardShortcut(); - - nsAutoString shortcut; - keyBinding.ToString(shortcut); - - *pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(), shortcut.Length()); - return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY; -} - -STDMETHODIMP -MsaaAccessible::get_accFocus( - /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) { - if (!pvarChild) return E_INVALIDARG; - - VariantInit(pvarChild); - - // clang-format off - // VT_EMPTY: None. This object does not have the keyboard focus itself - // and does not contain a child that has the keyboard focus. - // VT_I4: lVal is CHILDID_SELF. The object itself has the keyboard focus. - // VT_I4: lVal contains the child ID of the child element with the keyboard focus. - // VT_DISPATCH: pdispVal member is the address of the IDispatch interface - // for the child object with the keyboard focus. - // clang-format on - LocalAccessible* localAcc = LocalAcc(); - if (!localAcc) return CO_E_OBJNOTCONNECTED; - - // Return the current IAccessible child that has focus - LocalAccessible* focusedAccessible = localAcc->FocusedChild(); - - if (focusedAccessible == localAcc) { - pvarChild->vt = VT_I4; - pvarChild->lVal = CHILDID_SELF; - } else if (focusedAccessible) { - pvarChild->vt = VT_DISPATCH; - pvarChild->pdispVal = NativeAccessible(focusedAccessible); - } else { - pvarChild->vt = VT_EMPTY; // No focus or focus is not a child - } - - return S_OK; -} - -/** - * This helper class implements IEnumVARIANT for a nsTArray containing - * accessible objects. - */ -class AccessibleEnumerator final : public IEnumVARIANT { - public: - explicit AccessibleEnumerator(const nsTArray<LocalAccessible*>& aArray) - : mArray(aArray.Clone()), mCurIndex(0) {} - AccessibleEnumerator(const AccessibleEnumerator& toCopy) - : mArray(toCopy.mArray.Clone()), mCurIndex(toCopy.mCurIndex) {} - ~AccessibleEnumerator() {} - - // IUnknown - DECL_IUNKNOWN - - // IEnumVARIANT - STDMETHODIMP Next(unsigned long celt, VARIANT FAR* rgvar, - unsigned long FAR* pceltFetched); - STDMETHODIMP Skip(unsigned long celt); - STDMETHODIMP Reset() { - mCurIndex = 0; - return S_OK; - } - STDMETHODIMP Clone(IEnumVARIANT FAR* FAR* ppenum); - - private: - nsTArray<LocalAccessible*> mArray; - uint32_t mCurIndex; -}; - -STDMETHODIMP -AccessibleEnumerator::QueryInterface(REFIID iid, void** ppvObject) { - if (iid == IID_IEnumVARIANT) { - *ppvObject = static_cast<IEnumVARIANT*>(this); - AddRef(); - return S_OK; - } - if (iid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown*>(this); - AddRef(); - return S_OK; - } - - *ppvObject = nullptr; - return E_NOINTERFACE; -} - -STDMETHODIMP -AccessibleEnumerator::Next(unsigned long celt, VARIANT FAR* rgvar, - unsigned long FAR* pceltFetched) { - uint32_t length = mArray.Length(); - HRESULT hr = S_OK; - - // Can't get more elements than there are... - if (celt > length - mCurIndex) { - hr = S_FALSE; - celt = length - mCurIndex; - } - - // Copy the elements of the array into rgvar. - for (uint32_t i = 0; i < celt; ++i, ++mCurIndex) { - rgvar[i].vt = VT_DISPATCH; - rgvar[i].pdispVal = MsaaAccessible::NativeAccessible(mArray[mCurIndex]); - } - - if (pceltFetched) *pceltFetched = celt; - - return hr; -} - -STDMETHODIMP -AccessibleEnumerator::Clone(IEnumVARIANT FAR* FAR* ppenum) { - *ppenum = new AccessibleEnumerator(*this); - NS_ADDREF(*ppenum); - return S_OK; -} - -STDMETHODIMP -AccessibleEnumerator::Skip(unsigned long celt) { - uint32_t length = mArray.Length(); - // Check if we can skip the requested number of elements - if (celt > length - mCurIndex) { - mCurIndex = length; - return S_FALSE; - } - mCurIndex += celt; - return S_OK; -} - -/** - * This method is called when a client wants to know which children of a node - * are selected. Note that this method can only find selected children for - * accessible object which implement SelectAccessible. - * - * The VARIANT return value arguement is expected to either contain a single - * IAccessible or an IEnumVARIANT of IAccessibles. We return the IEnumVARIANT - * regardless of the number of children selected, unless there are none selected - * in which case we return an empty VARIANT. - * - * We get the selected options from the select's accessible object and wrap - * those in an AccessibleEnumerator which we then put in the return VARIANT. - * - * returns a VT_EMPTY VARIANT if: - * - there are no selected children for this object - * - the object is not the type that can have children selected - */ -STDMETHODIMP -MsaaAccessible::get_accSelection(VARIANT __RPC_FAR* pvarChildren) { - if (!pvarChildren) return E_INVALIDARG; - - VariantInit(pvarChildren); - pvarChildren->vt = VT_EMPTY; - - LocalAccessible* localAcc = LocalAcc(); - if (!localAcc) return CO_E_OBJNOTCONNECTED; - - if (!localAcc->IsSelect()) { - return S_OK; - } - - AutoTArray<LocalAccessible*, 10> selectedItems; - localAcc->SelectedItems(&selectedItems); - uint32_t count = selectedItems.Length(); - if (count == 1) { - pvarChildren->vt = VT_DISPATCH; - pvarChildren->pdispVal = NativeAccessible(selectedItems[0]); - } else if (count > 1) { - RefPtr<AccessibleEnumerator> pEnum = - new AccessibleEnumerator(selectedItems); - AssociateCOMObjectForDisconnection(pEnum); - pvarChildren->vt = - VT_UNKNOWN; // this must be VT_UNKNOWN for an IEnumVARIANT - NS_ADDREF(pvarChildren->punkVal = pEnum); - } - // If count == 0, vt is already VT_EMPTY, so there's nothing else to do. - - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::get_accDefaultAction( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszDefaultAction) { - if (!pszDefaultAction) return E_INVALIDARG; - - *pszDefaultAction = nullptr; - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->get_accDefaultAction(kVarChildIdSelf, pszDefaultAction); - } - - nsAutoString defaultAction; - LocalAcc()->ActionNameAt(0, defaultAction); - - *pszDefaultAction = - ::SysAllocStringLen(defaultAction.get(), defaultAction.Length()); - return *pszDefaultAction ? S_OK : E_OUTOFMEMORY; -} - -STDMETHODIMP -MsaaAccessible::accSelect( - /* [in] */ long flagsSelect, - /* [optional][in] */ VARIANT varChild) { - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->accSelect(flagsSelect, kVarChildIdSelf); - } - - LocalAccessible* localAcc = LocalAcc(); - if (flagsSelect & SELFLAG_TAKEFOCUS) { - if (XRE_IsContentProcess()) { - // In this case we might have been invoked while the IPC MessageChannel is - // waiting on a sync reply. We cannot dispatch additional IPC while that - // is happening, so we dispatch TakeFocus from the main thread to - // guarantee that we are outside any IPC. - nsCOMPtr<nsIRunnable> runnable = mozilla::NewRunnableMethod( - "LocalAccessible::TakeFocus", localAcc, &LocalAccessible::TakeFocus); - NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL); - return S_OK; - } - localAcc->TakeFocus(); - return S_OK; - } - - if (flagsSelect & SELFLAG_TAKESELECTION) { - localAcc->TakeSelection(); - return S_OK; - } - - if (flagsSelect & SELFLAG_ADDSELECTION) { - localAcc->SetSelected(true); - return S_OK; - } - - if (flagsSelect & SELFLAG_REMOVESELECTION) { - localAcc->SetSelected(false); - return S_OK; - } - - return E_FAIL; -} - -STDMETHODIMP -MsaaAccessible::accLocation( - /* [out] */ long __RPC_FAR* pxLeft, - /* [out] */ long __RPC_FAR* pyTop, - /* [out] */ long __RPC_FAR* pcxWidth, - /* [out] */ long __RPC_FAR* pcyHeight, - /* [optional][in] */ VARIANT varChild) { - if (!pxLeft || !pyTop || !pcxWidth || !pcyHeight) return E_INVALIDARG; - - *pxLeft = 0; - *pyTop = 0; - *pcxWidth = 0; - *pcyHeight = 0; - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, - kVarChildIdSelf); - } - - LocalAccessible* localAcc = LocalAcc(); - if (!localAcc) { - return CO_E_OBJNOTCONNECTED; - } - - nsIntRect rect = localAcc->Bounds(); - - *pxLeft = rect.X(); - *pyTop = rect.Y(); - *pcxWidth = rect.Width(); - *pcyHeight = rect.Height(); - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::accNavigate( - /* [in] */ long navDir, - /* [optional][in] */ VARIANT varStart, - /* [retval][out] */ VARIANT __RPC_FAR* pvarEndUpAt) { - if (!pvarEndUpAt) return E_INVALIDARG; - - VariantInit(pvarEndUpAt); - - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varStart, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->accNavigate(navDir, kVarChildIdSelf, pvarEndUpAt); - } - - LocalAccessible* localAcc = LocalAcc(); - LocalAccessible* navAccessible = nullptr; - Maybe<RelationType> xpRelation; - -#define RELATIONTYPE(geckoType, stringType, atkType, msaaType, ia2Type) \ - case msaaType: \ - xpRelation.emplace(RelationType::geckoType); \ - break; - - switch (navDir) { - case NAVDIR_FIRSTCHILD: - if (localAcc->IsProxy()) { - if (!nsAccUtils::MustPrune(localAcc->Proxy())) { - navAccessible = WrapperFor(localAcc->Proxy()->RemoteFirstChild()); - } - } else { - if (!nsAccUtils::MustPrune(localAcc)) - navAccessible = localAcc->LocalFirstChild(); - } - break; - case NAVDIR_LASTCHILD: - if (localAcc->IsProxy()) { - if (!nsAccUtils::MustPrune(localAcc->Proxy())) { - navAccessible = WrapperFor(localAcc->Proxy()->RemoteLastChild()); - } - } else { - if (!nsAccUtils::MustPrune(localAcc)) - navAccessible = localAcc->LocalLastChild(); - } - break; - case NAVDIR_NEXT: - navAccessible = localAcc->IsProxy() - ? WrapperFor(localAcc->Proxy()->RemoteNextSibling()) - : localAcc->LocalNextSibling(); - break; - case NAVDIR_PREVIOUS: - navAccessible = localAcc->IsProxy() - ? WrapperFor(localAcc->Proxy()->RemotePrevSibling()) - : localAcc->LocalPrevSibling(); - break; - case NAVDIR_DOWN: - case NAVDIR_LEFT: - case NAVDIR_RIGHT: - case NAVDIR_UP: - return E_NOTIMPL; - - // MSAA relationship extensions to accNavigate -#include "RelationTypeMap.h" - - default: - return E_INVALIDARG; - } - -#undef RELATIONTYPE - - pvarEndUpAt->vt = VT_EMPTY; - - if (xpRelation) { - Relation rel = localAcc->RelationByType(*xpRelation); - navAccessible = rel.Next(); - } - - if (!navAccessible) return E_FAIL; - - pvarEndUpAt->pdispVal = NativeAccessible(navAccessible); - pvarEndUpAt->vt = VT_DISPATCH; - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::accHitTest( - /* [in] */ long xLeft, - /* [in] */ long yTop, - /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) { - if (!pvarChild) return E_INVALIDARG; - - VariantInit(pvarChild); - - LocalAccessible* localAcc = LocalAcc(); - if (!localAcc) return CO_E_OBJNOTCONNECTED; - - LocalAccessible* accessible = localAcc->LocalChildAtPoint( - xLeft, yTop, Accessible::EWhichChildAtPoint::DirectChild); - - // if we got a child - if (accessible) { - // if the child is us - if (accessible == localAcc) { - pvarChild->vt = VT_I4; - pvarChild->lVal = CHILDID_SELF; - } else { // its not create a LocalAccessible for it. - pvarChild->vt = VT_DISPATCH; - pvarChild->pdispVal = NativeAccessible(accessible); - } - } else { - // no child at that point - pvarChild->vt = VT_EMPTY; - return S_FALSE; - } - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::accDoDefaultAction( - /* [optional][in] */ VARIANT varChild) { - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->accDoDefaultAction(kVarChildIdSelf); - } - - return LocalAcc()->DoAction(0) ? S_OK : E_INVALIDARG; -} - -STDMETHODIMP -MsaaAccessible::put_accName( - /* [optional][in] */ VARIANT varChild, - /* [in] */ BSTR szName) { - return E_NOTIMPL; -} - -STDMETHODIMP -MsaaAccessible::put_accValue( - /* [optional][in] */ VARIANT varChild, - /* [in] */ BSTR szValue) { - RefPtr<IAccessible> accessible; - HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); - if (FAILED(hr)) { - return hr; - } - - if (accessible) { - return accessible->put_accValue(kVarChildIdSelf, szValue); - } - - HyperTextAccessible* ht = LocalAcc()->AsHyperText(); - if (!ht) { - return E_NOTIMPL; - } - - uint32_t length = ::SysStringLen(szValue); - nsAutoString text(szValue, length); - ht->ReplaceText(text); - return S_OK; -} - -// IDispatch methods - -STDMETHODIMP -MsaaAccessible::GetTypeInfoCount(UINT* pctinfo) { - if (!pctinfo) return E_INVALIDARG; - - *pctinfo = 1; - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { - if (!ppTInfo) return E_INVALIDARG; - - *ppTInfo = nullptr; - - if (iTInfo != 0) return DISP_E_BADINDEX; - - ITypeInfo* typeInfo = GetTI(lcid); - if (!typeInfo) return E_FAIL; - - typeInfo->AddRef(); - *ppTInfo = typeInfo; - - return S_OK; -} - -STDMETHODIMP -MsaaAccessible::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, - LCID lcid, DISPID* rgDispId) { - ITypeInfo* typeInfo = GetTI(lcid); - if (!typeInfo) return E_FAIL; - - HRESULT hr = DispGetIDsOfNames(typeInfo, rgszNames, cNames, rgDispId); - return hr; -} - -STDMETHODIMP -MsaaAccessible::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, - DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr) { - ITypeInfo* typeInfo = GetTI(lcid); - if (!typeInfo) return E_FAIL; - - return typeInfo->Invoke(static_cast<IAccessible*>(this), dispIdMember, wFlags, - pDispParams, pVarResult, pExcepInfo, puArgErr); -}
--- a/accessible/windows/msaa/MsaaAccessible.h +++ b/accessible/windows/msaa/MsaaAccessible.h @@ -59,151 +59,33 @@ class MsaaAccessible : public ia2Accessi // collection is disabled there. if (XRE_IsContentProcess()) { mAssociatedCOMObjectsForDisconnection.AppendElement(aObject); } } void MsaaShutdown(); - static IDispatch* NativeAccessible(LocalAccessible* aAccessible); - - // IAccessible - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent( - /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispParent) - override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChildCount( - /* [retval][out] */ long __RPC_FAR* pcountChildren) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChild( - /* [in] */ VARIANT varChild, - /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispChild) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accName( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszName) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accValue( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszValue) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accDescription( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszDescription) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accRole( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ VARIANT __RPC_FAR* pvarRole) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accState( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ VARIANT __RPC_FAR* pvarState) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accHelp( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszHelp) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accHelpTopic( - /* [out] */ BSTR __RPC_FAR* pszHelpFile, - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ long __RPC_FAR* pidTopic) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszKeyboardShortcut) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accFocus( - /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accSelection( - /* [retval][out] */ VARIANT __RPC_FAR* pvarChildren) override; - virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accDefaultAction( - /* [optional][in] */ VARIANT varChild, - /* [retval][out] */ BSTR __RPC_FAR* pszDefaultAction) override; - virtual /* [id] */ HRESULT STDMETHODCALLTYPE accSelect( - /* [in] */ long flagsSelect, - /* [optional][in] */ VARIANT varChild) override; - virtual /* [id] */ HRESULT STDMETHODCALLTYPE accLocation( - /* [out] */ long __RPC_FAR* pxLeft, - /* [out] */ long __RPC_FAR* pyTop, - /* [out] */ long __RPC_FAR* pcxWidth, - /* [out] */ long __RPC_FAR* pcyHeight, - /* [optional][in] */ VARIANT varChild) override; - virtual /* [id] */ HRESULT STDMETHODCALLTYPE accNavigate( - /* [in] */ long navDir, - /* [optional][in] */ VARIANT varStart, - /* [retval][out] */ VARIANT __RPC_FAR* pvarEndUpAt) override; - virtual /* [id] */ HRESULT STDMETHODCALLTYPE accHitTest( - /* [in] */ long xLeft, - /* [in] */ long yTop, - /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) override; - virtual /* [id] */ HRESULT STDMETHODCALLTYPE accDoDefaultAction( - /* [optional][in] */ VARIANT varChild) override; - virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_accName( - /* [optional][in] */ VARIANT varChild, - /* [in] */ BSTR szName) override; - virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_accValue( - /* [optional][in] */ VARIANT varChild, - /* [in] */ BSTR szValue) override; - - // IDispatch (support of scripting languages like VB) - virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override; - virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, - ITypeInfo** ppTInfo) override; - virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, - LPOLESTR* rgszNames, - UINT cNames, LCID lcid, - DISPID* rgDispId) override; - virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, - LCID lcid, WORD wFlags, - DISPPARAMS* pDispParams, - VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, - UINT* puArgErr) override; - protected: virtual ~MsaaAccessible(); uint32_t mID; static MsaaIdGenerator sIDGen; HRESULT ResolveChild(const VARIANT& aVarChild, IAccessible** aOutInterface); - enum navRelations { - NAVRELATION_CONTROLLED_BY = 0x1000, - NAVRELATION_CONTROLLER_FOR = 0x1001, - NAVRELATION_LABEL_FOR = 0x1002, - NAVRELATION_LABELLED_BY = 0x1003, - NAVRELATION_MEMBER_OF = 0x1004, - NAVRELATION_NODE_CHILD_OF = 0x1005, - NAVRELATION_FLOWS_TO = 0x1006, - NAVRELATION_FLOWS_FROM = 0x1007, - NAVRELATION_SUBWINDOW_OF = 0x1008, - NAVRELATION_EMBEDS = 0x1009, - NAVRELATION_EMBEDDED_BY = 0x100a, - NAVRELATION_POPUP_FOR = 0x100b, - NAVRELATION_PARENT_WINDOW_OF = 0x100c, - NAVRELATION_DEFAULT_BUTTON = 0x100d, - NAVRELATION_DESCRIBED_BY = 0x100e, - NAVRELATION_DESCRIPTION_FOR = 0x100f, - NAVRELATION_NODE_PARENT_OF = 0x1010, - NAVRELATION_CONTAINING_DOCUMENT = 0x1011, - NAVRELATION_CONTAINING_TAB_PANE = 0x1012, - NAVRELATION_CONTAINING_WINDOW = 0x1013, - NAVRELATION_CONTAINING_APPLICATION = 0x1014, - NAVRELATION_DETAILS = 0x1015, - NAVRELATION_DETAILS_FOR = 0x1016, - NAVRELATION_ERROR = 0x1017, - NAVRELATION_ERROR_FOR = 0x1018 - }; - private: /** * Find a remote accessible by the given child ID. */ [[nodiscard]] already_AddRefed<IAccessible> GetRemoteIAccessibleFor( const VARIANT& aVarChild); nsTArray<RefPtr<IUnknown>> mAssociatedCOMObjectsForDisconnection; - - /** - * Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it. - */ - static ITypeInfo* GetTI(LCID lcid); - static ITypeInfo* gTypeInfo; }; } // namespace a11y } // namespace mozilla #ifdef XP_WIN // Undo the windows.h damage # undef GetMessage