diff options
author | dtseng@chromium.org <dtseng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-29 23:53:17 +0000 |
---|---|---|
committer | dtseng@chromium.org <dtseng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-29 23:53:17 +0000 |
commit | 405acd1cd89d050b17c965ffa8dba6b8c93966cb (patch) | |
tree | 0b80961be0266119ea3b74e84ac5ea7c6e290be8 /chrome/browser/accessibility | |
parent | ea1ecd6126334171ecc13d3adc64e22bda5750f4 (diff) | |
download | chromium_src-405acd1cd89d050b17c965ffa8dba6b8c93966cb.zip chromium_src-405acd1cd89d050b17c965ffa8dba6b8c93966cb.tar.gz chromium_src-405acd1cd89d050b17c965ffa8dba6b8c93966cb.tar.bz2 |
Various fixes in web contents. Ignore unknown roles, recognize headings and return the level as the value attribute. Recognize lists. Return the correct checked state. Generate children lazily.
BUG=55661
TEST=manually with VoiceOver. Passing BrowserAccessibilityTest.* (unit_test).
Review URL: http://codereview.chromium.org/4192003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64522 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/accessibility')
7 files changed, 91 insertions, 41 deletions
diff --git a/chrome/browser/accessibility/browser_accessibility.cc b/chrome/browser/accessibility/browser_accessibility.cc index 9cd21b1..21a1dc0 100644 --- a/chrome/browser/accessibility/browser_accessibility.cc +++ b/chrome/browser/accessibility/browser_accessibility.cc @@ -20,6 +20,14 @@ BrowserAccessibility::BrowserAccessibility() BrowserAccessibility::~BrowserAccessibility() { } +void BrowserAccessibility::ReplaceChild( + BrowserAccessibility* old_acc, BrowserAccessibility* new_acc) { + DCHECK_EQ(children_[old_acc->index_in_parent_], old_acc); + + old_acc = children_[old_acc->index_in_parent_]; + children_[old_acc->index_in_parent_] = new_acc; +} + void BrowserAccessibility::Initialize( BrowserAccessibilityManager* manager, BrowserAccessibility* parent, @@ -102,11 +110,3 @@ BrowserAccessibility* BrowserAccessibility::GetNextSibling() { return NULL; } - -void BrowserAccessibility::ReplaceChild( - const BrowserAccessibility* old_acc, BrowserAccessibility* new_acc) { - DCHECK_EQ(children_[old_acc->index_in_parent_], old_acc); - - old_acc = children_[old_acc->index_in_parent_]; - children_[old_acc->index_in_parent_] = new_acc; -} diff --git a/chrome/browser/accessibility/browser_accessibility.h b/chrome/browser/accessibility/browser_accessibility.h index 6e6b8fb..2e39ba0 100644 --- a/chrome/browser/accessibility/browser_accessibility.h +++ b/chrome/browser/accessibility/browser_accessibility.h @@ -55,6 +55,11 @@ class BrowserAccessibility { // than windows. virtual void ReleaseReference() = 0; + // Replace a child object. Used when updating the accessibility tree. + virtual void ReplaceChild( + BrowserAccessibility* old_acc, + BrowserAccessibility* new_acc); + // Initialize this object void Initialize(BrowserAccessibilityManager* manager, BrowserAccessibility* parent, @@ -85,11 +90,6 @@ class BrowserAccessibility { // of its parent. BrowserAccessibility* GetNextSibling(); - // Replace a child object. Used when updating the accessibility tree. - void ReplaceChild( - const BrowserAccessibility* old_acc, - BrowserAccessibility* new_acc); - // Accessors const std::map<int32, string16>& attributes() const { return attributes_; } int32 child_id() const { return child_id_; } diff --git a/chrome/browser/accessibility/browser_accessibility_cocoa.h b/chrome/browser/accessibility/browser_accessibility_cocoa.h index b6b32e0..4533499 100644 --- a/chrome/browser/accessibility/browser_accessibility_cocoa.h +++ b/chrome/browser/accessibility/browser_accessibility_cocoa.h @@ -19,6 +19,7 @@ @interface BrowserAccessibilityCocoa : NSObject { @private BrowserAccessibility* browserAccessibility_; + scoped_nsobject<NSMutableArray> children_; id<BrowserAccessibilityDelegateCocoa> delegate_; } @@ -29,6 +30,9 @@ - (id)initWithObject:(BrowserAccessibility*)accessibility delegate:(id<BrowserAccessibilityDelegateCocoa>)delegate; +// Invalidate children for a non-ignored ancestor (including self). +- (void)childrenChanged; + // Children is an array of BrowserAccessibility objects, representing // the accessibility children of this object. @property(nonatomic, readonly) NSArray* children; diff --git a/chrome/browser/accessibility/browser_accessibility_cocoa.mm b/chrome/browser/accessibility/browser_accessibility_cocoa.mm index ebfbf2c..38c3b59 100644 --- a/chrome/browser/accessibility/browser_accessibility_cocoa.mm +++ b/chrome/browser/accessibility/browser_accessibility_cocoa.mm @@ -36,23 +36,25 @@ struct RoleEntry { static const RoleEntry roles[] = { { WebAccessibility::ROLE_NONE, NSAccessibilityUnknownRole }, { WebAccessibility::ROLE_BUTTON, NSAccessibilityButtonRole }, - { WebAccessibility::ROLE_RADIO_BUTTON, NSAccessibilityRadioButtonRole }, { WebAccessibility::ROLE_CHECKBOX, NSAccessibilityCheckBoxRole }, - { WebAccessibility::ROLE_STATIC_TEXT, NSAccessibilityStaticTextRole}, - { WebAccessibility::ROLE_IMAGE, NSAccessibilityImageRole}, - { WebAccessibility::ROLE_TEXT_FIELD, NSAccessibilityTextFieldRole}, - { WebAccessibility::ROLE_TEXTAREA, NSAccessibilityTextAreaRole}, - { WebAccessibility::ROLE_LINK, NSAccessibilityLinkRole}, - { WebAccessibility::ROLE_SCROLLAREA, NSAccessibilityScrollAreaRole}, - { WebAccessibility::ROLE_SCROLLBAR, NSAccessibilityScrollBarRole}, - { WebAccessibility::ROLE_RADIO_GROUP, NSAccessibilityRadioGroupRole}, - { WebAccessibility::ROLE_TABLE, NSAccessibilityTableRole}, - { WebAccessibility::ROLE_TAB_GROUP, NSAccessibilityTabGroupRole}, - { WebAccessibility::ROLE_IGNORED, NSAccessibilityUnknownRole}, - { WebAccessibility::ROLE_WEB_AREA, @"AXWebArea"}, - { WebAccessibility::ROLE_GROUP, NSAccessibilityGroupRole}, - { WebAccessibility::ROLE_GRID, NSAccessibilityGridRole}, - { WebAccessibility::ROLE_WEBCORE_LINK, NSAccessibilityLinkRole}, + { WebAccessibility::ROLE_GRID, NSAccessibilityGridRole }, + { WebAccessibility::ROLE_GROUP, NSAccessibilityGroupRole }, + { WebAccessibility::ROLE_HEADING, @"AXHeading" }, + { WebAccessibility::ROLE_IGNORED, NSAccessibilityUnknownRole }, + { WebAccessibility::ROLE_IMAGE, NSAccessibilityImageRole }, + { WebAccessibility::ROLE_LINK, NSAccessibilityLinkRole }, + { WebAccessibility::ROLE_LIST, NSAccessibilityListRole }, + { WebAccessibility::ROLE_RADIO_BUTTON, NSAccessibilityRadioButtonRole }, + { WebAccessibility::ROLE_RADIO_GROUP, NSAccessibilityRadioGroupRole }, + { WebAccessibility::ROLE_SCROLLAREA, NSAccessibilityScrollAreaRole }, + { WebAccessibility::ROLE_SCROLLBAR, NSAccessibilityScrollBarRole }, + { WebAccessibility::ROLE_STATIC_TEXT, NSAccessibilityStaticTextRole }, + { WebAccessibility::ROLE_TABLE, NSAccessibilityTableRole }, + { WebAccessibility::ROLE_TAB_GROUP, NSAccessibilityTabGroupRole }, + { WebAccessibility::ROLE_TEXT_FIELD, NSAccessibilityTextFieldRole }, + { WebAccessibility::ROLE_TEXTAREA, NSAccessibilityTextAreaRole }, + { WebAccessibility::ROLE_WEB_AREA, @"AXWebArea" }, + { WebAccessibility::ROLE_WEBCORE_LINK, NSAccessibilityLinkRole }, }; // GetState checks the bitmask used in webaccessibility.h to check @@ -87,21 +89,36 @@ bool GetState(BrowserAccessibility* accessibility, int state) { // Returns an array of BrowserAccessibilityCocoa objects, representing the // accessibility children of this object. - (NSArray*)children { - NSMutableArray* ret = [[[NSMutableArray alloc] - initWithCapacity:browserAccessibility_->GetChildCount()] autorelease]; - for (uint32 index = 0; - index < browserAccessibility_->GetChildCount(); - ++index) { - [ret addObject: - browserAccessibility_->GetChild(index)->toBrowserAccessibilityCocoa()]; + if (!children_.get()) { + children_.reset([[NSMutableArray alloc] + initWithCapacity:browserAccessibility_->GetChildCount()] ); + for (uint32 index = 0; + index < browserAccessibility_->GetChildCount(); + ++index) { + BrowserAccessibilityCocoa* child = + browserAccessibility_->GetChild(index)->toBrowserAccessibilityCocoa(); + if ([child isIgnored]) + [children_ addObjectsFromArray:[child children]]; + else + [children_ addObject:child]; } - return ret; + } + return children_; +} + +- (void)childrenChanged { + if (![self isIgnored]) { + children_.reset(); + } else { + [browserAccessibility_->GetParent()->toBrowserAccessibilityCocoa() + childrenChanged]; + } } // Returns whether or not this node should be ignored in the // accessibility tree. - (BOOL)isIgnored { - return browserAccessibility_->role() == WebAccessibility::ROLE_IGNORED; + return [self role] == NSAccessibilityUnknownRole; } // The origin of this accessibility object in the page's document. @@ -191,7 +208,21 @@ bool GetState(BrowserAccessibility* accessibility, int state) { WebAccessibility::ATTR_HELP); } if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { - return base::SysUTF16ToNSString(browserAccessibility_->value()); + if ([self role] == @"AXHeading") { + NSString* headingLevel = + NSStringForWebAccessibilityAttribute( + browserAccessibility_->attributes(), + WebAccessibility::ATTR_HTML_TAG); + if ([headingLevel length] >= 2) { + return [NSNumber numberWithInt: + [[headingLevel substringFromIndex:1] intValue]]; + } + } else if ([self role] == NSAccessibilityCheckBoxRole) { + return [NSNumber numberWithInt:GetState( + browserAccessibility_, WebAccessibility::STATE_CHECKED) ? 1 : 0]; + } else { + return base::SysUTF16ToNSString(browserAccessibility_->value()); + } } if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { return [self roleDescription]; @@ -272,8 +303,7 @@ bool GetState(BrowserAccessibility* accessibility, int state) { for (BrowserAccessibilityCocoa* childToCheck in [self children]) { if ([child isEqual:childToCheck]) return index; - if (![childToCheck isIgnored]) - ++index; + ++index; } return NSNotFound; } diff --git a/chrome/browser/accessibility/browser_accessibility_mac.h b/chrome/browser/accessibility/browser_accessibility_mac.h index eed09fc..ff1eedd 100644 --- a/chrome/browser/accessibility/browser_accessibility_mac.h +++ b/chrome/browser/accessibility/browser_accessibility_mac.h @@ -21,6 +21,12 @@ class BrowserAccessibilityMac : public BrowserAccessibility { virtual void Initialize(); virtual void ReleaseReference(); + // Overrides from BrowserAccessibility. + // Used to know when to update the cocoa children. + virtual void ReplaceChild( + BrowserAccessibility* old_acc, + BrowserAccessibility* new_acc); + // The BrowserAccessibilityCocoa associated with us. BrowserAccessibilityCocoa* native_view() const { return browser_accessibility_cocoa_; diff --git a/chrome/browser/accessibility/browser_accessibility_mac.mm b/chrome/browser/accessibility/browser_accessibility_mac.mm index 3048b60..e8698a0 100644 --- a/chrome/browser/accessibility/browser_accessibility_mac.mm +++ b/chrome/browser/accessibility/browser_accessibility_mac.mm @@ -45,6 +45,13 @@ void BrowserAccessibilityMac::ReleaseReference() { } } +void BrowserAccessibilityMac::ReplaceChild( + BrowserAccessibility* old_acc, + BrowserAccessibility* new_acc) { + BrowserAccessibility::ReplaceChild(old_acc, new_acc); + [browser_accessibility_cocoa_ childrenChanged]; +} + BrowserAccessibilityCocoa* BrowserAccessibility::toBrowserAccessibilityCocoa() { return static_cast<BrowserAccessibilityMac*>(this)-> native_view(); diff --git a/chrome/browser/accessibility/browser_accessibility_mac_unittest.mm b/chrome/browser/accessibility/browser_accessibility_mac_unittest.mm index 821b9af..a9a0a5d 100644 --- a/chrome/browser/accessibility/browser_accessibility_mac_unittest.mm +++ b/chrome/browser/accessibility/browser_accessibility_mac_unittest.mm @@ -51,6 +51,7 @@ class BrowserAccessibilityTest : public CocoaTest { root.location.y = 0; root.location.width = 500; root.location.height = 100; + root.role = WebAccessibility::ROLE_WEB_AREA; root.attributes[WebAccessibility::ATTR_HELP] = ASCIIToUTF16("HelpText"); WebAccessibility child1; @@ -59,12 +60,14 @@ class BrowserAccessibilityTest : public CocoaTest { child1.location.y = 0; child1.location.width = 250; child1.location.height = 100; + child1.role = WebAccessibility::ROLE_BUTTON; WebAccessibility child2; child2.location.x = 250; child2.location.y = 0; child2.location.width = 250; child2.location.height = 100; + child2.role = WebAccessibility::ROLE_HEADING; root.children.push_back(child1); root.children.push_back(child2); |