summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authordtseng@chromium.org <dtseng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-13 18:50:10 +0000
committerdtseng@chromium.org <dtseng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-13 18:50:10 +0000
commit1dbadbd465e5cce4031dd20eb901ac7da2d67668 (patch)
tree83f16e5657ccc3a17c6059f72dbba171fce8c478 /chrome
parentfd21468f5e0b3d8523a6ad93e337e27632c2b1b6 (diff)
downloadchromium_src-1dbadbd465e5cce4031dd20eb901ac7da2d67668.zip
chromium_src-1dbadbd465e5cce4031dd20eb901ac7da2d67668.tar.gz
chromium_src-1dbadbd465e5cce4031dd20eb901ac7da2d67668.tar.bz2
Refactoring of BrowserAccessibility (Mac) to use cross platform base classes.
BUG=none TEST=passing unit tests. Review URL: http://codereview.chromium.org/3696003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62431 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/accessibility/browser_accessibility.h8
-rw-r--r--chrome/browser/accessibility/browser_accessibility_mac.h59
-rw-r--r--chrome/browser/accessibility/browser_accessibility_mac.mm27
-rw-r--r--chrome/browser/accessibility/browser_accessibility_manager.cc7
-rw-r--r--chrome/browser/accessibility/browser_accessibility_manager_mac.h33
-rw-r--r--chrome/browser/accessibility/browser_accessibility_manager_mac.mm80
-rw-r--r--chrome/browser/cocoa/browser_accessibility.h33
-rw-r--r--chrome/browser/cocoa/browser_accessibility.mm119
-rw-r--r--chrome/browser/cocoa/browser_accessibility_delegate.h12
-rw-r--r--chrome/browser/cocoa/browser_accessibility_unittest.mm53
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.h21
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm82
-rw-r--r--chrome/chrome_browser.gypi4
13 files changed, 407 insertions, 131 deletions
diff --git a/chrome/browser/accessibility/browser_accessibility.h b/chrome/browser/accessibility/browser_accessibility.h
index bdf374e..62cffb5 100644
--- a/chrome/browser/accessibility/browser_accessibility.h
+++ b/chrome/browser/accessibility/browser_accessibility.h
@@ -15,7 +15,9 @@
#include "webkit/glue/webaccessibility.h"
class BrowserAccessibilityManager;
-#if defined(OS_WIN)
+#if defined(OS_MACOSX)
+class BrowserAccessibilityMac;
+#elif defined(OS_WIN)
class BrowserAccessibilityWin;
#endif
@@ -97,7 +99,9 @@ class BrowserAccessibility {
int32 index_in_parent() const { return index_in_parent_; }
WebKit::WebRect location() const { return location_; }
-#if defined(OS_WIN)
+#if defined(OS_MACOSX)
+ BrowserAccessibilityMac* toBrowserAccessibilityMac();
+#elif defined(OS_WIN)
BrowserAccessibilityWin* toBrowserAccessibilityWin();
#endif
diff --git a/chrome/browser/accessibility/browser_accessibility_mac.h b/chrome/browser/accessibility/browser_accessibility_mac.h
new file mode 100644
index 0000000..136be99
--- /dev/null
+++ b/chrome/browser/accessibility/browser_accessibility_mac.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2010 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 CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MAC_H_
+#define CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MAC_H_
+#pragma once
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "chrome/browser/accessibility/browser_accessibility.h"
+
+@class BrowserAccessibilityCocoa;
+
+class BrowserAccessibilityMac : public BrowserAccessibility {
+ public:
+ // Implementation of BrowserAccessibility.
+ virtual void Initialize();
+ virtual void ReleaseReference();
+
+ // Accessers that allow the cocoa wrapper to read these values.
+ const string16& name() const { return name_; }
+ const string16& value() const { return value_; }
+ const std::map<int32, string16>& attributes() const { return attributes_; }
+
+ const std::vector<std::pair<string16, string16> >& html_attributes() const {
+ return html_attributes_;
+ }
+
+ int32 role() const { return role_; }
+ int32 state() const { return state_; }
+ const string16& role_name() const { return role_name_; }
+
+ // Accesser and setter for
+ // the BrowserAccessibilityCocoa associated with us.
+ BrowserAccessibilityCocoa* native_view() const {
+ return browser_accessibility_cocoa_;
+ }
+
+ void native_view(BrowserAccessibilityCocoa* v) {
+ browser_accessibility_cocoa_ = v;
+ }
+
+ private:
+ // This gives BrowserAccessibility::Create access to the class constructor.
+ friend class BrowserAccessibility;
+
+ BrowserAccessibilityMac();
+
+ // Allows access to the BrowserAccessibilityCocoa which wraps this.
+ // BrowserAccessibility. We only initialize this member if the accessibility
+ // API requests this object.
+ BrowserAccessibilityCocoa* browser_accessibility_cocoa_;
+ DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityMac);
+};
+
+#endif // CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MAC_H_
diff --git a/chrome/browser/accessibility/browser_accessibility_mac.mm b/chrome/browser/accessibility/browser_accessibility_mac.mm
new file mode 100644
index 0000000..1a6c1d4
--- /dev/null
+++ b/chrome/browser/accessibility/browser_accessibility_mac.mm
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 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.
+
+#import "chrome/browser/accessibility/browser_accessibility_mac.h"
+
+// Static.
+BrowserAccessibility* BrowserAccessibility::Create() {
+ return new BrowserAccessibilityMac();
+}
+
+BrowserAccessibilityMac::BrowserAccessibilityMac() {
+}
+
+// TODO(dtseng): ensure we create BrowserAccessibilityCocoa here
+// (RenderWidgetHostViewCocoa to BrowserAccessibilityManagerMac refactoring).
+void BrowserAccessibilityMac::Initialize() {
+}
+
+// TODO(dtseng): ensure we cleanup BrowserAccessibilityCocoa and this class.
+// (RenderWidgetHostViewCocoa to BrowserAccessibilityManagerMac refactoring).
+void BrowserAccessibilityMac::ReleaseReference() {
+}
+
+BrowserAccessibilityMac* BrowserAccessibility::toBrowserAccessibilityMac() {
+ return static_cast<BrowserAccessibilityMac*>(this);
+}
diff --git a/chrome/browser/accessibility/browser_accessibility_manager.cc b/chrome/browser/accessibility/browser_accessibility_manager.cc
index c663666..eb17e6e 100644
--- a/chrome/browser/accessibility/browser_accessibility_manager.cc
+++ b/chrome/browser/accessibility/browser_accessibility_manager.cc
@@ -140,6 +140,13 @@ void BrowserAccessibilityManager::OnAccessibilityObjectFocusChange(
focus_ = new_browser_acc;
if (delegate_ && delegate_->HasFocus())
GotFocus();
+ // Mac currently does not have a BrowserAccessibilityDelegate.
+ else if (!delegate_) {
+ NotifyAccessibilityEvent(
+ ViewHostMsg_AccessibilityNotification_Params::
+ NOTIFICATION_TYPE_FOCUS_CHANGED,
+ focus_);
+ }
}
void BrowserAccessibilityManager::OnAccessibilityObjectLoadComplete(
diff --git a/chrome/browser/accessibility/browser_accessibility_manager_mac.h b/chrome/browser/accessibility/browser_accessibility_manager_mac.h
new file mode 100644
index 0000000..892de15
--- /dev/null
+++ b/chrome/browser/accessibility/browser_accessibility_manager_mac.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 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 CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_MAC_H_
+#define CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_MAC_H_
+#pragma once
+
+#import <Cocoa/Cocoa.h>
+
+#include "chrome/browser/accessibility/browser_accessibility_manager.h"
+
+class BrowserAccessibilityManagerMac : public BrowserAccessibilityManager {
+ public:
+ // Implementation of BrowserAccessibilityManager.
+ virtual void NotifyAccessibilityEvent(
+ ViewHostMsg_AccessibilityNotification_Params::NotificationType n,
+ BrowserAccessibility* node);
+
+ private:
+ // This gives BrowserAccessibilityManager::Create access to the class
+ // constructor.
+ friend class BrowserAccessibilityManager;
+
+ BrowserAccessibilityManagerMac(gfx::NativeView parent_view,
+ const webkit_glue::WebAccessibility& src,
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory);
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerMac);
+};
+
+#endif // CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_MAC_H_
diff --git a/chrome/browser/accessibility/browser_accessibility_manager_mac.mm b/chrome/browser/accessibility/browser_accessibility_manager_mac.mm
new file mode 100644
index 0000000..8aadf8b
--- /dev/null
+++ b/chrome/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -0,0 +1,80 @@
+// Copyright (c) 2010 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 "chrome/browser/accessibility/browser_accessibility_manager_mac.h"
+
+#include "chrome/browser/accessibility/browser_accessibility_mac.h"
+#import "chrome/browser/cocoa/browser_accessibility.h"
+// TODO(dtseng): move to delegate?
+#import "chrome/browser/renderer_host/render_widget_host_view_mac.h"
+
+// static
+BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
+ gfx::NativeView parent_view,
+ const WebAccessibility& src,
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory) {
+ return new BrowserAccessibilityManagerMac(
+ parent_view, src, delegate, factory);
+}
+
+BrowserAccessibility* BrowserAccessibilityFactory::Create() {
+ return BrowserAccessibility::Create();
+}
+
+BrowserAccessibilityManagerMac::BrowserAccessibilityManagerMac(
+ gfx::NativeView parent_window,
+ const webkit_glue::WebAccessibility& src,
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory)
+ : BrowserAccessibilityManager(parent_window, src, delegate, factory) {
+}
+
+void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
+ ViewHostMsg_AccessibilityNotification_Params::NotificationType n,
+ BrowserAccessibility* node) {
+ // TODO(dtseng): support all notifications.
+ NSString* event_id = @"";
+ switch (n) {
+ case ViewHostMsg_AccessibilityNotification_Params::
+ NOTIFICATION_TYPE_CHECK_STATE_CHANGED:
+ return;
+ case ViewHostMsg_AccessibilityNotification_Params::
+ NOTIFICATION_TYPE_CHILDREN_CHANGED:
+ event_id = NSAccessibilityValueChangedNotification;
+ if (GetRoot() == node)
+ [((RenderWidgetHostViewCocoa*)GetParentView())
+ setAccessibilityTreeRoot:GetRoot()];
+ else
+ [node->GetParent()->toBrowserAccessibilityMac()->native_view()
+ updateDescendants];
+ break;
+ case ViewHostMsg_AccessibilityNotification_Params::
+ NOTIFICATION_TYPE_FOCUS_CHANGED:
+ event_id = NSAccessibilityFocusedUIElementChangedNotification;
+ if (GetRoot() == node)
+ [((RenderWidgetHostViewCocoa*)GetParentView())
+ setAccessibilityTreeRoot:GetRoot()];
+ else
+ [node->GetParent()->toBrowserAccessibilityMac()->native_view()
+ updateDescendants];
+ break;
+ case ViewHostMsg_AccessibilityNotification_Params::
+ NOTIFICATION_TYPE_LOAD_COMPLETE:
+ [((RenderWidgetHostViewCocoa*)GetParentView())
+ setAccessibilityTreeRoot:GetRoot()];
+ return;
+ case ViewHostMsg_AccessibilityNotification_Params::
+ NOTIFICATION_TYPE_VALUE_CHANGED:
+ event_id = NSAccessibilityValueChangedNotification;
+ break;
+ case ViewHostMsg_AccessibilityNotification_Params::
+ NOTIFICATION_TYPE_SELECTED_TEXT_CHANGED:
+ return;
+ }
+ BrowserAccessibilityCocoa* native_node = node->toBrowserAccessibilityMac()->
+ native_view();
+ DCHECK(native_node);
+ NSAccessibilityPostNotification(native_node, event_id);
+}
diff --git a/chrome/browser/cocoa/browser_accessibility.h b/chrome/browser/cocoa/browser_accessibility.h
index 32af50e..7a6fdb4 100644
--- a/chrome/browser/cocoa/browser_accessibility.h
+++ b/chrome/browser/cocoa/browser_accessibility.h
@@ -2,40 +2,45 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_H
-#define CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_H
+#ifndef CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_H_
+#define CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_H_
#pragma once
#import <Cocoa/Cocoa.h>
#import "base/scoped_nsobject.h"
+#include "chrome/browser/accessibility/browser_accessibility_mac.h"
#import "chrome/browser/cocoa/browser_accessibility_delegate.h"
-#include "webkit/glue/webaccessibility.h"
-using webkit_glue::WebAccessibility;
-
-// BrowserAccessibility is a cocoa wrapper around the WebAccessibility
+// BrowserAccessibilityCocoa is a cocoa wrapper around the BrowserAccessibility
// object. The renderer converts webkit's accessibility tree into a
// WebAccessibility tree and passes it to the browser process over IPC.
// This class converts it into a format Cocoa can query.
-@interface BrowserAccessibility : NSObject {
+@interface BrowserAccessibilityCocoa : NSObject {
@private
- WebAccessibility webAccessibility_;
- id<BrowserAccessibilityDelegate> delegate_;
+ BrowserAccessibility* browserAccessibility_;
+ id<BrowserAccessibilityDelegateCocoa> delegate_;
scoped_nsobject<NSMutableArray> children_;
// The parent of the accessibility object. This can be another
- // BrowserAccessibility or a RenderWidgetHostViewCocoa.
+ // BrowserAccessibilityCocoa or a RenderWidgetHostViewCocoa.
id parent_; // weak
}
// This creates a cocoa browser accessibility object around
-// the webkit glue WebAccessibility object. The delegate is
+// the cross platform BrowserAccessibility object. The delegate is
// used to communicate with the host renderer. None of these
// parameters can be null.
-- (id)initWithObject:(const WebAccessibility&)accessibility
- delegate:(id<BrowserAccessibilityDelegate>)delegate
+- (id)initWithObject:(BrowserAccessibility*)accessibility
+ delegate:(id<BrowserAccessibilityDelegateCocoa>)delegate
parent:(id)parent;
+// Updates children from backing BrowserAccessibility.
+- (NSArray*)updateChildren;
+// Updates all descendants from the backing BrowserAccessibility.
+- (void)updateDescendants;
+
+@property(nonatomic, readonly) BrowserAccessibility* browserAccessibility;
+
// Children is an array of BrowserAccessibility objects, representing
// the accessibility children of this object.
@property(nonatomic, readonly) NSArray* children;
@@ -54,4 +59,4 @@ using webkit_glue::WebAccessibility;
@end
-#endif // CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_H
+#endif // CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_H_
diff --git a/chrome/browser/cocoa/browser_accessibility.mm b/chrome/browser/cocoa/browser_accessibility.mm
index 06b9cfb..abef731 100644
--- a/chrome/browser/cocoa/browser_accessibility.mm
+++ b/chrome/browser/cocoa/browser_accessibility.mm
@@ -13,8 +13,6 @@
#include "grit/webkit_strings.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
-using webkit_glue::WebAccessibility;
-
namespace {
// Returns an autoreleased copy of the WebAccessibility's attribute.
@@ -59,67 +57,89 @@ static const RoleEntry roles[] = {
// GetState checks the bitmask used in webaccessibility.h to check
// if the given state was set on the accessibility object.
-bool GetState(WebAccessibility accessibility, int state) {
- return ((accessibility.state >> state) & 1);
+bool GetState(BrowserAccessibility* accessibility, int state) {
+ // TODO(dtseng): add accesser.
+ return ((accessibility->toBrowserAccessibilityMac()->state() >>
+ state) & 1);
}
} // namespace
-@implementation BrowserAccessibility
+@implementation BrowserAccessibilityCocoa
-- (id)initWithObject:(const WebAccessibility&)accessibility
- delegate:(id<BrowserAccessibilityDelegate>)delegate
+- (id)initWithObject:(BrowserAccessibility*)accessibility
+ delegate:(id<BrowserAccessibilityDelegateCocoa>)delegate
parent:(id)parent {
if ((self = [super init])) {
- webAccessibility_ = accessibility;
+ browserAccessibility_ = accessibility;
parent_ = parent;
delegate_ = delegate;
+ // Set the proper native view for the new object?
+ browserAccessibility_->toBrowserAccessibilityMac()->native_view(self);
}
return self;
}
-// Returns an array of BrowserAccessibility objects, representing the
+- (BrowserAccessibility*)browserAccessibility {
+ return browserAccessibility_;
+}
+
+// Returns an array of BrowserAccessibilityCocoa objects, representing the
// accessibility children of this object.
- (NSArray*)children {
if (!children_.get()) {
- const std::vector<WebAccessibility>& accessibilityChildren =
- webAccessibility_.children;
- children_.reset(
- [[NSMutableArray alloc]
- initWithCapacity:accessibilityChildren.size()]);
- std::vector<WebAccessibility>::const_iterator iterator;
- for (iterator = accessibilityChildren.begin();
- iterator != accessibilityChildren.end();
- ++iterator) {
- scoped_nsobject<BrowserAccessibility> child(
- [[BrowserAccessibility alloc]
- initWithObject:*iterator
- delegate:delegate_
- parent:self]);
- [children_ addObject:child];
- }
+ return [self updateChildren];
+ } else {
+ return children_.get();
}
+}
+
+- (NSArray*)updateChildren {
+ children_.reset(
+ [[NSMutableArray alloc]
+ initWithCapacity:browserAccessibility_->GetChildCount()]);
+ for (uint32 index = 0;
+ index < browserAccessibility_->GetChildCount();
+ ++index) {
+ scoped_nsobject<BrowserAccessibilityCocoa> child(
+ [[BrowserAccessibilityCocoa alloc]
+ initWithObject:browserAccessibility_->GetChild(index)
+ delegate:delegate_
+ parent:self]);
+ [children_ addObject:child];
+ }
return children_;
}
+- (void)updateDescendants {
+ NSArray* newChildren = [self updateChildren];
+ for (uint32 i = 0; i < [newChildren count]; ++i) {
+ [(BrowserAccessibilityCocoa*)[newChildren objectAtIndex:i]
+ updateDescendants];
+ }
+}
+
// Returns whether or not this node should be ignored in the
// accessibility tree.
- (BOOL)isIgnored {
- return webAccessibility_.role == WebAccessibility::ROLE_IGNORED;
+ return browserAccessibility_->toBrowserAccessibilityMac()->role() ==
+ WebAccessibility::ROLE_IGNORED;
}
// The origin of this accessibility object in the page's document.
// This is relative to webkit's top-left origin, not Cocoa's
// bottom-left origin.
- (NSPoint)origin {
- return NSMakePoint(webAccessibility_.location.x,
- webAccessibility_.location.y);
+ return NSMakePoint(browserAccessibility_->location().x,
+ browserAccessibility_->location().y);
}
// Returns a string indicating the role of this object.
- (NSString*)role {
NSString* role = NSAccessibilityUnknownRole;
- WebAccessibility::Role value = webAccessibility_.role;
+ WebAccessibility::Role value =
+ static_cast<WebAccessibility::Role>( browserAccessibility_->
+ toBrowserAccessibilityMac()->role());
const size_t numRoles = sizeof(roles) / sizeof(roles[0]);
for (size_t i = 0; i < numRoles; ++i) {
if (roles[i].value == value) {
@@ -147,18 +167,21 @@ bool GetState(WebAccessibility accessibility, int state) {
// Returns the size of this object.
- (NSSize)size {
- return NSMakeSize(webAccessibility_.location.width,
- webAccessibility_.location.height);
+ return NSMakeSize(browserAccessibility_->location().width,
+ browserAccessibility_->location().height);
}
// Returns the accessibility value for the given attribute. If the value isn't
// supported this will return nil.
- (id)accessibilityAttributeValue:(NSString*)attribute {
+ BrowserAccessibilityMac* browserAccessibilityMac = browserAccessibility_->
+ toBrowserAccessibilityMac();
if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
return [self role];
}
if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
- return NSStringForWebAccessibilityAttribute(webAccessibility_.attributes,
+ return NSStringForWebAccessibilityAttribute(
+ browserAccessibilityMac->attributes(),
WebAccessibility::ATTR_DESCRIPTION);
}
if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
@@ -180,23 +203,25 @@ bool GetState(WebAccessibility accessibility, int state) {
}
}
if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) {
- return base::SysUTF16ToNSString(webAccessibility_.name);
+ return base::SysUTF16ToNSString(browserAccessibilityMac->name());
}
if ([attribute isEqualToString:NSAccessibilityHelpAttribute]) {
- return NSStringForWebAccessibilityAttribute(webAccessibility_.attributes,
- WebAccessibility::ATTR_HELP);
+ return NSStringForWebAccessibilityAttribute(
+ browserAccessibilityMac->attributes(),
+ WebAccessibility::ATTR_HELP);
}
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
- return base::SysUTF16ToNSString(webAccessibility_.value);
+ return base::SysUTF16ToNSString(browserAccessibilityMac->value());
}
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
return [self roleDescription];
}
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
NSNumber* ret = [NSNumber numberWithBool:
- GetState(webAccessibility_, WebAccessibility::STATE_FOCUSED)];
+ GetState(browserAccessibility_, WebAccessibility::STATE_FOCUSED)];
return ret;
}
+ // TODO(dtseng): provide complete implementations for the following.
if ([attribute isEqualToString:NSAccessibilityEnabledAttribute] ||
[attribute isEqualToString:@"AXVisited"] ||
[attribute isEqualToString:@"AXLoaded"]) {
@@ -261,16 +286,10 @@ bool GetState(WebAccessibility accessibility, int state) {
nil];
}
-// Returns the deepest child that has user focus.
-// TODO(feldstein): This does not work yet.
-- (id)accessibilityFocusedUIElement {
- return self;
-}
-
// Returns the index of the child in this objects array of children.
- (NSUInteger)accessibilityIndexOfChild:(id)child {
NSUInteger index = 0;
- for (BrowserAccessibility* childToCheck in [self children]) {
+ for (BrowserAccessibilityCocoa* childToCheck in [self children]) {
if ([child isEqual:childToCheck])
return index;
if (![childToCheck isIgnored])
@@ -283,9 +302,9 @@ bool GetState(WebAccessibility accessibility, int state) {
// accessibility API via |accessibilitySetValue:forAttribute:|.
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute {
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
- return GetState(webAccessibility_, WebAccessibility::STATE_FOCUSABLE);
+ return GetState(browserAccessibility_, WebAccessibility::STATE_FOCUSABLE);
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
- return !GetState(webAccessibility_, WebAccessibility::STATE_READONLY);
+ return !GetState(browserAccessibility_, WebAccessibility::STATE_READONLY);
return NO;
}
@@ -299,7 +318,7 @@ bool GetState(WebAccessibility accessibility, int state) {
// that backs this object.
- (void)accessibilityPerformAction:(NSString*)action {
// TODO(feldstein): Support more actions.
- [delegate_ doDefaultAction:webAccessibility_.id];
+ [delegate_ doDefaultAction:browserAccessibility_->renderer_id()];
}
// Returns the description of the given action.
@@ -320,7 +339,7 @@ bool GetState(WebAccessibility accessibility, int state) {
NSNumber* focusedNumber = value;
BOOL focused = [focusedNumber intValue];
[delegate_ setAccessibilityFocus:focused
- accessibilityId:webAccessibility_.id];
+ accessibilityId:browserAccessibility_->renderer_id()];
}
}
@@ -348,13 +367,13 @@ bool GetState(WebAccessibility accessibility, int state) {
}
- (BOOL)isEqual:(id)object {
- if (![object isKindOfClass:[BrowserAccessibility class]])
+ if (![object isKindOfClass:[BrowserAccessibilityCocoa class]])
return NO;
return ([self hash] == [object hash]);
}
- (NSUInteger)hash {
- return webAccessibility_.id;
+ return browserAccessibility_->renderer_id();
}
@end
diff --git a/chrome/browser/cocoa/browser_accessibility_delegate.h b/chrome/browser/cocoa/browser_accessibility_delegate.h
index 800174d91..3ee821c 100644
--- a/chrome/browser/cocoa/browser_accessibility_delegate.h
+++ b/chrome/browser/cocoa/browser_accessibility_delegate.h
@@ -2,22 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_DELEGATE_H
-#define CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_DELEGATE_H
+#ifndef CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_DELEGATE_H_
+#define CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_DELEGATE_H_
#pragma once
-@class BrowserAccessibility;
+@class BrowserAccessibilityCocoa;
@class NSWindow;
// This protocol is used by the BrowserAccessibility objects to pass messages
// to, or otherwise communicate with, their underlying WebAccessibility
// objects over the IPC boundary.
-@protocol BrowserAccessibilityDelegate
-- (NSPoint)accessibilityPointInScreen:(BrowserAccessibility*)accessibility;
+@protocol BrowserAccessibilityDelegateCocoa
+- (NSPoint)accessibilityPointInScreen:(BrowserAccessibilityCocoa*)accessibility;
- (void)doDefaultAction:(int32)accessibilityObjectId;
- (void)setAccessibilityFocus:(BOOL)focus
accessibilityId:(int32)accessibilityObjectId;
- (NSWindow*)window;
@end
-#endif // CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_DELEGATE_H
+#endif // CHROME_BROWSER_COCOA_BROWSER_ACCESSIBILITY_DELEGATE_H_
diff --git a/chrome/browser/cocoa/browser_accessibility_unittest.mm b/chrome/browser/cocoa/browser_accessibility_unittest.mm
index 104c26e..27bee1a 100644
--- a/chrome/browser/cocoa/browser_accessibility_unittest.mm
+++ b/chrome/browser/cocoa/browser_accessibility_unittest.mm
@@ -6,14 +6,16 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/accessibility/browser_accessibility_mac.h"
#include "chrome/browser/cocoa/browser_accessibility.h"
#include "chrome/browser/cocoa/cocoa_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"
-@interface MockAccessibilityDelegate : NSObject<BrowserAccessibilityDelegate>
+@interface MockAccessibilityDelegate :
+ NSObject<BrowserAccessibilityDelegateCocoa>
-- (NSPoint)accessibilityPointInScreen:(BrowserAccessibility*)accessibility;
+- (NSPoint)accessibilityPointInScreen:(BrowserAccessibilityCocoa*)accessibility;
- (void)doDefaultAction:(int32)accessibilityObjectId;
- (void)setAccessibilityFocus:(BOOL)focus
accessibilityId:(int32)accessibilityObjectId;
@@ -23,7 +25,8 @@
@implementation MockAccessibilityDelegate
-- (NSPoint)accessibilityPointInScreen:(BrowserAccessibility*)accessibility {
+- (NSPoint)accessibilityPointInScreen:
+ (BrowserAccessibilityCocoa*)accessibility {
return NSZeroPoint;
}
- (void)doDefaultAction:(int32)accessibilityObjectId {
@@ -62,24 +65,50 @@ class BrowserAccessibilityTest : public CocoaTest {
child2.location.width = 250;
child2.location.height = 100;
- root.children.push_back(child1);
- root.children.push_back(child2);
+ // TODO(dtseng): use BrowserAccessibilityManagerMac once it manages
+ // these objects.
+ BrowserAccessibility* rootBrowserAccessibility =
+ BrowserAccessibility::Create();
+ BrowserAccessibility* child1BrowserAccessibility =
+ BrowserAccessibility::Create();
+ BrowserAccessibility* child2BrowserAccessibility =
+ BrowserAccessibility::Create();
+
+ rootBrowserAccessibility->Initialize(NULL,
+ NULL,
+ 0,
+ 0,
+ root);
+ child1BrowserAccessibility->Initialize(NULL,
+ NULL,
+ 0,
+ 0,
+ child1);
+ child2BrowserAccessibility->Initialize(NULL,
+ NULL,
+ 0,
+ 0,
+ child2);
+
+ rootBrowserAccessibility->AddChild(child1BrowserAccessibility);
+ rootBrowserAccessibility->AddChild(child2BrowserAccessibility);
delegate_.reset([[MockAccessibilityDelegate alloc] init]);
accessibility_.reset(
- [[BrowserAccessibility alloc] initWithObject:root
- delegate:delegate_
- parent:delegate_]);
+ [[BrowserAccessibilityCocoa alloc]
+ initWithObject:rootBrowserAccessibility
+ delegate:delegate_
+ parent:delegate_]);
}
protected:
scoped_nsobject<MockAccessibilityDelegate> delegate_;
- scoped_nsobject<BrowserAccessibility> accessibility_;
+ scoped_nsobject<BrowserAccessibilityCocoa> accessibility_;
};
// Standard hit test.
TEST_F(BrowserAccessibilityTest, HitTestTest) {
- BrowserAccessibility* firstChild =
+ BrowserAccessibilityCocoa* firstChild =
[accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
EXPECT_NSEQ(@"Child1",
[firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
@@ -87,7 +116,7 @@ TEST_F(BrowserAccessibilityTest, HitTestTest) {
// Test doing a hit test on the edge of a child.
TEST_F(BrowserAccessibilityTest, EdgeHitTest) {
- BrowserAccessibility* firstChild =
+ BrowserAccessibilityCocoa* firstChild =
[accessibility_ accessibilityHitTest:NSMakePoint(0, 0)];
EXPECT_NSEQ(@"Child1",
[firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
@@ -97,7 +126,7 @@ TEST_F(BrowserAccessibilityTest, EdgeHitTest) {
// the hit test has been narrowed down to this object or one of its children
// so it should return itself since it has no better hit result.
TEST_F(BrowserAccessibilityTest, InvalidHitTestCoordsTest) {
- BrowserAccessibility* hitTestResult =
+ BrowserAccessibilityCocoa* hitTestResult =
[accessibility_ accessibilityHitTest:NSMakePoint(-50, 50)];
EXPECT_NSEQ(accessibility_, hitTestResult);
}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h
index 16a78fc..f41ae8d 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h
@@ -13,6 +13,7 @@
#include "base/scoped_ptr.h"
#include "base/task.h"
#include "base/time.h"
+#include "chrome/browser/accessibility/browser_accessibility_manager.h"
#include "chrome/browser/cocoa/base_view.h"
#include "chrome/browser/cocoa/browser_accessibility.h"
#include "chrome/browser/cocoa/browser_accessibility_delegate.h"
@@ -41,16 +42,15 @@ class RWHVMEditCommandHelper;
: BaseView <RenderWidgetHostViewMacOwner,
NSTextInput,
NSChangeSpelling,
- BrowserAccessibilityDelegate> {
+ BrowserAccessibilityDelegateCocoa> {
@private
scoped_ptr<RenderWidgetHostViewMac> renderWidgetHostView_;
BOOL canBeKeyView_;
BOOL takesFocusOnlyOnMouseDown_;
BOOL closeOnDeactivate_;
- BOOL rendererAccessible_;
- BOOL accessibilityRequested_;
- BOOL accessibilityReceived_;
scoped_ptr<RWHVMEditCommandHelper> editCommand_helper_;
+
+ // TODO(dtseng): refactor to BrowserAccessibilityManagerMac.
scoped_nsobject<NSArray> accessibilityChildren_;
// These are part of the magic tooltip code from WebKit's WebHTMLView:
@@ -142,7 +142,7 @@ class RWHVMEditCommandHelper;
// Cancel ongoing composition (abandon the marked text).
- (void)cancelComposition;
// Set the new accessibility tree.
-- (void)setAccessibilityTree:(const webkit_glue::WebAccessibility&) tree;
+- (void)setAccessibilityTreeRoot:(BrowserAccessibility*) treeRoot;
// Confirm ongoing composition.
- (void)confirmComposition;
@@ -220,8 +220,10 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
virtual void WindowFrameChanged();
virtual void SetBackground(const SkBitmap& background);
virtual bool ContainsNativeView(gfx::NativeView native_view) const;
- virtual void UpdateAccessibilityTree(
- const webkit_glue::WebAccessibility& tree);
+
+ virtual void OnAccessibilityNotifications(
+ const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params);
+
// Methods associated with GPU-accelerated plug-in instances and the
// accelerated compositor.
virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle(bool opaque,
@@ -274,6 +276,8 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
// paint requests by expanding the invalid rect rather than actually painting.
bool about_to_validate_and_paint_;
+ scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_;
+
// This is true when we have already scheduled a call to
// |-callSetNeedsDisplayInRect:| but it has not been fulfilled yet. Used to
// prevent us from scheduling multiple calls.
@@ -344,9 +348,6 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
// Used for positioning a popup menu.
NSView* parent_view_;
- // Whether or not web accessibility is enabled.
- bool renderer_accessible_;
-
// selected text on the renderer.
std::string selected_text_;
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index 768de34..e6a6ba6 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -444,10 +444,9 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget)
initWithRenderWidgetHostViewMac:this] autorelease];
render_widget_host_->set_view(this);
- // Turn on accessibility only if one or both of these flags is true.
- renderer_accessible_ = IsVoiceOverRunning() ||
- CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceRendererAccessibility);
+ // Turn on accessibility only if VoiceOver is running.
+ if (IsVoiceOverRunning())
+ render_widget_host_->EnableRendererAccessibility();
}
RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
@@ -1151,11 +1150,20 @@ bool RenderWidgetHostViewMac::ContainsNativeView(
return false;
}
-void RenderWidgetHostViewMac::UpdateAccessibilityTree(
- const webkit_glue::WebAccessibility& tree) {
- if (renderer_accessible_) {
- [cocoa_view_ setAccessibilityTree:tree];
+void RenderWidgetHostViewMac::OnAccessibilityNotifications(
+ const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) {
+ if (!browser_accessibility_manager_.get()) {
+ // Use empty document to process notifications
+ webkit_glue::WebAccessibility empty_document;
+ empty_document.role = WebAccessibility::ROLE_WEB_AREA;
+ empty_document.state = 0;
+ browser_accessibility_manager_.reset(
+ BrowserAccessibilityManager::Create(cocoa_view_, empty_document, NULL));
+ // TODO(dtseng): refactor to BrowserAccessibilityManagerMac.
+ [cocoa_view_
+ setAccessibilityTreeRoot:browser_accessibility_manager_->GetRoot()];
}
+ browser_accessibility_manager_->OnAccessibilityNotifications(params);
}
void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
@@ -1186,12 +1194,6 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
canBeKeyView_ = YES;
takesFocusOnlyOnMouseDown_ = NO;
closeOnDeactivate_ = NO;
-
- rendererAccessible_ =
- !CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableRendererAccessibility);
- accessibilityRequested_ = NO;
- accessibilityReceived_ = NO;
}
return self;
}
@@ -1771,14 +1773,15 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
// Create the BrowserAccessibility tree from the WebAccessibility tree passed
// from the renderer.
-- (void)setAccessibilityTree:(const webkit_glue::WebAccessibility&) tree {
- BrowserAccessibility* root =
- [[BrowserAccessibility alloc] initWithObject:tree
- delegate:self
- parent:self];
+// TODO(dtseng): refactor to BrowserAccessibilityManagerMac.
+- (void)setAccessibilityTreeRoot:(BrowserAccessibility*) treeRoot {
+ BrowserAccessibilityCocoa* root =
+ [[BrowserAccessibilityCocoa alloc] initWithObject:treeRoot
+ delegate:self
+ parent:self];
[root autorelease];
accessibilityChildren_.reset([[NSArray alloc] initWithObjects:root, nil]);
- accessibilityReceived_ = YES;
+ [root updateDescendants];
}
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute
@@ -1798,36 +1801,23 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
}
- (id)accessibilityAttributeValue:(NSString *)attribute {
- if (!accessibilityRequested_) {
- renderWidgetHostView_->render_widget_host_->EnableRendererAccessibility();
- accessibilityRequested_ = YES;
- }
- if (accessibilityReceived_) {
- if (rendererAccessible_ &&
- [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
+ if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
+ // TODO(dtseng): refactor to BrowserAccessibilityManagerMac.
return accessibilityChildren_.get();
} else if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
return NSAccessibilityScrollAreaRole;
}
- }
id ret = [super accessibilityAttributeValue:attribute];
return ret;
}
- (id)accessibilityHitTest:(NSPoint)point {
- if (!accessibilityRequested_) {
- renderWidgetHostView_->render_widget_host_->EnableRendererAccessibility();
- accessibilityRequested_ = YES;
- }
- if (!accessibilityReceived_) {
- return self;
- }
NSPoint pointInWindow = [[self window] convertScreenToBase:point];
NSPoint localPoint = [self convertPoint:pointInWindow fromView:nil];
localPoint.y = NSHeight([self bounds]) - localPoint.y;
if ([accessibilityChildren_ count] == 0)
return self;
- BrowserAccessibility* root = [accessibilityChildren_ objectAtIndex:0];
+ BrowserAccessibilityCocoa* root = [accessibilityChildren_ objectAtIndex:0];
id obj = [root accessibilityHitTest:localPoint];
return obj;
}
@@ -1840,6 +1830,23 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
return [accessibilityChildren_ indexOfObject:child];
}
+- (id)accessibilityFocusedUIElement {
+ BrowserAccessibilityManager* manager =
+ renderWidgetHostView_->browser_accessibility_manager_.get();
+ if (manager) {
+ BrowserAccessibility* focused_item = manager->GetFocus(NULL);
+ DCHECK(focused_item);
+ if (focused_item) {
+ BrowserAccessibilityCocoa* focused_item_cocoa =
+ focused_item->toBrowserAccessibilityMac()->native_view();
+ DCHECK(focused_item_cocoa);
+ if (focused_item_cocoa)
+ return focused_item_cocoa;
+ }
+ }
+ return [super accessibilityFocusedUIElement];
+}
+
- (void)doDefaultAction:(int32)accessibilityObjectId {
renderWidgetHostView_->render_widget_host_->
AccessibilityDoDefaultAction(accessibilityObjectId);
@@ -1847,7 +1854,8 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
// Convert a web accessibility's location in web coordinates into a cocoa
// screen coordinate.
-- (NSPoint)accessibilityPointInScreen:(BrowserAccessibility*)accessibility {
+- (NSPoint)accessibilityPointInScreen:
+ (BrowserAccessibilityCocoa*)accessibility {
NSPoint origin = [accessibility origin];
NSSize size = [accessibility size];
origin.y = NSHeight([self bounds]) - origin.y;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index db6aa60..8b898be 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -65,6 +65,10 @@
'browser/accessibility/browser_accessibility_state.h',
'browser/accessibility/browser_accessibility_manager.cc',
'browser/accessibility/browser_accessibility_manager.h',
+ 'browser/accessibility/browser_accessibility_manager_mac.h',
+ 'browser/accessibility/browser_accessibility_manager_mac.mm',
+ 'browser/accessibility/browser_accessibility_mac.h',
+ 'browser/accessibility/browser_accessibility_mac.mm',
'browser/accessibility/browser_accessibility_manager_win.cc',
'browser/accessibility/browser_accessibility_manager_win.h',
'browser/accessibility/browser_accessibility_win.cc',