summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authordmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-06 15:25:00 +0000
committerdmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-06 15:25:00 +0000
commit075d97d34cd147da28f536c5d4e4b6bea1bfef43 (patch)
tree72d594b1681035d0efd34b6c854ee77dcd2cb6b2 /content
parent0944741242d9ed32323b06a8026a62b89de2a9bf (diff)
downloadchromium_src-075d97d34cd147da28f536c5d4e4b6bea1bfef43.zip
chromium_src-075d97d34cd147da28f536c5d4e4b6bea1bfef43.tar.gz
chromium_src-075d97d34cd147da28f536c5d4e4b6bea1bfef43.tar.bz2
Add initial GTK web accessibility framework (new with valgrind fix).
This is the same as http://codereview.chromium.org/9839069/ which was landed but reverted due to a valgrind failure in content_unittests. The valgrind failure was because browser_accessibility_manager_unittest.cc is constructing its own subclass of BrowserAccessibility (for testing), but BrowserAccessibilityManagerGtk was assuming that any BrowserAccessibility could be static_casted to a BrowserAccessibilityGtk. I fixed this by making ToBrowserAccessibilityGtk() a virtual method with a default impl that returns NULL. Original change: This enables Linux desktop assistive technology such as the Orca screen reader to access the web contents. Builds on the same accessibility stack used by Mac & Windows already. This change works with Orca now, but it's minimal: all that works is getting the correct feedback when you tab through focusable links and controls in a webpage. Future changes will add the rest of the support. BUG=24585 TEST=Run Chrome on desktop Linux with Orca turned on, tab through links. TBR=darin,sky Review URL: https://chromiumcodereview.appspot.com/10381010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135593 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/accessibility/browser_accessibility.cc22
-rw-r--r--content/browser/accessibility/browser_accessibility.h14
-rw-r--r--content/browser/accessibility/browser_accessibility_cocoa.mm17
-rw-r--r--content/browser/accessibility/browser_accessibility_gtk.cc343
-rw-r--r--content/browser/accessibility/browser_accessibility_gtk.h93
-rw-r--r--content/browser/accessibility/browser_accessibility_mac.h5
-rw-r--r--content/browser/accessibility/browser_accessibility_mac.mm5
-rw-r--r--content/browser/accessibility/browser_accessibility_mac_unittest.mm5
-rw-r--r--content/browser/accessibility/browser_accessibility_manager.cc8
-rw-r--r--content/browser/accessibility/browser_accessibility_manager.h2
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_gtk.cc71
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_gtk.h41
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_mac.mm10
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_win.cc2
-rw-r--r--content/browser/accessibility/browser_accessibility_win.cc99
-rw-r--r--content/browser/accessibility/browser_accessibility_win.h3
-rw-r--r--content/browser/accessibility/browser_accessibility_win_unittest.cc14
-rw-r--r--content/browser/accessibility/dump_accessibility_tree_helper_mac.mm3
-rw-r--r--content/browser/accessibility/dump_accessibility_tree_helper_win.cc2
-rw-r--r--content/browser/renderer_host/render_widget_host_view_gtk.cc76
-rw-r--r--content/browser/renderer_host/render_widget_host_view_gtk.h25
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm9
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc2
-rw-r--r--content/content_browser.gypi4
24 files changed, 783 insertions, 92 deletions
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 4f81569..93e8f9c 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -15,9 +15,11 @@ typedef WebAccessibility::FloatAttribute FloatAttribute;
typedef WebAccessibility::IntAttribute IntAttribute;
typedef WebAccessibility::StringAttribute StringAttribute;
-#if (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(USE_AURA)
-// There's no OS-specific implementation of BrowserAccessibilityManager
-// on Unix, so just instantiate the base class.
+#if !defined(OS_MACOSX) && \
+ !(defined(OS_WIN) && !defined(USE_AURA)) && \
+ !defined(TOOLKIT_GTK)
+// We have subclassess of BrowserAccessibility on Mac, Linux/GTK,
+// and non-Aura Win. For any other platform, instantiate the base class.
// static
BrowserAccessibility* BrowserAccessibility::Create() {
return new BrowserAccessibility();
@@ -202,6 +204,20 @@ void BrowserAccessibility::NativeReleaseReference() {
delete this;
}
+#if defined(OS_MACOSX)
+BrowserAccessibilityMac* BrowserAccessibility::ToBrowserAccessibilityMac() {
+ return NULL;
+}
+#elif defined(OS_WIN)
+BrowserAccessibilityWin* BrowserAccessibility::ToBrowserAccessibilityWin() {
+ return NULL;
+}
+#elif defined(TOOLKIT_GTK)
+BrowserAccessibilityGtk* BrowserAccessibility::ToBrowserAccessibilityGtk() {
+ return NULL;
+}
+#endif
+
bool BrowserAccessibility::GetBoolAttribute(
BoolAttribute attribute, bool* value) const {
BoolAttrMap::const_iterator iter = bool_attributes_.find(attribute);
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index 0fbb3eb..c789c19 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -16,10 +16,12 @@
#include "webkit/glue/webaccessibility.h"
class BrowserAccessibilityManager;
-#if defined(OS_MACOSX) && __OBJC__
-@class BrowserAccessibilityCocoa;
+#if defined(OS_MACOSX)
+class BrowserAccessibilityMac;
#elif defined(OS_WIN)
class BrowserAccessibilityWin;
+#elif defined(TOOLKIT_GTK)
+class BrowserAccessibilityGtk;
#endif
using webkit_glue::WebAccessibility;
@@ -187,10 +189,12 @@ class CONTENT_EXPORT BrowserAccessibility {
bool instance_active() const { return instance_active_; }
int32 ref_count() const { return ref_count_; }
-#if defined(OS_MACOSX) && __OBJC__
- BrowserAccessibilityCocoa* toBrowserAccessibilityCocoa();
+#if defined(OS_MACOSX)
+ virtual BrowserAccessibilityMac* ToBrowserAccessibilityMac();
#elif defined(OS_WIN)
- BrowserAccessibilityWin* toBrowserAccessibilityWin();
+ virtual BrowserAccessibilityWin* ToBrowserAccessibilityWin();
+#elif defined(TOOLKIT_GTK)
+ virtual BrowserAccessibilityGtk* ToBrowserAccessibilityGtk();
#endif
// Retrieve the value of a bool attribute from the bool attribute
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index b282cad..3a434ff 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -12,6 +12,7 @@
#include "base/string16.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
+#include "content/browser/accessibility/browser_accessibility_mac.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/public/common/content_client.h"
#include "grit/webkit_strings.h"
@@ -343,7 +344,8 @@ NSDictionary* attributeToMethodNameMap = nil;
index < browserAccessibility_->child_count();
++index) {
BrowserAccessibilityCocoa* child =
- browserAccessibility_->GetChild(index)->toBrowserAccessibilityCocoa();
+ browserAccessibility_->GetChild(index)->
+ ToBrowserAccessibilityMac()->native_view();
if ([child isIgnored])
[children_ addObjectsFromArray:[child children]];
else
@@ -362,7 +364,7 @@ NSDictionary* attributeToMethodNameMap = nil;
// a DCHECK in the future.
if (child) {
BrowserAccessibilityCocoa* child_cocoa =
- child->toBrowserAccessibilityCocoa();
+ child->ToBrowserAccessibilityMac()->native_view();
[children_ addObject:child_cocoa];
}
}
@@ -373,9 +375,9 @@ NSDictionary* attributeToMethodNameMap = nil;
- (void)childrenChanged {
if (![self isIgnored]) {
children_.reset();
- } else {
- [browserAccessibility_->parent()->toBrowserAccessibilityCocoa()
- childrenChanged];
+ } else if (browserAccessibility_->parent()) {
+ [browserAccessibility_->parent()->ToBrowserAccessibilityMac()->native_view()
+ childrenChanged];
}
}
@@ -488,7 +490,8 @@ NSDictionary* attributeToMethodNameMap = nil;
// A nil parent means we're the root.
if (browserAccessibility_->parent()) {
return NSAccessibilityUnignoredAncestor(
- browserAccessibility_->parent()->toBrowserAccessibilityCocoa());
+ browserAccessibility_->parent()->ToBrowserAccessibilityMac()->
+ native_view());
} else {
// Hook back up to RenderWidgetHostViewCocoa.
return browserAccessibility_->manager()->GetParentView();
@@ -632,7 +635,7 @@ NSDictionary* attributeToMethodNameMap = nil;
BrowserAccessibility* titleElement =
browserAccessibility_->manager()->GetFromRendererID(titleElementId);
if (titleElement)
- return titleElement->toBrowserAccessibilityCocoa();
+ return titleElement->ToBrowserAccessibilityMac()->native_view();
}
return nil;
}
diff --git a/content/browser/accessibility/browser_accessibility_gtk.cc b/content/browser/accessibility/browser_accessibility_gtk.cc
new file mode 100644
index 0000000..7a3e3f7
--- /dev/null
+++ b/content/browser/accessibility/browser_accessibility_gtk.cc
@@ -0,0 +1,343 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/accessibility/browser_accessibility_gtk.h"
+
+#include "base/utf_string_conversions.h"
+#include "content/browser/accessibility/browser_accessibility_manager_gtk.h"
+#include "content/common/accessibility_messages.h"
+
+#include <gtk/gtk.h>
+
+using webkit_glue::WebAccessibility;
+
+// The maximum length of an autogenerated unique type name string,
+// generated from the 16-bit interface mask from an AtkObject.
+// 30 is enough for the prefix "WAIType" + 5 hex chars (max) */
+static const int kWAITypeNameLen = 30;
+
+static gpointer browser_accessibility_parent_class = NULL;
+
+static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
+ BrowserAccessibilityAtk* atk_object) {
+ if (!atk_object)
+ return NULL;
+
+ return atk_object->m_object;
+}
+
+static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
+ AtkObject* atk_object) {
+ if (!IS_BROWSER_ACCESSIBILITY(atk_object))
+ return NULL;
+
+ return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object));
+}
+
+static const gchar* browser_accessibility_get_name(AtkObject* atk_object) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ return obj->atk_acc_name().c_str();
+}
+
+static const gchar* browser_accessibility_get_description(
+ AtkObject* atk_object) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ string16 description;
+ obj->GetStringAttribute(WebAccessibility::ATTR_DESCRIPTION, &description);
+ return UTF16ToUTF8(description).c_str();
+}
+
+static AtkObject* browser_accessibility_get_parent(AtkObject* atk_object) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ if (obj->parent())
+ return obj->parent()->ToBrowserAccessibilityGtk()->GetAtkObject();
+ else
+ return gtk_widget_get_accessible(obj->manager()->GetParentView());
+}
+
+static gint browser_accessibility_get_n_children(AtkObject* atk_object) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ return obj->children().size();
+}
+
+static AtkObject* browser_accessibility_ref_child(
+ AtkObject* atk_object, gint index) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ AtkObject* result =
+ obj->children()[index]->ToBrowserAccessibilityGtk()->GetAtkObject();
+ g_object_ref(result);
+ return result;
+}
+
+static gint browser_accessibility_get_index_in_parent(AtkObject* atk_object) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ return obj->index_in_parent();
+}
+
+static AtkAttributeSet* browser_accessibility_get_attributes(
+ AtkObject* atk_object) {
+ return NULL;
+}
+
+static AtkRole browser_accessibility_get_role(AtkObject* atk_object) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ return obj->atk_role();
+}
+
+static AtkStateSet* browser_accessibility_ref_state_set(AtkObject* atk_object) {
+ BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
+ AtkStateSet* state_set =
+ ATK_OBJECT_CLASS(browser_accessibility_parent_class)->
+ ref_state_set(atk_object);
+ int32 state = obj->state();
+
+ if ((state >> WebAccessibility::STATE_FOCUSABLE) & 1)
+ atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE);
+ if (obj->manager()->GetFocus(NULL) == obj)
+ atk_state_set_add_state(state_set, ATK_STATE_FOCUSED);
+
+ return state_set;
+}
+
+static AtkRelationSet* browser_accessibility_ref_relation_set(
+ AtkObject* atk_object) {
+ AtkRelationSet* relation_set =
+ ATK_OBJECT_CLASS(browser_accessibility_parent_class)
+ ->ref_relation_set(atk_object);
+ return relation_set;
+}
+
+static void browser_accessibility_init(AtkObject* atk_object, gpointer data) {
+ if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) {
+ ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize(
+ atk_object, data);
+ }
+
+ BROWSER_ACCESSIBILITY(atk_object)->m_object =
+ reinterpret_cast<BrowserAccessibilityGtk*>(data);
+}
+
+static void browser_accessibility_finalize(GObject* atk_object) {
+ G_OBJECT_CLASS(browser_accessibility_parent_class)->finalize(atk_object);
+}
+
+static void browser_accessibility_class_init(AtkObjectClass* klass) {
+ GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
+ browser_accessibility_parent_class = g_type_class_peek_parent(klass);
+
+ gobject_class->finalize = browser_accessibility_finalize;
+ klass->initialize = browser_accessibility_init;
+ klass->get_name = browser_accessibility_get_name;
+ klass->get_description = browser_accessibility_get_description;
+ klass->get_parent = browser_accessibility_get_parent;
+ klass->get_n_children = browser_accessibility_get_n_children;
+ klass->ref_child = browser_accessibility_ref_child;
+ klass->get_role = browser_accessibility_get_role;
+ klass->ref_state_set = browser_accessibility_ref_state_set;
+ klass->get_index_in_parent = browser_accessibility_get_index_in_parent;
+ klass->get_attributes = browser_accessibility_get_attributes;
+ klass->ref_relation_set = browser_accessibility_ref_relation_set;
+}
+
+GType browser_accessibility_get_type() {
+ static volatile gsize type_volatile = 0;
+
+ if (g_once_init_enter(&type_volatile)) {
+ static const GTypeInfo tinfo = {
+ sizeof(BrowserAccessibilityAtkClass),
+ (GBaseInitFunc) 0,
+ (GBaseFinalizeFunc) 0,
+ (GClassInitFunc) browser_accessibility_class_init,
+ (GClassFinalizeFunc) 0,
+ 0, /* class data */
+ sizeof(BrowserAccessibilityAtk), /* instance size */
+ 0, /* nb preallocs */
+ (GInstanceInitFunc) 0,
+ 0 /* value table */
+ };
+
+ GType type = g_type_register_static(
+ ATK_TYPE_OBJECT, "BrowserAccessibility", &tinfo, GTypeFlags(0));
+ g_once_init_leave(&type_volatile, type);
+ }
+
+ return type_volatile;
+}
+
+static guint16 GetInterfaceMaskFromObject(BrowserAccessibilityGtk* obj) {
+ return 0;
+}
+
+static const char* GetUniqueAccessibilityTypeName(guint16 interface_mask)
+{
+ static char name[kWAITypeNameLen + 1];
+
+ sprintf(name, "WAIType%x", interface_mask);
+ name[kWAITypeNameLen] = '\0';
+
+ return name;
+}
+
+static const GInterfaceInfo AtkInterfacesInitFunctions[] = {
+};
+
+enum WAIType {
+ WAI_ACTION,
+ WAI_SELECTION,
+ WAI_EDITABLE_TEXT,
+ WAI_TEXT,
+ WAI_COMPONENT,
+ WAI_IMAGE,
+ WAI_TABLE,
+ WAI_HYPERTEXT,
+ WAI_HYPERLINK,
+ WAI_DOCUMENT,
+ WAI_VALUE,
+};
+
+static GType GetAtkInterfaceTypeFromWAIType(WAIType type) {
+ switch (type) {
+ case WAI_ACTION:
+ return ATK_TYPE_ACTION;
+ case WAI_SELECTION:
+ return ATK_TYPE_SELECTION;
+ case WAI_EDITABLE_TEXT:
+ return ATK_TYPE_EDITABLE_TEXT;
+ case WAI_TEXT:
+ return ATK_TYPE_TEXT;
+ case WAI_COMPONENT:
+ return ATK_TYPE_COMPONENT;
+ case WAI_IMAGE:
+ return ATK_TYPE_IMAGE;
+ case WAI_TABLE:
+ return ATK_TYPE_TABLE;
+ case WAI_HYPERTEXT:
+ return ATK_TYPE_HYPERTEXT;
+ case WAI_HYPERLINK:
+ return ATK_TYPE_HYPERLINK_IMPL;
+ case WAI_DOCUMENT:
+ return ATK_TYPE_DOCUMENT;
+ case WAI_VALUE:
+ return ATK_TYPE_VALUE;
+ }
+
+ return G_TYPE_INVALID;
+}
+
+static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) {
+ static const GTypeInfo type_info = {
+ sizeof(BrowserAccessibilityAtkClass),
+ (GBaseInitFunc) 0,
+ (GBaseFinalizeFunc) 0,
+ (GClassInitFunc) 0,
+ (GClassFinalizeFunc) 0,
+ 0, /* class data */
+ sizeof(BrowserAccessibilityAtk), /* instance size */
+ 0, /* nb preallocs */
+ (GInstanceInitFunc) 0,
+ 0 /* value table */
+ };
+
+ guint16 interface_mask = GetInterfaceMaskFromObject(obj);
+ const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask);
+ GType type = g_type_from_name(atk_type_name);
+ if (type)
+ return type;
+
+ type = g_type_register_static(BROWSER_ACCESSIBILITY_TYPE,
+ atk_type_name,
+ &type_info,
+ GTypeFlags(0));
+ for (guint i = 0; i < G_N_ELEMENTS(AtkInterfacesInitFunctions); i++) {
+ if (interface_mask & (1 << i)) {
+ g_type_add_interface_static(
+ type,
+ GetAtkInterfaceTypeFromWAIType(static_cast<WAIType>(i)),
+ &AtkInterfacesInitFunctions[i]);
+ }
+ }
+
+ return type;
+}
+
+BrowserAccessibilityAtk* browser_accessibility_new(
+ BrowserAccessibilityGtk* obj) {
+ GType type = GetAccessibilityTypeFromObject(obj);
+ AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0));
+
+ atk_object_initialize(atk_object, obj);
+
+ return BROWSER_ACCESSIBILITY(atk_object);
+}
+
+void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object) {
+}
+
+// static
+BrowserAccessibility* BrowserAccessibility::Create() {
+ return new BrowserAccessibilityGtk();
+}
+
+BrowserAccessibilityGtk::BrowserAccessibilityGtk() {
+ atk_object_ = ATK_OBJECT(browser_accessibility_new(this));
+}
+
+BrowserAccessibilityGtk::~BrowserAccessibilityGtk() {
+ browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_));
+}
+
+BrowserAccessibilityGtk* BrowserAccessibilityGtk::ToBrowserAccessibilityGtk() {
+ return this;
+}
+
+AtkObject* BrowserAccessibilityGtk::GetAtkObject() const {
+ if (!G_IS_OBJECT(atk_object_))
+ return NULL;
+ return atk_object_;
+}
+
+void BrowserAccessibilityGtk::PreInitialize() {
+ BrowserAccessibility::PreInitialize();
+ InitRoleAndState();
+
+ if (this->parent()) {
+ atk_object_set_parent(
+ atk_object_,
+ this->parent()->ToBrowserAccessibilityGtk()->GetAtkObject());
+ }
+}
+
+void BrowserAccessibilityGtk::InitRoleAndState() {
+ atk_acc_name_ = UTF16ToUTF8(name()).c_str();
+
+ switch(role_) {
+ case WebAccessibility::ROLE_BUTTON:
+ atk_role_ = ATK_ROLE_PUSH_BUTTON;
+ break;
+ case WebAccessibility::ROLE_CHECKBOX:
+ atk_role_ = ATK_ROLE_CHECK_BOX;
+ break;
+ case WebAccessibility::ROLE_COMBO_BOX:
+ atk_role_ = ATK_ROLE_COMBO_BOX;
+ break;
+ case WebAccessibility::ROLE_LINK:
+ atk_role_ = ATK_ROLE_LINK;
+ break;
+ case WebAccessibility::ROLE_RADIO_BUTTON:
+ atk_role_ = ATK_ROLE_RADIO_BUTTON;
+ break;
+ case WebAccessibility::ROLE_TEXTAREA:
+ atk_role_ = ATK_ROLE_ENTRY;
+ break;
+ case WebAccessibility::ROLE_TEXT_FIELD:
+ atk_role_ = ATK_ROLE_ENTRY;
+ break;
+ case WebAccessibility::ROLE_WEBCORE_LINK:
+ atk_role_ = ATK_ROLE_LINK;
+ break;
+ default:
+ atk_role_ = ATK_ROLE_UNKNOWN;
+ break;
+ }
+}
diff --git a/content/browser/accessibility/browser_accessibility_gtk.h b/content/browser/accessibility/browser_accessibility_gtk.h
new file mode 100644
index 0000000..222da8a
--- /dev/null
+++ b/content/browser/accessibility/browser_accessibility_gtk.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_GTK_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_GTK_H_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "webkit/glue/webaccessibility.h"
+
+#include <atk/atk.h>
+
+using webkit_glue::WebAccessibility;
+
+class BrowserAccessibilityGtk;
+class BrowserAccessibilityManagerGtk;
+
+G_BEGIN_DECLS
+
+#define BROWSER_ACCESSIBILITY_TYPE (browser_accessibility_get_type())
+#define BROWSER_ACCESSIBILITY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST( \
+ (obj), BROWSER_ACCESSIBILITY_TYPE, BrowserAccessibilityAtk))
+#define BROWSER_ACCESSIBILITY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST( \
+ (klass), BROWSER_ACCESSIBILITY_TYPE, BrowserAccessibilityAtkClass))
+#define IS_BROWSER_ACCESSIBILITY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), BROWSER_ACCESSIBILITY_TYPE))
+#define IS_BROWSER_ACCESSIBILITY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), BROWSER_ACCESSIBILITY_TYPE))
+#define BROWSER_ACCESSIBILITY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS( \
+ (obj), BROWSER_ACCESSIBILITY_TYPE, BrowserAccessibilityAtkClass))
+
+typedef struct _BrowserAccessibilityAtk BrowserAccessibilityAtk;
+typedef struct _BrowserAccessibilityAtkClass BrowserAccessibilityAtkClass;
+
+struct _BrowserAccessibilityAtk {
+ AtkObject parent;
+ BrowserAccessibilityGtk* m_object;
+};
+
+struct _BrowserAccessibilityAtkClass {
+ AtkObjectClass parent_class;
+};
+
+GType browser_accessibility_get_type (void) G_GNUC_CONST;
+
+BrowserAccessibilityAtk* browser_accessibility_new(
+ BrowserAccessibilityGtk* object);
+
+BrowserAccessibilityGtk* browser_accessibility_get_object(
+ BrowserAccessibilityAtk* atk_object);
+
+void browser_accessibility_detach (BrowserAccessibilityAtk* atk_object);
+
+AtkObject* browser_accessibility_get_focused_element(
+ BrowserAccessibilityAtk* atk_object);
+
+G_END_DECLS
+
+class BrowserAccessibilityGtk : public BrowserAccessibility {
+ public:
+ BrowserAccessibilityGtk();
+
+ virtual ~BrowserAccessibilityGtk();
+
+ AtkObject* GetAtkObject() const;
+
+ AtkRole atk_role() { return atk_role_; }
+ const std::string& atk_acc_name() { return atk_acc_name_; }
+
+ // BrowserAccessibility methods.
+ virtual void PreInitialize() OVERRIDE;
+ virtual BrowserAccessibilityGtk* ToBrowserAccessibilityGtk() OVERRIDE;
+
+ private:
+ virtual void InitRoleAndState();
+
+ // Give BrowserAccessibility::Create access to our constructor.
+ friend class BrowserAccessibility;
+
+ AtkObject* atk_object_;
+ AtkRole atk_role_;
+ std::string atk_acc_name_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityGtk);
+};
+
+#endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_GTK_H_
diff --git a/content/browser/accessibility/browser_accessibility_mac.h b/content/browser/accessibility/browser_accessibility_mac.h
index c6fd27e..7eae766 100644
--- a/content/browser/accessibility/browser_accessibility_mac.h
+++ b/content/browser/accessibility/browser_accessibility_mac.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,6 +12,7 @@
#include "base/memory/scoped_nsobject.h"
#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/common/content_export.h"
@class BrowserAccessibilityCocoa;
@@ -23,6 +24,8 @@ class BrowserAccessibilityMac : public BrowserAccessibility {
// Overrides from BrowserAccessibility.
virtual void DetachTree(std::vector<BrowserAccessibility*>* nodes) OVERRIDE;
+ CONTENT_EXPORT virtual BrowserAccessibilityMac*
+ ToBrowserAccessibilityMac() OVERRIDE;
// The BrowserAccessibilityCocoa associated with us.
BrowserAccessibilityCocoa* native_view() const {
diff --git a/content/browser/accessibility/browser_accessibility_mac.mm b/content/browser/accessibility/browser_accessibility_mac.mm
index 6a209d8..ff0ab2f 100644
--- a/content/browser/accessibility/browser_accessibility_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_mac.mm
@@ -53,7 +53,6 @@ void BrowserAccessibilityMac::DetachTree(
BrowserAccessibility::DetachTree(nodes);
}
-BrowserAccessibilityCocoa* BrowserAccessibility::toBrowserAccessibilityCocoa() {
- return static_cast<BrowserAccessibilityMac*>(this)->
- native_view();
+BrowserAccessibilityMac* BrowserAccessibilityMac::ToBrowserAccessibilityMac() {
+ return this;
}
diff --git a/content/browser/accessibility/browser_accessibility_mac_unittest.mm b/content/browser/accessibility/browser_accessibility_mac_unittest.mm
index bb80935..1477c89 100644
--- a/content/browser/accessibility/browser_accessibility_mac_unittest.mm
+++ b/content/browser/accessibility/browser_accessibility_mac_unittest.mm
@@ -8,6 +8,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_cocoa.h"
+#include "content/browser/accessibility/browser_accessibility_mac.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"
@@ -77,8 +78,8 @@ class BrowserAccessibilityTest : public ui::CocoaTest {
delegate_.reset([[MockAccessibilityDelegate alloc] init]);
manager_.reset(
BrowserAccessibilityManager::Create(delegate_, root, NULL));
- accessibility_.reset([manager_->GetRoot()->toBrowserAccessibilityCocoa()
- retain]);
+ accessibility_.reset([manager_->GetRoot()->ToBrowserAccessibilityMac()->
+ native_view() retain]);
}
protected:
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index 9c5329d..4440d28 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -21,9 +21,11 @@ BrowserAccessibility* BrowserAccessibilityFactory::Create() {
// static
int32 BrowserAccessibilityManager::next_child_id_ = -1;
-#if (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(USE_AURA)
-// There's no OS-specific implementation of BrowserAccessibilityManager
-// on Unix, so just instantiate the base class.
+#if !defined(OS_MACOSX) && \
+ !(defined(OS_WIN) && !defined(USE_AURA)) && \
+ !defined(TOOLKIT_GTK)
+// We have subclassess of BrowserAccessibilityManager on Mac, Linux/GTK,
+// and non-Aura Win. For any other platform, instantiate the base class.
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
gfx::NativeView parent_view,
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index 8b2d7fd..7e1757b 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -133,7 +133,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager {
gfx::NativeView GetParentView();
#if defined(OS_WIN)
- BrowserAccessibilityManagerWin* toBrowserAccessibilityManagerWin();
+ BrowserAccessibilityManagerWin* ToBrowserAccessibilityManagerWin();
#endif
// Return the object that has focus, if it's a descandant of the
diff --git a/content/browser/accessibility/browser_accessibility_manager_gtk.cc b/content/browser/accessibility/browser_accessibility_manager_gtk.cc
new file mode 100644
index 0000000..4bac86a
--- /dev/null
+++ b/content/browser/accessibility/browser_accessibility_manager_gtk.cc
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/accessibility/browser_accessibility_manager_gtk.h"
+
+#include "content/browser/accessibility/browser_accessibility_gtk.h"
+#include "content/common/accessibility_messages.h"
+
+using webkit_glue::WebAccessibility;
+
+// static
+BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
+ gfx::NativeView parent_view,
+ const WebAccessibility& src,
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory) {
+ return new BrowserAccessibilityManagerGtk(
+ parent_view,
+ src,
+ delegate,
+ factory);
+}
+
+BrowserAccessibilityManagerGtk::BrowserAccessibilityManagerGtk(
+ GtkWidget* parent_view,
+ const WebAccessibility& src,
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory)
+ : BrowserAccessibilityManager(parent_view, src, delegate, factory) {
+}
+
+BrowserAccessibilityManagerGtk::~BrowserAccessibilityManagerGtk() {
+}
+
+void BrowserAccessibilityManagerGtk::NotifyAccessibilityEvent(
+ int type,
+ BrowserAccessibility* node) {
+ if (!node->ToBrowserAccessibilityGtk())
+ return;
+ AtkObject* atk_object = node->ToBrowserAccessibilityGtk()->GetAtkObject();
+
+ switch (type) {
+ case AccessibilityNotificationChildrenChanged:
+ RecursivelySendChildrenChanged(GetRoot()->ToBrowserAccessibilityGtk());
+ break;
+ case AccessibilityNotificationFocusChanged:
+ // Note: atk_focus_tracker_notify may be deprecated in the future;
+ // follow this bug for the replacement:
+ // https://bugzilla.gnome.org/show_bug.cgi?id=649575#c4
+ g_signal_emit_by_name(atk_object, "focus-event", true);
+ atk_focus_tracker_notify(atk_object);
+ break;
+ default:
+ break;
+ }
+}
+
+void BrowserAccessibilityManagerGtk::RecursivelySendChildrenChanged(
+ BrowserAccessibilityGtk* node) {
+ AtkObject* atkObject = node->ToBrowserAccessibilityGtk()->GetAtkObject();
+ for (unsigned int i = 0; i < node->children().size(); ++i) {
+ BrowserAccessibilityGtk* child =
+ node->children()[i]->ToBrowserAccessibilityGtk();
+ g_signal_emit_by_name(atkObject,
+ "children-changed::add",
+ i,
+ child->GetAtkObject());
+ RecursivelySendChildrenChanged(child);
+ }
+}
diff --git a/content/browser/accessibility/browser_accessibility_manager_gtk.h b/content/browser/accessibility/browser_accessibility_manager_gtk.h
new file mode 100644
index 0000000..4de6678
--- /dev/null
+++ b/content/browser/accessibility/browser_accessibility_manager_gtk.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_GTK_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_GTK_H_
+#pragma once
+
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "webkit/glue/webaccessibility.h"
+
+class BrowserAccessibilityGtk;
+struct ViewHostMsg_AccessibilityNotification_Params;
+
+using webkit_glue::WebAccessibility;
+
+// Manages a tree of BrowserAccessibilityGtk objects.
+class BrowserAccessibilityManagerGtk : public BrowserAccessibilityManager {
+ public:
+ virtual ~BrowserAccessibilityManagerGtk();
+
+ // BrowserAccessibilityManager methods
+ virtual void NotifyAccessibilityEvent(int type, BrowserAccessibility* node)
+ OVERRIDE;
+
+ private:
+ BrowserAccessibilityManagerGtk(
+ GtkWidget* parent_window,
+ const WebAccessibility& src,
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory);
+
+ void RecursivelySendChildrenChanged(BrowserAccessibilityGtk* node);
+
+ // Give BrowserAccessibilityManager::Create access to our constructor.
+ friend class BrowserAccessibilityManager;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerGtk);
+};
+
+#endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_GTK_H_
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 92da9d5..e6163c6 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -6,6 +6,7 @@
#import "base/logging.h"
#import "content/browser/accessibility/browser_accessibility_cocoa.h"
+#import "content/browser/accessibility/browser_accessibility_mac.h"
#include "content/common/accessibility_messages.h"
// static
@@ -29,6 +30,13 @@ BrowserAccessibilityManagerMac::BrowserAccessibilityManagerMac(
void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
int type,
BrowserAccessibility* node) {
+ BrowserAccessibilityMac* mac_node = node->ToBrowserAccessibilityMac();
+ if (!mac_node)
+ return;
+ BrowserAccessibilityCocoa* native_node = mac_node->native_view();
+ if (!native_node)
+ return;
+
// Refer to AXObjectCache.mm (webkit).
NSString* event_id = @"";
switch (type) {
@@ -98,7 +106,5 @@ void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
event_id = NSAccessibilityValueChangedNotification;
break;
}
- BrowserAccessibilityCocoa* native_node = node->toBrowserAccessibilityCocoa();
- DCHECK(native_node);
NSAccessibilityPostNotification(native_node, event_id);
}
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index a00d233..b54d6fe 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -23,7 +23,7 @@ BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
}
BrowserAccessibilityManagerWin*
-BrowserAccessibilityManager::toBrowserAccessibilityManagerWin() {
+BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() {
return static_cast<BrowserAccessibilityManagerWin*>(this);
}
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index 8d38e01..a0b1aa0 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -135,7 +135,7 @@ STDMETHODIMP BrowserAccessibilityRelation::get_target(
return E_FAIL;
*target = static_cast<IAccessible*>(
- result->toBrowserAccessibilityWin()->NewReference());
+ result->ToBrowserAccessibilityWin()->NewReference());
return S_OK;
}
@@ -176,8 +176,8 @@ BrowserAccessibility* BrowserAccessibility::Create() {
return instance->NewReference();
}
-BrowserAccessibilityWin* BrowserAccessibility::toBrowserAccessibilityWin() {
- return static_cast<BrowserAccessibilityWin*>(this);
+BrowserAccessibilityWin* BrowserAccessibilityWin::ToBrowserAccessibilityWin() {
+ return this;
}
BrowserAccessibilityWin::BrowserAccessibilityWin()
@@ -238,7 +238,7 @@ STDMETHODIMP BrowserAccessibilityWin::accHitTest(LONG x_left,
child->lVal = CHILDID_SELF;
} else {
child->vt = VT_DISPATCH;
- child->pdispVal = result->toBrowserAccessibilityWin()->NewReference();
+ child->pdispVal = result->ToBrowserAccessibilityWin()->NewReference();
}
return S_OK;
}
@@ -307,7 +307,7 @@ STDMETHODIMP BrowserAccessibilityWin::accNavigate(
}
end->vt = VT_DISPATCH;
- end->pdispVal = result->toBrowserAccessibilityWin()->NewReference();
+ end->pdispVal = result->ToBrowserAccessibilityWin()->NewReference();
return S_OK;
}
@@ -465,11 +465,13 @@ STDMETHODIMP BrowserAccessibilityWin::get_accParent(IDispatch** disp_parent) {
if (!disp_parent)
return E_INVALIDARG;
- IAccessible* parent = parent_->toBrowserAccessibilityWin();
- if (parent == NULL) {
+ IAccessible* parent;
+ if (parent_) {
+ parent = parent_->ToBrowserAccessibilityWin();
+ } else {
// This happens if we're the root of the tree;
// return the IAccessible for the window.
- parent = manager_->toBrowserAccessibilityManagerWin()->
+ parent = manager_->ToBrowserAccessibilityManagerWin()->
GetParentWindowIAccessible();
}
@@ -566,7 +568,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accSelection(VARIANT* selected) {
if (children_[i]->HasState(WebAccessibility::STATE_SELECTED)) {
selected->vt = VT_DISPATCH;
selected->pdispVal =
- children_[i]->toBrowserAccessibilityWin()->NewReference();
+ children_[i]->ToBrowserAccessibilityWin()->NewReference();
return S_OK;
}
}
@@ -581,7 +583,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accSelection(VARIANT* selected) {
if (children_[i]->HasState(WebAccessibility::STATE_SELECTED)) {
enum_variant->ItemAt(index)->vt = VT_DISPATCH;
enum_variant->ItemAt(index)->pdispVal =
- children_[i]->toBrowserAccessibilityWin()->NewReference();
+ children_[i]->ToBrowserAccessibilityWin()->NewReference();
++index;
}
}
@@ -1072,8 +1074,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnIndex(
return S_FALSE;
int cell_id = unique_cell_ids_[cell_index];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
int col_index;
if (cell &&
cell->GetIntAttribute(
@@ -1179,15 +1180,14 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowDescription(
for (int i = 0; i < columns; ++i) {
int cell_id = cell_ids_[row * columns + i];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
- if (cell && cell->role_ == WebAccessibility::ROLE_ROW_HEADER) {
- if (cell->name_.size() > 0) {
- *description = SysAllocString(cell->name_.c_str());
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
+ if (cell && cell->role() == WebAccessibility::ROLE_ROW_HEADER) {
+ if (cell->name().size() > 0) {
+ *description = SysAllocString(cell->name().c_str());
return S_OK;
}
- return cell->GetStringAttributeAsBstr(
+ return cell->ToBrowserAccessibilityWin()->GetStringAttributeAsBstr(
WebAccessibility::ATTR_DESCRIPTION, description);
}
}
@@ -1218,8 +1218,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowExtentAt(
return E_INVALIDARG;
int cell_id = cell_ids_[row * columns + column];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
int rowspan;
if (cell &&
cell->GetIntAttribute(
@@ -1255,8 +1254,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowIndex(
return S_FALSE;
int cell_id = unique_cell_ids_[cell_index];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
int cell_row_index;
if (cell &&
cell->GetIntAttribute(
@@ -1388,8 +1386,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowColumnExtentsAtIndex(
return S_FALSE;
int cell_id = unique_cell_ids_[index];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
int rowspan;
int colspan;
if (cell &&
@@ -1526,9 +1523,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnHeaderCells(
for (int i = 0; i < rows; ++i) {
int cell_id = table->cell_ids()[i * columns + column];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
- if (cell && cell->role_ == WebAccessibility::ROLE_COLUMN_HEADER)
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
+ if (cell && cell->role() == WebAccessibility::ROLE_COLUMN_HEADER)
(*n_column_header_cells)++;
}
@@ -1537,11 +1533,11 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnHeaderCells(
int index = 0;
for (int i = 0; i < rows; ++i) {
int cell_id = table->cell_ids()[i * columns + column];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
- if (cell && cell->role_ == WebAccessibility::ROLE_COLUMN_HEADER) {
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
+ if (cell && cell->role() == WebAccessibility::ROLE_COLUMN_HEADER) {
(*cell_accessibles)[index] =
- static_cast<IAccessible*>(cell->NewReference());
+ static_cast<IAccessible*>(
+ cell->ToBrowserAccessibilityWin()->NewReference());
++index;
}
}
@@ -1624,9 +1620,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells(
for (int i = 0; i < columns; ++i) {
int cell_id = table->cell_ids()[row * columns + i];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
- if (cell && cell->role_ == WebAccessibility::ROLE_ROW_HEADER)
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
+ if (cell && cell->role() == WebAccessibility::ROLE_ROW_HEADER)
(*n_row_header_cells)++;
}
@@ -1635,11 +1630,11 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells(
int index = 0;
for (int i = 0; i < columns; ++i) {
int cell_id = table->cell_ids()[row * columns + i];
- BrowserAccessibilityWin* cell =
- manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
- if (cell && cell->role_ == WebAccessibility::ROLE_ROW_HEADER) {
+ BrowserAccessibility* cell = manager_->GetFromRendererID(cell_id);
+ if (cell && cell->role() == WebAccessibility::ROLE_ROW_HEADER) {
(*cell_accessibles)[index] =
- static_cast<IAccessible*>(cell->NewReference());
+ static_cast<IAccessible*>(
+ cell->ToBrowserAccessibilityWin()->NewReference());
++index;
}
}
@@ -1737,7 +1732,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_table(
}
*table = static_cast<IAccessibleTable*>(
- find_table->toBrowserAccessibilityWin()->NewReference());
+ find_table->ToBrowserAccessibilityWin()->NewReference());
return S_OK;
}
@@ -2095,7 +2090,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_hyperlink(
}
BrowserAccessibilityWin* child =
- children_[hyperlinks_[index]]->toBrowserAccessibilityWin();
+ children_[hyperlinks_[index]]->ToBrowserAccessibilityWin();
*hyperlink = static_cast<IAccessibleHyperlink*>(child->NewReference());
return S_OK;
}
@@ -2397,7 +2392,12 @@ STDMETHODIMP BrowserAccessibilityWin::get_parentNode(ISimpleDOMNode** node) {
if (!node)
return E_INVALIDARG;
- *node = parent_->toBrowserAccessibilityWin()->NewReference();
+ if (!parent_) {
+ *node = NULL;
+ return S_FALSE;
+ }
+
+ *node = parent_->ToBrowserAccessibilityWin()->NewReference();
return S_OK;
}
@@ -2409,7 +2409,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_firstChild(ISimpleDOMNode** node) {
return E_INVALIDARG;
if (children_.size()) {
- *node = children_[0]->toBrowserAccessibilityWin()->NewReference();
+ *node = children_[0]->ToBrowserAccessibilityWin()->NewReference();
return S_OK;
} else {
*node = NULL;
@@ -2425,7 +2425,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_lastChild(ISimpleDOMNode** node) {
return E_INVALIDARG;
if (children_.size()) {
- *node = children_[children_.size() - 1]->toBrowserAccessibilityWin()->
+ *node = children_[children_.size() - 1]->ToBrowserAccessibilityWin()->
NewReference();
return S_OK;
} else {
@@ -2444,7 +2444,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_previousSibling(
if (parent_ && index_in_parent_ > 0) {
*node = parent_->children()[index_in_parent_ - 1]->
- toBrowserAccessibilityWin()->NewReference();
+ ToBrowserAccessibilityWin()->NewReference();
return S_OK;
} else {
*node = NULL;
@@ -2463,7 +2463,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_nextSibling(ISimpleDOMNode** node) {
index_in_parent_ >= 0 &&
index_in_parent_ < static_cast<int>(parent_->children().size()) - 1) {
*node = parent_->children()[index_in_parent_ + 1]->
- toBrowserAccessibilityWin()->NewReference();
+ ToBrowserAccessibilityWin()->NewReference();
return S_OK;
} else {
*node = NULL;
@@ -2481,7 +2481,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_childAt(
return E_INVALIDARG;
if (child_index < children_.size()) {
- *node = children_[child_index]->toBrowserAccessibilityWin()->NewReference();
+ *node = children_[child_index]->ToBrowserAccessibilityWin()->NewReference();
return S_OK;
} else {
*node = NULL;
@@ -2848,9 +2848,9 @@ BrowserAccessibilityWin* BrowserAccessibilityWin::GetTargetFromChildID(
return this;
if (child_id >= 1 && child_id <= static_cast<LONG>(children_.size()))
- return children_[child_id - 1]->toBrowserAccessibilityWin();
+ return children_[child_id - 1]->ToBrowserAccessibilityWin();
- return manager_->GetFromChildID(child_id)->toBrowserAccessibilityWin();
+ return manager_->GetFromChildID(child_id)->ToBrowserAccessibilityWin();
}
HRESULT BrowserAccessibilityWin::GetStringAttributeAsBstr(
@@ -2944,7 +2944,8 @@ LONG BrowserAccessibilityWin::FindBoundary(
BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromRendererID(
int32 renderer_id) {
- return manager_->GetFromRendererID(renderer_id)->toBrowserAccessibilityWin();
+ BrowserAccessibility* result = manager_->GetFromRendererID(renderer_id);
+ return result ? result->ToBrowserAccessibilityWin() : NULL;
}
void BrowserAccessibilityWin::InitRoleAndState() {
diff --git a/content/browser/accessibility/browser_accessibility_win.h b/content/browser/accessibility/browser_accessibility_win.h
index 6386e5f..60ca7db 100644
--- a/content/browser/accessibility/browser_accessibility_win.h
+++ b/content/browser/accessibility/browser_accessibility_win.h
@@ -13,6 +13,7 @@
#include <vector>
+#include "base/compiler_specific.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/common/content_export.h"
#include "third_party/iaccessible2/ia2_api_all.h"
@@ -100,6 +101,8 @@ BrowserAccessibilityWin
CONTENT_EXPORT virtual void PostInitialize();
CONTENT_EXPORT virtual void NativeAddReference();
CONTENT_EXPORT virtual void NativeReleaseReference();
+ CONTENT_EXPORT virtual BrowserAccessibilityWin* ToBrowserAccessibilityWin()
+ OVERRIDE;
//
// IAccessible methods.
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc
index 4afcd27..7841d4b 100644
--- a/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -115,7 +115,7 @@ TEST_F(BrowserAccessibilityTest, TestNoLeaks) {
new CountedBrowserAccessibilityFactory());
ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
IAccessible* root_accessible =
- manager->GetRoot()->toBrowserAccessibilityWin();
+ manager->GetRoot()->ToBrowserAccessibilityWin();
IDispatch* root_iaccessible = NULL;
IDispatch* child1_iaccessible = NULL;
VARIANT var_child;
@@ -170,7 +170,7 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
// Query for the text IAccessible and verify that it returns "old text" as its
// value.
base::win::ScopedComPtr<IDispatch> text_dispatch;
- HRESULT hr = manager->GetRoot()->toBrowserAccessibilityWin()->get_accChild(
+ HRESULT hr = manager->GetRoot()->ToBrowserAccessibilityWin()->get_accChild(
CreateI4Variant(1), text_dispatch.Receive());
ASSERT_EQ(S_OK, hr);
@@ -199,7 +199,7 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
// Query for the text IAccessible and verify that it now returns "new text"
// as its value.
- hr = manager->GetRoot()->toBrowserAccessibilityWin()->get_accChild(
+ hr = manager->GetRoot()->ToBrowserAccessibilityWin()->get_accChild(
CreateI4Variant(1),
text_dispatch.Receive());
ASSERT_EQ(S_OK, hr);
@@ -297,9 +297,9 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) {
ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_);
BrowserAccessibilityWin* root_obj =
- manager->GetRoot()->toBrowserAccessibilityWin();
+ manager->GetRoot()->ToBrowserAccessibilityWin();
BrowserAccessibilityWin* text1_obj =
- root_obj->GetChild(0)->toBrowserAccessibilityWin();
+ root_obj->GetChild(0)->ToBrowserAccessibilityWin();
BSTR text;
long start;
@@ -393,7 +393,7 @@ TEST_F(BrowserAccessibilityTest, TestSimpleHypertext) {
ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);
BrowserAccessibilityWin* root_obj =
- manager->GetRoot()->toBrowserAccessibilityWin();
+ manager->GetRoot()->ToBrowserAccessibilityWin();
BSTR text;
@@ -477,7 +477,7 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) {
ASSERT_EQ(7, CountedBrowserAccessibility::global_obj_count_);
BrowserAccessibilityWin* root_obj =
- manager->GetRoot()->toBrowserAccessibilityWin();
+ manager->GetRoot()->ToBrowserAccessibilityWin();
BSTR text;
diff --git a/content/browser/accessibility/dump_accessibility_tree_helper_mac.mm b/content/browser/accessibility/dump_accessibility_tree_helper_mac.mm
index 50c40cd..afdd1f1 100644
--- a/content/browser/accessibility/dump_accessibility_tree_helper_mac.mm
+++ b/content/browser/accessibility/dump_accessibility_tree_helper_mac.mm
@@ -15,7 +15,8 @@ void DumpAccessibilityTreeHelper::Initialize() {}
string16 DumpAccessibilityTreeHelper::ToString(BrowserAccessibility* node,
char* prefix) {
- BrowserAccessibilityCocoa* cocoa_node = node->toBrowserAccessibilityCocoa();
+ BrowserAccessibilityCocoa* cocoa_node = node->ToBrowserAccessibilityMac()->
+ native_view();
NSString* dump =
[NSString stringWithFormat:@"%s%@ "
"subrole=%@ "
diff --git a/content/browser/accessibility/dump_accessibility_tree_helper_win.cc b/content/browser/accessibility/dump_accessibility_tree_helper_win.cc
index a567b2b..f1d2c80 100644
--- a/content/browser/accessibility/dump_accessibility_tree_helper_win.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_helper_win.cc
@@ -197,7 +197,7 @@ string16 DumpAccessibilityTreeHelper::ToString(
if (role_string_map.empty())
Initialize();
- BrowserAccessibilityWin* acc_obj = node->toBrowserAccessibilityWin();
+ BrowserAccessibilityWin* acc_obj = node->ToBrowserAccessibilityWin();
string16 state;
std::map<int32, string16>::iterator it;
diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.cc b/content/browser/renderer_host/render_widget_host_view_gtk.cc
index 15a0073..91c3ddf 100644
--- a/content/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/content/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -27,6 +27,7 @@
#include "base/time.h"
#include "base/utf_offset_string_conversions.h"
#include "base/utf_string_conversions.h"
+#include "content/browser/accessibility/browser_accessibility_gtk.h"
#include "content/browser/renderer_host/backing_store_gtk.h"
#include "content/browser/renderer_host/gtk_im_context_wrapper.h"
#include "content/browser/renderer_host/gtk_key_bindings_handler.h"
@@ -111,6 +112,11 @@ using WebKit::WebMouseWheelEvent;
// static methods.
class RenderWidgetHostViewGtkWidget {
public:
+ static AtkObject* GetAccessible(void* userdata) {
+ return (static_cast<RenderWidgetHostViewGtk*>(userdata))->
+ GetAccessible();
+ }
+
static GtkWidget* CreateNewWidget(RenderWidgetHostViewGtk* host_view) {
GtkWidget* widget = gtk_preserve_window_new();
gtk_widget_set_name(widget, "chrome-render-widget-host-view");
@@ -169,6 +175,10 @@ class RenderWidgetHostViewGtkWidget {
g_signal_connect_after(widget, "scroll-event",
G_CALLBACK(OnMouseScrollEvent), host_view);
+ // Route calls to get_accessible to the view.
+ gtk_preserve_window_set_accessible_factory(
+ GTK_PRESERVE_WINDOW(widget), GetAccessible, host_view);
+
return widget;
}
@@ -1404,3 +1414,69 @@ void content::RenderWidgetHostViewPort::GetDefaultScreenInfo(
gdk_display_get_default_group(gdk_display_get_default());
content::GetScreenInfoFromNativeWindow(gdk_window, results);
}
+
+void RenderWidgetHostViewGtk::SetAccessibilityFocus(int acc_obj_id) {
+ if (!host_)
+ return;
+
+ host_->AccessibilitySetFocus(acc_obj_id);
+}
+
+void RenderWidgetHostViewGtk::AccessibilityDoDefaultAction(int acc_obj_id) {
+ if (!host_)
+ return;
+
+ host_->AccessibilityDoDefaultAction(acc_obj_id);
+}
+
+void RenderWidgetHostViewGtk::AccessibilityScrollToMakeVisible(
+ int acc_obj_id, gfx::Rect subfocus) {
+ if (!host_)
+ return;
+
+ host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
+}
+
+void RenderWidgetHostViewGtk::AccessibilityScrollToPoint(
+ int acc_obj_id, gfx::Point point) {
+ if (!host_)
+ return;
+
+ host_->AccessibilityScrollToPoint(acc_obj_id, point);
+}
+
+void RenderWidgetHostViewGtk::AccessibilitySetTextSelection(
+ int acc_obj_id, int start_offset, int end_offset) {
+ if (!host_)
+ return;
+
+ host_->AccessibilitySetTextSelection(acc_obj_id, start_offset, end_offset);
+}
+
+void RenderWidgetHostViewGtk::OnAccessibilityNotifications(
+ const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
+ if (!browser_accessibility_manager_.get()) {
+ GtkWidget* parent = gtk_widget_get_parent(view_.get());
+ browser_accessibility_manager_.reset(
+ BrowserAccessibilityManager::CreateEmptyDocument(
+ parent, static_cast<WebAccessibility::State>(0), this));
+ }
+ browser_accessibility_manager_->OnAccessibilityNotifications(params);
+}
+
+AtkObject* RenderWidgetHostViewGtk::GetAccessible() {
+ RenderWidgetHostImpl::From(GetRenderWidgetHost())->
+ SetAccessibilityMode(AccessibilityModeComplete);
+
+ if (!browser_accessibility_manager_.get()) {
+ GtkWidget* parent = gtk_widget_get_parent(view_.get());
+ browser_accessibility_manager_.reset(
+ BrowserAccessibilityManager::CreateEmptyDocument(
+ parent, static_cast<WebAccessibility::State>(0), this));
+ }
+ BrowserAccessibilityGtk* root =
+ browser_accessibility_manager_->GetRoot()->ToBrowserAccessibilityGtk();
+
+ atk_object_set_role(root->GetAtkObject(), ATK_ROLE_HTML_CONTAINER);
+ return root->GetAtkObject();
+}
diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.h b/content/browser/renderer_host/render_widget_host_view_gtk.h
index 0f7c00a..db9a6a7 100644
--- a/content/browser/renderer_host/render_widget_host_view_gtk.h
+++ b/content/browser/renderer_host/render_widget_host_view_gtk.h
@@ -13,6 +13,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/time.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/content_export.h"
#include "ui/base/animation/animation_delegate.h"
@@ -42,7 +43,9 @@ typedef struct _GtkSelectionData GtkSelectionData;
// -----------------------------------------------------------------------------
// See comments in render_widget_host_view.h about this class and its members.
// -----------------------------------------------------------------------------
-class RenderWidgetHostViewGtk : public content::RenderWidgetHostViewBase {
+class CONTENT_EXPORT RenderWidgetHostViewGtk
+ : public content::RenderWidgetHostViewBase,
+ public BrowserAccessibilityDelegate {
public:
virtual ~RenderWidgetHostViewGtk();
@@ -122,6 +125,9 @@ class RenderWidgetHostViewGtk : public content::RenderWidgetHostViewBase {
virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
virtual bool LockMouse() OVERRIDE;
virtual void UnlockMouse() OVERRIDE;
+ virtual void OnAccessibilityNotifications(
+ const std::vector<AccessibilityHostMsg_NotificationParams>& params)
+ OVERRIDE;
// If the widget is aligned with an edge of the monitor its on and the user
// attempts to drag past that edge we track the number of times it has
@@ -146,6 +152,19 @@ class RenderWidgetHostViewGtk : public content::RenderWidgetHostViewBase {
bool RetrieveSurrounding(std::string* text, size_t* cursor_index);
+ // BrowserAccessibilityDelegate implementation.
+ virtual void SetAccessibilityFocus(int acc_obj_id) OVERRIDE;
+ virtual void AccessibilityDoDefaultAction(int acc_obj_id) OVERRIDE;
+ virtual void AccessibilityScrollToMakeVisible(
+ int acc_obj_id, gfx::Rect subfocus) OVERRIDE;
+ virtual void AccessibilityScrollToPoint(
+ int acc_obj_id, gfx::Point point) OVERRIDE;
+ virtual void AccessibilitySetTextSelection(
+ int acc_obj_id, int start_offset, int end_offset) OVERRIDE;
+
+ // Get the root of the AtkObject* tree for accessibility.
+ AtkObject* GetAccessible();
+
protected:
friend class content::RenderWidgetHostView;
@@ -287,6 +306,10 @@ class RenderWidgetHostViewGtk : public content::RenderWidgetHostViewBase {
// menus and drags.
GdkEventButton* last_mouse_down_;
+ // Instance of accessibility information for the root of the AtkObject
+ // tree representation of the WebKit render tree.
+ scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_;
+
ui::GtkSignalRegistrar signals_;
};
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 83f76a8..c3acf4b 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -20,6 +20,7 @@
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#import "content/browser/accessibility/browser_accessibility_cocoa.h"
+#import "content/browser/accessibility/browser_accessibility_mac.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/plugin_process_host.h"
#import "content/browser/renderer_host/accelerated_plugin_view_mac.h"
@@ -2106,7 +2107,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
[attribute isEqualToString:NSAccessibilityContentsAttribute]) &&
manager) {
return [NSArray arrayWithObjects:manager->
- GetRoot()->toBrowserAccessibilityCocoa(), nil];
+ GetRoot()->ToBrowserAccessibilityMac()->native_view(), nil];
} else if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
return NSAccessibilityScrollAreaRole;
}
@@ -2129,7 +2130,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
localPoint.y = NSHeight([self bounds]) - localPoint.y;
BrowserAccessibilityCocoa* root = renderWidgetHostView_->
GetBrowserAccessibilityManager()->
- GetRoot()->toBrowserAccessibilityCocoa();
+ GetRoot()->ToBrowserAccessibilityMac()->native_view();
id obj = [root accessibilityHitTest:localPoint];
return obj;
}
@@ -2143,7 +2144,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
renderWidgetHostView_->GetBrowserAccessibilityManager();
// Only child is root.
if (manager &&
- manager->GetRoot()->toBrowserAccessibilityCocoa() == child) {
+ manager->GetRoot()->ToBrowserAccessibilityMac()->native_view() == child) {
return 0;
} else {
return NSNotFound;
@@ -2158,7 +2159,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
DCHECK(focused_item);
if (focused_item) {
BrowserAccessibilityCocoa* focused_item_cocoa =
- focused_item->toBrowserAccessibilityCocoa();
+ focused_item->ToBrowserAccessibilityMac()->native_view();
DCHECK(focused_item_cocoa);
if (focused_item_cocoa)
return focused_item_cocoa;
diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc
index 5cd8d27..60b596c 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -478,7 +478,7 @@ RenderWidgetHostViewWin::GetNativeViewAccessible() {
}
return GetBrowserAccessibilityManager()->GetRoot()->
- toBrowserAccessibilityWin();
+ ToBrowserAccessibilityWin();
}
void RenderWidgetHostViewWin::MovePluginWindows(
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 36ab74e..10efd83 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -166,10 +166,14 @@
'browser/accessibility/browser_accessibility_cocoa.h',
'browser/accessibility/browser_accessibility_cocoa.mm',
'browser/accessibility/browser_accessibility_delegate_mac.h',
+ 'browser/accessibility/browser_accessibility_gtk.cc',
+ 'browser/accessibility/browser_accessibility_gtk.h',
'browser/accessibility/browser_accessibility_mac.h',
'browser/accessibility/browser_accessibility_mac.mm',
'browser/accessibility/browser_accessibility_manager.cc',
'browser/accessibility/browser_accessibility_manager.h',
+ 'browser/accessibility/browser_accessibility_manager_gtk.cc',
+ 'browser/accessibility/browser_accessibility_manager_gtk.h',
'browser/accessibility/browser_accessibility_manager_mac.h',
'browser/accessibility/browser_accessibility_manager_mac.mm',
'browser/accessibility/browser_accessibility_manager_win.cc',