|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "ServiceProvider.h" |
|
8 |
|
9 #include "ApplicationAccessibleWrap.h" |
|
10 #include "Compatibility.h" |
|
11 #include "DocAccessible.h" |
|
12 #include "nsAccUtils.h" |
|
13 #include "nsCoreUtils.h" |
|
14 #include "Relation.h" |
|
15 #include "uiaRawElmProvider.h" |
|
16 |
|
17 #include "mozilla/Preferences.h" |
|
18 #include "nsIDocShell.h" |
|
19 |
|
20 #include "ISimpleDOMNode_i.c" |
|
21 |
|
22 namespace mozilla { |
|
23 namespace a11y { |
|
24 |
|
25 IMPL_IUNKNOWN_QUERY_HEAD(ServiceProvider) |
|
26 IMPL_IUNKNOWN_QUERY_IFACE(IServiceProvider) |
|
27 IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAccessible) |
|
28 |
|
29 |
|
30 //////////////////////////////////////////////////////////////////////////////// |
|
31 // IServiceProvider |
|
32 |
|
33 STDMETHODIMP |
|
34 ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID, |
|
35 void** aInstancePtr) |
|
36 { |
|
37 if (!aInstancePtr) |
|
38 return E_INVALIDARG; |
|
39 |
|
40 *aInstancePtr = nullptr; |
|
41 |
|
42 // UIA IAccessibleEx |
|
43 if (aGuidService == IID_IAccessibleEx && |
|
44 Preferences::GetBool("accessibility.uia.enable")) { |
|
45 uiaRawElmProvider* accEx = new uiaRawElmProvider(mAccessible); |
|
46 HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr); |
|
47 if (FAILED(hr)) |
|
48 delete accEx; |
|
49 |
|
50 return hr; |
|
51 } |
|
52 |
|
53 // Provide a special service ID for getting the accessible for the browser tab |
|
54 // document that contains this accessible object. If this accessible object |
|
55 // is not inside a browser tab then the service fails with E_NOINTERFACE. |
|
56 // A use case for this is for screen readers that need to switch context or |
|
57 // 'virtual buffer' when focus moves from one browser tab area to another. |
|
58 static const GUID SID_IAccessibleContentDocument = |
|
59 { 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} }; |
|
60 if (aGuidService == SID_IAccessibleContentDocument) { |
|
61 if (aIID != IID_IAccessible) |
|
62 return E_NOINTERFACE; |
|
63 |
|
64 Relation rel = mAccessible->RelationByType(RelationType::CONTAINING_TAB_PANE); |
|
65 AccessibleWrap* tabDoc = static_cast<AccessibleWrap*>(rel.Next()); |
|
66 if (!tabDoc) |
|
67 return E_NOINTERFACE; |
|
68 |
|
69 *aInstancePtr = static_cast<IAccessible*>(tabDoc); |
|
70 (reinterpret_cast<IUnknown*>(*aInstancePtr))->AddRef(); |
|
71 return S_OK; |
|
72 } |
|
73 |
|
74 // Can get to IAccessibleApplication from any node via QS |
|
75 if (aGuidService == IID_IAccessibleApplication || |
|
76 (Compatibility::IsJAWS() && aIID == IID_IAccessibleApplication)) { |
|
77 ApplicationAccessibleWrap* applicationAcc = |
|
78 static_cast<ApplicationAccessibleWrap*>(ApplicationAcc()); |
|
79 if (!applicationAcc) |
|
80 return E_NOINTERFACE; |
|
81 |
|
82 return applicationAcc->QueryInterface(aIID, aInstancePtr); |
|
83 } |
|
84 |
|
85 static const GUID IID_SimpleDOMDeprecated = |
|
86 { 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} }; |
|
87 if (aGuidService == IID_ISimpleDOMNode || |
|
88 aGuidService == IID_SimpleDOMDeprecated || |
|
89 aGuidService == IID_IAccessible || aGuidService == IID_IAccessible2) |
|
90 return mAccessible->QueryInterface(aIID, aInstancePtr); |
|
91 |
|
92 return E_INVALIDARG; |
|
93 } |
|
94 |
|
95 } // namespace a11y |
|
96 } // namespace mozilla |