OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/browser/accessibility/browser_accessibility_manager.h" | 5 #include "content/browser/accessibility/browser_accessibility_manager.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "content/browser/accessibility/browser_accessibility.h" | 8 #include "content/browser/accessibility/browser_accessibility.h" |
9 #include "content/common/view_messages.h" | 9 #include "content/common/view_messages.h" |
10 | 10 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 gfx::Rect BrowserAccessibilityManager::GetViewBounds() { | 225 gfx::Rect BrowserAccessibilityManager::GetViewBounds() { |
226 if (delegate_) | 226 if (delegate_) |
227 return delegate_->GetViewBounds(); | 227 return delegate_->GetViewBounds(); |
228 return gfx::Rect(); | 228 return gfx::Rect(); |
229 } | 229 } |
230 | 230 |
231 void BrowserAccessibilityManager::UpdateNode( | 231 void BrowserAccessibilityManager::UpdateNode( |
232 const WebAccessibility& src, | 232 const WebAccessibility& src, |
233 bool include_children) { | 233 bool include_children) { |
234 BrowserAccessibility* current = NULL; | 234 BrowserAccessibility* current = NULL; |
| 235 |
| 236 // Look for the node to replace. Either we're replacing the whole tree |
| 237 // (role is ROOT_WEB_AREA) or we look it up based on its renderer ID. |
235 if (src.role == WebAccessibility::ROLE_ROOT_WEB_AREA) { | 238 if (src.role == WebAccessibility::ROLE_ROOT_WEB_AREA) { |
236 // As an exceptional case, there can only be one root of the tree, so | |
237 // if we get a new root, replace the current root no matter what the | |
238 // current root's renderer ID is. | |
239 current = root_; | 239 current = root_; |
240 renderer_id_to_child_id_map_.erase(current->renderer_id()); | |
241 renderer_id_to_child_id_map_[src.id] = current->child_id(); | |
242 } else { | 240 } else { |
243 // Otherwise, replace the node based on its renderer ID. | |
244 base::hash_map<int32, int32>::iterator iter = | 241 base::hash_map<int32, int32>::iterator iter = |
245 renderer_id_to_child_id_map_.find(src.id); | 242 renderer_id_to_child_id_map_.find(src.id); |
246 if (iter != renderer_id_to_child_id_map_.end()) { | 243 if (iter != renderer_id_to_child_id_map_.end()) { |
247 int32 child_id = iter->second; | 244 int32 child_id = iter->second; |
248 current = GetFromChildID(child_id); | 245 current = GetFromChildID(child_id); |
249 } | 246 } |
250 } | 247 } |
251 | 248 |
| 249 // If we can't find the node to replace, we're out of sync with the |
| 250 // renderer (this would be a bug). |
| 251 DCHECK(current); |
252 if (!current) | 252 if (!current) |
253 return; | 253 return; |
254 | 254 |
| 255 // If this update is just for a single node (|include_children| is false), |
| 256 // modify |current| directly and return - no tree changes are needed. |
255 if (!include_children) { | 257 if (!include_children) { |
256 DCHECK_EQ(0U, src.children.size()); | 258 DCHECK_EQ(0U, src.children.size()); |
257 current->Initialize( | 259 current->Initialize( |
258 this, | 260 this, |
259 current->parent(), | 261 current->parent(), |
260 current->child_id(), | 262 current->child_id(), |
261 current->index_in_parent(), | 263 current->index_in_parent(), |
262 src); | 264 src); |
263 current->SendNodeUpdateEvents(); | 265 current->SendNodeUpdateEvents(); |
264 return; | 266 return; |
(...skipping 10 matching lines...) Expand all Loading... |
275 // Build a new tree, reusing old nodes if possible. Each node that's | 277 // Build a new tree, reusing old nodes if possible. Each node that's |
276 // reused will have its reference count incremented by one. | 278 // reused will have its reference count incremented by one. |
277 current = CreateAccessibilityTree( | 279 current = CreateAccessibilityTree( |
278 current_parent, src, current_index_in_parent, true); | 280 current_parent, src, current_index_in_parent, true); |
279 | 281 |
280 // Decrement the reference count of all nodes in the old tree, which will | 282 // Decrement the reference count of all nodes in the old tree, which will |
281 // delete any nodes no longer needed. | 283 // delete any nodes no longer needed. |
282 for (int i = 0; i < static_cast<int>(old_tree_nodes.size()); i++) | 284 for (int i = 0; i < static_cast<int>(old_tree_nodes.size()); i++) |
283 old_tree_nodes[i]->InternalReleaseReference(false); | 285 old_tree_nodes[i]->InternalReleaseReference(false); |
284 | 286 |
285 if (!focus_ || !focus_->instance_active()) | 287 // If the only reference to the focused node is focus_ itself, then the |
286 SetFocus(root_, false); | 288 // focused node is no longer in the tree, so set the focus to the root. |
| 289 if (focus_ && focus_->ref_count() == 1) { |
| 290 SetFocus(root_, true); |
| 291 if (!delegate_ || delegate_->HasFocus()) |
| 292 NotifyAccessibilityEvent(ViewHostMsg_AccEvent::FOCUS_CHANGED, focus_); |
| 293 } |
287 } | 294 } |
288 | 295 |
289 BrowserAccessibility* BrowserAccessibilityManager::CreateAccessibilityTree( | 296 BrowserAccessibility* BrowserAccessibilityManager::CreateAccessibilityTree( |
290 BrowserAccessibility* parent, | 297 BrowserAccessibility* parent, |
291 const WebAccessibility& src, | 298 const WebAccessibility& src, |
292 int index_in_parent, | 299 int index_in_parent, |
293 bool send_show_events) { | 300 bool send_show_events) { |
294 BrowserAccessibility* instance = NULL; | 301 BrowserAccessibility* instance = NULL; |
295 int32 child_id = 0; | 302 int32 child_id = 0; |
296 bool children_can_send_show_events = send_show_events; | 303 bool children_can_send_show_events = send_show_events; |
(...skipping 29 matching lines...) Expand all Loading... |
326 } else { | 333 } else { |
327 // Otherwise, create a new instance. | 334 // Otherwise, create a new instance. |
328 instance = factory_->Create(); | 335 instance = factory_->Create(); |
329 child_id = GetNextChildID(); | 336 child_id = GetNextChildID(); |
330 children_can_send_show_events = false; | 337 children_can_send_show_events = false; |
331 } | 338 } |
332 | 339 |
333 instance->Initialize(this, parent, child_id, index_in_parent, src); | 340 instance->Initialize(this, parent, child_id, index_in_parent, src); |
334 child_id_map_[child_id] = instance; | 341 child_id_map_[child_id] = instance; |
335 renderer_id_to_child_id_map_[src.id] = child_id; | 342 renderer_id_to_child_id_map_[src.id] = child_id; |
| 343 |
| 344 if (src.role == WebAccessibility::ROLE_ROOT_WEB_AREA) |
| 345 root_ = instance; |
| 346 |
336 if ((src.state >> WebAccessibility::STATE_FOCUSED) & 1) | 347 if ((src.state >> WebAccessibility::STATE_FOCUSED) & 1) |
337 SetFocus(instance, false); | 348 SetFocus(instance, false); |
338 for (int i = 0; i < static_cast<int>(src.children.size()); ++i) { | 349 for (int i = 0; i < static_cast<int>(src.children.size()); ++i) { |
339 BrowserAccessibility* child = CreateAccessibilityTree( | 350 BrowserAccessibility* child = CreateAccessibilityTree( |
340 instance, src.children[i], i, children_can_send_show_events); | 351 instance, src.children[i], i, children_can_send_show_events); |
341 instance->AddChild(child); | 352 instance->AddChild(child); |
342 } | 353 } |
343 | 354 |
344 // Note: the purpose of send_show_events and children_can_send_show_events | 355 // Note: the purpose of send_show_events and children_can_send_show_events |
345 // is so that we send a single OBJECT_SHOW event for the root of a subtree | 356 // is so that we send a single OBJECT_SHOW event for the root of a subtree |
346 // that just appeared for the first time, but not on any descendant of | 357 // that just appeared for the first time, but not on any descendant of |
347 // that subtree. | 358 // that subtree. |
348 if (send_show_events) | 359 if (send_show_events) |
349 NotifyAccessibilityEvent(ViewHostMsg_AccEvent::OBJECT_SHOW, instance); | 360 NotifyAccessibilityEvent(ViewHostMsg_AccEvent::OBJECT_SHOW, instance); |
350 | 361 |
351 instance->SendNodeUpdateEvents(); | 362 instance->SendNodeUpdateEvents(); |
352 | 363 |
353 return instance; | 364 return instance; |
354 } | 365 } |
OLD | NEW |