Fix accessibility of remaining input types on Android
This fixes the accessibility of the html select element and html input elements with a type of date, time, and color. BUG=378799 Review URL: https://codereview.chromium.org/739063002 Cr-Commit-Position: refs/heads/master@{#305145}
This commit is contained in:
content
browser
test
@ -6,6 +6,7 @@
|
||||
|
||||
#include "base/i18n/break_iterator.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
|
||||
#include "content/common/accessibility_messages.h"
|
||||
@ -76,6 +77,10 @@ bool BrowserAccessibilityAndroid::PlatformIsLeaf() const {
|
||||
if (HasFocusableChild())
|
||||
return false;
|
||||
|
||||
// Date and time controls should drop their children.
|
||||
if (GetRole() == ui::AX_ROLE_DATE || GetRole() == ui::AX_ROLE_TIME)
|
||||
return true;
|
||||
|
||||
// Headings with text can drop their children.
|
||||
base::string16 name = GetText();
|
||||
if (GetRole() == ui::AX_ROLE_HEADING && !name.empty())
|
||||
@ -251,12 +256,15 @@ const char* BrowserAccessibilityAndroid::GetClassName() const {
|
||||
case ui::AX_ROLE_SLIDER:
|
||||
class_name = "android.widget.SeekBar";
|
||||
break;
|
||||
case ui::AX_ROLE_COLOR_WELL:
|
||||
case ui::AX_ROLE_COMBO_BOX:
|
||||
case ui::AX_ROLE_DATE:
|
||||
case ui::AX_ROLE_POP_UP_BUTTON:
|
||||
case ui::AX_ROLE_TIME:
|
||||
class_name = "android.widget.Spinner";
|
||||
break;
|
||||
case ui::AX_ROLE_BUTTON:
|
||||
case ui::AX_ROLE_MENU_BUTTON:
|
||||
case ui::AX_ROLE_POP_UP_BUTTON:
|
||||
class_name = "android.widget.Button";
|
||||
break;
|
||||
case ui::AX_ROLE_CHECK_BOX:
|
||||
@ -319,13 +327,29 @@ base::string16 BrowserAccessibilityAndroid::GetText() const {
|
||||
// name on Android, not 2 or 3 like on Windows or Mac.
|
||||
|
||||
// First, always return the |value| attribute if this is an
|
||||
// editable text field.
|
||||
if (!value().empty() &&
|
||||
(GetRole() == ui::AX_ROLE_EDITABLE_TEXT ||
|
||||
GetRole() == ui::AX_ROLE_TEXT_AREA ||
|
||||
GetRole() == ui::AX_ROLE_TEXT_FIELD ||
|
||||
HasState(ui::AX_STATE_EDITABLE))) {
|
||||
return base::UTF8ToUTF16(value());
|
||||
// input field.
|
||||
if (!value().empty()) {
|
||||
if (HasState(ui::AX_STATE_EDITABLE))
|
||||
return base::UTF8ToUTF16(value());
|
||||
|
||||
switch (GetRole()) {
|
||||
case ui::AX_ROLE_COMBO_BOX:
|
||||
case ui::AX_ROLE_EDITABLE_TEXT:
|
||||
case ui::AX_ROLE_POP_UP_BUTTON:
|
||||
case ui::AX_ROLE_TEXT_AREA:
|
||||
case ui::AX_ROLE_TEXT_FIELD:
|
||||
return base::UTF8ToUTF16(value());
|
||||
}
|
||||
}
|
||||
|
||||
// For color wells, the color is stored in separate attributes.
|
||||
// Perhaps we could return color names in the future?
|
||||
if (GetRole() == ui::AX_ROLE_COLOR_WELL) {
|
||||
int red = GetIntAttribute(ui::AX_ATTR_COLOR_VALUE_RED);
|
||||
int green = GetIntAttribute(ui::AX_ATTR_COLOR_VALUE_GREEN);
|
||||
int blue = GetIntAttribute(ui::AX_ATTR_COLOR_VALUE_BLUE);
|
||||
return base::UTF8ToUTF16(
|
||||
base::StringPrintf("#%02X%02X%02X", red, green, blue));
|
||||
}
|
||||
|
||||
// Always prefer visible text if this is a link. Sites sometimes add
|
||||
@ -343,8 +367,17 @@ base::string16 BrowserAccessibilityAndroid::GetText() const {
|
||||
// Blink, making the platform-specific mapping to accessible text simpler.
|
||||
base::string16 description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION);
|
||||
base::string16 help = GetString16Attribute(ui::AX_ATTR_HELP);
|
||||
|
||||
base::string16 placeholder;
|
||||
GetHtmlAttribute("placeholder", &placeholder);
|
||||
switch (GetRole()) {
|
||||
case ui::AX_ROLE_DATE:
|
||||
case ui::AX_ROLE_EDITABLE_TEXT:
|
||||
case ui::AX_ROLE_TEXT_AREA:
|
||||
case ui::AX_ROLE_TEXT_FIELD:
|
||||
case ui::AX_ROLE_TIME:
|
||||
GetHtmlAttribute("placeholder", &placeholder);
|
||||
}
|
||||
|
||||
int title_elem_id = GetIntAttribute(
|
||||
ui::AX_ATTR_TITLE_UI_ELEMENT);
|
||||
base::string16 text;
|
||||
@ -356,7 +389,7 @@ base::string16 BrowserAccessibilityAndroid::GetText() const {
|
||||
text = help;
|
||||
else if (!name().empty())
|
||||
text = base::UTF8ToUTF16(name());
|
||||
else if (GetRole() == ui::AX_ROLE_TEXT_FIELD && !placeholder.empty())
|
||||
else if (!placeholder.empty())
|
||||
text = placeholder;
|
||||
else if (!value().empty())
|
||||
text = base::UTF8ToUTF16(value());
|
||||
|
@ -784,9 +784,7 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
|
||||
RunTest(FILE_PATH_LITERAL("input-checkbox-in-menu.html"));
|
||||
}
|
||||
|
||||
// http://crbug.com/378799
|
||||
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
|
||||
DISABLED_AccessibilityInputColor) {
|
||||
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputColor) {
|
||||
RunTest(FILE_PATH_LITERAL("input-color.html"));
|
||||
}
|
||||
|
||||
@ -829,9 +827,7 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputRadio) {
|
||||
RunTest(FILE_PATH_LITERAL("input-radio.html"));
|
||||
}
|
||||
|
||||
// http://crbug.com/378799
|
||||
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
|
||||
DISABLED_AccessibilityInputRange) {
|
||||
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputRange) {
|
||||
RunTest(FILE_PATH_LITERAL("input-range.html"));
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
android.webkit.WebView focusable focused scrollable
|
||||
android.view.View
|
||||
android.view.View focusable
|
||||
android.widget.Spinner clickable focusable name='#FF9900'
|
||||
|
@ -1,4 +1,3 @@
|
||||
android.webkit.WebView focusable focused scrollable
|
||||
android.view.View
|
||||
android.view.View focusable input_type=20
|
||||
android.view.View
|
||||
android.widget.Spinner clickable focusable name='2008-09-01' input_type=20
|
||||
|
@ -1,13 +1,13 @@
|
||||
AXWebArea AXRoleDescription='HTML content'
|
||||
AXGroup AXRoleDescription='group'
|
||||
AXDateField AXRoleDescription='date field'
|
||||
AXDateField AXRoleDescription='date field' AXValue='2008-09-01'
|
||||
AXGroup AXRoleDescription='group'
|
||||
AXGroup AXRoleDescription='group'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='0'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='9'
|
||||
AXStaticText AXRoleDescription='text' AXValue='/'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='0'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='1'
|
||||
AXStaticText AXRoleDescription='text' AXValue='/'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='0'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='2008'
|
||||
AXPopUpButton AXRoleDescription='pop up button'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='0'
|
||||
AXButton AXRoleDescription='button'
|
||||
|
@ -5,7 +5,7 @@
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<input type="date">
|
||||
<input type="date" value="2008-09-01">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,3 +1,3 @@
|
||||
android.webkit.WebView focusable focused scrollable
|
||||
android.view.View
|
||||
android.widget.SeekBar focusable range item_index=44 item_count=100 range_min=1 range_max=10 range_current_value=5
|
||||
android.widget.SeekBar clickable focusable range name='5' item_index=44 item_count=100 range_min=1 range_max=10 range_current_value=5
|
||||
|
@ -1,4 +1,3 @@
|
||||
android.webkit.WebView focusable focused scrollable
|
||||
android.view.View
|
||||
android.view.View focusable input_type=36
|
||||
android.view.View
|
||||
android.widget.Spinner clickable focusable name='00:00:00' input_type=36
|
||||
|
@ -1,12 +1,12 @@
|
||||
AXWebArea AXRoleDescription='HTML content'
|
||||
AXGroup AXRoleDescription='group'
|
||||
AXTimeField AXRoleDescription='time field'
|
||||
AXTimeField AXRoleDescription='time field' AXValue='00:00:00'
|
||||
AXGroup AXRoleDescription='group'
|
||||
AXGroup AXRoleDescription='group'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='0'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='12'
|
||||
AXStaticText AXRoleDescription='text' AXValue=':'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='0'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='0'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='1'
|
||||
AXIncrementor AXRoleDescription='stepper' AXValue='0'
|
||||
AXButton AXRoleDescription='button'
|
||||
AXButton AXRoleDescription='button'
|
||||
|
@ -4,6 +4,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<input type="time">
|
||||
<input type="time" value="00:00:00">
|
||||
</body>
|
||||
</html>
|
||||
|
@ -9,7 +9,7 @@ android.webkit.WebView focusable focused scrollable
|
||||
android.widget.CheckBox checkable clickable focusable name='Checkbox: '
|
||||
android.view.View
|
||||
android.view.View clickable name='Color:'
|
||||
android.view.View focusable
|
||||
android.widget.Spinner clickable focusable name='#000000'
|
||||
android.view.View
|
||||
android.view.View clickable name='Email:'
|
||||
android.widget.EditText editable_text focusable input_type=209
|
||||
@ -28,7 +28,7 @@ android.webkit.WebView focusable focused scrollable
|
||||
android.widget.RadioButton checkable clickable focusable name='Radio: '
|
||||
android.view.View
|
||||
android.view.View clickable name='Range:'
|
||||
android.widget.SeekBar focusable range item_index=50 item_count=100 range_max=100 range_current_value=50
|
||||
android.widget.SeekBar clickable focusable range name='50' item_index=50 item_count=100 range_max=100 range_current_value=50
|
||||
android.view.View
|
||||
android.view.View clickable name='Reset:'
|
||||
android.widget.Button clickable focusable name='Reset'
|
||||
|
@ -1,5 +1,5 @@
|
||||
android.webkit.WebView focusable focused scrollable
|
||||
android.view.View
|
||||
android.widget.Button clickable focusable name='Placeholder option'
|
||||
android.widget.Button clickable focusable name='Option 2'
|
||||
android.widget.Button clickable focusable name='Option 1'
|
||||
android.widget.Spinner clickable focusable name='Placeholder option'
|
||||
android.widget.Spinner clickable focusable name='Option 2'
|
||||
android.widget.Spinner clickable focusable name='Option 1'
|
||||
|
Reference in New Issue
Block a user