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 |