summaryrefslogtreecommitdiffstats
path: root/content/browser
diff options
context:
space:
mode:
authordmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-29 15:08:39 +0000
committerdmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-29 15:08:39 +0000
commit5123b36099d7dfff857b2d170e8593f60b77df12 (patch)
tree73ce8d7e827a933cb6a032c72d2d50a8e42bf6b9 /content/browser
parentb6e695a9c6fa185592c01bd16fcbd7b95296e571 (diff)
downloadchromium_src-5123b36099d7dfff857b2d170e8593f60b77df12.zip
chromium_src-5123b36099d7dfff857b2d170e8593f60b77df12.tar.gz
chromium_src-5123b36099d7dfff857b2d170e8593f60b77df12.tar.bz2
Add support for a few more Mac accessibility attributes.
Includes ARIA live regions, required fields, sliders and other range controls, and list subroles. Interestingly, implementing the list subroles causes VoiceOver to stop making lists hierarchical, which is one thing that made Chrome seem weird compared to Safari. BUG=none TEST=manual testing Review URL: http://codereview.chromium.org/8036022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103275 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/accessibility/browser_accessibility_cocoa.mm146
1 files changed, 131 insertions, 15 deletions
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 7f605e5..fd765730 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -21,7 +21,6 @@
// this object.
extern "C" void NSAccessibilityUnregisterUniqueIdForUIElement(id element);
-typedef WebAccessibility::IntAttribute IntAttribute;
typedef WebAccessibility::StringAttribute StringAttribute;
namespace {
@@ -183,6 +182,8 @@ static const AttributeToMethodNameEntry attributeToMethodNameContainer[] = {
{ NSAccessibilityEnabledAttribute, @"enabled" },
{ NSAccessibilityFocusedAttribute, @"focused" },
{ NSAccessibilityHelpAttribute, @"help" },
+ { NSAccessibilityMaxValueAttribute, @"maxValue" },
+ { NSAccessibilityMinValueAttribute, @"minValue" },
{ NSAccessibilityNumberOfCharactersAttribute, @"numberOfCharacters" },
{ NSAccessibilityParentAttribute, @"parent" },
{ NSAccessibilityPositionAttribute, @"position" },
@@ -198,7 +199,14 @@ static const AttributeToMethodNameEntry attributeToMethodNameContainer[] = {
{ NSAccessibilityValueAttribute, @"value" },
{ NSAccessibilityVisibleCharacterRangeAttribute, @"visibleCharacterRange" },
{ NSAccessibilityWindowAttribute, @"window" },
+ { @"AXAccessKey", @"accessKey" },
+ { @"AXARIAAtomic", @"ariaAtomic" },
+ { @"AXARIABusy", @"ariaBusy" },
+ { @"AXARIALive", @"ariaLive" },
+ { @"AXARIARelevant", @"ariaRelevant" },
{ @"AXLoaded", @"loaded" },
+ { @"AXLoadingProgress", @"loadingProgress" },
+ { @"AXRequired", @"required" },
{ @"AXVisited", @"visited" },
};
@@ -262,6 +270,38 @@ NSDictionary* attributeToMethodNameMap = nil;
[super dealloc];
}
+- (NSString*)accessKey {
+ return NSStringForStringAttribute(
+ browserAccessibility_->string_attributes(),
+ WebAccessibility::ATTR_ACCESS_KEY);
+}
+
+- (NSNumber*)ariaAtomic {
+ bool boolValue = false;
+ browserAccessibility_->GetBoolAttribute(
+ WebAccessibility::ATTR_LIVE_ATOMIC, &boolValue);
+ return [NSNumber numberWithBool:boolValue];
+}
+
+- (NSNumber*)ariaBusy {
+ bool boolValue = false;
+ browserAccessibility_->GetBoolAttribute(
+ WebAccessibility::ATTR_LIVE_BUSY, &boolValue);
+ return [NSNumber numberWithBool:boolValue];
+}
+
+- (NSString*)ariaLive {
+ return NSStringForStringAttribute(
+ browserAccessibility_->string_attributes(),
+ WebAccessibility::ATTR_LIVE_STATUS);
+}
+
+- (NSString*)ariaRelevant {
+ return NSStringForStringAttribute(
+ browserAccessibility_->string_attributes(),
+ WebAccessibility::ATTR_LIVE_RELEVANT);
+}
+
// Returns an array of BrowserAccessibilityCocoa objects, representing the
// accessibility children of this object.
- (NSArray*)children {
@@ -350,6 +390,31 @@ NSDictionary* attributeToMethodNameMap = nil;
return [NSNumber numberWithBool:YES];
}
+- (NSNumber*)loadingProgress {
+ float floatValue = 0.0;
+ browserAccessibility_->GetFloatAttribute(
+ WebAccessibility::ATTR_DOC_LOADING_PROGRESS, &floatValue);
+ return [NSNumber numberWithFloat:floatValue];
+}
+
+- (NSNumber*)maxValue {
+ float floatValue = 0.0;
+ browserAccessibility_->GetFloatAttribute(
+ WebAccessibility::ATTR_MAX_VALUE_FOR_RANGE, &floatValue);
+ return [NSNumber numberWithFloat:floatValue];
+}
+
+- (NSNumber*)minValue {
+ float floatValue = 0.0;
+ browserAccessibility_->GetFloatAttribute(
+ WebAccessibility::ATTR_MIN_VALUE_FOR_RANGE, &floatValue);
+ return [NSNumber numberWithFloat:floatValue];
+}
+
+- (NSNumber*)numberOfCharacters {
+ return [NSNumber numberWithInt:browserAccessibility_->value().length()];
+}
+
// 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.
@@ -358,10 +423,6 @@ NSDictionary* attributeToMethodNameMap = nil;
browserAccessibility_->location().y());
}
-- (NSNumber*)numberOfCharacters {
- return [NSNumber numberWithInt:browserAccessibility_->value().length()];
-}
-
- (id)parent {
// A nil parent means we're the root.
if (browserAccessibility_->parent()) {
@@ -377,6 +438,11 @@ NSDictionary* attributeToMethodNameMap = nil;
return [NSValue valueWithPoint:[delegate_ accessibilityPointInScreen:self]];
}
+- (NSNumber*)required {
+ return [NSNumber numberWithBool:
+ !GetState(browserAccessibility_, WebAccessibility::STATE_REQUIRED)];
+}
+
// Returns a string indicating the role of this object.
- (NSString*)role {
WebAccessibility::Role browserAccessibilityRole =
@@ -456,22 +522,28 @@ NSDictionary* attributeToMethodNameMap = nil;
// Returns a subrole based upon the role.
- (NSString*) subrole {
- // TODO: support attachments
- // TODO: support lists -> NSAccessibilityContentListSubrole ||
- // NSAccessibilityDefinitionListSubrole
-
WebAccessibility::Role browserAccessibilityRole =
- static_cast<WebAccessibility::Role>( browserAccessibility_->role());
-
+ static_cast<WebAccessibility::Role>(browserAccessibility_->role());
if (browserAccessibilityRole == WebAccessibility::ROLE_TEXT_FIELD &&
GetState(browserAccessibility_, WebAccessibility::STATE_PROTECTED)) {
return @"AXSecureTextField";
}
+ NSString* htmlTag = NSStringForStringAttribute(
+ browserAccessibility_->string_attributes(),
+ WebAccessibility::ATTR_HTML_TAG);
+
+ if (browserAccessibilityRole == WebAccessibility::ROLE_LIST) {
+ if ([htmlTag isEqualToString:@"ul"] ||
+ [htmlTag isEqualToString:@"ol"]) {
+ return @"AXContentList";
+ } else if ([htmlTag isEqualToString:@"dl"]) {
+ return @"AXDefinitionList";
+ }
+ }
std::map<WebAccessibility::Role, NSString*>::iterator it =
webAccessibilityToNativeSubrole.find(browserAccessibilityRole);
-
if (it != webAccessibilityToNativeSubrole.end())
return it->second;
else
@@ -527,9 +599,24 @@ NSDictionary* attributeToMethodNameMap = nil;
return @"";
} else if ([role isEqualToString:NSAccessibilityCheckBoxRole] ||
[role isEqualToString:NSAccessibilityRadioButtonRole]) {
- return [NSNumber numberWithInt:GetState(
- browserAccessibility_, WebAccessibility::STATE_CHECKED) ? 1 : 0];
+ int checkOrRadioValue = GetState(
+ browserAccessibility_, WebAccessibility::STATE_CHECKED) ? 1 : 0;
+ bool mixed = false;
+ browserAccessibility_->GetBoolAttribute(
+ WebAccessibility::ATTR_BUTTON_MIXED, &mixed);
+ if (mixed)
+ checkOrRadioValue = 2;
+ return [NSNumber numberWithInt:checkOrRadioValue];
+ } else if ([role isEqualToString:NSAccessibilityProgressIndicatorRole] ||
+ [role isEqualToString:NSAccessibilitySliderRole] ||
+ [role isEqualToString:NSAccessibilityScrollBarRole]) {
+ float floatValue;
+ if (browserAccessibility_->GetFloatAttribute(
+ WebAccessibility::ATTR_VALUE_FOR_RANGE, &floatValue)) {
+ return [NSNumber numberWithFloat:floatValue];
+ }
}
+
return base::SysUTF16ToNSString(browserAccessibility_->value());
}
@@ -721,6 +808,8 @@ NSDictionary* attributeToMethodNameMap = nil;
NSAccessibilityValueAttribute,
NSAccessibilityWindowAttribute,
NSAccessibilityURLAttribute,
+ @"AXAccessKey",
+ @"AXRequired",
@"AXVisited",
nil];
@@ -732,7 +821,10 @@ NSDictionary* attributeToMethodNameMap = nil;
NSAccessibilityRowsAttribute,
nil]];
} else if ([role isEqualToString:@"AXWebArea"]) {
- [ret addObject:@"AXLoaded"];
+ [ret addObjectsFromArray:[NSArray arrayWithObjects:
+ @"AXLoaded",
+ @"AXLoadingProgress",
+ nil]];
} else if ([role isEqualToString:NSAccessibilityTextFieldRole] ||
[role isEqualToString:NSAccessibilityTextAreaRole]) {
[ret addObjectsFromArray:[NSArray arrayWithObjects:
@@ -744,6 +836,30 @@ NSDictionary* attributeToMethodNameMap = nil;
nil]];
} else if ([role isEqualToString:NSAccessibilityTabGroupRole]) {
[ret addObject:NSAccessibilityTabsAttribute];
+ } else if ([role isEqualToString:NSAccessibilityProgressIndicatorRole] ||
+ [role isEqualToString:NSAccessibilitySliderRole] ||
+ [role isEqualToString:NSAccessibilityScrollBarRole]) {
+ [ret addObjectsFromArray:[NSArray arrayWithObjects:
+ NSAccessibilityMaxValueAttribute,
+ NSAccessibilityMinValueAttribute,
+ nil]];
+ }
+
+ // Live regions.
+ string16 s;
+ if (browserAccessibility_->GetStringAttribute(
+ WebAccessibility::ATTR_LIVE_STATUS, &s)) {
+ [ret addObjectsFromArray:[NSArray arrayWithObjects:
+ @"AXARIALive",
+ @"AXARIARelevant",
+ nil]];
+ }
+ if (browserAccessibility_->GetStringAttribute(
+ WebAccessibility::ATTR_CONTAINER_LIVE_STATUS, &s)) {
+ [ret addObjectsFromArray:[NSArray arrayWithObjects:
+ @"AXARIAAtomic",
+ @"AXARIABusy",
+ nil]];
}
return ret;