| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/accessibility/accessibility_tree_formatter.h" | 5 #include "content/browser/accessibility/accessibility_tree_formatter.h" |
| 6 | 6 |
| 7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 return rangeDict.Pass(); | 76 return rangeDict.Pass(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 // Returns true if |value| is an NSValue containing a NSRange. | 79 // Returns true if |value| is an NSValue containing a NSRange. |
| 80 bool IsRangeValue(id value) { | 80 bool IsRangeValue(id value) { |
| 81 if (![value isKindOfClass:[NSValue class]]) | 81 if (![value isKindOfClass:[NSValue class]]) |
| 82 return false; | 82 return false; |
| 83 return 0 == strcmp([value objCType], @encode(NSRange)); | 83 return 0 == strcmp([value objCType], @encode(NSRange)); |
| 84 } | 84 } |
| 85 | 85 |
| 86 scoped_ptr<base::Value> PopulateObject(id value); |
| 87 |
| 88 scoped_ptr<base::ListValue> PopulateArray(NSArray* array) { |
| 89 scoped_ptr<base::ListValue> list(new base::ListValue); |
| 90 for (NSUInteger i = 0; i < [array count]; i++) |
| 91 list->Append(PopulateObject([array objectAtIndex:i]).release()); |
| 92 return list.Pass(); |
| 93 } |
| 94 |
| 95 scoped_ptr<base::StringValue> StringForBrowserAccessibility( |
| 96 BrowserAccessibilityCocoa* obj) { |
| 97 NSString* description = [obj role]; |
| 98 id value = [obj value]; |
| 99 id roleDescription = [obj roleDescription]; |
| 100 if (value != nil && ![value isEqualToString:@""]) { |
| 101 description = [NSString stringWithFormat:@"%@ %@", description, value]; |
| 102 } else if ([description isEqualToString:NSAccessibilityGroupRole] && |
| 103 roleDescription != nil && |
| 104 ![roleDescription isEqualToString:@""]) { |
| 105 description = [NSString stringWithFormat:@"%@ %@", |
| 106 description, roleDescription]; |
| 107 } |
| 108 return scoped_ptr<base::StringValue>( |
| 109 new base::StringValue(SysNSStringToUTF16(description))).Pass(); |
| 110 } |
| 111 |
| 112 scoped_ptr<base::Value> PopulateObject(id value) { |
| 113 if ([value isKindOfClass:[NSArray class]]) |
| 114 return scoped_ptr<base::Value>(PopulateArray((NSArray*) value)); |
| 115 if (IsRangeValue(value)) |
| 116 return scoped_ptr<base::Value>(PopulateRange([value rangeValue])); |
| 117 if ([value isKindOfClass:[BrowserAccessibilityCocoa class]]) { |
| 118 std::string str; |
| 119 StringForBrowserAccessibility(value)->GetAsString(&str); |
| 120 return scoped_ptr<base::Value>(StringForBrowserAccessibility( |
| 121 (BrowserAccessibilityCocoa*) value)); |
| 122 } |
| 123 |
| 124 return scoped_ptr<base::Value>( |
| 125 new base::StringValue( |
| 126 SysNSStringToUTF16([NSString stringWithFormat:@"%@", value]))).Pass(); |
| 127 } |
| 128 |
| 86 NSArray* BuildAllAttributesArray() { | 129 NSArray* BuildAllAttributesArray() { |
| 87 NSArray* array = [NSArray arrayWithObjects: | 130 NSArray* array = [NSArray arrayWithObjects: |
| 88 NSAccessibilityRoleDescriptionAttribute, | 131 NSAccessibilityRoleDescriptionAttribute, |
| 89 NSAccessibilityTitleAttribute, | 132 NSAccessibilityTitleAttribute, |
| 90 NSAccessibilityValueAttribute, | 133 NSAccessibilityValueAttribute, |
| 91 NSAccessibilityMinValueAttribute, | 134 NSAccessibilityMinValueAttribute, |
| 92 NSAccessibilityMaxValueAttribute, | 135 NSAccessibilityMaxValueAttribute, |
| 93 NSAccessibilityValueDescriptionAttribute, | 136 NSAccessibilityValueDescriptionAttribute, |
| 94 NSAccessibilityDescriptionAttribute, | 137 NSAccessibilityDescriptionAttribute, |
| 95 NSAccessibilityHelpAttribute, | 138 NSAccessibilityHelpAttribute, |
| 96 @"AXInvalid", | 139 @"AXInvalid", |
| 97 NSAccessibilityDisclosingAttribute, | 140 NSAccessibilityDisclosingAttribute, |
| 98 NSAccessibilityDisclosureLevelAttribute, | 141 NSAccessibilityDisclosureLevelAttribute, |
| 99 @"AXAccessKey", | 142 @"AXAccessKey", |
| 100 @"AXARIAAtomic", | 143 @"AXARIAAtomic", |
| 101 @"AXARIABusy", | 144 @"AXARIABusy", |
| 102 @"AXARIALive", | 145 @"AXARIALive", |
| 103 @"AXARIARelevant", | 146 @"AXARIARelevant", |
| 104 NSAccessibilityColumnIndexRangeAttribute, | 147 NSAccessibilityColumnIndexRangeAttribute, |
| 105 NSAccessibilityEnabledAttribute, | 148 NSAccessibilityEnabledAttribute, |
| 106 NSAccessibilityFocusedAttribute, | 149 NSAccessibilityFocusedAttribute, |
| 107 NSAccessibilityIndexAttribute, | 150 NSAccessibilityIndexAttribute, |
| 108 @"AXLoaded", | 151 @"AXLoaded", |
| 109 @"AXLoadingProcess", | 152 @"AXLoadingProcess", |
| 110 NSAccessibilityNumberOfCharactersAttribute, | 153 NSAccessibilityNumberOfCharactersAttribute, |
| 111 NSAccessibilityOrientationAttribute, | 154 NSAccessibilityOrientationAttribute, |
| 112 @"AXRequired", | 155 @"AXRequired", |
| 113 NSAccessibilityRowIndexRangeAttribute, | 156 NSAccessibilityRowIndexRangeAttribute, |
| 157 NSAccessibilityTitleUIElementAttribute, |
| 114 NSAccessibilityURLAttribute, | 158 NSAccessibilityURLAttribute, |
| 115 NSAccessibilityVisibleCharacterRangeAttribute, | 159 NSAccessibilityVisibleCharacterRangeAttribute, |
| 116 @"AXVisited", | 160 @"AXVisited", |
| 161 @"AXLinkedUIElements", |
| 117 nil]; | 162 nil]; |
| 118 return [array retain]; | 163 return [array retain]; |
| 119 } | 164 } |
| 120 | 165 |
| 121 } // namespace | 166 } // namespace |
| 122 | 167 |
| 123 void AccessibilityTreeFormatter::Initialize() { | 168 void AccessibilityTreeFormatter::Initialize() { |
| 124 } | 169 } |
| 125 | 170 |
| 126 | 171 |
| 127 void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node, | 172 void AccessibilityTreeFormatter::AddProperties(const BrowserAccessibility& node, |
| 128 base::DictionaryValue* dict) { | 173 base::DictionaryValue* dict) { |
| 129 BrowserAccessibilityCocoa* cocoa_node = | 174 BrowserAccessibilityCocoa* cocoa_node = |
| 130 const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityCocoa(); | 175 const_cast<BrowserAccessibility*>(&node)->ToBrowserAccessibilityCocoa(); |
| 131 NSArray* supportedAttributes = [cocoa_node accessibilityAttributeNames]; | 176 NSArray* supportedAttributes = [cocoa_node accessibilityAttributeNames]; |
| 132 | 177 |
| 133 string role = SysNSStringToUTF8( | 178 string role = SysNSStringToUTF8( |
| 134 [cocoa_node accessibilityAttributeValue:NSAccessibilityRoleAttribute]); | 179 [cocoa_node accessibilityAttributeValue:NSAccessibilityRoleAttribute]); |
| 135 dict->SetString(SysNSStringToUTF8(NSAccessibilityRoleAttribute), role); | 180 dict->SetString(SysNSStringToUTF8(NSAccessibilityRoleAttribute), role); |
| 136 | 181 |
| 137 NSString* subrole = | 182 NSString* subrole = |
| 138 [cocoa_node accessibilityAttributeValue:NSAccessibilitySubroleAttribute]; | 183 [cocoa_node accessibilityAttributeValue:NSAccessibilitySubroleAttribute]; |
| 139 if (subrole != nil) { | 184 if (subrole != nil) { |
| 140 dict->SetString(SysNSStringToUTF8(NSAccessibilitySubroleAttribute), | 185 dict->SetString(SysNSStringToUTF8(NSAccessibilitySubroleAttribute), |
| 141 SysNSStringToUTF8(subrole)); | 186 SysNSStringToUTF8(subrole)); |
| 142 } | 187 } |
| 143 | 188 |
| 144 CR_DEFINE_STATIC_LOCAL(NSArray*, all_attributes, (BuildAllAttributesArray())); | 189 CR_DEFINE_STATIC_LOCAL(NSArray*, all_attributes, (BuildAllAttributesArray())); |
| 145 for (NSString* requestedAttribute in all_attributes) { | 190 for (NSString* requestedAttribute in all_attributes) { |
| 146 if (![supportedAttributes containsObject:requestedAttribute]) { | 191 if (![supportedAttributes containsObject:requestedAttribute]) |
| 147 continue; | 192 continue; |
| 148 } | |
| 149 id value = [cocoa_node accessibilityAttributeValue:requestedAttribute]; | 193 id value = [cocoa_node accessibilityAttributeValue:requestedAttribute]; |
| 150 if (IsRangeValue(value)) { | 194 if (value != nil) { |
| 151 dict->Set( | 195 dict->Set( |
| 152 SysNSStringToUTF8(requestedAttribute), | 196 SysNSStringToUTF8(requestedAttribute), |
| 153 PopulateRange([value rangeValue]).release()); | 197 PopulateObject(value).release()); |
| 154 } else if (value != nil) { | |
| 155 dict->SetString( | |
| 156 SysNSStringToUTF8(requestedAttribute), | |
| 157 SysNSStringToUTF16([NSString stringWithFormat:@"%@", value])); | |
| 158 } | 198 } |
| 159 } | 199 } |
| 160 dict->Set(kPositionDictAttr, PopulatePosition(node).release()); | 200 dict->Set(kPositionDictAttr, PopulatePosition(node).release()); |
| 161 dict->Set(kSizeDictAttr, PopulateSize(cocoa_node).release()); | 201 dict->Set(kSizeDictAttr, PopulateSize(cocoa_node).release()); |
| 162 } | 202 } |
| 163 | 203 |
| 164 base::string16 AccessibilityTreeFormatter::ToString( | 204 base::string16 AccessibilityTreeFormatter::ToString( |
| 165 const base::DictionaryValue& dict, | 205 const base::DictionaryValue& dict, |
| 166 const base::string16& indent) { | 206 const base::string16& indent) { |
| 167 base::string16 line; | 207 base::string16 line; |
| 168 NSArray* defaultAttributes = | 208 NSArray* defaultAttributes = |
| 169 [NSArray arrayWithObjects:NSAccessibilityTitleAttribute, | 209 [NSArray arrayWithObjects:NSAccessibilityTitleAttribute, |
| 170 NSAccessibilityValueAttribute, | 210 NSAccessibilityValueAttribute, |
| 171 nil]; | 211 nil]; |
| 172 string s_value; | 212 string s_value; |
| 173 dict.GetString(SysNSStringToUTF8(NSAccessibilityRoleAttribute), &s_value); | 213 dict.GetString(SysNSStringToUTF8(NSAccessibilityRoleAttribute), &s_value); |
| 174 WriteAttribute(true, base::UTF8ToUTF16(s_value), &line); | 214 WriteAttribute(true, base::UTF8ToUTF16(s_value), &line); |
| 175 | 215 |
| 176 string subroleAttribute = SysNSStringToUTF8(NSAccessibilitySubroleAttribute); | 216 string subroleAttribute = SysNSStringToUTF8(NSAccessibilitySubroleAttribute); |
| 177 if (dict.GetString(subroleAttribute, &s_value)) { | 217 if (dict.GetString(subroleAttribute, &s_value)) { |
| 178 WriteAttribute(false, | 218 WriteAttribute(false, |
| 179 StringPrintf("%s=%s", | 219 StringPrintf("%s=%s", |
| 180 subroleAttribute.c_str(), s_value.c_str()), | 220 subroleAttribute.c_str(), s_value.c_str()), |
| 181 &line); | 221 &line); |
| 182 } | 222 } |
| 183 | 223 |
| 184 CR_DEFINE_STATIC_LOCAL(NSArray*, all_attributes, (BuildAllAttributesArray())); | 224 CR_DEFINE_STATIC_LOCAL(NSArray*, all_attributes, (BuildAllAttributesArray())); |
| 185 for (NSString* requestedAttribute in all_attributes) { | 225 for (NSString* requestedAttribute in all_attributes) { |
| 186 string requestedAttributeUTF8 = SysNSStringToUTF8(requestedAttribute); | 226 string requestedAttributeUTF8 = SysNSStringToUTF8(requestedAttribute); |
| 187 const base::DictionaryValue* d_value; | 227 if (dict.GetString(requestedAttributeUTF8, &s_value)) { |
| 188 if (dict.GetDictionary(requestedAttributeUTF8, &d_value)) { | 228 WriteAttribute([defaultAttributes containsObject:requestedAttribute], |
| 229 StringPrintf("%s='%s'", |
| 230 requestedAttributeUTF8.c_str(), |
| 231 s_value.c_str()), |
| 232 &line); |
| 233 continue; |
| 234 } |
| 235 const base::Value* value; |
| 236 if (dict.Get(requestedAttributeUTF8, &value)) { |
| 189 std::string json_value; | 237 std::string json_value; |
| 190 base::JSONWriter::Write(d_value, &json_value); | 238 base::JSONWriter::Write(value, &json_value); |
| 191 WriteAttribute( | 239 WriteAttribute( |
| 192 [defaultAttributes containsObject:requestedAttribute], | 240 [defaultAttributes containsObject:requestedAttribute], |
| 193 StringPrintf("%s=%s", | 241 StringPrintf("%s=%s", |
| 194 requestedAttributeUTF8.c_str(), | 242 requestedAttributeUTF8.c_str(), |
| 195 json_value.c_str()), | 243 json_value.c_str()), |
| 196 &line); | 244 &line); |
| 197 } | 245 } |
| 198 if (!dict.GetString(requestedAttributeUTF8, &s_value)) | |
| 199 continue; | |
| 200 WriteAttribute([defaultAttributes containsObject:requestedAttribute], | |
| 201 StringPrintf("%s='%s'", | |
| 202 requestedAttributeUTF8.c_str(), | |
| 203 s_value.c_str()), | |
| 204 &line); | |
| 205 } | 246 } |
| 206 const base::DictionaryValue* d_value = NULL; | 247 const base::DictionaryValue* d_value = NULL; |
| 207 if (dict.GetDictionary(kPositionDictAttr, &d_value)) { | 248 if (dict.GetDictionary(kPositionDictAttr, &d_value)) { |
| 208 WriteAttribute(false, | 249 WriteAttribute(false, |
| 209 FormatCoordinates(kPositionDictAttr, | 250 FormatCoordinates(kPositionDictAttr, |
| 210 kXCoordDictAttr, kYCoordDictAttr, | 251 kXCoordDictAttr, kYCoordDictAttr, |
| 211 *d_value), | 252 *d_value), |
| 212 &line); | 253 &line); |
| 213 } | 254 } |
| 214 if (dict.GetDictionary(kSizeDictAttr, &d_value)) { | 255 if (dict.GetDictionary(kSizeDictAttr, &d_value)) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 242 const string AccessibilityTreeFormatter::GetAllowString() { | 283 const string AccessibilityTreeFormatter::GetAllowString() { |
| 243 return "@MAC-ALLOW:"; | 284 return "@MAC-ALLOW:"; |
| 244 } | 285 } |
| 245 | 286 |
| 246 // static | 287 // static |
| 247 const string AccessibilityTreeFormatter::GetDenyString() { | 288 const string AccessibilityTreeFormatter::GetDenyString() { |
| 248 return "@MAC-DENY:"; | 289 return "@MAC-DENY:"; |
| 249 } | 290 } |
| 250 | 291 |
| 251 } // namespace content | 292 } // namespace content |
| OLD | NEW |