OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "webkit/glue/webaccessibility.h" |
6 | 6 |
7 #include "AXObjectCache.h" | 7 #include "webkit/api/public/WebAccessibilityCache.h" |
8 #include "Document.h" | |
9 #include "Frame.h" | |
10 #include "RefPtr.h" | |
11 #undef LOG | |
12 | |
13 #include "webkit/glue/webaccessibilitymanager_impl.h" | |
14 | |
15 #include "webkit/api/public/WebAccessibilityObject.h" | 8 #include "webkit/api/public/WebAccessibilityObject.h" |
16 #include "webkit/api/src/WebFrameImpl.h" | 9 #include "webkit/api/public/WebAccessibilityRole.h" |
17 #include "webkit/api/src/WebViewImpl.h" | 10 #include "webkit/api/public/WebPoint.h" |
18 #include "webkit/glue/glue_accessibility_object.h" | 11 #include "webkit/api/public/WebRect.h" |
19 #include "webkit/glue/glue_util.h" | 12 #include "webkit/api/public/WebString.h" |
20 | 13 |
| 14 using WebKit::WebAccessibilityCache; |
| 15 using WebKit::WebAccessibilityRole; |
21 using WebKit::WebAccessibilityObject; | 16 using WebKit::WebAccessibilityObject; |
22 using WebKit::WebFrameImpl; | 17 using WebKit::WebPoint; |
23 using WebKit::WebView; | 18 using WebKit::WebRect; |
| 19 using WebKit::WebString; |
24 | 20 |
25 namespace webkit_glue { | 21 namespace webkit_glue { |
26 | 22 |
27 // struct WebAccessibilityManagerImpl::GlueAccessibilityObjectRoot | 23 // Provides a conversion between the WebKit::WebAccessibilityRole and a role |
28 struct WebAccessibilityManagerImpl::GlueAccessibilityObjectRoot { | 24 // supported on the Browser side. Listed alphabetically by the |
29 GlueAccessibilityObjectRoot() {} | 25 // WebAccessibilityRole (except for default role). |
30 | 26 WebAccessibility::Role ConvertRole(WebKit::WebAccessibilityRole role) { |
31 // Root of the WebKit AccessibilityObject tree. | 27 switch (role) { |
32 RefPtr<GlueAccessibilityObject> acc_obj_root_; | 28 case WebKit::WebAccessibilityRoleLandmarkApplication: |
33 }; | 29 return WebAccessibility::ROLE_APPLICATION; |
34 | 30 case WebKit::WebAccessibilityRoleCell: |
35 /*static*/ | 31 return WebAccessibility::ROLE_CELL; |
36 WebAccessibilityManager* WebAccessibilityManager::Create() { | 32 case WebKit::WebAccessibilityRoleCheckBox: |
37 return new WebAccessibilityManagerImpl(); | 33 return WebAccessibility::ROLE_CHECKBUTTON; |
| 34 case WebKit::WebAccessibilityRoleColumn: |
| 35 return WebAccessibility::ROLE_COLUMN; |
| 36 case WebKit::WebAccessibilityRoleColumnHeader: |
| 37 return WebAccessibility::ROLE_COLUMNHEADER; |
| 38 case WebKit::WebAccessibilityRoleDocumentArticle: |
| 39 case WebKit::WebAccessibilityRoleWebArea: |
| 40 return WebAccessibility::ROLE_DOCUMENT; |
| 41 case WebKit::WebAccessibilityRoleImageMap: |
| 42 case WebKit::WebAccessibilityRoleImage: |
| 43 return WebAccessibility::ROLE_GRAPHIC; |
| 44 case WebKit::WebAccessibilityRoleDocumentRegion: |
| 45 case WebKit::WebAccessibilityRoleRadioGroup: |
| 46 case WebKit::WebAccessibilityRoleGroup: |
| 47 return WebAccessibility::ROLE_GROUPING; |
| 48 case WebKit::WebAccessibilityRoleLink: |
| 49 case WebKit::WebAccessibilityRoleWebCoreLink: |
| 50 return WebAccessibility::ROLE_LINK; |
| 51 case WebKit::WebAccessibilityRoleList: |
| 52 return WebAccessibility::ROLE_LIST; |
| 53 case WebKit::WebAccessibilityRoleListBox: |
| 54 return WebAccessibility::ROLE_LISTBOX; |
| 55 case WebKit::WebAccessibilityRoleListBoxOption: |
| 56 return WebAccessibility::ROLE_LISTITEM; |
| 57 case WebKit::WebAccessibilityRoleMenuBar: |
| 58 return WebAccessibility::ROLE_MENUBAR; |
| 59 case WebKit::WebAccessibilityRoleMenuButton: |
| 60 case WebKit::WebAccessibilityRoleMenuItem: |
| 61 return WebAccessibility::ROLE_MENUITEM; |
| 62 case WebKit::WebAccessibilityRoleMenu: |
| 63 return WebAccessibility::ROLE_MENUPOPUP; |
| 64 case WebKit::WebAccessibilityRoleOutline: |
| 65 return WebAccessibility::ROLE_OUTLINE; |
| 66 case WebKit::WebAccessibilityRoleTabGroup: |
| 67 return WebAccessibility::ROLE_PAGETABLIST; |
| 68 case WebKit::WebAccessibilityRoleProgressIndicator: |
| 69 return WebAccessibility::ROLE_PROGRESSBAR; |
| 70 case WebKit::WebAccessibilityRoleButton: |
| 71 return WebAccessibility::ROLE_PUSHBUTTON; |
| 72 case WebKit::WebAccessibilityRoleRadioButton: |
| 73 return WebAccessibility::ROLE_RADIOBUTTON; |
| 74 case WebKit::WebAccessibilityRoleRow: |
| 75 return WebAccessibility::ROLE_ROW; |
| 76 case WebKit::WebAccessibilityRoleRowHeader: |
| 77 return WebAccessibility::ROLE_ROWHEADER; |
| 78 case WebKit::WebAccessibilityRoleSplitter: |
| 79 return WebAccessibility::ROLE_SEPARATOR; |
| 80 case WebKit::WebAccessibilityRoleSlider: |
| 81 return WebAccessibility::ROLE_SLIDER; |
| 82 case WebKit::WebAccessibilityRoleStaticText: |
| 83 return WebAccessibility::ROLE_STATICTEXT; |
| 84 case WebKit::WebAccessibilityRoleApplicationStatus: |
| 85 return WebAccessibility::ROLE_STATUSBAR; |
| 86 case WebKit::WebAccessibilityRoleTable: |
| 87 return WebAccessibility::ROLE_TABLE; |
| 88 case WebKit::WebAccessibilityRoleListMarker: |
| 89 case WebKit::WebAccessibilityRoleTextField: |
| 90 case WebKit::WebAccessibilityRoleTextArea: |
| 91 return WebAccessibility::ROLE_TEXT; |
| 92 case WebKit::WebAccessibilityRoleToolbar: |
| 93 return WebAccessibility::ROLE_TOOLBAR; |
| 94 case WebKit::WebAccessibilityRoleUserInterfaceTooltip: |
| 95 return WebAccessibility::ROLE_TOOLTIP; |
| 96 case WebKit::WebAccessibilityRoleDocument: |
| 97 case WebKit::WebAccessibilityRoleUnknown: |
| 98 default: |
| 99 // This is the default role. |
| 100 return WebAccessibility::ROLE_CLIENT; |
| 101 } |
38 } | 102 } |
39 | 103 |
40 // class WebAccessibilityManagerImpl | 104 long ConvertState(const WebAccessibilityObject& o) { |
41 WebAccessibilityManagerImpl::WebAccessibilityManagerImpl() | 105 long state = 0; |
42 : root_(new GlueAccessibilityObjectRoot), | 106 if (o.isChecked()) |
43 acc_obj_id_(1000) { | 107 state |= static_cast<long>(1 << WebAccessibility::STATE_CHECKED); |
| 108 |
| 109 if (o.canSetFocusAttribute()) |
| 110 state |= static_cast<long>(1 << WebAccessibility::STATE_FOCUSABLE); |
| 111 |
| 112 if (o.isFocused()) |
| 113 state |= static_cast<long>(1 << WebAccessibility::STATE_FOCUSED); |
| 114 |
| 115 if (o.isHovered()) |
| 116 state |= static_cast<long>(1 << WebAccessibility::STATE_HOTTRACKED); |
| 117 |
| 118 if (o.isIndeterminate()) |
| 119 state |= static_cast<long>(1 << WebAccessibility::STATE_INDETERMINATE); |
| 120 |
| 121 if (o.isAnchor()) |
| 122 state |= static_cast<long>(1 << WebAccessibility::STATE_LINKED); |
| 123 |
| 124 if (o.isMultiSelect()) |
| 125 state |= static_cast<long>(1 << WebAccessibility::STATE_MULTISELECTABLE); |
| 126 |
| 127 if (o.isOffScreen()) |
| 128 state |= static_cast<long>(1 << WebAccessibility::STATE_OFFSCREEN); |
| 129 |
| 130 if (o.isPressed()) |
| 131 state |= static_cast<long>(1 << WebAccessibility::STATE_PRESSED); |
| 132 |
| 133 if (o.isPasswordField()) |
| 134 state |= static_cast<long>(1 << WebAccessibility::STATE_PROTECTED); |
| 135 |
| 136 if (o.isReadOnly()) |
| 137 state |= static_cast<long>(1 << WebAccessibility::STATE_READONLY); |
| 138 |
| 139 if (o.isVisited()) |
| 140 state |= static_cast<long>(1 << WebAccessibility::STATE_TRAVERSED); |
| 141 |
| 142 if (!o.isEnabled()) |
| 143 state |= static_cast<long>(1 << WebAccessibility::STATE_UNAVAILABLE); |
| 144 |
| 145 return state; |
44 } | 146 } |
45 | 147 |
46 WebAccessibilityManagerImpl::~WebAccessibilityManagerImpl() { | 148 |
47 int_to_glue_acc_obj_map_.clear(); | 149 bool WebAccessibility::GetAccObjInfo(WebAccessibilityCache* cache, |
48 acc_obj_to_int_map_.clear(); | |
49 } | |
50 | |
51 bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view, | |
52 const WebAccessibility::InParams& in_params, | 150 const WebAccessibility::InParams& in_params, |
53 WebAccessibility::OutParams* out_params) { | 151 WebAccessibility::OutParams* out_params) { |
54 if (!root_->acc_obj_root_ && !InitAccObjRoot(view)) { | 152 |
55 // Failure in retrieving or initializing the root. | 153 // Find object requested by |object_id|. |
56 return false; | 154 WebAccessibilityObject active_acc_obj; |
57 } | |
58 | |
59 // Function input parameters. | |
60 int object_id = in_params.object_id; | |
61 int child_id = in_params.child_id; | |
62 | 155 |
63 // Since ids assigned by Chrome starts at 1000, whereas platform-specific ids | 156 // Since ids assigned by Chrome starts at 1000, whereas platform-specific ids |
64 // used to reference a child will be in a wholly different range, we know | 157 // used to reference a child will be in a wholly different range, we know |
65 // that any id that high should be treated as a non-direct descendant. | 158 // that any id that high should be treated as a non-direct descendant. |
66 if (in_params.child_id >= 1000) { | 159 bool local_child = false; |
| 160 if (cache->isValidId(in_params.child_id)) { |
67 // Object is not a direct child, re-map the input parameters accordingly. | 161 // Object is not a direct child, re-map the input parameters accordingly. |
68 // The object to be retrieved is referred to by the |in_params.child_id|, as | 162 // The object to be retrieved is referred to by the |in_params.child_id|, as |
69 // a result of e.g. a focus event. The local |child_id| is set to 0, to | 163 // a result of e.g. a focus event. |
70 // indicate that any function call should refer to the object itself. | 164 active_acc_obj = cache->getObjectById(in_params.child_id); |
71 object_id = in_params.child_id; | 165 } else { |
72 child_id = 0; | 166 local_child = true; |
| 167 |
| 168 active_acc_obj = cache->getObjectById(in_params.object_id); |
| 169 if (active_acc_obj.isNull()) |
| 170 return false; |
| 171 |
| 172 // child_id == 0 means self. Otherwise, it's a local child - 1. |
| 173 if (in_params.child_id > 0) { |
| 174 unsigned index = in_params.child_id - 1; |
| 175 if (index >= active_acc_obj.childCount()) |
| 176 return false; |
| 177 |
| 178 active_acc_obj = active_acc_obj.childAt(index); |
| 179 } |
73 } | 180 } |
74 | 181 |
75 // Find GlueAccessibilityObject requested by |object_id|. | 182 if (active_acc_obj.isNull()) |
76 IntToGlueAccObjMap::iterator it = | |
77 int_to_glue_acc_obj_map_.find(object_id); | |
78 if (it == int_to_glue_acc_obj_map_.end() || !it->second) { | |
79 // Map did not contain a valid instance of the data requested. | |
80 return false; | 183 return false; |
81 } | |
82 RefPtr<GlueAccessibilityObject> active_acc_obj = it->second; | |
83 | 184 |
84 // Temp paramters for holding output information. | 185 // Temp paramters for holding output information. |
85 RefPtr<GlueAccessibilityObject> out_acc_obj = NULL; | 186 WebAccessibilityObject out_acc_obj; |
86 WebCore::String out_string; | 187 string16 out_string; |
87 | 188 |
88 switch (in_params.function_id) { | 189 switch (in_params.function_id) { |
89 case WebAccessibility::FUNCTION_DODEFAULTACTION : | 190 case WebAccessibility::FUNCTION_DODEFAULTACTION: { |
90 if (!active_acc_obj->DoDefaultAction(child_id)) | 191 if (!active_acc_obj.performDefaultAction()) |
91 return false; | 192 return false; |
92 break; | 193 break; |
93 case WebAccessibility::FUNCTION_HITTEST : | 194 } |
94 out_acc_obj = active_acc_obj->HitTest(in_params.input_long1, | 195 case WebAccessibility::FUNCTION_HITTEST: { |
95 in_params.input_long2); | 196 WebPoint point(in_params.input_long1, in_params.input_long2); |
96 if (!out_acc_obj.get()) | 197 out_acc_obj = active_acc_obj.hitTest(point); |
97 return false; | 198 if (out_acc_obj.isNull()) |
98 break; | 199 return false; |
99 case WebAccessibility::FUNCTION_LOCATION : | 200 break; |
100 if (!active_acc_obj->Location(&out_params->output_long1, | 201 } |
101 &out_params->output_long2, | 202 case WebAccessibility::FUNCTION_LOCATION: { |
102 &out_params->output_long3, | 203 WebRect rect = active_acc_obj.boundingBoxRect(); |
103 &out_params->output_long4, | 204 out_params->output_long1 = rect.x; |
104 child_id)) { | 205 out_params->output_long2 = rect.y; |
105 return false; | 206 out_params->output_long3 = rect.width; |
| 207 out_params->output_long4 = rect.height; |
| 208 break; |
| 209 } |
| 210 case WebAccessibility::FUNCTION_NAVIGATE: { |
| 211 WebAccessibility::Direction dir = |
| 212 static_cast<WebAccessibility::Direction>(in_params.input_long1); |
| 213 switch (dir) { |
| 214 case WebAccessibility::DIRECTION_DOWN: |
| 215 case WebAccessibility::DIRECTION_UP: |
| 216 case WebAccessibility::DIRECTION_LEFT: |
| 217 case WebAccessibility::DIRECTION_RIGHT: |
| 218 // These directions are not implemented, matching Mozilla and IE. |
| 219 return false; |
| 220 case WebAccessibility::DIRECTION_LASTCHILD: |
| 221 case WebAccessibility::DIRECTION_FIRSTCHILD: |
| 222 // MSDN states that navigating to first/last child can only be from |
| 223 // self. |
| 224 if (!local_child) |
| 225 return false; |
| 226 |
| 227 if (dir == WebAccessibility::DIRECTION_FIRSTCHILD) { |
| 228 out_acc_obj = active_acc_obj.firstChild(); |
| 229 } else { |
| 230 out_acc_obj = active_acc_obj.lastChild(); |
| 231 } |
| 232 break; |
| 233 case WebAccessibility::DIRECTION_NEXT: |
| 234 case WebAccessibility::DIRECTION_PREVIOUS: { |
| 235 if (dir == WebAccessibility::DIRECTION_NEXT) { |
| 236 out_acc_obj = active_acc_obj.nextSibling(); |
| 237 } else { |
| 238 out_acc_obj = active_acc_obj.previousSibling(); |
| 239 } |
| 240 break; |
| 241 } |
| 242 default: |
| 243 return false; |
106 } | 244 } |
107 break; | 245 if (out_acc_obj.isNull()) |
108 case WebAccessibility::FUNCTION_NAVIGATE : | 246 return false; |
109 out_acc_obj = active_acc_obj->Navigate( | 247 break; |
110 static_cast<WebAccessibility::Direction>(in_params.input_long1), | 248 } |
111 child_id); | 249 case WebAccessibility::FUNCTION_GETCHILD: { |
112 if (!out_acc_obj.get()) | 250 out_params->object_id = in_params.object_id; |
113 return false; | 251 out_acc_obj = active_acc_obj; |
114 break; | 252 break; |
115 case WebAccessibility::FUNCTION_GETCHILD : | 253 } |
116 if (child_id == 0) { | 254 case WebAccessibility::FUNCTION_CHILDCOUNT: { |
117 // If child requested is self, stay with the same accessibility object. | 255 out_params->output_long1 = active_acc_obj.childCount(); |
118 out_params->object_id = in_params.object_id; | 256 break; |
119 out_acc_obj = active_acc_obj.get(); | 257 } |
120 } else { | 258 case WebAccessibility::FUNCTION_DEFAULTACTION: { |
121 out_acc_obj = active_acc_obj->GetChild(child_id); | 259 out_string = active_acc_obj.actionVerb(); |
122 } | 260 if (out_string.empty()) |
123 | 261 return false; |
124 if (!out_acc_obj.get()) | 262 break; |
125 return false; | 263 } |
126 break; | 264 case WebAccessibility::FUNCTION_DESCRIPTION: { |
127 case WebAccessibility::FUNCTION_CHILDCOUNT : | 265 out_string = active_acc_obj.accessibilityDescription(); |
128 if (!active_acc_obj->ChildCount(&out_params->output_long1)) | 266 if (out_string.empty()) |
129 return false; | 267 return false; |
130 break; | 268 // From the Mozilla MSAA implementation: |
131 case WebAccessibility::FUNCTION_DEFAULTACTION : | 269 // "Signal to screen readers that this description is speakable and is not |
132 if (!active_acc_obj->DefaultAction(child_id, &out_string)) | 270 // a formatted positional information description. Don't localize the |
133 return false; | 271 // 'Description: ' part of this string, it will be parsed out by assistive |
134 break; | 272 // technologies." |
135 case WebAccessibility::FUNCTION_DESCRIPTION : | 273 out_string = L"Description: " + out_string; |
136 if (!active_acc_obj->Description(child_id, &out_string)) | 274 break; |
137 return false; | 275 } |
138 break; | 276 case WebAccessibility::FUNCTION_GETFOCUSEDCHILD: { |
139 case WebAccessibility::FUNCTION_GETFOCUSEDCHILD : | 277 out_acc_obj = active_acc_obj.focusedChild(); |
140 out_acc_obj = active_acc_obj->GetFocusedChild(); | 278 if (out_acc_obj.isNull()) |
141 if (!out_acc_obj.get()) | 279 return false; |
142 return false; | 280 break; |
143 break; | 281 } |
144 case WebAccessibility::FUNCTION_HELPTEXT : | 282 case WebAccessibility::FUNCTION_HELPTEXT: { |
145 if (!active_acc_obj->HelpText(child_id, &out_string)) | 283 out_string = active_acc_obj.helpText(); |
146 return false; | 284 if (out_string.empty()) |
147 break; | 285 return false; |
148 case WebAccessibility::FUNCTION_KEYBOARDSHORTCUT : | 286 break; |
149 if (!active_acc_obj->KeyboardShortcut(child_id, &out_string)) | 287 } |
150 return false; | 288 case WebAccessibility::FUNCTION_KEYBOARDSHORTCUT: { |
151 break; | 289 out_string = active_acc_obj.keyboardShortcut(); |
152 case WebAccessibility::FUNCTION_NAME : | 290 if (out_string.empty()) |
153 if (!active_acc_obj->Name(child_id, &out_string)) | 291 return false; |
154 return false; | 292 break; |
155 break; | 293 } |
156 case WebAccessibility::FUNCTION_GETPARENT : | 294 case WebAccessibility::FUNCTION_NAME: { |
157 out_acc_obj = active_acc_obj->GetParent(); | 295 out_string = active_acc_obj.title(); |
158 if (!out_acc_obj.get()) | 296 if (out_string.empty()) |
159 return false; | 297 return false; |
160 break; | 298 break; |
161 case WebAccessibility::FUNCTION_ROLE : | 299 } |
162 if (!active_acc_obj->Role(child_id, &out_params->output_long1)) | 300 case WebAccessibility::FUNCTION_GETPARENT: { |
163 return false; | 301 out_acc_obj = active_acc_obj.parentObject(); |
164 break; | 302 if (out_acc_obj.isNull()) |
165 case WebAccessibility::FUNCTION_STATE : | 303 return false; |
166 if (!active_acc_obj->State(child_id, &out_params->output_long1)) | 304 break; |
167 return false; | 305 } |
168 break; | 306 case WebAccessibility::FUNCTION_ROLE: { |
169 case WebAccessibility::FUNCTION_VALUE : | 307 out_params->output_long1 = ConvertRole(active_acc_obj.roleValue()); |
170 if (!active_acc_obj->Value(child_id, &out_string)) | 308 break; |
171 return false; | 309 } |
172 break; | 310 case WebAccessibility::FUNCTION_STATE: { |
| 311 out_params->output_long1 = ConvertState(active_acc_obj); |
| 312 break; |
| 313 } |
| 314 case WebAccessibility::FUNCTION_VALUE: { |
| 315 out_string = active_acc_obj.stringValue(); |
| 316 if (out_string.empty()) |
| 317 return false; |
| 318 break; |
| 319 } |
173 default: | 320 default: |
174 // Non-supported function id. | 321 // Non-supported function id. |
175 return false; | 322 return false; |
176 } | 323 } |
177 | 324 |
178 // Output and hashmap assignments, as appropriate. | 325 // Output and hashmap assignments, as appropriate. |
179 if (!out_string.isEmpty()) | 326 if (!out_string.empty()) |
180 out_params->output_string = StringToString16(out_string); | 327 out_params->output_string = out_string; |
181 | 328 |
182 if (out_acc_obj) { | 329 if (out_acc_obj.isNull()) |
183 AccObjToIntMap::iterator it = | 330 return true; |
184 acc_obj_to_int_map_.find(out_acc_obj->accessibilityObject()); | 331 |
185 | 332 int id = cache->addOrGetId(out_acc_obj); |
186 if (it != acc_obj_to_int_map_.end()) { | 333 out_params->object_id = id; |
187 // Data already present in map, return previously assigned id. | 334 out_params->output_long1 = -1; |
188 out_params->object_id = it->second; | 335 |
189 out_params->output_long1 = -1; | |
190 } else { | |
191 // Insert new GlueAccessibilityObject in hashmaps. | |
192 int_to_glue_acc_obj_map_[acc_obj_id_] = out_acc_obj.get(); | |
193 acc_obj_to_int_map_[out_acc_obj->accessibilityObject()] = acc_obj_id_; | |
194 out_params->object_id = acc_obj_id_++; | |
195 out_params->output_long1 = -1; | |
196 } | |
197 } | |
198 // TODO(klink): Handle simple objects returned. | 336 // TODO(klink): Handle simple objects returned. |
199 return true; | 337 return true; |
200 } | 338 } |
201 | 339 |
202 bool WebAccessibilityManagerImpl::InitAccObjRoot(WebView* view) { | |
203 // Enable accessibility and retrieve Document. | |
204 WebCore::AXObjectCache::enableAccessibility(); | |
205 WebFrameImpl* main_frame_impl = | |
206 static_cast<WebFrameImpl*>(view->mainFrame()); | |
207 if (!main_frame_impl || !main_frame_impl->frame()) | |
208 return false; | |
209 | |
210 WebCore::Document* doc = main_frame_impl->frame()->document(); | |
211 | |
212 if (!doc || !doc->renderer()) | |
213 return false; | |
214 | |
215 if (!root_->acc_obj_root_) { | |
216 // Either we've never had a wrapper for this frame's top-level Document, | |
217 // the Document renderer was destroyed and its wrapper was detached, or | |
218 // the previous Document is in the page cache, and the current document | |
219 // needs to be wrapped. | |
220 root_->acc_obj_root_ = GlueAccessibilityObject::CreateInstance(doc-> | |
221 axObjectCache()->getOrCreate(doc->renderer())); | |
222 } | |
223 // Insert root in hashmaps. | |
224 int_to_glue_acc_obj_map_[acc_obj_id_] = root_->acc_obj_root_.get(); | |
225 acc_obj_to_int_map_[root_->acc_obj_root_->accessibilityObject()] = | |
226 acc_obj_id_++; | |
227 | |
228 return true; | |
229 } | |
230 | |
231 bool WebAccessibilityManagerImpl::ClearAccObjMap(int acc_obj_id, | |
232 bool clear_all) { | |
233 if (clear_all) { | |
234 // Clear maps and invalidate root. | |
235 int_to_glue_acc_obj_map_.clear(); | |
236 acc_obj_to_int_map_.clear(); | |
237 root_->acc_obj_root_ = 0; | |
238 return true; | |
239 } | |
240 | |
241 IntToGlueAccObjMap::iterator it = int_to_glue_acc_obj_map_.find(acc_obj_id); | |
242 | |
243 if (it == int_to_glue_acc_obj_map_.end()) { | |
244 // Element not found. | |
245 return false; | |
246 } | |
247 | |
248 if (it->second) { | |
249 // Erase element from reverse hashmap. | |
250 AccObjToIntMap::iterator it2 = | |
251 acc_obj_to_int_map_.find(it->second->accessibilityObject()); | |
252 | |
253 if (it2 != acc_obj_to_int_map_.end()) | |
254 acc_obj_to_int_map_.erase(it2); | |
255 } | |
256 int_to_glue_acc_obj_map_.erase(it); | |
257 | |
258 if (acc_obj_id == 1000) { | |
259 // Invalidate root. | |
260 root_->acc_obj_root_ = 0; | |
261 } | |
262 return true; | |
263 } | |
264 | |
265 int WebAccessibilityManagerImpl::FocusAccObj( | |
266 const WebAccessibilityObject& object) { | |
267 if (object.isNull()) { | |
268 // Return with failure. | |
269 return -1; | |
270 } | |
271 | |
272 RefPtr<WebCore::AccessibilityObject> acc_obj = | |
273 WebAccessibilityObjectToAccessibilityObject(object); | |
274 | |
275 AccObjToIntMap::iterator it = acc_obj_to_int_map_.find(acc_obj.get()); | |
276 | |
277 if (it != acc_obj_to_int_map_.end()) | |
278 return it->second; | |
279 | |
280 // Insert new accessibility object in hashmaps and return its newly | |
281 // assigned accessibility object id. | |
282 int_to_glue_acc_obj_map_[acc_obj_id_] = | |
283 GlueAccessibilityObject::CreateInstance(acc_obj.get()); | |
284 acc_obj_to_int_map_[acc_obj.get()] = acc_obj_id_; | |
285 | |
286 return acc_obj_id_++; | |
287 } | |
288 | |
289 } // namespace webkit_glue | 340 } // namespace webkit_glue |
OLD | NEW |