bug 832158 - implement IServiceProvider with a taer off r=surkov

This commit is contained in:
Trevor Saunders 2013-01-09 15:01:10 -05:00
parent 073ed19b99
commit 68a21f1293
7 changed files with 159 additions and 153 deletions

View File

@ -15,12 +15,12 @@
#include "nsIAccessibleEvent.h"
#include "nsIAccessibleRelation.h"
#include "nsWinUtils.h"
#include "ServiceProvider.h"
#include "Relation.h"
#include "Role.h"
#include "RootAccessible.h"
#include "sdnAccessible.h"
#include "States.h"
#include "uiaRawElmProvider.h"
#ifdef A11Y_LOG
#include "Logging.h"
@ -90,7 +90,7 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
*ppv = static_cast<IEnumVARIANT*>(new ChildrenEnumVariant(this));
} else if (IID_IServiceProvider == iid)
*ppv = static_cast<IServiceProvider*>(this);
*ppv = new ServiceProvider(this);
else if (IID_IAccessible2 == iid && !Compatibility::IsIA2Off())
*ppv = static_cast<IAccessible2*>(this);
else if (IID_ISimpleDOMNode == iid) {
@ -127,32 +127,6 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
A11Y_TRYBLOCK_END
}
////////////////////////////////////////////////////////////////////////////////
// IServiceProvider
STDMETHODIMP
AccessibleWrap::QueryService(REFGUID aGuidService, REFIID aIID,
void** aInstancePtr)
{
if (!aInstancePtr)
return E_INVALIDARG;
*aInstancePtr = NULL;
// UIA IAccessibleEx
if (aGuidService == IID_IAccessibleEx &&
Preferences::GetBool("accessibility.uia.enable")) {
uiaRawElmProvider* accEx = new uiaRawElmProvider(this);
HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
if (FAILED(hr))
delete accEx;
return hr;
}
return nsAccessNodeWrap::QueryService(aGuidService, aIID, aInstancePtr);
}
//-----------------------------------------------------
// IAccessible methods
//-----------------------------------------------------

View File

@ -138,11 +138,6 @@ public: // construction, destruction
// Return the registered OLE class ID of this object's CfDataObj.
CLSID GetClassID() const;
// IServiceProvider
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
REFIID aIID,
void** aInstancePtr);
public: // COM interface IAccessible
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent(
/* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent);

View File

@ -29,6 +29,7 @@ CPPSRCS = \
Compatibility.cpp \
EnumVariant.cpp \
Platform.cpp \
ServiceProvider.cpp \
RootAccessibleWrap.cpp \
TextLeafAccessibleWrap.cpp \
$(NULL)

View File

@ -0,0 +1,117 @@
/* -*- 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/. */
#include "ServiceProvider.h"
#include "ApplicationAccessibleWrap.h"
#include "Compatibility.h"
#include "DocAccessible.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "uiaRawElmProvider.h"
#include "mozilla/Preferences.h"
#include "nsIDocShell.h"
#include "ISimpleDOMNode_i.c"
namespace mozilla {
namespace a11y {
IMPL_IUNKNOWN_QUERY_HEAD(ServiceProvider)
IMPL_IUNKNOWN_QUERY_IFACE(IServiceProvider)
return mAccessible->QueryInterface(aIID, aInstancePtr);
A11Y_TRYBLOCK_END
}
////////////////////////////////////////////////////////////////////////////////
// IServiceProvider
STDMETHODIMP
ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID,
void** aInstancePtr)
{
if (!aInstancePtr)
return E_INVALIDARG;
*aInstancePtr = NULL;
// UIA IAccessibleEx
if (aGuidService == IID_IAccessibleEx &&
Preferences::GetBool("accessibility.uia.enable")) {
uiaRawElmProvider* accEx = new uiaRawElmProvider(mAccessible);
HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
if (FAILED(hr))
delete accEx;
return hr;
}
// Provide a special service ID for getting the accessible for the browser tab
// document that contains this accessible object. If this accessible object
// is not inside a browser tab then the service fails with E_NOINTERFACE.
// A use case for this is for screen readers that need to switch context or
// 'virtual buffer' when focus moves from one browser tab area to another.
static const GUID SID_IAccessibleContentDocument =
{ 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
if (aGuidService == SID_IAccessibleContentDocument) {
if (aIID != IID_IAccessible)
return E_NOINTERFACE;
nsCOMPtr<nsIDocShell> docShell =
nsCoreUtils::GetDocShellFor(mAccessible->GetNode());
if (!docShell)
return E_UNEXPECTED;
// Walk up the parent chain without crossing the boundary at which item
// types change, preventing us from walking up out of tab content.
nsCOMPtr<nsIDocShellTreeItem> root;
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
if (!root)
return E_UNEXPECTED;
// If the item type is typeContent, we assume we are in browser tab content.
// Note this includes content such as about:addons, for consistency.
int32_t itemType;
root->GetItemType(&itemType);
if (itemType != nsIDocShellTreeItem::typeContent)
return E_NOINTERFACE;
// Make sure this is a document.
DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
if (!docAcc)
return E_UNEXPECTED;
*aInstancePtr = static_cast<IAccessible*>(docAcc);
(reinterpret_cast<IUnknown*>(*aInstancePtr))->AddRef();
return S_OK;
}
// Can get to IAccessibleApplication from any node via QS
if (aGuidService == IID_IAccessibleApplication ||
(Compatibility::IsJAWS() && aIID == IID_IAccessibleApplication)) {
ApplicationAccessibleWrap* applicationAcc =
static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
if (!applicationAcc)
return E_NOINTERFACE;
return applicationAcc->QueryInterface(aIID, aInstancePtr);
}
static const GUID IID_SimpleDOMDeprecated =
{ 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
if (aGuidService == IID_ISimpleDOMNode ||
aGuidService == IID_SimpleDOMDeprecated ||
aGuidService == IID_IAccessible || aGuidService == IID_IAccessible2)
return mAccessible->QueryInterface(aIID, aInstancePtr);
return E_INVALIDARG;
}
} // namespace a11y
} // namespace mozilla

View File

@ -0,0 +1,37 @@
/* -*- 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/. */
#ifndef mozilla_a11y_ServiceProvider_h_
#define mozilla_a11y_ServiceProvider_h_
#include <servprov.h>
#include "AccessibleWrap.h"
namespace mozilla {
namespace a11y {
class ServiceProvider MOZ_FINAL : public IServiceProvider
{
public:
ServiceProvider(AccessibleWrap* aAcc) : mRefCnt(0), mAccessible(aAcc) {}
~ServiceProvider() {}
DECL_IUNKNOWN
// IServiceProvider
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
REFIID aIID,
void** aInstancePtr);
private:
nsRefPtr<AccessibleWrap> mAccessible;
};
}
}
#endif

View File

@ -5,22 +5,9 @@
#include "nsAccessNodeWrap.h"
#include "AccessibleApplication.h"
#include "ApplicationAccessibleWrap.h"
#include "sdnAccessible.h"
#include "Compatibility.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "DocAccessible.h"
#include "nsWinUtils.h"
#include "RootAccessible.h"
#include "Statistics.h"
#include "nsAttrName.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMHTMLElement.h"
#include "nsINameSpaceManager.h"
#include "nsPIDOMWindow.h"
#include "nsIServiceManager.h"
@ -47,101 +34,6 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
NS_IMPL_ISUPPORTS_INHERITED0(nsAccessNodeWrap, nsAccessNode)
STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
{
*ppv = nullptr;
if (IID_IUnknown == iid) {
*ppv = static_cast<IUnknown*>(this);
} else {
return E_NOINTERFACE; //iid not supported.
}
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
return S_OK;
}
STDMETHODIMP
nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
{
*ppv = nullptr;
// Provide a special service ID for getting the accessible for the browser tab
// document that contains this accessible object. If this accessible object
// is not inside a browser tab then the service fails with E_NOINTERFACE.
// A use case for this is for screen readers that need to switch context or
// 'virtual buffer' when focus moves from one browser tab area to another.
static const GUID SID_IAccessibleContentDocument =
{ 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
if (guidService == SID_IAccessibleContentDocument) {
if (iid != IID_IAccessible)
return E_NOINTERFACE;
nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mContent);
if (!docShell)
return E_UNEXPECTED;
// Walk up the parent chain without crossing the boundary at which item
// types change, preventing us from walking up out of tab content.
nsCOMPtr<nsIDocShellTreeItem> root;
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
if (!root)
return E_UNEXPECTED;
// If the item type is typeContent, we assume we are in browser tab content.
// Note this includes content such as about:addons, for consistency.
int32_t itemType;
root->GetItemType(&itemType);
if (itemType != nsIDocShellTreeItem::typeContent)
return E_NOINTERFACE;
// Make sure this is a document.
DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
if (!docAcc)
return E_UNEXPECTED;
*ppv = static_cast<IAccessible*>(docAcc);
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
return S_OK;
}
// Can get to IAccessibleApplication from any node via QS
if (guidService == IID_IAccessibleApplication ||
(Compatibility::IsJAWS() && iid == IID_IAccessibleApplication)) {
ApplicationAccessibleWrap* applicationAcc =
static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
if (!applicationAcc)
return E_NOINTERFACE;
return applicationAcc->QueryInterface(iid, ppv);
}
/**
* To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
* or any IAccessible2 interface on should use IServiceProvider like this:
* -----------------------------------------------------------------------
* ISimpleDOMDocument *pAccDoc = NULL;
* IServiceProvider *pServProv = NULL;
* pAcc->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
* if (pServProv) {
* const GUID unused;
* pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
* pServProv->Release();
* }
*/
static const GUID IID_SimpleDOMDeprecated =
{ 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
if (guidService == IID_ISimpleDOMNode ||
guidService == IID_SimpleDOMDeprecated ||
guidService == IID_IAccessible || guidService == IID_IAccessible2)
return QueryInterface(iid, ppv);
return E_INVALIDARG;
}
int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo)
{
if (aCode == EXCEPTION_ACCESS_VIOLATION) {

View File

@ -53,8 +53,7 @@ namespace a11y {
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
#endif
class nsAccessNodeWrap : public nsAccessNode,
public IServiceProvider
class nsAccessNodeWrap : public nsAccessNode
{
public:
NS_DECL_ISUPPORTS_INHERITED
@ -63,15 +62,6 @@ public: // construction, destruction
nsAccessNodeWrap(nsIContent* aContent, DocAccessible* aDoc);
virtual ~nsAccessNodeWrap();
// IUnknown
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID aIID,
void** aInstancePtr);
// IServiceProvider
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
REFIID aIID,
void** aInstancePtr);
static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg,