Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/browser_accessibility_android.h" | 5 #include "content/browser/accessibility/browser_accessibility_android.h" |
| 6 | 6 |
| 7 #include "base/i18n/break_iterator.h" | 7 #include "base/i18n/break_iterator.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 if (InternalChildCount() > 0 && !HasOnlyStaticTextChildren()) | 340 if (InternalChildCount() > 0 && !HasOnlyStaticTextChildren()) |
| 341 return base::string16(); | 341 return base::string16(); |
| 342 } | 342 } |
| 343 | 343 |
| 344 // We can only expose one accessible name on Android, | 344 // We can only expose one accessible name on Android, |
| 345 // not 2 or 3 like on Windows or Mac. | 345 // not 2 or 3 like on Windows or Mac. |
| 346 | 346 |
| 347 // First, always return the |value| attribute if this is an | 347 // First, always return the |value| attribute if this is an |
| 348 // input field. | 348 // input field. |
| 349 base::string16 value = GetValue(); | 349 base::string16 value = GetValue(); |
| 350 if (!value.empty()) { | 350 if (!value.empty() && ShouldExposeValueAsName()) |
|
David Tseng
2016/03/17 22:55:15
So, in the Android world, text is same as name?
W
| |
| 351 if (HasState(ui::AX_STATE_EDITABLE)) | 351 return value; |
| 352 return value; | |
| 353 | |
| 354 switch (GetRole()) { | |
| 355 case ui::AX_ROLE_COMBO_BOX: | |
| 356 case ui::AX_ROLE_POP_UP_BUTTON: | |
| 357 case ui::AX_ROLE_TEXT_FIELD: | |
| 358 return value; | |
| 359 } | |
| 360 } | |
| 361 | 352 |
| 362 // For color wells, the color is stored in separate attributes. | 353 // For color wells, the color is stored in separate attributes. |
| 363 // Perhaps we could return color names in the future? | 354 // Perhaps we could return color names in the future? |
|
David Tseng
2016/03/17 22:55:15
Unrelated; this begs to be made into a TODO with a
| |
| 364 if (GetRole() == ui::AX_ROLE_COLOR_WELL) { | 355 if (GetRole() == ui::AX_ROLE_COLOR_WELL) { |
| 365 int color = GetIntAttribute(ui::AX_ATTR_COLOR_VALUE); | 356 int color = GetIntAttribute(ui::AX_ATTR_COLOR_VALUE); |
| 366 int red = (color >> 16) & 0xFF; | 357 int red = (color >> 16) & 0xFF; |
| 367 int green = (color >> 8) & 0xFF; | 358 int green = (color >> 8) & 0xFF; |
| 368 int blue = color & 0xFF; | 359 int blue = color & 0xFF; |
| 369 return base::UTF8ToUTF16( | 360 return base::UTF8ToUTF16( |
| 370 base::StringPrintf("#%02X%02X%02X", red, green, blue)); | 361 base::StringPrintf("#%02X%02X%02X", red, green, blue)); |
| 371 } | 362 } |
| 372 | 363 |
| 373 base::string16 text = GetString16Attribute(ui::AX_ATTR_NAME); | 364 base::string16 text = GetString16Attribute(ui::AX_ATTR_NAME); |
| 374 base::string16 description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION); | |
| 375 if (!description.empty()) { | |
| 376 if (!text.empty()) | |
| 377 text += base::ASCIIToUTF16(" "); | |
| 378 text += description; | |
| 379 } | |
| 380 | |
| 381 if (text.empty()) | 365 if (text.empty()) |
| 382 text = value; | 366 text = value; |
| 383 | 367 |
| 384 // This is called from PlatformIsLeaf, so don't call PlatformChildCount | 368 // This is called from PlatformIsLeaf, so don't call PlatformChildCount |
| 385 // from within this! | 369 // from within this! |
| 386 if (text.empty() && | 370 if (text.empty() && |
| 387 (HasOnlyStaticTextChildren() || | 371 (HasOnlyStaticTextChildren() || |
| 388 (IsFocusable() && HasOnlyTextAndImageChildren()))) { | 372 (IsFocusable() && HasOnlyTextAndImageChildren()))) { |
| 389 for (uint32_t i = 0; i < InternalChildCount(); i++) { | 373 for (uint32_t i = 0; i < InternalChildCount(); i++) { |
| 390 BrowserAccessibility* child = InternalGetChild(i); | 374 BrowserAccessibility* child = InternalGetChild(i); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 408 url = url.substr(slash_index + 1); | 392 url = url.substr(slash_index + 1); |
| 409 size_t dot_index = url.rfind('.'); | 393 size_t dot_index = url.rfind('.'); |
| 410 if (dot_index != std::string::npos) | 394 if (dot_index != std::string::npos) |
| 411 url = url.substr(0, dot_index); | 395 url = url.substr(0, dot_index); |
| 412 text = url; | 396 text = url; |
| 413 } | 397 } |
| 414 | 398 |
| 415 return text; | 399 return text; |
| 416 } | 400 } |
| 417 | 401 |
| 402 base::string16 BrowserAccessibilityAndroid::GetDescription() const { | |
| 403 // If we're returning the value as the main text, then return the | |
| 404 // accessible name as the only accessible text. | |
|
David Tseng
2016/03/17 22:55:15
Can you reword this last part? Accessible text or
| |
| 405 base::string16 value = GetValue(); | |
| 406 if (!value.empty() && ShouldExposeValueAsName()) | |
|
David Tseng
2016/03/17 22:55:15
Can you move this non-empty value check into Shoul
| |
| 407 return GetString16Attribute(ui::AX_ATTR_NAME); | |
| 408 | |
| 409 return GetString16Attribute(ui::AX_ATTR_DESCRIPTION); | |
| 410 } | |
| 411 | |
| 418 base::string16 BrowserAccessibilityAndroid::GetRoleDescription() const { | 412 base::string16 BrowserAccessibilityAndroid::GetRoleDescription() const { |
| 419 content::ContentClient* content_client = content::GetContentClient(); | 413 content::ContentClient* content_client = content::GetContentClient(); |
| 420 | 414 |
| 421 // As a special case, if we have a heading level return a string like | 415 // As a special case, if we have a heading level return a string like |
| 422 // "heading level 1", etc. | 416 // "heading level 1", etc. |
| 423 if (GetRole() == ui::AX_ROLE_HEADING) { | 417 if (GetRole() == ui::AX_ROLE_HEADING) { |
| 424 int level = GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL); | 418 int level = GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL); |
| 425 if (level >= 1 && level <= 6) { | 419 if (level >= 1 && level <= 6) { |
| 426 std::vector<base::string16> values; | 420 std::vector<base::string16> values; |
| 427 values.push_back(base::IntToString16(level)); | 421 values.push_back(base::IntToString16(level)); |
| (...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1335 } | 1329 } |
| 1336 } | 1330 } |
| 1337 return true; | 1331 return true; |
| 1338 } | 1332 } |
| 1339 | 1333 |
| 1340 bool BrowserAccessibilityAndroid::IsIframe() const { | 1334 bool BrowserAccessibilityAndroid::IsIframe() const { |
| 1341 return (GetRole() == ui::AX_ROLE_IFRAME || | 1335 return (GetRole() == ui::AX_ROLE_IFRAME || |
| 1342 GetRole() == ui::AX_ROLE_IFRAME_PRESENTATIONAL); | 1336 GetRole() == ui::AX_ROLE_IFRAME_PRESENTATIONAL); |
| 1343 } | 1337 } |
| 1344 | 1338 |
| 1339 bool BrowserAccessibilityAndroid::ShouldExposeValueAsName() const { | |
| 1340 if (HasState(ui::AX_STATE_EDITABLE)) | |
| 1341 return true; | |
| 1342 | |
| 1343 switch (GetRole()) { | |
| 1344 case ui::AX_ROLE_COMBO_BOX: | |
| 1345 case ui::AX_ROLE_POP_UP_BUTTON: | |
| 1346 case ui::AX_ROLE_TEXT_FIELD: | |
| 1347 return true; | |
| 1348 } | |
| 1349 | |
| 1350 return false; | |
| 1351 } | |
| 1352 | |
| 1345 void BrowserAccessibilityAndroid::OnDataChanged() { | 1353 void BrowserAccessibilityAndroid::OnDataChanged() { |
| 1346 BrowserAccessibility::OnDataChanged(); | 1354 BrowserAccessibility::OnDataChanged(); |
| 1347 | 1355 |
| 1348 if (IsEditableText()) { | 1356 if (IsEditableText()) { |
| 1349 base::string16 value = GetValue(); | 1357 base::string16 value = GetValue(); |
| 1350 if (value != new_value_) { | 1358 if (value != new_value_) { |
| 1351 old_value_ = new_value_; | 1359 old_value_ = new_value_; |
| 1352 new_value_ = value; | 1360 new_value_ = value; |
| 1353 } | 1361 } |
| 1354 } | 1362 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1384 int BrowserAccessibilityAndroid::CountChildrenWithRole(ui::AXRole role) const { | 1392 int BrowserAccessibilityAndroid::CountChildrenWithRole(ui::AXRole role) const { |
| 1385 int count = 0; | 1393 int count = 0; |
| 1386 for (uint32_t i = 0; i < PlatformChildCount(); i++) { | 1394 for (uint32_t i = 0; i < PlatformChildCount(); i++) { |
| 1387 if (PlatformGetChild(i)->GetRole() == role) | 1395 if (PlatformGetChild(i)->GetRole() == role) |
| 1388 count++; | 1396 count++; |
| 1389 } | 1397 } |
| 1390 return count; | 1398 return count; |
| 1391 } | 1399 } |
| 1392 | 1400 |
| 1393 } // namespace content | 1401 } // namespace content |
| OLD | NEW |