| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 // Find the node corresponding to the id that's the target of the | 380 // Find the node corresponding to the id that's the target of the |
| 381 // event (which may not be the root of the update tree). | 381 // event (which may not be the root of the update tree). |
| 382 ui::AXNode* node = tree_->GetFromId(detail.id); | 382 ui::AXNode* node = tree_->GetFromId(detail.id); |
| 383 if (!node) | 383 if (!node) |
| 384 continue; | 384 continue; |
| 385 | 385 |
| 386 ui::AXEvent event_type = detail.event_type; | 386 ui::AXEvent event_type = detail.event_type; |
| 387 if (event_type == ui::AX_EVENT_FOCUS || | 387 if (event_type == ui::AX_EVENT_FOCUS || |
| 388 event_type == ui::AX_EVENT_BLUR) { | 388 event_type == ui::AX_EVENT_BLUR) { |
| 389 if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN && | 389 if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN && |
| 390 osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED) | 390 osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED) { |
| 391 osk_state_ = OSK_ALLOWED; | 391 osk_state_ = OSK_ALLOWED; |
| 392 } |
| 392 | 393 |
| 393 bool is_menu_list_option = | 394 // We already handled all focus events above. |
| 394 node->data().role == ui::AX_ROLE_MENU_LIST_OPTION; | 395 continue; |
| 395 | |
| 396 // Skip all focus events other than ones on menu list options; | |
| 397 // we've already handled them, above. Menu list options are a weird | |
| 398 // exception because the menu list itself has focus but we need to fire | |
| 399 // focus events on the individual options. | |
| 400 if (!is_menu_list_option) | |
| 401 continue; | |
| 402 } | 396 } |
| 403 | 397 |
| 404 // Fire the native event. | 398 // Fire the native event. |
| 405 BrowserAccessibility* event_target = GetFromAXNode(node); | 399 BrowserAccessibility* event_target = GetFromAXNode(node); |
| 406 if (event_target) { | 400 if (event_target) { |
| 407 NotifyAccessibilityEvent( | 401 NotifyAccessibilityEvent( |
| 408 BrowserAccessibilityEvent::FromBlink, | 402 BrowserAccessibilityEvent::FromBlink, |
| 409 event_type, | 403 event_type, |
| 410 event_target); | 404 event_target); |
| 411 } | 405 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 } | 476 } |
| 483 | 477 |
| 484 // The "scrolled to anchor" notification is a great way to get a | 478 // The "scrolled to anchor" notification is a great way to get a |
| 485 // screen reader to jump directly to a specific location in a document. | 479 // screen reader to jump directly to a specific location in a document. |
| 486 NotifyAccessibilityEvent( | 480 NotifyAccessibilityEvent( |
| 487 BrowserAccessibilityEvent::FromFindInPageResult, | 481 BrowserAccessibilityEvent::FromFindInPageResult, |
| 488 ui::AX_EVENT_SCROLLED_TO_ANCHOR, | 482 ui::AX_EVENT_SCROLLED_TO_ANCHOR, |
| 489 node); | 483 node); |
| 490 } | 484 } |
| 491 | 485 |
| 492 BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus( | 486 BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendant( |
| 493 BrowserAccessibility* focus) { | 487 BrowserAccessibility* focus) { |
| 494 if (!focus) | 488 if (!focus) |
| 495 return NULL; | 489 return nullptr; |
| 496 | 490 |
| 497 int active_descendant_id; | 491 int32_t active_descendant_id; |
| 492 BrowserAccessibility* active_descendant = nullptr; |
| 498 if (focus->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, | 493 if (focus->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, |
| 499 &active_descendant_id)) { | 494 &active_descendant_id)) { |
| 500 BrowserAccessibility* active_descendant = | 495 active_descendant = focus->manager()->GetFromID(active_descendant_id); |
| 501 focus->manager()->GetFromID(active_descendant_id); | |
| 502 if (active_descendant) | |
| 503 return active_descendant; | |
| 504 } | 496 } |
| 497 |
| 498 if (focus->GetRole() == ui::AX_ROLE_POP_UP_BUTTON) { |
| 499 BrowserAccessibility* child = focus->InternalGetChild(0); |
| 500 if (child && child->GetRole() == ui::AX_ROLE_MENU_LIST_POPUP) { |
| 501 // The active descendant is found on the menu list popup, i.e. on the |
| 502 // actual list and not on the button that opens it. |
| 503 // If there is no active descendant, focus should stay on the button so |
| 504 // that Windows screen readers would enable their virtual cursor. |
| 505 if (child->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, |
| 506 &active_descendant_id)) { |
| 507 active_descendant = child->manager()->GetFromID(active_descendant_id); |
| 508 } |
| 509 } |
| 510 } |
| 511 |
| 512 if (active_descendant) |
| 513 return active_descendant; |
| 514 |
| 505 return focus; | 515 return focus; |
| 506 } | 516 } |
| 507 | 517 |
| 508 bool BrowserAccessibilityManager::NativeViewHasFocus() { | 518 bool BrowserAccessibilityManager::NativeViewHasFocus() { |
| 509 BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager(); | 519 BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager(); |
| 510 if (delegate) | 520 if (delegate) |
| 511 return delegate->AccessibilityViewHasFocus(); | 521 return delegate->AccessibilityViewHasFocus(); |
| 512 return false; | 522 return false; |
| 513 } | 523 } |
| 514 | 524 |
| 515 BrowserAccessibility* BrowserAccessibilityManager::GetFocus() { | 525 BrowserAccessibility* BrowserAccessibilityManager::GetFocus() { |
| 516 BrowserAccessibilityManager* root_manager = GetRootManager(); | 526 BrowserAccessibilityManager* root_manager = GetRootManager(); |
| 517 if (!root_manager) | 527 if (!root_manager) |
| 518 root_manager = this; | 528 root_manager = this; |
| 519 int32_t focused_tree_id = root_manager->GetTreeData().focused_tree_id; | 529 int32_t focused_tree_id = root_manager->GetTreeData().focused_tree_id; |
| 520 | 530 |
| 521 BrowserAccessibilityManager* focused_manager = nullptr; | 531 BrowserAccessibilityManager* focused_manager = nullptr; |
| 522 if (focused_tree_id) | 532 if (focused_tree_id) |
| 523 focused_manager =BrowserAccessibilityManager::FromID(focused_tree_id); | 533 focused_manager =BrowserAccessibilityManager::FromID(focused_tree_id); |
| 534 |
| 535 // BrowserAccessibilityManager::FromID(focused_tree_id) may return nullptr |
| 536 // if the tree is not created or has been destroyed. |
| 524 if (!focused_manager) | 537 if (!focused_manager) |
| 525 focused_manager = root_manager; | 538 focused_manager = root_manager; |
| 526 | 539 |
| 527 return focused_manager->GetFocusFromThisOrDescendantFrame(); | 540 return focused_manager->GetFocusFromThisOrDescendantFrame(); |
| 528 } | 541 } |
| 529 | 542 |
| 530 BrowserAccessibility* | 543 BrowserAccessibility* |
| 531 BrowserAccessibilityManager::GetFocusFromThisOrDescendantFrame() { | 544 BrowserAccessibilityManager::GetFocusFromThisOrDescendantFrame() { |
| 532 int32_t focus_id = GetTreeData().focus_id; | 545 int32_t focus_id = GetTreeData().focus_id; |
| 533 BrowserAccessibility* obj = GetFromID(focus_id); | 546 BrowserAccessibility* obj = GetFromID(focus_id); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 tree_source(tree_->CreateTreeSource()); | 902 tree_source(tree_->CreateTreeSource()); |
| 890 ui::AXTreeSerializer<const ui::AXNode*, | 903 ui::AXTreeSerializer<const ui::AXNode*, |
| 891 ui::AXNodeData, | 904 ui::AXNodeData, |
| 892 ui::AXTreeData> serializer(tree_source.get()); | 905 ui::AXTreeData> serializer(tree_source.get()); |
| 893 ui::AXTreeUpdate update; | 906 ui::AXTreeUpdate update; |
| 894 serializer.SerializeChanges(tree_->root(), &update); | 907 serializer.SerializeChanges(tree_->root(), &update); |
| 895 return update; | 908 return update; |
| 896 } | 909 } |
| 897 | 910 |
| 898 } // namespace content | 911 } // namespace content |
| OLD | NEW |