Bug 1431256 part 2: AccessibleHandler: Implementation of IAccessible2 for text leaf accessibles using data provided in AccChildData. r?MarcoZ
For text leaf accessibles, the HandlerProvider::AllChildren property provides text and other necessary information in an AccChildData struct, rather than providing the full accessible object.
Therefore, we must provide a specific local implementation of IAccessible2 which answers queries based on the data provided in this struct.
MozReview-Commit-ID: 8BYMF59EoTe
new file mode 100644
--- /dev/null
+++ b/accessible/ipc/win/handler/HandlerTextLeaf.cpp
@@ -0,0 +1,402 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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/. */
+
+#if defined(MOZILLA_INTERNAL_API)
+#error This code is NOT for internal Gecko use!
+#endif // defined(MOZILLA_INTERNAL_API)
+
+#include "HandlerTextLeaf.h"
+#include "mozilla/Assertions.h"
+
+namespace mozilla {
+namespace a11y {
+
+HandlerTextLeaf::HandlerTextLeaf(IDispatch* aParent,
+ long aIndexInParent, HWND aHwnd,
+ AccChildData& aData)
+: mParent(aParent)
+, mIndexInParent(aIndexInParent)
+, mHwnd(aHwnd)
+, mData(aData)
+{
+ MOZ_ASSERT(aParent);
+}
+
+HandlerTextLeaf::~HandlerTextLeaf()
+{
+ if (mData.mText) {
+ ::SysFreeString(mData.mText);
+ }
+}
+
+IMPL_IUNKNOWN_QUERY_HEAD(HandlerTextLeaf)
+IMPL_IUNKNOWN_QUERY_IFACE(IDispatch)
+IMPL_IUNKNOWN_QUERY_IFACE(IAccessible)
+IMPL_IUNKNOWN_QUERY_IFACE(IAccessible2)
+IMPL_IUNKNOWN_QUERY_IFACE(IServiceProvider)
+IMPL_IUNKNOWN_QUERY_TAIL
+
+/*** IDispatch ***/
+
+HRESULT
+HandlerTextLeaf::GetTypeInfoCount(UINT *pctinfo)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
+ LCID lcid, DISPID *rgDispId)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
+ WORD wFlags, DISPPARAMS *pDispParams,
+ VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
+ UINT *puArgErr)
+{
+ return E_NOTIMPL;
+}
+
+/*** IAccessible ***/
+
+HRESULT
+HandlerTextLeaf::get_accParent(IDispatch **ppdispParent)
+{
+ if (!ppdispParent) {
+ return E_INVALIDARG;
+ }
+
+ RefPtr<IDispatch> parent(mParent);
+ parent.forget(ppdispParent);
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_accChildCount(long *pcountChildren)
+{
+ if (!pcountChildren) {
+ return E_INVALIDARG;
+ }
+
+ *pcountChildren = 0;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_accChild(VARIANT varChild, IDispatch **ppdispChild)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_accName(VARIANT varChild, BSTR *pszName)
+{
+ if (varChild.lVal != CHILDID_SELF || !pszName) {
+ return E_INVALIDARG;
+ }
+
+ *pszName = CopyBSTR(mData.mText);
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_accValue(VARIANT varChild, BSTR *pszValue)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_accDescription(VARIANT varChild, BSTR *pszDescription)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_accRole(VARIANT varChild, VARIANT *pvarRole)
+{
+ if (varChild.lVal != CHILDID_SELF || !pvarRole) {
+ return E_INVALIDARG;
+ }
+
+ pvarRole->vt = VT_I4;
+ pvarRole->lVal = mData.mTextRole;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_accState(VARIANT varChild, VARIANT *pvarState)
+{
+ if (varChild.lVal != CHILDID_SELF || !pvarState) {
+ return E_INVALIDARG;
+ }
+
+ pvarState->vt = VT_I4;
+ pvarState->lVal = mData.mTextState;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_accHelp(VARIANT varChild, BSTR *pszHelp)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_accHelpTopic(BSTR *pszHelpFile, VARIANT varChild,
+ long *pidTopic)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_accKeyboardShortcut(VARIANT varChild,
+ BSTR *pszKeyboardShortcut)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_accFocus(VARIANT *pvarChild)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_accSelection(VARIANT *pvarChildren)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_accDefaultAction(VARIANT varChild,
+ BSTR *pszDefaultAction)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::accSelect(long flagsSelect, VARIANT varChild)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::accLocation(long *pxLeft, long *pyTop, long *pcxWidth,
+ long *pcyHeight, VARIANT varChild)
+{
+ if (varChild.lVal != CHILDID_SELF || !pxLeft || !pyTop || !pcxWidth ||
+ !pcyHeight) {
+ return E_INVALIDARG;
+ }
+
+ *pxLeft = mData.mTextLeft;
+ *pyTop = mData.mTextTop;
+ *pcxWidth = mData.mTextWidth;
+ *pcyHeight = mData.mTextHeight;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::accNavigate(long navDir, VARIANT varStart,
+ VARIANT *pvarEndUpAt)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::accHitTest( long xLeft, long yTop, VARIANT *pvarChild)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::accDoDefaultAction(VARIANT varChild)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::put_accName(VARIANT varChild, BSTR szName)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::put_accValue(VARIANT varChild, BSTR szValue)
+{
+ return E_NOTIMPL;
+}
+
+/*** IAccessible2 ***/
+
+HRESULT
+HandlerTextLeaf::get_nRelations(long* nRelations)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_relation(long relationIndex,
+ IAccessibleRelation** relation)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_relations(long maxRelations,
+ IAccessibleRelation** relations,
+ long* nRelations)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::role(long* role)
+{
+ if (!role) {
+ return E_INVALIDARG;
+ }
+
+ *role = mData.mTextRole;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::scrollTo(IA2ScrollType scrollType)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::scrollToPoint(IA2CoordinateType coordinateType, long x,
+ long y)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_groupPosition(long* groupLevel, long* similarItemsInGroup,
+ long* positionInGroup)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_states(AccessibleStates* states)
+{
+ if (!states) {
+ return E_INVALIDARG;
+ }
+
+ *states = 0;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_extendedRole(BSTR* extendedRole)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_localizedExtendedRole(BSTR* localizedExtendedRole)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_nExtendedStates(long* nExtendedStates)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_extendedStates(long maxExtendedStates,
+ BSTR** extendedStates,
+ long* nExtendedStates)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_localizedExtendedStates(long maxLocalizedExtendedStates,
+ BSTR** localizedExtendedStates,
+ long* nLocalizedExtendedStates)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_uniqueID(long* uniqueID)
+{
+ if (!uniqueID) {
+ return E_INVALIDARG;
+ }
+
+ *uniqueID = mData.mTextId;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_windowHandle(HWND* windowHandle)
+{
+ if (!windowHandle) {
+ return E_INVALIDARG;
+ }
+
+ *windowHandle = mHwnd;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_indexInParent(long* indexInParent)
+{
+ if (!indexInParent) {
+ return E_INVALIDARG;
+ }
+
+ *indexInParent = mIndexInParent;
+ return S_OK;
+}
+
+HRESULT
+HandlerTextLeaf::get_locale(IA2Locale* locale)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT
+HandlerTextLeaf::get_attributes(BSTR* attributes)
+{
+ return E_NOTIMPL;
+}
+
+/*** IServiceProvider ***/
+
+HRESULT
+HandlerTextLeaf::QueryService(REFGUID aServiceId, REFIID aIid,
+ void** aOutInterface)
+{
+ if (aIid == IID_IAccessible2) {
+ RefPtr<IAccessible2> ia2(this);
+ ia2.forget(aOutInterface);
+ return S_OK;
+ }
+
+ return E_INVALIDARG;
+}
+
+} // namespace a11y
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/accessible/ipc/win/handler/HandlerTextLeaf.h
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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/. */
+
+#if defined(MOZILLA_INTERNAL_API)
+#error This code is NOT for internal Gecko use!
+#endif // defined(MOZILLA_INTERNAL_API)
+
+#ifndef mozilla_a11y_HandlerTextLeaf_h
+#define mozilla_a11y_HandlerTextLeaf_h
+
+#include "AccessibleHandler.h"
+#include "IUnknownImpl.h"
+#include "mozilla/RefPtr.h"
+
+namespace mozilla {
+namespace a11y {
+
+class HandlerTextLeaf final : public IAccessible2
+ , public IServiceProvider
+{
+public:
+ explicit HandlerTextLeaf(IDispatch* aParent, long aIndexInParent,
+ HWND aHwnd, AccChildData& aData);
+
+ DECL_IUNKNOWN
+
+ // IDispatch
+ STDMETHODIMP GetTypeInfoCount(UINT *pctinfo) override;
+ STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) override;
+ STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
+ LCID lcid, DISPID *rgDispId) override;
+ STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
+ DISPPARAMS *pDispParams, VARIANT *pVarResult,
+ EXCEPINFO *pExcepInfo, UINT *puArgErr) override;
+
+ // IAccessible
+ STDMETHODIMP get_accParent(IDispatch **ppdispParent) override;
+ STDMETHODIMP get_accChildCount(long *pcountChildren) override;
+ STDMETHODIMP get_accChild(VARIANT varChild, IDispatch **ppdispChild) override;
+ STDMETHODIMP get_accName(VARIANT varChild, BSTR *pszName) override;
+ STDMETHODIMP get_accValue(VARIANT varChild, BSTR *pszValue) override;
+ STDMETHODIMP get_accDescription(VARIANT varChild, BSTR *pszDescription) override;
+ STDMETHODIMP get_accRole(VARIANT varChild, VARIANT *pvarRole) override;
+ STDMETHODIMP get_accState(VARIANT varChild, VARIANT *pvarState) override;
+ STDMETHODIMP get_accHelp(VARIANT varChild, BSTR *pszHelp) override;
+ STDMETHODIMP get_accHelpTopic(BSTR *pszHelpFile, VARIANT varChild,
+ long *pidTopic) override;
+ STDMETHODIMP get_accKeyboardShortcut(VARIANT varChild,
+ BSTR *pszKeyboardShortcut) override;
+ STDMETHODIMP get_accFocus(VARIANT *pvarChild) override;
+ STDMETHODIMP get_accSelection(VARIANT *pvarChildren) override;
+ STDMETHODIMP get_accDefaultAction(VARIANT varChild,
+ BSTR *pszDefaultAction) override;
+ STDMETHODIMP accSelect(long flagsSelect, VARIANT varChild) override;
+ STDMETHODIMP accLocation(long *pxLeft, long *pyTop, long *pcxWidth,
+ long *pcyHeight, VARIANT varChild) override;
+ STDMETHODIMP accNavigate(long navDir, VARIANT varStart,
+ VARIANT *pvarEndUpAt) override;
+ STDMETHODIMP accHitTest( long xLeft, long yTop, VARIANT *pvarChild) override;
+ STDMETHODIMP accDoDefaultAction(VARIANT varChild) override;
+ STDMETHODIMP put_accName(VARIANT varChild, BSTR szName) override;
+ STDMETHODIMP put_accValue(VARIANT varChild, BSTR szValue) override;
+
+ // IAccessible2
+ STDMETHODIMP get_nRelations(long* nRelations) override;
+ STDMETHODIMP get_relation(long relationIndex,
+ IAccessibleRelation** relation) override;
+ STDMETHODIMP get_relations(long maxRelations, IAccessibleRelation** relations,
+ long* nRelations) override;
+ STDMETHODIMP role(long* role) override;
+ STDMETHODIMP scrollTo(IA2ScrollType scrollType) override;
+ STDMETHODIMP scrollToPoint(IA2CoordinateType coordinateType, long x,
+ long y) override;
+ STDMETHODIMP get_groupPosition(long* groupLevel, long* similarItemsInGroup,
+ long* positionInGroup) override;
+ STDMETHODIMP get_states(AccessibleStates* states) override;
+ STDMETHODIMP get_extendedRole(BSTR* extendedRole) override;
+ STDMETHODIMP get_localizedExtendedRole(BSTR* localizedExtendedRole) override;
+ STDMETHODIMP get_nExtendedStates(long* nExtendedStates) override;
+ STDMETHODIMP get_extendedStates(long maxExtendedStates, BSTR** extendedStates,
+ long* nExtendedStates) override;
+ STDMETHODIMP get_localizedExtendedStates(long maxLocalizedExtendedStates,
+ BSTR** localizedExtendedStates,
+ long* nLocalizedExtendedStates) override;
+ STDMETHODIMP get_uniqueID(long* uniqueID) override;
+ STDMETHODIMP get_windowHandle(HWND* windowHandle) override;
+ STDMETHODIMP get_indexInParent(long* indexInParent) override;
+ STDMETHODIMP get_locale(IA2Locale* locale) override;
+ STDMETHODIMP get_attributes(BSTR* attributes) override;
+
+ // IServiceProvider
+ STDMETHODIMP QueryService(REFGUID aServiceId, REFIID aIid,
+ void** aOutInterface) override;
+
+private:
+ ~HandlerTextLeaf();
+
+ RefPtr<IDispatch> mParent;
+ long mIndexInParent;
+ HWND mHwnd;
+ AccChildData mData;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif // mozilla_a11y_HandlerTextLeaf_h
--- a/accessible/ipc/win/handler/moz.build
+++ b/accessible/ipc/win/handler/moz.build
@@ -19,16 +19,17 @@ LOCAL_INCLUDES += [
SOURCES += [
'!dlldata.c',
'!HandlerData_c.c',
'!HandlerData_i.c',
'!HandlerData_p.c',
'AccessibleHandler.cpp',
'AccessibleHandlerControl.cpp',
'HandlerRelation.cpp',
+ 'HandlerTextLeaf.cpp',
]
GENERATED_FILES += [
'dlldata.c',
'HandlerData.h',
'HandlerData.tlb',
'HandlerData_c.c',
'HandlerData_i.c',