[Storage] Blob Storage Refactoring pt 1:
[chromium-blink-merge.git] / content / browser / accessibility / browser_accessibility_manager_mac.mm
blob2000d025accf9c94b41f72a4dd9df91fbce75a16
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
3 // found in the LICENSE file.
5 #include "content/browser/accessibility/browser_accessibility_manager_mac.h"
7 #import "base/logging.h"
8 #import "content/browser/accessibility/browser_accessibility_cocoa.h"
9 #import "content/browser/accessibility/browser_accessibility_mac.h"
10 #include "content/common/accessibility_messages.h"
12 namespace content {
14 // static
15 BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
16     const ui::AXTreeUpdate& initial_tree,
17     BrowserAccessibilityDelegate* delegate,
18     BrowserAccessibilityFactory* factory) {
19   return new BrowserAccessibilityManagerMac(
20       NULL, initial_tree, delegate, factory);
23 BrowserAccessibilityManagerMac::BrowserAccessibilityManagerMac(
24     NSView* parent_view,
25     const ui::AXTreeUpdate& initial_tree,
26     BrowserAccessibilityDelegate* delegate,
27     BrowserAccessibilityFactory* factory)
28     : BrowserAccessibilityManager(delegate, factory),
29       parent_view_(parent_view),
30       created_live_region_(false) {
31   Initialize(initial_tree);
34 // static
35 ui::AXTreeUpdate BrowserAccessibilityManagerMac::GetEmptyDocument() {
36   ui::AXNodeData empty_document;
37   empty_document.id = 0;
38   empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
39   empty_document.state =
40       1 << ui::AX_STATE_READ_ONLY;
41   ui::AXTreeUpdate update;
42   update.nodes.push_back(empty_document);
43   return update;
46 BrowserAccessibility* BrowserAccessibilityManagerMac::GetFocus(
47     BrowserAccessibility* root) {
48   BrowserAccessibility* node = GetActiveDescendantFocus(root);
49   return node;
52 void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
53     ui::AXEvent event_type,
54     BrowserAccessibility* node) {
55   if (!node->IsNative())
56     return;
58   // Refer to AXObjectCache.mm (webkit).
59   NSString* event_id = @"";
60   switch (event_type) {
61     case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
62       if (node->GetRole() == ui::AX_ROLE_TREE) {
63         event_id = NSAccessibilitySelectedRowsChangedNotification;
64       } else {
65         event_id = NSAccessibilityFocusedUIElementChangedNotification;
66         BrowserAccessibility* active_descendant_focus =
67             GetActiveDescendantFocus(GetRoot());
68         if (active_descendant_focus)
69           node = active_descendant_focus;
70       }
72       break;
73     case ui::AX_EVENT_ALERT:
74       // Not used on Mac.
75       return;
76     case ui::AX_EVENT_BLUR:
77       // A no-op on Mac.
78       return;
79     case ui::AX_EVENT_CHECKED_STATE_CHANGED:
80       // Not used on Mac.
81       return;
82     case ui::AX_EVENT_CHILDREN_CHANGED:
83       // TODO(dtseng): no clear equivalent on Mac.
84       return;
85     case ui::AX_EVENT_FOCUS:
86       event_id = NSAccessibilityFocusedUIElementChangedNotification;
87       break;
88     case ui::AX_EVENT_LAYOUT_COMPLETE:
89       event_id = @"AXLayoutComplete";
90       break;
91     case ui::AX_EVENT_LIVE_REGION_CHANGED:
92       event_id = @"AXLiveRegionChanged";
93       break;
94     case ui::AX_EVENT_LOAD_COMPLETE:
95       event_id = @"AXLoadComplete";
96       break;
97     case ui::AX_EVENT_MENU_LIST_VALUE_CHANGED:
98       // Not used on Mac.
99       return;
100     case ui::AX_EVENT_ROW_COUNT_CHANGED:
101       event_id = NSAccessibilityRowCountChangedNotification;
102       break;
103     case ui::AX_EVENT_ROW_COLLAPSED:
104       event_id = @"AXRowCollapsed";
105       break;
106     case ui::AX_EVENT_ROW_EXPANDED:
107       event_id = @"AXRowExpanded";
108       break;
109     case ui::AX_EVENT_SCROLLED_TO_ANCHOR:
110       // Not used on Mac.
111       return;
112     case ui::AX_EVENT_SELECTED_CHILDREN_CHANGED:
113       event_id = NSAccessibilitySelectedChildrenChangedNotification;
114       break;
115     case ui::AX_EVENT_TEXT_SELECTION_CHANGED:
116       event_id = NSAccessibilitySelectedTextChangedNotification;
117       break;
118     case ui::AX_EVENT_VALUE_CHANGED:
119       event_id = NSAccessibilityValueChangedNotification;
120       break;
121     case ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED:
122       // Not used on Mac.
123       return;
124     case ui::AX_EVENT_AUTOCORRECTION_OCCURED:
125       // Not used on Mac.
126       return;
127     case ui::AX_EVENT_INVALID_STATUS_CHANGED:
128       // Not used on Mac.
129       return;
130     case ui::AX_EVENT_LOCATION_CHANGED:
131       // Not used on Mac.
132       return;
133     case ui::AX_EVENT_MENU_LIST_ITEM_SELECTED:
134       // Not used on Mac.
135       return;
136     case ui::AX_EVENT_TEXT_CHANGED:
137       // Not used on Mac.
138       return;
139     default:
140       LOG(WARNING) << "Unknown accessibility event: " << event_type;
141       return;
142   }
143   BrowserAccessibilityCocoa* native_node = node->ToBrowserAccessibilityCocoa();
144   DCHECK(native_node);
145   NSAccessibilityPostNotification(native_node, event_id);
148 void BrowserAccessibilityManagerMac::OnNodeCreationFinished(ui::AXNode* node) {
149   BrowserAccessibility* obj = GetFromAXNode(node);
150   if (obj && obj->HasStringAttribute(ui::AX_ATTR_LIVE_STATUS))
151     created_live_region_ = true;
154 void BrowserAccessibilityManagerMac::OnTreeUpdateFinished() {
155   if (!created_live_region_)
156     return;
158   // This code is to work around a bug in VoiceOver, where a new live
159   // region that gets added is ignored. VoiceOver seems to only scan the
160   // page for live regions once. By recreating the NSAccessibility
161   // object for the root of the tree, we force VoiceOver to clear out its
162   // internal state and find newly-added live regions this time.
163   BrowserAccessibilityMac* root =
164       static_cast<BrowserAccessibilityMac*>(GetRoot());
165   root->RecreateNativeObject();
166   NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, root);
168   created_live_region_ = false;
171 }  // namespace content