| Index: content/browser/accessibility/browser_accessibility_manager.cc
|
| diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
|
| index 45d5ec24629c47a4ef2e493c29a7a5f41ea47ec7..c946deeff340609c4752372231909e152f9ff19d 100644
|
| --- a/content/browser/accessibility/browser_accessibility_manager.cc
|
| +++ b/content/browser/accessibility/browser_accessibility_manager.cc
|
| @@ -123,6 +123,7 @@ BrowserAccessibilityManager::BrowserAccessibilityManager(
|
| : delegate_(delegate),
|
| factory_(factory),
|
| tree_(new ui::AXSerializableTree()),
|
| + focus_(NULL),
|
| user_is_navigating_away_(false),
|
| osk_state_(OSK_ALLOWED),
|
| ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID),
|
| @@ -137,6 +138,7 @@ BrowserAccessibilityManager::BrowserAccessibilityManager(
|
| : delegate_(delegate),
|
| factory_(factory),
|
| tree_(new ui::AXSerializableTree()),
|
| + focus_(NULL),
|
| user_is_navigating_away_(false),
|
| osk_state_(OSK_ALLOWED),
|
| ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID),
|
| @@ -160,6 +162,9 @@ void BrowserAccessibilityManager::Initialize(
|
| LOG(FATAL) << tree_->error();
|
| }
|
| }
|
| +
|
| + if (!focus_)
|
| + SetFocus(tree_->root(), false);
|
| }
|
|
|
| // static
|
| @@ -238,15 +243,13 @@ const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() {
|
| }
|
|
|
| void BrowserAccessibilityManager::OnWindowFocused() {
|
| - BrowserAccessibility* focus = GetFocus();
|
| - if (focus)
|
| - NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, focus);
|
| + if (focus_)
|
| + NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
|
| }
|
|
|
| void BrowserAccessibilityManager::OnWindowBlurred() {
|
| - BrowserAccessibility* focus = GetFocus();
|
| - if (focus)
|
| - NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, focus);
|
| + if (focus_)
|
| + NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, GetFromAXNode(focus_));
|
| }
|
|
|
| void BrowserAccessibilityManager::UserIsNavigatingAway() {
|
| @@ -266,12 +269,11 @@ void BrowserAccessibilityManager::NavigationFailed() {
|
| }
|
|
|
| void BrowserAccessibilityManager::GotMouseDown() {
|
| - BrowserAccessibility* focus = GetFocus();
|
| - if (!focus)
|
| + if (!focus_)
|
| return;
|
|
|
| osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
|
| - NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, focus);
|
| + NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
|
| }
|
|
|
| bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() {
|
| @@ -280,6 +282,8 @@ bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() {
|
|
|
| void BrowserAccessibilityManager::OnAccessibilityEvents(
|
| const std::vector<AXEventNotificationDetails>& details) {
|
| + bool should_send_initial_focus = false;
|
| +
|
| // Process all changes to the accessibility tree first.
|
| for (uint32_t index = 0; index < details.size(); ++index) {
|
| const AXEventNotificationDetails& detail = details[index];
|
| @@ -292,8 +296,17 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
|
| }
|
| return;
|
| }
|
| +
|
| + // Set focus to the root if it's not anywhere else.
|
| + if (!focus_) {
|
| + SetFocus(tree_->root(), false);
|
| + should_send_initial_focus = true;
|
| + }
|
| }
|
|
|
| + if (should_send_initial_focus && NativeViewHasFocus())
|
| + NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
|
| +
|
| // Now iterate over the events again and fire the events.
|
| for (uint32_t index = 0; index < details.size(); index++) {
|
| const AXEventNotificationDetails& detail = details[index];
|
| @@ -307,6 +320,8 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
|
| ui::AXEvent event_type = detail.event_type;
|
| if (event_type == ui::AX_EVENT_FOCUS ||
|
| event_type == ui::AX_EVENT_BLUR) {
|
| + SetFocus(node, false);
|
| +
|
| if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN &&
|
| osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
|
| osk_state_ = OSK_ALLOWED;
|
| @@ -372,19 +387,20 @@ void BrowserAccessibilityManager::ActivateFindInPageResult(
|
| }
|
|
|
| BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus(
|
| - BrowserAccessibility* focus) {
|
| - if (!focus)
|
| + BrowserAccessibility* root) {
|
| + BrowserAccessibility* node = BrowserAccessibilityManager::GetFocus(root);
|
| + if (!node)
|
| return NULL;
|
|
|
| int active_descendant_id;
|
| - if (focus->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
|
| - &active_descendant_id)) {
|
| + if (node->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
|
| + &active_descendant_id)) {
|
| BrowserAccessibility* active_descendant =
|
| - focus->manager()->GetFromID(active_descendant_id);
|
| + node->manager()->GetFromID(active_descendant_id);
|
| if (active_descendant)
|
| return active_descendant;
|
| }
|
| - return focus;
|
| + return node;
|
| }
|
|
|
| bool BrowserAccessibilityManager::NativeViewHasFocus() {
|
| @@ -394,33 +410,39 @@ bool BrowserAccessibilityManager::NativeViewHasFocus() {
|
| return false;
|
| }
|
|
|
| -BrowserAccessibility* BrowserAccessibilityManager::GetFocus() {
|
| - int32_t focus_id = GetTreeData().focus_id;
|
| - BrowserAccessibility* obj = GetFromID(focus_id);
|
| - if (!obj)
|
| - return GetRoot();
|
| +BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
|
| + BrowserAccessibility* root) {
|
| + if (!focus_)
|
| + return nullptr;
|
| +
|
| + if (root && !focus_->IsDescendantOf(root->node()))
|
| + return nullptr;
|
|
|
| + BrowserAccessibility* obj = GetFromAXNode(focus_);
|
| + DCHECK(obj);
|
| if (obj->HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
|
| BrowserAccessibilityManager* child_manager =
|
| BrowserAccessibilityManager::FromID(
|
| obj->GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID));
|
| if (child_manager)
|
| - return child_manager->GetFocus();
|
| + return child_manager->GetFocus(child_manager->GetRoot());
|
| }
|
|
|
| return obj;
|
| }
|
|
|
| -void BrowserAccessibilityManager::SetFocus(const BrowserAccessibility& node) {
|
| - if (delegate_)
|
| - delegate_->AccessibilitySetFocus(node.GetId());
|
| +void BrowserAccessibilityManager::SetFocus(ui::AXNode* node, bool notify) {
|
| + if (focus_ != node)
|
| + focus_ = node;
|
| +
|
| + if (notify && node && delegate_)
|
| + delegate_->AccessibilitySetFocus(node->id());
|
| }
|
|
|
| -void BrowserAccessibilityManager::SetFocusLocallyForTesting(
|
| - BrowserAccessibility* node) {
|
| - ui::AXTreeData data = GetTreeData();
|
| - data.focus_id = node->GetId();
|
| - tree_->UpdateData(data);
|
| +void BrowserAccessibilityManager::SetFocus(BrowserAccessibility* obj,
|
| + bool notify) {
|
| + if (obj->node())
|
| + SetFocus(obj->node(), notify);
|
| }
|
|
|
| void BrowserAccessibilityManager::DoDefaultAction(
|
| @@ -656,6 +678,12 @@ void BrowserAccessibilityManager::OnTreeDataChanged(ui::AXTree* tree) {
|
| void BrowserAccessibilityManager::OnNodeWillBeDeleted(ui::AXTree* tree,
|
| ui::AXNode* node) {
|
| DCHECK(node);
|
| + if (node == focus_ && tree_) {
|
| + if (node != tree_->root())
|
| + SetFocus(tree_->root(), false);
|
| + else
|
| + focus_ = NULL;
|
| + }
|
| if (id_wrapper_map_.find(node->id()) == id_wrapper_map_.end())
|
| return;
|
| GetFromAXNode(node)->Destroy();
|
|
|