Chromium Code Reviews| Index: content/browser/accessibility/browser_accessibility_manager_win.cc |
| diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc |
| index 200f832835b8130d79e44a106fe3e8cc541ccc8e..b760056efbc9bc7f9e64cb249ff96b604ae6fd35 100644 |
| --- a/content/browser/accessibility/browser_accessibility_manager_win.cc |
| +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc |
| @@ -73,8 +73,8 @@ IAccessible* BrowserAccessibilityManagerWin::GetParentIAccessible() { |
| return delegate_->AccessibilityGetNativeViewAccessible(); |
| } |
| -void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, |
| - LONG child_id) { |
| +void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent( |
| + DWORD event, BrowserAccessibility* node) { |
| if (!delegate_) |
| return; |
| @@ -82,10 +82,46 @@ void BrowserAccessibilityManagerWin::MaybeCallNotifyWinEvent(DWORD event, |
| if (!hwnd) |
| return; |
| + // Inline text boxes are an internal implementation detail, we don't |
| + // expose them to Windows. |
| + if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) |
| + return; |
| + |
| + // It doesn't make sense to fire a REORDER event on a leaf node; that |
| + // happens when the node has internal children line inline text boxes. |
| + if (event == EVENT_OBJECT_REORDER && node->PlatformIsLeaf()) |
| + return; |
| + |
| + // Don't fire focus, or load complete notifications if the |
| + // window isn't focused, because that can confuse screen readers into |
| + // entering their "browse" mode. |
| + if ((event == EVENT_OBJECT_FOCUS || |
| + event == IA2_EVENT_DOCUMENT_LOAD_COMPLETE) && |
| + (!delegate_->AccessibilityViewHasFocus())) { |
| + return; |
| + } |
| + |
| + // NVDA gets confused if we focus the main document element when it hasn't |
| + // finished loading and it has no children at all, so suppress that event. |
| + if (event == EVENT_OBJECT_FOCUS && |
| + node == GetRoot() && |
| + node->PlatformChildCount() == 0 && |
| + !node->HasState(ui::AX_STATE_BUSY) && |
| + !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) { |
| + return; |
| + } |
| + |
| + // If a focus event is needed on the root, fire that first before |
| + // this event. |
| + if (event == EVENT_OBJECT_FOCUS && node == GetRoot()) |
| + focus_event_on_root_needed_ = false; |
| + else if (focus_event_on_root_needed_) |
| + OnWindowFocused(); |
| + |
| + LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win(); |
|
aboxhall
2015/01/22 21:22:09
Why is (was) this called child_id rather than node
dmazzoni
2015/01/23 23:26:13
That's the name of the ::NotifyWinEvent parameter,
|
| ::NotifyWinEvent(event, hwnd, OBJID_CLIENT, child_id); |
| } |
| - |
| void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXNode* node) { |
| BrowserAccessibilityManager::OnNodeCreated(node); |
| BrowserAccessibility* obj = GetFromAXNode(node); |
| @@ -129,41 +165,6 @@ void BrowserAccessibilityManagerWin::OnWindowFocused() { |
| void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| ui::AXEvent event_type, |
| BrowserAccessibility* node) { |
| - if (!delegate_ || !delegate_->AccessibilityGetAcceleratedWidget()) |
| - return; |
| - |
| - // Inline text boxes are an internal implementation detail, we don't |
| - // expose them to Windows. |
| - if (node->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) |
| - return; |
| - |
| - // Don't fire focus, blur, or load complete notifications if the |
| - // window isn't focused, because that can confuse screen readers into |
| - // entering their "browse" mode. |
| - if ((event_type == ui::AX_EVENT_FOCUS || |
| - event_type == ui::AX_EVENT_BLUR || |
| - event_type == ui::AX_EVENT_LOAD_COMPLETE) && |
| - (!delegate_ || !delegate_->AccessibilityViewHasFocus())) { |
| - return; |
| - } |
| - |
| - // NVDA gets confused if we focus the main document element when it hasn't |
| - // finished loading and it has no children at all, so suppress that event. |
| - if (event_type == ui::AX_EVENT_FOCUS && |
| - node == GetRoot() && |
| - node->PlatformChildCount() == 0 && |
| - !node->HasState(ui::AX_STATE_BUSY) && |
| - !node->GetBoolAttribute(ui::AX_ATTR_DOC_LOADED)) { |
| - return; |
| - } |
| - |
| - // If a focus event is needed on the root, fire that first before |
| - // this event. |
| - if (event_type == ui::AX_EVENT_FOCUS && node == GetRoot()) |
| - focus_event_on_root_needed_ = false; |
| - else if (focus_event_on_root_needed_) |
| - OnWindowFocused(); |
| - |
| LONG event_id = EVENT_MIN; |
| switch (event_type) { |
| case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED: |
| @@ -172,9 +173,6 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| case ui::AX_EVENT_ALERT: |
| event_id = EVENT_SYSTEM_ALERT; |
| break; |
| - case ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED: |
| - event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED; |
| - break; |
| case ui::AX_EVENT_AUTOCORRECTION_OCCURED: |
| event_id = IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED; |
| break; |
| @@ -183,18 +181,12 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| event_id = EVENT_OBJECT_FOCUS; |
| node = GetRoot(); |
| break; |
| - case ui::AX_EVENT_CHECKED_STATE_CHANGED: |
| - event_id = EVENT_OBJECT_STATECHANGE; |
| - break; |
| case ui::AX_EVENT_CHILDREN_CHANGED: |
| event_id = EVENT_OBJECT_REORDER; |
| break; |
| case ui::AX_EVENT_FOCUS: |
| event_id = EVENT_OBJECT_FOCUS; |
| break; |
| - case ui::AX_EVENT_INVALID_STATUS_CHANGED: |
| - event_id = EVENT_OBJECT_STATECHANGE; |
| - break; |
| case ui::AX_EVENT_LIVE_REGION_CHANGED: |
| if (node->GetBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY)) |
| return; |
| @@ -209,12 +201,6 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| case ui::AX_EVENT_MENU_LIST_VALUE_CHANGED: |
| event_id = EVENT_OBJECT_VALUECHANGE; |
| break; |
| - case ui::AX_EVENT_HIDE: |
| - event_id = EVENT_OBJECT_HIDE; |
| - break; |
| - case ui::AX_EVENT_SHOW: |
| - event_id = EVENT_OBJECT_SHOW; |
| - break; |
| case ui::AX_EVENT_SCROLL_POSITION_CHANGED: |
| event_id = EVENT_SYSTEM_SCROLLINGEND; |
| break; |
| @@ -224,15 +210,9 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED: |
| event_id = EVENT_OBJECT_SELECTIONWITHIN; |
| break; |
| - case ui::AX_EVENT_TEXT_CHANGED: |
| - event_id = EVENT_OBJECT_NAMECHANGE; |
| - break; |
| case ui::AX_EVENT_TEXT_SELECTION_CHANGED: |
| event_id = IA2_EVENT_TEXT_CARET_MOVED; |
| break; |
| - case ui::AX_EVENT_VALUE_CHANGED: |
| - event_id = EVENT_OBJECT_VALUECHANGE; |
| - break; |
| default: |
| // Not all WebKit accessibility events result in a Windows |
| // accessibility notification. |
| @@ -244,8 +224,7 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| // the AT client will then call get_accChild on the HWND's accessibility |
| // object and pass it that same id, which we can use to retrieve the |
| // IAccessible for this node. |
| - LONG child_id = node->ToBrowserAccessibilityWin()->unique_id_win(); |
| - MaybeCallNotifyWinEvent(event_id, child_id); |
| + MaybeCallNotifyWinEvent(event_id, node); |
| } |
| // If this is a layout complete notification (sent when a container scrolls) |
| @@ -255,8 +234,7 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| tracked_scroll_object_ && |
| tracked_scroll_object_->IsDescendantOf(node)) { |
| MaybeCallNotifyWinEvent( |
| - IA2_EVENT_VISIBLE_DATA_CHANGED, |
| - tracked_scroll_object_->ToBrowserAccessibilityWin()->unique_id_win()); |
| + IA2_EVENT_VISIBLE_DATA_CHANGED, tracked_scroll_object_); |
| tracked_scroll_object_->Release(); |
| tracked_scroll_object_ = NULL; |
| } |
| @@ -265,11 +243,20 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( |
| void BrowserAccessibilityManagerWin::OnAtomicUpdateFinished( |
| bool root_changed, |
| const std::vector<ui::AXTreeDelegate::Change>& changes) { |
| + BrowserAccessibilityManager::OnAtomicUpdateFinished(root_changed, changes); |
| + |
| if (root_changed) { |
| // In order to make screen readers aware of the new accessibility root, |
| // we need to fire a focus event on it. |
| OnWindowFocused(); |
| } |
| + |
| + // Second pass. |
|
aboxhall
2015/01/22 21:22:09
Why do we need to do a second pass?
dmazzoni
2015/01/23 23:26:13
Because updating IAccessibleText requires the chil
|
| + for (size_t i = 0; i < changes.size(); ++i) { |
| + BrowserAccessibility* obj = GetFromAXNode(changes[i].node); |
| + if (obj) |
| + obj->ToBrowserAccessibilityWin()->UpdateIAccessibleText(); |
| + } |
| } |
| void BrowserAccessibilityManagerWin::TrackScrollingObject( |