Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: webkit/glue/glue_accessibility.cc

Issue 4057: Adds MSAA/IAccessible exposure of web content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <comdef.h>
6
7 #include "config.h"
8
9 #pragma warning(push, 0)
10 #include "AccessibleDocument.h"
11 #include "AXObjectCache.h"
12 #include "Document.h"
13 #include "Frame.h"
14 #pragma warning(pop)
15 #undef LOG
16
17 #include "webkit/glue/glue_accessibility.h"
18
19 #include "chrome/browser/iaccessible_function_ids.h"
20 #include "webkit/glue/webframe_impl.h"
21 #include "webkit/glue/webview_impl.h"
22
23 // struct GlueAccessibility::GlueAccessibilityRoot
24 struct GlueAccessibility::GlueAccessibilityRoot {
25 GlueAccessibilityRoot() {}
26
27 // Root of the WebKit IAccessible tree.
28 COMPtr<AccessibleDocument> accessibility_root_;
29 };
30
31 // class GlueAccessibility
32 GlueAccessibility::GlueAccessibility()
33 : root_(new GlueAccessibilityRoot) {
34 }
35
36 GlueAccessibility::~GlueAccessibility() {
37 delete root_;
38 }
39
40 bool GlueAccessibility::GetAccessibilityInfo(WebView* view,
41 const ViewMsg_Accessibility_In_Params& in_params,
42 ViewHostMsg_Accessibility_Out_Params* out_params) {
43 if (!root_->accessibility_root_ && !InitAccessibilityRoot(view)) {
44 // Failure in retrieving the root.
45 return false;
46 }
47
48 // Temporary storing for the currently active IAccessible.
49 COMPtr<IAccessible> active_iaccessible;
50 IntToIAccessibleMap::iterator it =
51 int_to_iaccessible_map_.find(in_params.iaccessible_id);
52
53 if (it == int_to_iaccessible_map_.end()) {
54 // Map did not contain the data requested.
55 return false;
56 }
57
58 active_iaccessible = it->second;
59
60 if (!active_iaccessible) {
61 // Requested IAccessible not found. Paranoia check.
62 NOTREACHED();
63 return false;
64 }
65
66 // Input VARIANT, determined by the browser side to be of type VT_I4.
67 VARIANT input_variant;
68 input_variant.vt = VT_I4;
69 input_variant.lVal = in_params.input_variant_lval;
70
71 // Output variables, used locally to retrieve data.
72 VARIANT output_variant;
73 ::VariantInit(&output_variant);
74 BSTR output_bstr;
75 bool string_output = false;
76 HRESULT hr = S_FALSE;
77
78 switch (in_params.iaccessible_function_id) {
79 case IACCESSIBLE_FUNC_ACCDODEFAULTACTION :
80 hr = active_iaccessible->accDoDefaultAction(input_variant);
81 break;
82 case IACCESSIBLE_FUNC_ACCHITTEST :
83 hr = active_iaccessible->accHitTest(in_params.input_long1,
84 in_params.input_long2,
85 &output_variant);
86 break;
87 case IACCESSIBLE_FUNC_ACCLOCATION :
88 hr = active_iaccessible->accLocation(&out_params->output_long1,
89 &out_params->output_long2,
90 &out_params->output_long3,
91 &out_params->output_long4,
92 input_variant);
93 break;
94 case IACCESSIBLE_FUNC_ACCNAVIGATE :
95 hr = active_iaccessible->accNavigate(in_params.input_long1, input_variant,
96 &output_variant);
97 break;
98 case IACCESSIBLE_FUNC_GET_ACCCHILD :
99 if (input_variant.lVal == CHILDID_SELF) {
100 // If child requested is CHILDID_SELF, stay with the same IAccessible.
101 out_params->iaccessible_id = in_params.iaccessible_id;
102 hr = S_OK;
103 break;
104 }
105 hr = active_iaccessible->get_accChild(input_variant,
106 reinterpret_cast<IDispatch **>(&output_variant.pdispVal));
107 output_variant.vt = VT_DISPATCH;
108 break;
109 case IACCESSIBLE_FUNC_GET_ACCCHILDCOUNT :
110 hr = active_iaccessible->get_accChildCount(&out_params->output_long1);
111 break;
112 case IACCESSIBLE_FUNC_GET_ACCDEFAULTACTION :
113 hr = active_iaccessible->get_accDefaultAction(input_variant,
114 &output_bstr);
115 string_output = true;
116 break;
117 case IACCESSIBLE_FUNC_GET_ACCDESCRIPTION :
118 hr = active_iaccessible->get_accDescription(input_variant, &output_bstr);
119 string_output = true;
120 break;
121 case IACCESSIBLE_FUNC_GET_ACCFOCUS :
122 hr = active_iaccessible->get_accFocus(&output_variant);
123 break;
124 case IACCESSIBLE_FUNC_GET_ACCHELP :
125 hr = active_iaccessible->get_accHelp(input_variant, &output_bstr);
126 string_output = true;
127 break;
128 case IACCESSIBLE_FUNC_GET_ACCKEYBOARDSHORTCUT :
129 hr = active_iaccessible->get_accKeyboardShortcut(input_variant,
130 &output_bstr);
131 string_output = true;
132 break;
133 case IACCESSIBLE_FUNC_GET_ACCNAME :
134 hr = active_iaccessible->get_accName(input_variant, &output_bstr);
135 string_output = true;
136 break;
137 case IACCESSIBLE_FUNC_GET_ACCPARENT :
138 hr = active_iaccessible->get_accParent(
139 reinterpret_cast<IDispatch **>(&output_variant.pdispVal));
140 output_variant.vt = VT_DISPATCH;
141 break;
142 case IACCESSIBLE_FUNC_GET_ACCROLE :
143 hr = active_iaccessible->get_accRole(input_variant, &output_variant);
144 break;
145 case IACCESSIBLE_FUNC_GET_ACCSTATE :
146 hr = active_iaccessible->get_accState(input_variant, &output_variant);
147 break;
148 case IACCESSIBLE_FUNC_GET_ACCVALUE :
149 hr = active_iaccessible->get_accValue(input_variant, &output_bstr);
150 string_output = true;
151 break;
152 default:
153 // Memory cleanup.
154 ::VariantClear(&input_variant);
155 ::VariantClear(&output_variant);
156
157 // Non-supported function id.
158 return false;
159 }
160
161 // Return code handling.
162 if (hr == S_OK) {
163 out_params->return_code = true;
164
165 // All is ok, assign output string if needed.
166 if (string_output) {
167 out_params->output_string = _bstr_t(output_bstr);
168 ::SysFreeString(output_bstr);
169 }
170
171 } else if (hr == S_FALSE) {
172 out_params->return_code = false;
173 } else {
174 // Memory cleanup.
175 ::VariantClear(&input_variant);
176 ::VariantClear(&output_variant);
177
178 // Generate a generic failure on the browser side. Input validation is the
179 // responsibility of the browser side, as is correctly handling calls to
180 // non-supported functions appropriately.
181 return false;
182 }
183
184 // Output and hashmap assignments, as appropriate.
185 if (output_variant.vt == VT_DISPATCH && output_variant.pdispVal) {
186 IAccessibleToIntMap::iterator it =
187 iaccessible_to_int_map_.find(
188 reinterpret_cast<IAccessible *>(output_variant.pdispVal));
189
190 if (it != iaccessible_to_int_map_.end()) {
191 // Data already present in map, return previously assigned id.
192 out_params->iaccessible_id = it->second;
193 out_params->output_long1 = -1;
194 } else {
195 // Insert new IAccessible in hashmaps.
196 int_to_iaccessible_map_[iaccessible_id_] =
197 reinterpret_cast<IAccessible *>(output_variant.pdispVal);
198 iaccessible_to_int_map_[
199 reinterpret_cast<IAccessible *>(output_variant.pdispVal)] =
200 iaccessible_id_;
201 out_params->iaccessible_id = iaccessible_id_++;
202 out_params->output_long1 = -1;
203 }
204 } else if (output_variant.vt == VT_I4) {
205 out_params->output_long1 = output_variant.lVal;
206 }
207
208 // Memory cleanup.
209 ::VariantClear(&input_variant);
210 ::VariantClear(&output_variant);
211
212 return true;
213 }
214
215 bool GlueAccessibility::InitAccessibilityRoot(WebView* view) {
216 WebCore::AXObjectCache::enableAccessibility();
217 iaccessible_id_ = 0;
218
219 WebFrame* main_frame = view->GetMainFrame();
220
221 if (!main_frame)
222 return false;
223
224 WebFrameImpl* main_frame_impl = static_cast<WebFrameImpl*>(main_frame);
225 WebCore::Frame* frame = main_frame_impl->frame();
226
227 WebCore::Document* currentDocument = frame->document();
228 if (!currentDocument) {
229 root_->accessibility_root_ = 0;
230 return false;
231 } else if (!root_->accessibility_root_ ||
232 root_->accessibility_root_->document() != currentDocument) {
233 // Either we've never had a wrapper for this frame's top-level Document,
234 // the Document renderer was destroyed and its wrapper was detached, or
235 // the previous Document is in the page cache, and the current document
236 // needs to be wrapped.
237 root_->accessibility_root_ = new AccessibleDocument(currentDocument);
238 }
239 // Insert root in hashmaps.
240 int_to_iaccessible_map_[iaccessible_id_] = root_->accessibility_root_.get();
241 iaccessible_to_int_map_[root_->accessibility_root_.get()] = iaccessible_id_++;
242
243 return true;
244 }
245
246 bool GlueAccessibility::ClearIAccessibleMap(int iaccessible_id,
247 bool clear_all) {
248 if (clear_all) {
249 // Clear maps and invalidate root.
250 int_to_iaccessible_map_.clear();
251 iaccessible_to_int_map_.clear();
252 root_->accessibility_root_ = 0;
253 return true;
254 }
255
256 IntToIAccessibleMap::iterator it =
257 int_to_iaccessible_map_.find(iaccessible_id);
258
259 if (it == int_to_iaccessible_map_.end()) {
260 // Element not found.
261 return false;
262 } else {
263 if (it->second) {
264 // Erase element from reverse hashmap.
265 IAccessibleToIntMap::iterator it2 =
266 iaccessible_to_int_map_.find(it->second);
267
268 DCHECK(it2 != iaccessible_to_int_map_.end());
269 iaccessible_to_int_map_.erase(it2);
270 }
271
272 int_to_iaccessible_map_.erase(it);
273
274 if (iaccessible_id == 0) {
275 // Invalidate root.
276 root_->accessibility_root_ = 0;
277 }
278 }
279
280 return true;
281 }
OLDNEW
« webkit/glue/glue_accessibility.h ('K') | « webkit/glue/glue_accessibility.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698