mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-14 10:43:24 +00:00
Bug 135485: Active Accessibility: should we cache accessible children of an accessible node? r=jgaunt. sr=alecf
This commit is contained in:
parent
be03eba8f7
commit
b63bf48de8
@ -82,18 +82,18 @@ CComModule _Module;
|
||||
//-----------------------------------------------------
|
||||
// construction
|
||||
//-----------------------------------------------------
|
||||
Accessible::Accessible(nsIAccessible* aAcc, nsIDOMNode* aNode, HWND aWnd): SimpleDOMNode(aAcc, aNode, aWnd)
|
||||
Accessible::Accessible(nsIAccessible* aXPAccessible, nsIDOMNode* aNode, HWND aWnd):
|
||||
SimpleDOMNode(aXPAccessible, aNode, aWnd), mCachedChildCount(-1),
|
||||
mCachedFirstChild(nsnull), mCachedNextSibling(nsnull), mEnumVARIANTPosition(0),
|
||||
mXPAccessible(aXPAccessible)
|
||||
{
|
||||
mAccessible = aAcc; // The nsIAccessible we're proxying from
|
||||
// So we know when mCachedNextSibling is uninitialized vs. null
|
||||
mFlagBits.mIsLastSibling = PR_FALSE;
|
||||
|
||||
// Inherited from SimpleDOMNode
|
||||
mWnd = aWnd; // The window handle, for NotifyWinEvent, or getting the accessible parent thru the window parent
|
||||
m_cRef = 0; // for reference counting, so we know when to delete ourselves
|
||||
|
||||
// mCachedIndex and mCachedChild allows fast order(N) indexing of children when moving forward through the
|
||||
// list 1 at a time,rather than going back to the first child each time, it can just get the next sibling
|
||||
mCachedIndex = 0;
|
||||
mCachedChild = NULL;
|
||||
|
||||
#ifdef DEBUG_LEAKS
|
||||
printf("Accessibles=%d\n", ++gAccessibles);
|
||||
#endif
|
||||
@ -106,7 +106,13 @@ Accessible::Accessible(nsIAccessible* aAcc, nsIDOMNode* aNode, HWND aWnd): Simpl
|
||||
Accessible::~Accessible()
|
||||
{
|
||||
m_cRef = 0;
|
||||
mAccessible = mCachedChild = nsnull;
|
||||
mXPAccessible = nsnull;
|
||||
if (mCachedNextSibling) {
|
||||
mCachedNextSibling->Release();
|
||||
}
|
||||
if (mCachedFirstChild) {
|
||||
mCachedFirstChild->Release();
|
||||
}
|
||||
#ifdef DEBUG_LEAKS
|
||||
printf("Accessibles=%d\n", --gAccessibles);
|
||||
#endif
|
||||
@ -122,7 +128,12 @@ STDMETHODIMP Accessible::QueryInterface(REFIID iid, void** ppv)
|
||||
|
||||
if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid)
|
||||
*ppv = NS_STATIC_CAST(IAccessible*, this);
|
||||
|
||||
else if (IID_IEnumVARIANT == iid) {
|
||||
CacheMSAAChildren();
|
||||
if (mCachedChildCount > 0) // Don't support this interface for leaf elements
|
||||
*ppv = NS_STATIC_CAST(IEnumVARIANT*, this);
|
||||
}
|
||||
|
||||
if (NULL == *ppv)
|
||||
return SimpleDOMNode::QueryInterface(iid,ppv);
|
||||
|
||||
@ -147,8 +158,6 @@ HINSTANCE Accessible::gmAccLib = 0;
|
||||
HINSTANCE Accessible::gmUserLib = 0;
|
||||
LPFNACCESSIBLEOBJECTFROMWINDOW Accessible::gmAccessibleObjectFromWindow = 0;
|
||||
LPFNLRESULTFROMOBJECT Accessible::gmLresultFromObject = 0;
|
||||
|
||||
|
||||
LPFNNOTIFYWINEVENT Accessible::gmNotifyWinEvent = 0;
|
||||
|
||||
|
||||
@ -158,83 +167,76 @@ LPFNNOTIFYWINEVENT Accessible::gmNotifyWinEvent = 0;
|
||||
//-----------------------------------------------------
|
||||
|
||||
|
||||
STDMETHODIMP Accessible::AccessibleObjectFromWindow(
|
||||
HWND hwnd,
|
||||
DWORD dwObjectID,
|
||||
REFIID riid,
|
||||
void **ppvObject)
|
||||
STDMETHODIMP Accessible::AccessibleObjectFromWindow(HWND hwnd,
|
||||
DWORD dwObjectID,
|
||||
REFIID riid,
|
||||
void **ppvObject)
|
||||
{
|
||||
|
||||
// open the dll dynamically
|
||||
if (!gmAccLib)
|
||||
gmAccLib =::LoadLibrary("OLEACC.DLL");
|
||||
if (!gmAccLib)
|
||||
gmAccLib =::LoadLibrary("OLEACC.DLL");
|
||||
|
||||
if (gmAccLib) {
|
||||
if (!gmAccessibleObjectFromWindow)
|
||||
gmAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(gmAccLib,"AccessibleObjectFromWindow");
|
||||
if (gmAccLib) {
|
||||
if (!gmAccessibleObjectFromWindow)
|
||||
gmAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(gmAccLib,"AccessibleObjectFromWindow");
|
||||
|
||||
if (gmAccessibleObjectFromWindow)
|
||||
return gmAccessibleObjectFromWindow(hwnd, dwObjectID, riid, ppvObject);
|
||||
}
|
||||
|
||||
if (gmAccessibleObjectFromWindow)
|
||||
return gmAccessibleObjectFromWindow(hwnd, dwObjectID, riid, ppvObject);
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP Accessible::NotifyWinEvent(
|
||||
DWORD event,
|
||||
HWND hwnd,
|
||||
LONG idObjectType,
|
||||
LONG idObject)
|
||||
STDMETHODIMP Accessible::NotifyWinEvent(DWORD event,
|
||||
HWND hwnd,
|
||||
LONG idObjectType,
|
||||
LONG idObject)
|
||||
{
|
||||
|
||||
// open the dll dynamically
|
||||
if (!gmUserLib)
|
||||
gmUserLib =::LoadLibrary("USER32.DLL");
|
||||
if (!gmUserLib)
|
||||
gmUserLib =::LoadLibrary("USER32.DLL");
|
||||
|
||||
if (gmUserLib) {
|
||||
if (!gmNotifyWinEvent)
|
||||
gmNotifyWinEvent = (LPFNNOTIFYWINEVENT)GetProcAddress(gmUserLib,"NotifyWinEvent");
|
||||
if (gmUserLib) {
|
||||
if (!gmNotifyWinEvent)
|
||||
gmNotifyWinEvent = (LPFNNOTIFYWINEVENT)GetProcAddress(gmUserLib,"NotifyWinEvent");
|
||||
|
||||
if (gmNotifyWinEvent)
|
||||
return gmNotifyWinEvent(event, hwnd, idObjectType, idObject);
|
||||
}
|
||||
if (gmNotifyWinEvent)
|
||||
return gmNotifyWinEvent(event, hwnd, idObjectType, idObject);
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP_(LRESULT) Accessible::LresultFromObject(
|
||||
REFIID riid,
|
||||
WPARAM wParam,
|
||||
LPUNKNOWN pAcc)
|
||||
STDMETHODIMP_(LRESULT) Accessible::LresultFromObject(REFIID riid,
|
||||
WPARAM wParam,
|
||||
LPUNKNOWN pAcc)
|
||||
{
|
||||
// open the dll dynamically
|
||||
if (!gmAccLib)
|
||||
gmAccLib =::LoadLibrary("OLEACC.DLL");
|
||||
// open the dll dynamically
|
||||
if (!gmAccLib)
|
||||
gmAccLib =::LoadLibrary("OLEACC.DLL");
|
||||
|
||||
if (gmAccLib) {
|
||||
if (!gmAccessibleObjectFromWindow)
|
||||
gmLresultFromObject = (LPFNLRESULTFROMOBJECT)GetProcAddress(gmAccLib,"LresultFromObject");
|
||||
if (gmAccLib) {
|
||||
if (!gmAccessibleObjectFromWindow)
|
||||
gmLresultFromObject = (LPFNLRESULTFROMOBJECT)GetProcAddress(gmAccLib,"LresultFromObject");
|
||||
|
||||
if (gmLresultFromObject)
|
||||
return gmLresultFromObject(riid,wParam,pAcc);
|
||||
}
|
||||
if (gmLresultFromObject)
|
||||
return gmLresultFromObject(riid,wParam,pAcc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP Accessible::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> parent(nsnull);
|
||||
mAccessible->GetAccParent(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsIAccessible> xpParentAccessible;
|
||||
mXPAccessible->GetAccParent(getter_AddRefs(xpParentAccessible));
|
||||
|
||||
if (parent) {
|
||||
IAccessible* a = NewAccessible(parent, nsnull, mWnd);
|
||||
a->AddRef();
|
||||
*ppdispParent = a;
|
||||
if (xpParentAccessible) {
|
||||
IAccessible* msaaParentAccessible =
|
||||
NewAccessible(xpParentAccessible, nsnull, mWnd);
|
||||
msaaParentAccessible->AddRef();
|
||||
*ppdispParent = msaaParentAccessible;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -246,10 +248,10 @@ STDMETHODIMP Accessible::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispPa
|
||||
void* ptr = nsnull;
|
||||
HRESULT result = AccessibleObjectFromWindow(pWnd, OBJID_WINDOW, IID_IAccessible, &ptr);
|
||||
if (SUCCEEDED(result)) {
|
||||
IAccessible* a = (IAccessible*)ptr;
|
||||
IAccessible* msaaParentAccessible = (IAccessible*)ptr;
|
||||
// got one? return it.
|
||||
if (a) {
|
||||
*ppdispParent = a;
|
||||
if (msaaParentAccessible) {
|
||||
*ppdispParent = msaaParentAccessible;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -261,9 +263,10 @@ STDMETHODIMP Accessible::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispPa
|
||||
|
||||
STDMETHODIMP Accessible::get_accChildCount( long __RPC_FAR *pcountChildren)
|
||||
{
|
||||
PRInt32 count = 0;
|
||||
mAccessible->GetAccChildCount(&count);
|
||||
*pcountChildren = count;
|
||||
CacheMSAAChildren();
|
||||
|
||||
*pcountChildren = mCachedChildCount;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -271,27 +274,22 @@ STDMETHODIMP Accessible::get_accChild(
|
||||
/* [in] */ VARIANT varChild,
|
||||
/* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild)
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
*ppdispChild = NULL;
|
||||
|
||||
if (a)
|
||||
{
|
||||
// if its us return us
|
||||
if (a == mAccessible) {
|
||||
*ppdispChild = this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// create a new one.
|
||||
IAccessible* ia = NewAccessible(a, nsnull, mWnd);
|
||||
ia->AddRef();
|
||||
*ppdispChild = ia;
|
||||
if (varChild.vt != VT_I4)
|
||||
return E_FAIL;
|
||||
|
||||
if (varChild.lVal == CHILDID_SELF) {
|
||||
*ppdispChild = this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*ppdispChild = NULL;
|
||||
return E_FAIL;
|
||||
CacheMSAAChildren();
|
||||
|
||||
*ppdispChild = GetCachedChild(varChild.lVal - 1); // already addrefed
|
||||
|
||||
return (*ppdispChild)? S_OK: E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP Accessible::get_accName(
|
||||
@ -299,15 +297,14 @@ STDMETHODIMP Accessible::get_accName(
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszName)
|
||||
{
|
||||
*pszName = NULL;
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
if (a) {
|
||||
nsAutoString name;
|
||||
nsresult rv = a->GetAccName(name);
|
||||
if (NS_FAILED(rv))
|
||||
return S_FALSE;
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
if (xpAccessible) {
|
||||
nsAutoString name;
|
||||
if (NS_FAILED(xpAccessible->GetAccName(name)))
|
||||
return S_FALSE;
|
||||
|
||||
*pszName = ::SysAllocString(name.get());
|
||||
*pszName = ::SysAllocString(name.get());
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@ -319,15 +316,14 @@ STDMETHODIMP Accessible::get_accValue(
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszValue)
|
||||
{
|
||||
*pszValue = NULL;
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
if (a) {
|
||||
nsAutoString value;
|
||||
nsresult rv = a->GetAccValue(value);
|
||||
if (NS_FAILED(rv))
|
||||
return S_FALSE;
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
if (xpAccessible) {
|
||||
nsAutoString value;
|
||||
if (NS_FAILED(xpAccessible->GetAccValue(value)))
|
||||
return S_FALSE;
|
||||
|
||||
*pszValue = ::SysAllocString(value.get());
|
||||
*pszValue = ::SysAllocString(value.get());
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@ -339,13 +335,12 @@ STDMETHODIMP Accessible::get_accDescription(
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszDescription)
|
||||
{
|
||||
*pszDescription = NULL;
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
if (a) {
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
if (xpAccessible) {
|
||||
nsAutoString description;
|
||||
nsresult rv = a->GetAccDescription(description);
|
||||
if (NS_FAILED(rv))
|
||||
return S_FALSE;
|
||||
if (NS_FAILED(xpAccessible->GetAccDescription(description)))
|
||||
return S_FALSE;
|
||||
|
||||
*pszDescription = ::SysAllocString(description.get());
|
||||
}
|
||||
@ -357,45 +352,43 @@ STDMETHODIMP Accessible::get_accRole(
|
||||
/* [optional][in] */ VARIANT varChild,
|
||||
/* [retval][out] */ VARIANT __RPC_FAR *pvarRole)
|
||||
{
|
||||
VariantInit(pvarRole);
|
||||
pvarRole->vt = VT_I4;
|
||||
VariantInit(pvarRole);
|
||||
pvarRole->vt = VT_I4;
|
||||
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
|
||||
if (!a)
|
||||
return E_FAIL;
|
||||
if (!xpAccessible)
|
||||
return E_FAIL;
|
||||
|
||||
PRUint32 role = 0;
|
||||
nsresult rv = a->GetAccRole(&role);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
PRUint32 role = 0;
|
||||
if (NS_FAILED(xpAccessible->GetAccRole(&role)))
|
||||
return E_FAIL;
|
||||
|
||||
pvarRole->lVal = role;
|
||||
return S_OK;
|
||||
pvarRole->lVal = role;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP Accessible::get_accState(
|
||||
/* [optional][in] */ VARIANT varChild,
|
||||
/* [retval][out] */ VARIANT __RPC_FAR *pvarState)
|
||||
{
|
||||
VariantInit(pvarState);
|
||||
pvarState->vt = VT_I4;
|
||||
pvarState->lVal = 0;
|
||||
VariantInit(pvarState);
|
||||
pvarState->vt = VT_I4;
|
||||
pvarState->lVal = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
if (!a)
|
||||
return E_FAIL;
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
if (!xpAccessible)
|
||||
return E_FAIL;
|
||||
|
||||
PRUint32 state;
|
||||
nsresult rv = a->GetAccState(&state);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
PRUint32 state;
|
||||
if (NS_FAILED(xpAccessible->GetAccState(&state)))
|
||||
return E_FAIL;
|
||||
|
||||
pvarState->lVal = state;
|
||||
pvarState->lVal = state;
|
||||
|
||||
return S_OK;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -414,7 +407,7 @@ STDMETHODIMP Accessible::get_accHelpTopic(
|
||||
{
|
||||
*pszHelpFile = NULL;
|
||||
*pidTopic = 0;
|
||||
return S_FALSE;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP Accessible::get_accKeyboardShortcut(
|
||||
@ -422,11 +415,11 @@ STDMETHODIMP Accessible::get_accKeyboardShortcut(
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut)
|
||||
{
|
||||
*pszKeyboardShortcut = NULL;
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
if (a) {
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
if (xpAccessible) {
|
||||
nsAutoString shortcut;
|
||||
nsresult rv = a->GetAccKeyboardShortcut(shortcut);
|
||||
nsresult rv = xpAccessible->GetAccKeyboardShortcut(shortcut);
|
||||
if (NS_FAILED(rv))
|
||||
return S_FALSE;
|
||||
|
||||
@ -443,9 +436,9 @@ STDMETHODIMP Accessible::get_accFocus(
|
||||
VariantInit(pvarChild);
|
||||
|
||||
nsCOMPtr<nsIAccessible> focusedAccessible;
|
||||
if (NS_SUCCEEDED(mAccessible->GetAccFocused(getter_AddRefs(focusedAccessible)))) {
|
||||
if (NS_SUCCEEDED(mXPAccessible->GetAccFocused(getter_AddRefs(focusedAccessible)))) {
|
||||
pvarChild->vt = VT_DISPATCH;
|
||||
pvarChild->pdispVal = NewAccessible(focusedAccessible, nsnull, mWnd);
|
||||
pvarChild->pdispVal = NS_STATIC_CAST(IDispatch*, NewAccessible(focusedAccessible, nsnull, mWnd));
|
||||
pvarChild->pdispVal->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
@ -453,6 +446,7 @@ STDMETHODIMP Accessible::get_accFocus(
|
||||
pvarChild->vt = VT_EMPTY;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when a client wants to know which children of a node
|
||||
* are selected. Currently we only handle this for HTML selects, which are the
|
||||
@ -494,7 +488,7 @@ STDMETHODIMP Accessible::get_accSelection(
|
||||
VariantInit(pvarChildren);
|
||||
pvarChildren->vt = VT_EMPTY;
|
||||
|
||||
nsCOMPtr<nsIAccessibleSelectable> select(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleSelectable> select(do_QueryInterface(mXPAccessible));
|
||||
if (select) { // do we have an nsIAccessibleSelectable?
|
||||
// we have an accessible that can have children selected
|
||||
nsCOMPtr<nsISupportsArray> selectedOptions;
|
||||
@ -538,15 +532,14 @@ STDMETHODIMP Accessible::get_accDefaultAction(
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszDefaultAction)
|
||||
{
|
||||
*pszDefaultAction = NULL;
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
if (a) {
|
||||
nsAutoString defaultAction;
|
||||
nsresult rv = a->GetAccActionName(0,defaultAction);
|
||||
if (NS_FAILED(rv))
|
||||
return S_FALSE;
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
if (xpAccessible) {
|
||||
nsAutoString defaultAction;
|
||||
if (NS_FAILED(xpAccessible->GetAccActionName(0, defaultAction)))
|
||||
return S_FALSE;
|
||||
|
||||
*pszDefaultAction = ::SysAllocString(defaultAction.get());
|
||||
*pszDefaultAction = ::SysAllocString(defaultAction.get());
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@ -557,17 +550,19 @@ STDMETHODIMP Accessible::accSelect(
|
||||
/* [optional][in] */ VARIANT varChild)
|
||||
{
|
||||
// currently only handle focus and selection
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
|
||||
if (flagsSelect & (SELFLAG_TAKEFOCUS|SELFLAG_TAKESELECTION|SELFLAG_REMOVESELECTION))
|
||||
{
|
||||
if (flagsSelect & SELFLAG_TAKEFOCUS)
|
||||
mAccessible->AccTakeFocus();
|
||||
xpAccessible->AccTakeFocus();
|
||||
|
||||
if (flagsSelect & SELFLAG_TAKESELECTION)
|
||||
mAccessible->AccTakeSelection();
|
||||
xpAccessible->AccTakeSelection();
|
||||
|
||||
if (flagsSelect & SELFLAG_REMOVESELECTION)
|
||||
mAccessible->AccRemoveSelection();
|
||||
|
||||
xpAccessible->AccRemoveSelection();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -582,69 +577,143 @@ STDMETHODIMP Accessible::accLocation(
|
||||
/* [out] */ long __RPC_FAR *pcyHeight,
|
||||
/* [optional][in] */ VARIANT varChild)
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
GetNSAccessibleFor(varChild,a);
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
|
||||
if (a) {
|
||||
PRInt32 x,y,w,h;
|
||||
a->AccGetBounds(&x,&y,&w,&h);
|
||||
if (xpAccessible) {
|
||||
PRInt32 x, y, width, height;
|
||||
if (NS_FAILED(xpAccessible->AccGetBounds(&x, &y, &width, &height)))
|
||||
return E_FAIL;
|
||||
|
||||
*pxLeft = x;
|
||||
*pyTop = y;
|
||||
*pcxWidth = w;
|
||||
*pcyHeight = h;
|
||||
*pcxWidth = width;
|
||||
*pcyHeight = height;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
IAccessible *
|
||||
Accessible::GetCachedChild(long aChildNum)
|
||||
{
|
||||
// aChildNum of -1 just counts up the children
|
||||
// and stores the value in mCachedChildCount
|
||||
VARIANT varStart, varResult;
|
||||
VariantInit(&varStart);
|
||||
varStart.lVal = CHILDID_SELF;
|
||||
varStart.vt = VT_I4;
|
||||
|
||||
accNavigate(NAVDIR_FIRSTCHILD, varStart, &varResult);
|
||||
for (long index = 0; varResult.vt == VT_DISPATCH; ++index) {
|
||||
IAccessible *msaaAccessible = NS_STATIC_CAST(IAccessible*, varResult.pdispVal);
|
||||
if (aChildNum == index)
|
||||
return msaaAccessible;
|
||||
msaaAccessible->accNavigate(NAVDIR_NEXT, varStart, &varResult);
|
||||
msaaAccessible->Release();
|
||||
}
|
||||
if (mCachedChildCount < 0)
|
||||
mCachedChildCount = index;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void Accessible::CacheMSAAChildren()
|
||||
{
|
||||
if (mCachedChildCount < 0)
|
||||
GetCachedChild(-1); // This caches the children and sets mCachedChildCount
|
||||
}
|
||||
|
||||
STDMETHODIMP Accessible::accNavigate(
|
||||
/* [in] */ long navDir,
|
||||
/* [optional][in] */ VARIANT varStart,
|
||||
/* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt)
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> xpAccessibleStart, xpAccessibleResult;
|
||||
GetNSAccessibleFor(varStart, xpAccessibleStart);
|
||||
PRBool isNavigatingFromSelf = (xpAccessibleStart == mXPAccessible);
|
||||
VariantInit(pvarEndUpAt);
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc;
|
||||
IAccessible* msaaAccessible = nsnull;
|
||||
|
||||
switch(navDir) {
|
||||
case NAVDIR_DOWN:
|
||||
mAccessible->AccNavigateDown(getter_AddRefs(acc));
|
||||
xpAccessibleStart->AccNavigateDown(getter_AddRefs(xpAccessibleResult));
|
||||
break;
|
||||
case NAVDIR_FIRSTCHILD:
|
||||
mAccessible->GetAccFirstChild(getter_AddRefs(acc));
|
||||
if (mCachedChildCount == -1 || xpAccessibleStart != mXPAccessible) {
|
||||
xpAccessibleStart->GetAccFirstChild(getter_AddRefs(xpAccessibleResult));
|
||||
}
|
||||
else if (mCachedFirstChild) {
|
||||
msaaAccessible = mCachedFirstChild;
|
||||
}
|
||||
break;
|
||||
case NAVDIR_LASTCHILD:
|
||||
mAccessible->GetAccLastChild(getter_AddRefs(acc));
|
||||
xpAccessibleStart->GetAccLastChild(getter_AddRefs(xpAccessibleResult));
|
||||
break;
|
||||
case NAVDIR_LEFT:
|
||||
mAccessible->AccNavigateLeft(getter_AddRefs(acc));
|
||||
xpAccessibleStart->AccNavigateLeft(getter_AddRefs(xpAccessibleResult));
|
||||
break;
|
||||
case NAVDIR_NEXT:
|
||||
mAccessible->GetAccNextSibling(getter_AddRefs(acc));
|
||||
if (isNavigatingFromSelf && mCachedNextSibling) {
|
||||
msaaAccessible = mCachedNextSibling;
|
||||
}
|
||||
else if (!mFlagBits.mIsLastSibling) {
|
||||
xpAccessibleStart->GetAccNextSibling(getter_AddRefs(xpAccessibleResult));
|
||||
if (!xpAccessibleResult && isNavigatingFromSelf)
|
||||
mFlagBits.mIsLastSibling = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NAVDIR_PREVIOUS:
|
||||
mAccessible->GetAccPreviousSibling(getter_AddRefs(acc));
|
||||
xpAccessibleStart->GetAccPreviousSibling(getter_AddRefs(xpAccessibleResult));
|
||||
break;
|
||||
case NAVDIR_RIGHT:
|
||||
mAccessible->AccNavigateRight(getter_AddRefs(acc));
|
||||
xpAccessibleStart->AccNavigateRight(getter_AddRefs(xpAccessibleResult));
|
||||
break;
|
||||
case NAVDIR_UP:
|
||||
mAccessible->AccNavigateUp(getter_AddRefs(acc));
|
||||
xpAccessibleStart->AccNavigateUp(getter_AddRefs(xpAccessibleResult));
|
||||
break;
|
||||
}
|
||||
|
||||
if (acc) {
|
||||
IAccessible* a = NewAccessible(acc, nsnull, mWnd);
|
||||
a->AddRef();
|
||||
pvarEndUpAt->vt = VT_DISPATCH;
|
||||
pvarEndUpAt->pdispVal = a;
|
||||
return NS_OK;
|
||||
} else {
|
||||
pvarEndUpAt->vt = VT_EMPTY;
|
||||
return E_FAIL;
|
||||
if (xpAccessibleResult) {
|
||||
msaaAccessible = NewAccessible(xpAccessibleResult, nsnull, mWnd);
|
||||
if (isNavigatingFromSelf) {
|
||||
if (navDir == NAVDIR_NEXT) {
|
||||
if (mCachedNextSibling)
|
||||
mCachedNextSibling->Release();
|
||||
mCachedNextSibling = msaaAccessible;
|
||||
msaaAccessible->AddRef(); // addref for the caching
|
||||
}
|
||||
if (navDir == NAVDIR_FIRSTCHILD) {
|
||||
if (mCachedFirstChild)
|
||||
mCachedFirstChild->Release();
|
||||
mCachedFirstChild = msaaAccessible;
|
||||
msaaAccessible->AddRef(); // addref for the caching
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!msaaAccessible) {
|
||||
if (isNavigatingFromSelf) {
|
||||
if (navDir == NAVDIR_NEXT) {
|
||||
if (mCachedNextSibling)
|
||||
mCachedNextSibling->Release();
|
||||
mCachedNextSibling = nsnull;
|
||||
}
|
||||
if (navDir == NAVDIR_FIRSTCHILD) {
|
||||
if (mCachedFirstChild)
|
||||
mCachedFirstChild->Release();
|
||||
mCachedFirstChild = nsnull;
|
||||
mCachedChildCount = 0;
|
||||
}
|
||||
}
|
||||
pvarEndUpAt->vt = VT_EMPTY;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
pvarEndUpAt->pdispVal = NS_STATIC_CAST(IDispatch*, msaaAccessible);
|
||||
msaaAccessible->AddRef(); // addref for the getter
|
||||
pvarEndUpAt->vt = VT_DISPATCH;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP Accessible::accHitTest(
|
||||
@ -655,23 +724,22 @@ STDMETHODIMP Accessible::accHitTest(
|
||||
VariantInit(pvarChild);
|
||||
|
||||
// convert to window coords
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
|
||||
xLeft = xLeft;
|
||||
yTop = yTop;
|
||||
|
||||
mAccessible->AccGetAt(xLeft,yTop, getter_AddRefs(a));
|
||||
mXPAccessible->AccGetAt(xLeft, yTop, getter_AddRefs(xpAccessible));
|
||||
|
||||
// if we got a child
|
||||
if (a)
|
||||
{
|
||||
if (xpAccessible) {
|
||||
// if the child is us
|
||||
if (a == mAccessible) {
|
||||
if (xpAccessible == mXPAccessible) {
|
||||
pvarChild->vt = VT_I4;
|
||||
pvarChild->lVal = CHILDID_SELF;
|
||||
} else { // its not create an Accessible for it.
|
||||
pvarChild->vt = VT_DISPATCH;
|
||||
pvarChild->pdispVal = NewAccessible(a, nsnull, mWnd);
|
||||
pvarChild->pdispVal = NS_STATIC_CAST(IDispatch*, NewAccessible(xpAccessible, nsnull, mWnd));
|
||||
pvarChild->pdispVal->AddRef();
|
||||
}
|
||||
} else {
|
||||
@ -686,7 +754,13 @@ STDMETHODIMP Accessible::accHitTest(
|
||||
STDMETHODIMP Accessible::accDoDefaultAction(
|
||||
/* [optional][in] */ VARIANT varChild)
|
||||
{
|
||||
return NS_SUCCEEDED(mAccessible->AccDoAction(0))? NS_OK: DISP_E_MEMBERNOTFOUND;
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
GetNSAccessibleFor(varChild, xpAccessible);
|
||||
|
||||
if (!xpAccessible || FAILED(xpAccessible->AccDoAction(0))) {
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP Accessible::put_accName(
|
||||
@ -704,6 +778,81 @@ STDMETHODIMP Accessible::put_accValue(
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP
|
||||
Accessible::Next(ULONG aNumElementsRequested, VARIANT FAR* pvar, ULONG FAR* aNumElementsFetched)
|
||||
{
|
||||
CacheMSAAChildren();
|
||||
*aNumElementsFetched = 0;
|
||||
|
||||
if (aNumElementsRequested <= 0 || !pvar ||
|
||||
mEnumVARIANTPosition >= mCachedChildCount) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
VARIANT varStart;
|
||||
VariantInit(&varStart);
|
||||
varStart.lVal = CHILDID_SELF;
|
||||
varStart.vt = VT_I4;
|
||||
|
||||
accNavigate(NAVDIR_FIRSTCHILD, varStart, &pvar[0]);
|
||||
|
||||
for (long childIndex = 0; pvar[*aNumElementsFetched].vt == VT_DISPATCH; ++childIndex) {
|
||||
IAccessible *msaaAccessible = NS_STATIC_CAST(IAccessible*, pvar[*aNumElementsFetched].pdispVal);
|
||||
if (childIndex >= mEnumVARIANTPosition) {
|
||||
if ((*aNumElementsFetched)++ >= aNumElementsRequested)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
msaaAccessible->Release(); // this accessible will not be received by the caller
|
||||
}
|
||||
msaaAccessible->accNavigate(NAVDIR_NEXT, varStart, &pvar[*aNumElementsFetched] );
|
||||
}
|
||||
mEnumVARIANTPosition = childIndex;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
Accessible::Skip(ULONG aNumElements)
|
||||
{
|
||||
CacheMSAAChildren();
|
||||
|
||||
mEnumVARIANTPosition += aNumElements;
|
||||
|
||||
if (mEnumVARIANTPosition > mCachedChildCount)
|
||||
{
|
||||
mEnumVARIANTPosition = mCachedChildCount;
|
||||
return S_FALSE;
|
||||
}
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
Accessible::Reset(void)
|
||||
{
|
||||
mEnumVARIANTPosition = 0;
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
Accessible::Clone(IEnumVARIANT FAR* FAR* ppenum)
|
||||
{
|
||||
*ppenum = nsnull;
|
||||
CacheMSAAChildren();
|
||||
|
||||
IAccessible *msaaAccessible = new Accessible(mXPAccessible, mDOMNode, mWnd);
|
||||
if (!msaaAccessible)
|
||||
return E_FAIL;
|
||||
msaaAccessible->AddRef();
|
||||
QueryInterface(IID_IEnumVARIANT, (void**)ppenum);
|
||||
if (*ppenum)
|
||||
(*ppenum)->Skip(mEnumVARIANTPosition); // QI addrefed
|
||||
msaaAccessible->Release();
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
// For IDispatch support
|
||||
STDMETHODIMP
|
||||
Accessible::GetTypeInfoCount(UINT *p)
|
||||
@ -766,44 +915,28 @@ IAccessible *Accessible::NewAccessible(nsIAccessible *aNSAcc, nsIDOMNode *aNode,
|
||||
}
|
||||
|
||||
|
||||
void Accessible::GetNSAccessibleFor(VARIANT varChild, nsCOMPtr<nsIAccessible>& aAcc)
|
||||
void Accessible::GetNSAccessibleFor(VARIANT varChild, nsCOMPtr<nsIAccessible>& aXPAccessible)
|
||||
{
|
||||
// if its us real easy
|
||||
aXPAccessible = nsnull;
|
||||
|
||||
// if its us real easy - this seems to always be the case
|
||||
if (varChild.lVal == CHILDID_SELF) {
|
||||
aAcc = mAccessible;
|
||||
} else if (mCachedChild && varChild.lVal == mCachedIndex+1) {
|
||||
// if the cachedIndex is not self and the if its the one right
|
||||
// before the one we want to get. Then just ask it for its next.
|
||||
nsCOMPtr<nsIAccessible> next;
|
||||
mCachedChild->GetAccNextSibling(getter_AddRefs(next));
|
||||
if (next) {
|
||||
mCachedIndex++;
|
||||
mCachedChild = next;
|
||||
aXPAccessible = mXPAccessible;
|
||||
}
|
||||
else {
|
||||
// XXX aaronl
|
||||
// I can't find anything that uses VARIANT with a child num
|
||||
// so let's not worry about optimizing this.
|
||||
NS_NOTREACHED("MSAA VARIANT with child number being used");
|
||||
nsCOMPtr<nsIAccessible> xpAccessible;
|
||||
mXPAccessible->GetAccFirstChild(getter_AddRefs(xpAccessible));
|
||||
for (PRInt32 index = 0; xpAccessible; index ++) {
|
||||
aXPAccessible = xpAccessible;
|
||||
if (varChild.lVal == index)
|
||||
break;
|
||||
aXPAccessible->GetAccNextSibling(getter_AddRefs(xpAccessible));
|
||||
}
|
||||
|
||||
aAcc = next;
|
||||
return;
|
||||
|
||||
} else {
|
||||
// if the cachedindex is not the one right before we have to start at the begining
|
||||
nsCOMPtr<nsIAccessible> a;
|
||||
mAccessible->GetAccFirstChild(getter_AddRefs(mCachedChild));
|
||||
mCachedIndex = 1;
|
||||
while(mCachedChild)
|
||||
{
|
||||
if (varChild.lVal == mCachedIndex)
|
||||
{
|
||||
aAcc = mCachedChild;
|
||||
return;
|
||||
}
|
||||
|
||||
mCachedChild->GetAccNextSibling(getter_AddRefs(a));
|
||||
mCachedChild = a;
|
||||
mCachedIndex++;
|
||||
}
|
||||
|
||||
aAcc = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -850,7 +983,7 @@ DocAccessible::~DocAccessible()
|
||||
|
||||
STDMETHODIMP DocAccessible::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mXPAccessible));
|
||||
if (accDoc) {
|
||||
nsAutoString URL;
|
||||
if (NS_SUCCEEDED(accDoc->GetURL(URL))) {
|
||||
@ -863,7 +996,7 @@ STDMETHODIMP DocAccessible::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)
|
||||
|
||||
STDMETHODIMP DocAccessible::get_title( /* [out] */ BSTR __RPC_FAR *aTitle)
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mXPAccessible));
|
||||
if (accDoc) {
|
||||
nsAutoString title;
|
||||
if (NS_SUCCEEDED(accDoc->GetTitle(title))) { // getter_Copies(pszTitle)))) {
|
||||
@ -876,7 +1009,7 @@ STDMETHODIMP DocAccessible::get_title( /* [out] */ BSTR __RPC_FAR *aTitle)
|
||||
|
||||
STDMETHODIMP DocAccessible::get_mimeType(/* [out] */ BSTR __RPC_FAR *aMimeType)
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mXPAccessible));
|
||||
if (accDoc) {
|
||||
nsAutoString mimeType;
|
||||
if (NS_SUCCEEDED(accDoc->GetMimeType(mimeType))) {
|
||||
@ -889,7 +1022,7 @@ STDMETHODIMP DocAccessible::get_mimeType(/* [out] */ BSTR __RPC_FAR *aMimeType)
|
||||
|
||||
STDMETHODIMP DocAccessible::get_docType(/* [out] */ BSTR __RPC_FAR *aDocType)
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mXPAccessible));
|
||||
if (accDoc) {
|
||||
nsAutoString docType;
|
||||
if (NS_SUCCEEDED(accDoc->GetDocType(docType))) {
|
||||
@ -903,7 +1036,7 @@ STDMETHODIMP DocAccessible::get_docType(/* [out] */ BSTR __RPC_FAR *aDocType)
|
||||
STDMETHODIMP DocAccessible::get_nameSpaceURIForID(/* [in] */ short aNameSpaceID,
|
||||
/* [out] */ BSTR __RPC_FAR *aNameSpaceURI)
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mXPAccessible));
|
||||
if (accDoc) {
|
||||
*aNameSpaceURI = NULL;
|
||||
nsAutoString nameSpaceURI;
|
||||
@ -959,14 +1092,14 @@ RootAccessible::RootAccessible(nsIAccessible* aAcc, HWND aWnd):DocAccessible(aAc
|
||||
mListCount = 0;
|
||||
mNextPos = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessibleEventReceiver> r(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleEventReceiver> r(do_QueryInterface(mXPAccessible));
|
||||
if (r)
|
||||
r->AddAccessibleEventListener(this);
|
||||
}
|
||||
|
||||
RootAccessible::~RootAccessible()
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleEventReceiver> r(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleEventReceiver> r(do_QueryInterface(mXPAccessible));
|
||||
if (r)
|
||||
r->RemoveAccessibleEventListener();
|
||||
|
||||
@ -982,7 +1115,7 @@ void RootAccessible::GetNSAccessibleFor(VARIANT varChild, nsCOMPtr<nsIAccessible
|
||||
|
||||
aAcc = nsnull;
|
||||
if (varChild.lVal == UNIQUE_ID_CARET) {
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mAccessible));
|
||||
nsCOMPtr<nsIAccessibleDocument> accDoc(do_QueryInterface(mXPAccessible));
|
||||
if (accDoc) {
|
||||
nsCOMPtr<nsIAccessibleCaret> accessibleCaret;
|
||||
accDoc->GetCaretAccessible(getter_AddRefs(accessibleCaret));
|
||||
@ -1020,6 +1153,7 @@ NS_IMETHODIMP RootAccessible::HandleEvent(PRUint32 aEvent, nsIAccessible* aAcces
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 childID, worldID = OBJID_CLIENT;
|
||||
PRUint32 role;
|
||||
|
||||
|
@ -48,7 +48,6 @@
|
||||
#ifndef WM_GETOBJECT
|
||||
#define WM_GETOBJECT 0x03d
|
||||
#endif
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsIAccessibleEventListener.h"
|
||||
@ -58,9 +57,15 @@
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
struct FlagBits {
|
||||
PRUint8 mIsLastSibling: 1;
|
||||
};
|
||||
|
||||
typedef LRESULT (STDAPICALLTYPE *LPFNNOTIFYWINEVENT)(DWORD event,HWND hwnd,LONG idObjectType,LONG idObject);
|
||||
|
||||
class Accessible : public SimpleDOMNode, public IAccessible
|
||||
class Accessible : public SimpleDOMNode,
|
||||
public IAccessible,
|
||||
public IEnumVARIANT
|
||||
{
|
||||
public: // construction, destruction
|
||||
Accessible(nsIAccessible*, nsIDOMNode*, HWND aWin = 0);
|
||||
@ -161,6 +166,21 @@ class Accessible : public SimpleDOMNode, public IAccessible
|
||||
/* [optional][in] */ VARIANT varChild,
|
||||
/* [in] */ BSTR szValue);
|
||||
|
||||
public: // IEnumVariantMethods
|
||||
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Next(
|
||||
/* [in] */ ULONG celt,
|
||||
/* [length_is][size_is][out] */ VARIANT __RPC_FAR *rgVar,
|
||||
/* [out] */ ULONG __RPC_FAR *pCeltFetched);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Skip(
|
||||
/* [in] */ ULONG celt);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Reset( void);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Clone(
|
||||
/* [out] */ IEnumVARIANT __RPC_FAR *__RPC_FAR *ppEnum);
|
||||
|
||||
|
||||
// ====== Methods for IDispatch - for VisualBasic bindings (not implemented) ======
|
||||
|
||||
STDMETHODIMP GetTypeInfoCount(UINT *p);
|
||||
@ -179,13 +199,27 @@ class Accessible : public SimpleDOMNode, public IAccessible
|
||||
static STDMETHODIMP NotifyWinEvent(DWORD event,HWND hwnd,LONG idObjectType,LONG idObject);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIAccessible> mAccessible;
|
||||
nsCOMPtr<nsIAccessible> mXPAccessible;
|
||||
IAccessible *mCachedFirstChild;
|
||||
IAccessible *mCachedNextSibling;
|
||||
|
||||
nsCOMPtr<nsIAccessible> mCachedChild;
|
||||
LONG mCachedIndex;
|
||||
long mCachedChildCount;
|
||||
// mEnumVARIANTPosition not the current accessible's position, but a "cursor" of
|
||||
// where we are in the current list of children, with respect to
|
||||
// nsIEnumVariant::Reset(), Skip() and Next().
|
||||
long mEnumVARIANTPosition;
|
||||
FlagBits mFlagBits;
|
||||
|
||||
virtual void GetNSAccessibleFor(VARIANT varChild, nsCOMPtr<nsIAccessible>& aAcc);
|
||||
IAccessible *Accessible::NewAccessible(nsIAccessible *aNSAcc, nsIDOMNode *aNode, HWND aWnd);
|
||||
IAccessible *NewAccessible(nsIAccessible *aNSAcc, nsIDOMNode *aNode, HWND aWnd);
|
||||
|
||||
// Most IAccessible methods are not optimized to use the cache
|
||||
// when CHILDID_SELF is mot used in the VARIANT struct.
|
||||
// For this reason, a child number of CHILDID_SELF is recommended,
|
||||
// rather than using the child number you need in the VARIANT
|
||||
// This is what most assistive tech tends to do, so it shouldn't be a problem.
|
||||
void CacheMSAAChildren();
|
||||
IAccessible *GetCachedChild(long aChildNum);
|
||||
|
||||
private:
|
||||
/// the accessible library and cached methods
|
||||
|
Loading…
Reference in New Issue
Block a user