Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1107)

Unified Diff: chrome/browser/views/accessibility_event_router_views.cc

Issue 3056045: Improvements to accessibility extension api support for "views":... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/views/accessibility_event_router_views.cc
===================================================================
--- chrome/browser/views/accessibility_event_router_views.cc (revision 55065)
+++ chrome/browser/views/accessibility_event_router_views.cc (working copy)
@@ -11,10 +11,13 @@
#include "chrome/browser/extensions/extension_accessibility_api.h"
#include "chrome/browser/profile.h"
#include "chrome/common/notification_type.h"
+#include "views/accessibility/accessibility_types.h"
#include "views/controls/button/image_button.h"
#include "views/controls/button/menu_button.h"
#include "views/controls/button/native_button.h"
#include "views/controls/link.h"
+#include "views/controls/menu/menu_item_view.h"
+#include "views/controls/menu/submenu_view.h"
using views::FocusManager;
using views::View;
@@ -36,18 +39,6 @@
return false;
view_tree_profile_map_[view] = profile;
- FocusManager* focus_manager = view->GetFocusManager();
-
- // Add this object as a listener for this focus manager, but use a ref
- // count to ensure we only call AddFocusChangeListener on any given
- // focus manager once. Note that hash_map<FocusManager*, int>::operator[]
- // will initialize the ref count to zero if it's not already in the map.
- if (focus_manager_ref_count_[focus_manager] == 0) {
- focus_manager->AddFocusChangeListener(this);
- }
- focus_manager_ref_count_[focus_manager]++;
-
- view_info_map_[view].focus_manager = focus_manager;
return true;
}
@@ -55,15 +46,6 @@
DCHECK(view_tree_profile_map_.find(view) !=
view_tree_profile_map_.end());
view_tree_profile_map_.erase(view);
-
- // Decrement the ref count of the focus manager, and remove this object
- // as a listener if the count reaches zero.
- FocusManager* focus_manager = view_info_map_[view].focus_manager;
- DCHECK(focus_manager);
- focus_manager_ref_count_[focus_manager]--;
- if (focus_manager_ref_count_[focus_manager] == 0) {
- focus_manager->RemoveFocusChangeListener(this);
- }
}
void AccessibilityEventRouterViews::IgnoreView(View* view) {
@@ -79,15 +61,23 @@
view_info_map_.erase(view);
}
-//
-// views::FocusChangeListener
-//
-
-void AccessibilityEventRouterViews::FocusWillChange(
- View* focused_before, View* focused_now) {
- if (focused_now) {
- DispatchAccessibilityNotification(
- focused_now, NotificationType::ACCESSIBILITY_CONTROL_FOCUSED);
+void AccessibilityEventRouterViews::HandleAccessibilityEvent(
+ views::View* view, AccessibilityTypes::Event event_type) {
+ switch (event_type) {
+ case AccessibilityTypes::EVENT_FOCUS:
+ DispatchAccessibilityNotification(
+ view, NotificationType::ACCESSIBILITY_CONTROL_FOCUSED);
+ break;
+ case AccessibilityTypes::EVENT_MENUSTART:
+ case AccessibilityTypes::EVENT_MENUPOPUPSTART:
+ DispatchAccessibilityNotification(
+ view, NotificationType::ACCESSIBILITY_MENU_OPENED);
+ break;
+ case AccessibilityTypes::EVENT_MENUEND:
+ case AccessibilityTypes::EVENT_MENUPOPUPEND:
+ DispatchAccessibilityNotification(
+ view, NotificationType::ACCESSIBILITY_MENU_CLOSED);
+ break;
}
}
@@ -145,17 +135,38 @@
Profile* profile = NULL;
bool is_accessible;
FindView(view, &profile, &is_accessible);
+
+ // Special case: a menu isn't associated with any particular top-level
+ // window, so menu events get routed to the profile of the most recent
+ // event that was associated with a window, which should be the window
+ // that triggered opening the menu.
+ bool is_menu_event = IsMenuEvent(view, type);
+ if (is_menu_event && !profile && most_recent_profile_) {
+ profile = most_recent_profile_;
+ is_accessible = true;
+ }
+
if (!is_accessible)
return;
- if (view->GetClassName() == views::ImageButton::kViewClassName) {
+ most_recent_profile_ = profile;
+
+ AccessibilityTypes::Role role;
+ view->GetAccessibleRole(&role);
+ std::string class_name = view->GetClassName();
+
+ if (class_name == views::MenuButton::kViewClassName ||
+ type == NotificationType::ACCESSIBILITY_MENU_OPENED ||
+ type == NotificationType::ACCESSIBILITY_MENU_CLOSED) {
+ SendMenuNotification(view, type, profile);
+ } else if (is_menu_event) {
+ SendMenuItemNotification(view, type, profile);
+ } else if (class_name == views::ImageButton::kViewClassName ||
+ class_name == views::NativeButton::kViewClassName ||
+ class_name == views::TextButton::kViewClassName) {
SendButtonNotification(view, type, profile);
- } else if (view->GetClassName() == views::NativeButton::kViewClassName) {
- SendButtonNotification(view, type, profile);
- } else if (view->GetClassName() == views::Link::kViewClassName) {
+ } else if (class_name == views::Link::kViewClassName) {
SendLinkNotification(view, type, profile);
- } else if (view->GetClassName() == views::MenuButton::kViewClassName) {
- SendMenuNotification(view, type, profile);
}
}
@@ -176,3 +187,66 @@
AccessibilityMenuInfo info(profile, GetViewName(view));
SendAccessibilityNotification(type, &info);
}
+
+void AccessibilityEventRouterViews::SendMenuItemNotification(
+ View* view, NotificationType type, Profile* profile) {
+ std::string name = GetViewName(view);
+
+ bool has_submenu = false;
+ int index = -1;
+ int count = -1;
+
+ if (view->GetClassName() == views::MenuItemView::kViewClassName)
+ has_submenu = static_cast<views::MenuItemView*>(view)->HasSubmenu();
+
+ View* parent_menu = view->GetParent();
+ while (parent_menu != NULL && parent_menu->GetClassName() !=
+ views::SubmenuView::kViewClassName) {
+ parent_menu = parent_menu->GetParent();
+ }
+ if (parent_menu) {
+ count = 0;
+ RecursiveGetMenuItemIndexAndCount(parent_menu, view, &index, &count);
+ }
+
+ AccessibilityMenuItemInfo info(profile, name, has_submenu, index, count);
+ SendAccessibilityNotification(type, &info);
+}
+
+void AccessibilityEventRouterViews::RecursiveGetMenuItemIndexAndCount(
+ views::View* menu, views::View* item, int* index, int* count) {
+ for (int i = 0; i < menu->GetChildViewCount(); ++i) {
+ views::View* child = menu->GetChildViewAt(i);
+ int previous_count = *count;
+ RecursiveGetMenuItemIndexAndCount(child, item, index, count);
+ if (child->GetClassName() == views::MenuItemView::kViewClassName &&
+ *count == previous_count) {
+ if (item == child)
+ *index = *count;
+ (*count)++;
+ } else if (child->GetClassName() == views::TextButton::kViewClassName) {
+ if (item == child)
+ *index = *count;
+ (*count)++;
+ }
+ }
+}
+
+bool AccessibilityEventRouterViews::IsMenuEvent(
+ View* view, NotificationType type) {
+ if (type == NotificationType::ACCESSIBILITY_MENU_OPENED ||
+ type == NotificationType::ACCESSIBILITY_MENU_CLOSED)
+ return true;
+
+ while (view) {
+ AccessibilityTypes::Role role;
+ view->GetAccessibleRole(&role);
+ if (role == AccessibilityTypes::ROLE_MENUITEM ||
+ role == AccessibilityTypes::ROLE_MENUPOPUP) {
+ return true;
+ }
+ view = view->GetParent();
+ }
+
+ return false;
+}

Powered by Google App Engine
This is Rietveld 408576698