|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=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 file, |
|
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "uiaRawElmProvider.h" |
|
8 |
|
9 #include "AccessibleWrap.h" |
|
10 #include "ARIAMap.h" |
|
11 #include "nsIPersistentProperties2.h" |
|
12 |
|
13 using namespace mozilla; |
|
14 using namespace mozilla::a11y; |
|
15 |
|
16 //////////////////////////////////////////////////////////////////////////////// |
|
17 // uiaRawElmProvider |
|
18 //////////////////////////////////////////////////////////////////////////////// |
|
19 |
|
20 IMPL_IUNKNOWN2(uiaRawElmProvider, |
|
21 IAccessibleEx, |
|
22 IRawElementProviderSimple) |
|
23 |
|
24 //////////////////////////////////////////////////////////////////////////////// |
|
25 // IAccessibleEx |
|
26 |
|
27 STDMETHODIMP |
|
28 uiaRawElmProvider::GetObjectForChild(long aIdChild, |
|
29 __RPC__deref_out_opt IAccessibleEx** aAccEx) |
|
30 { |
|
31 A11Y_TRYBLOCK_BEGIN |
|
32 |
|
33 if (!aAccEx) |
|
34 return E_INVALIDARG; |
|
35 |
|
36 *aAccEx = nullptr; |
|
37 |
|
38 return mAcc->IsDefunct() ? CO_E_OBJNOTCONNECTED : S_OK; |
|
39 |
|
40 A11Y_TRYBLOCK_END |
|
41 } |
|
42 |
|
43 STDMETHODIMP |
|
44 uiaRawElmProvider::GetIAccessiblePair(__RPC__deref_out_opt IAccessible** aAcc, |
|
45 __RPC__out long* aIdChild) |
|
46 { |
|
47 A11Y_TRYBLOCK_BEGIN |
|
48 |
|
49 if (!aAcc || !aIdChild) |
|
50 return E_INVALIDARG; |
|
51 |
|
52 *aAcc = nullptr; |
|
53 *aIdChild = 0; |
|
54 |
|
55 if (mAcc->IsDefunct()) |
|
56 return CO_E_OBJNOTCONNECTED; |
|
57 |
|
58 *aIdChild = CHILDID_SELF; |
|
59 *aAcc = mAcc; |
|
60 mAcc->AddRef(); |
|
61 |
|
62 return S_OK; |
|
63 |
|
64 A11Y_TRYBLOCK_END |
|
65 } |
|
66 |
|
67 STDMETHODIMP |
|
68 uiaRawElmProvider::GetRuntimeId(__RPC__deref_out_opt SAFEARRAY** aRuntimeIds) |
|
69 { |
|
70 A11Y_TRYBLOCK_BEGIN |
|
71 |
|
72 if (!aRuntimeIds) |
|
73 return E_INVALIDARG; |
|
74 |
|
75 int ids[] = { UiaAppendRuntimeId, static_cast<int>(reinterpret_cast<intptr_t>(mAcc->UniqueID())) }; |
|
76 *aRuntimeIds = SafeArrayCreateVector(VT_I4, 0, 2); |
|
77 if (!*aRuntimeIds) |
|
78 return E_OUTOFMEMORY; |
|
79 |
|
80 for (LONG i = 0; i < (LONG)ArrayLength(ids); i++) |
|
81 SafeArrayPutElement(*aRuntimeIds, &i, (void*)&(ids[i])); |
|
82 |
|
83 return S_OK; |
|
84 |
|
85 A11Y_TRYBLOCK_END |
|
86 } |
|
87 |
|
88 STDMETHODIMP |
|
89 uiaRawElmProvider::ConvertReturnedElement(__RPC__in_opt IRawElementProviderSimple* aRawElmProvider, |
|
90 __RPC__deref_out_opt IAccessibleEx** aAccEx) |
|
91 { |
|
92 A11Y_TRYBLOCK_BEGIN |
|
93 |
|
94 if (!aRawElmProvider || !aAccEx) |
|
95 return E_INVALIDARG; |
|
96 |
|
97 *aAccEx = nullptr; |
|
98 |
|
99 void* instancePtr = nullptr; |
|
100 HRESULT hr = aRawElmProvider->QueryInterface(IID_IAccessibleEx, &instancePtr); |
|
101 if (SUCCEEDED(hr)) |
|
102 *aAccEx = static_cast<IAccessibleEx*>(instancePtr); |
|
103 |
|
104 return hr; |
|
105 |
|
106 A11Y_TRYBLOCK_END |
|
107 } |
|
108 |
|
109 //////////////////////////////////////////////////////////////////////////////// |
|
110 // IRawElementProviderSimple |
|
111 |
|
112 STDMETHODIMP |
|
113 uiaRawElmProvider::get_ProviderOptions(__RPC__out enum ProviderOptions* aOptions) |
|
114 { |
|
115 A11Y_TRYBLOCK_BEGIN |
|
116 |
|
117 if (!aOptions) |
|
118 return E_INVALIDARG; |
|
119 |
|
120 // This method is not used with IAccessibleEx implementations. |
|
121 *aOptions = ProviderOptions_ServerSideProvider; |
|
122 return S_OK; |
|
123 |
|
124 A11Y_TRYBLOCK_END |
|
125 } |
|
126 |
|
127 STDMETHODIMP |
|
128 uiaRawElmProvider::GetPatternProvider(PATTERNID aPatternId, |
|
129 __RPC__deref_out_opt IUnknown** aPatternProvider) |
|
130 { |
|
131 A11Y_TRYBLOCK_BEGIN |
|
132 |
|
133 if (!aPatternProvider) |
|
134 return E_INVALIDARG; |
|
135 |
|
136 *aPatternProvider = nullptr; |
|
137 return S_OK; |
|
138 |
|
139 A11Y_TRYBLOCK_END |
|
140 } |
|
141 |
|
142 STDMETHODIMP |
|
143 uiaRawElmProvider::GetPropertyValue(PROPERTYID aPropertyId, |
|
144 __RPC__out VARIANT* aPropertyValue) |
|
145 { |
|
146 A11Y_TRYBLOCK_BEGIN |
|
147 |
|
148 if (!aPropertyValue) |
|
149 return E_INVALIDARG; |
|
150 |
|
151 if (mAcc->IsDefunct()) |
|
152 return CO_E_OBJNOTCONNECTED; |
|
153 |
|
154 aPropertyValue->vt = VT_EMPTY; |
|
155 |
|
156 switch (aPropertyId) { |
|
157 // Accelerator Key / shortcut. |
|
158 case UIA_AcceleratorKeyPropertyId: { |
|
159 nsAutoString keyString; |
|
160 |
|
161 mAcc->KeyboardShortcut().ToString(keyString); |
|
162 |
|
163 if (!keyString.IsEmpty()) { |
|
164 aPropertyValue->vt = VT_BSTR; |
|
165 aPropertyValue->bstrVal = ::SysAllocString(keyString.get()); |
|
166 return S_OK; |
|
167 } |
|
168 |
|
169 break; |
|
170 } |
|
171 |
|
172 // Access Key / mneumonic. |
|
173 case UIA_AccessKeyPropertyId: { |
|
174 nsAutoString keyString; |
|
175 |
|
176 mAcc->AccessKey().ToString(keyString); |
|
177 |
|
178 if (!keyString.IsEmpty()) { |
|
179 aPropertyValue->vt = VT_BSTR; |
|
180 aPropertyValue->bstrVal = ::SysAllocString(keyString.get()); |
|
181 return S_OK; |
|
182 } |
|
183 |
|
184 break; |
|
185 } |
|
186 |
|
187 //ARIA Role / shortcut |
|
188 case UIA_AriaRolePropertyId: { |
|
189 nsAutoString xmlRoles; |
|
190 |
|
191 nsCOMPtr<nsIPersistentProperties> attributes = mAcc->Attributes(); |
|
192 attributes->GetStringProperty(NS_LITERAL_CSTRING("xml-roles"), xmlRoles); |
|
193 |
|
194 if(!xmlRoles.IsEmpty()) { |
|
195 aPropertyValue->vt = VT_BSTR; |
|
196 aPropertyValue->bstrVal = ::SysAllocString(xmlRoles.get()); |
|
197 return S_OK; |
|
198 } |
|
199 |
|
200 break; |
|
201 } |
|
202 |
|
203 //ARIA Properties |
|
204 case UIA_AriaPropertiesPropertyId: { |
|
205 nsAutoString ariaProperties; |
|
206 |
|
207 aria::AttrIterator attribIter(mAcc->GetContent()); |
|
208 nsAutoString attribName, attribValue; |
|
209 while (attribIter.Next(attribName, attribValue)) { |
|
210 ariaProperties.Append(attribName); |
|
211 ariaProperties.Append('='); |
|
212 ariaProperties.Append(attribValue); |
|
213 ariaProperties.Append(';'); |
|
214 } |
|
215 |
|
216 if (!ariaProperties.IsEmpty()) { |
|
217 //remove last delimiter: |
|
218 ariaProperties.Truncate(ariaProperties.Length()-1); |
|
219 aPropertyValue->vt = VT_BSTR; |
|
220 aPropertyValue->bstrVal = ::SysAllocString(ariaProperties.get()); |
|
221 return S_OK; |
|
222 } |
|
223 |
|
224 break; |
|
225 } |
|
226 } |
|
227 |
|
228 return S_OK; |
|
229 |
|
230 A11Y_TRYBLOCK_END |
|
231 } |
|
232 |
|
233 STDMETHODIMP |
|
234 uiaRawElmProvider::get_HostRawElementProvider(__RPC__deref_out_opt IRawElementProviderSimple** aRawElmProvider) |
|
235 { |
|
236 A11Y_TRYBLOCK_BEGIN |
|
237 |
|
238 if (!aRawElmProvider) |
|
239 return E_INVALIDARG; |
|
240 |
|
241 // This method is not used with IAccessibleEx implementations. |
|
242 *aRawElmProvider = nullptr; |
|
243 return S_OK; |
|
244 |
|
245 A11Y_TRYBLOCK_END |
|
246 } |