Commit f5ee46ef authored by Daniel Clark's avatar Daniel Clark Committed by Commit Bot

Add aria attributes to input time popup

This change assigns the proper ARIA roles and attributes to the time
picker popup to ensure a good experience with screen readers.  Prior to
this change the hour/minute/AM-PM columns were read as monolithic chunks
of numbers and the individual values were not selectable.  Now the
columns and cells have the proper ARIA roles, labels, and selection
management so that the popup works smoothly with a screen reader.

Bug: 1026544
Change-Id: Ifb16eceed8c4211537aee46cd4d09f771fea8635
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2088553Reviewed-by: default avatarAaron Leventhal <aleventhal@chromium.org>
Reviewed-by: default avatarIonel Popescu <iopopesc@microsoft.com>
Reviewed-by: default avatarMason Freed <masonfreed@chromium.org>
Reviewed-by: default avatarKevin Babbitt <kbabbitt@microsoft.com>
Commit-Queue: Dan Clark <daniec@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#752609}
parent 110cda3c
...@@ -1674,6 +1674,11 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, ...@@ -1674,6 +1674,11 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest,
RunHtmlTest(AccessibilityInputDateWithPopupOpenMultiple_TestFile); RunHtmlTest(AccessibilityInputDateWithPopupOpenMultiple_TestFile);
} }
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest,
AccessibilityInputTimeWithPopupOpen) {
RunHtmlTest(FILE_PATH_LITERAL("input-time-with-popup-open.html"));
}
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityInputDateTime) { IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityInputDateTime) {
RunHtmlTest(FILE_PATH_LITERAL("input-datetime.html")); RunHtmlTest(FILE_PATH_LITERAL("input-datetime.html"));
} }
......
#<skip - date and time controls drop their children, including the popup button, on Android>
[document web]
++[section]
++++[dateeditor]
++++++[section]
++++++++[section]
++++++++++[spin button] name='Hours' current=1.000000 minimum=1.000000 maximum=12.000000
++++++++++++[static] name='01'
++++++++++[static] name=':'
++++++++++[spin button] name='Minutes' current=50.000000 minimum=0.000000 maximum=59.000000
++++++++++++[static] name='50'
++++++++++[static] name=':'
++++++++++[spin button] name='Seconds' current=2.000000 minimum=0.000000 maximum=59.000000
++++++++++++[static] name='02'
++++++++++[static] name='.'
++++++++++[spin button] name='Milliseconds' current=922.000000 minimum=0.000000 maximum=999.000000
++++++++++++[static] name='922'
++++++++++[static] name=' '
++++++++++[spin button] name='AM/PM' current=2.000000 minimum=1.000000 maximum=2.000000
++++++++++++[static] name='PM'
++++++[push button] name='Show time picker'
++++++[document web]
++++++++[section]
++++++++++[section]
++++++++++++[list box] name='Hours'
++++++++++++++[list item] name='01' selectable selected
++++++++++++++[list item] name='02' selectable
++++++++++++++[list item] name='03' selectable
++++++++++++++[list item] name='04' selectable
++++++++++++++[list item] name='05' selectable
++++++++++++++[list item] name='06' selectable
++++++++++++++[list item] name='07' selectable
++++++++++++++[list item] name='08' selectable
++++++++++++++[list item] name='09' selectable
++++++++++++++[list item] name='10' selectable
++++++++++++++[list item] name='11' selectable
++++++++++++++[list item] name='12' selectable
++++++++++++[list box] name='Minutes'
++++++++++++++[list item] name='01' selectable
++++++++++++++[list item] name='02' selectable
++++++++++++++[list item] name='03' selectable
++++++++++++++[list item] name='04' selectable
++++++++++++++[list item] name='05' selectable
++++++++++++++[list item] name='06' selectable
++++++++++++++[list item] name='07' selectable
++++++++++++++[list item] name='08' selectable
++++++++++++++[list item] name='09' selectable
++++++++++++++[list item] name='10' selectable
++++++++++++++[list item] name='11' selectable
++++++++++++++[list item] name='12' selectable
++++++++++++++[list item] name='13' selectable
++++++++++++++[list item] name='14' selectable
++++++++++++++[list item] name='15' selectable
++++++++++++++[list item] name='16' selectable
++++++++++++++[list item] name='17' selectable
++++++++++++++[list item] name='18' selectable
++++++++++++++[list item] name='19' selectable
++++++++++++++[list item] name='20' selectable
++++++++++++++[list item] name='21' selectable
++++++++++++++[list item] name='22' selectable
++++++++++++++[list item] name='23' selectable
++++++++++++++[list item] name='24' selectable
++++++++++++++[list item] name='25' selectable
++++++++++++++[list item] name='26' selectable
++++++++++++++[list item] name='27' selectable
++++++++++++++[list item] name='28' selectable
++++++++++++++[list item] name='29' selectable
++++++++++++++[list item] name='30' selectable
++++++++++++++[list item] name='31' selectable
++++++++++++++[list item] name='32' selectable
++++++++++++++[list item] name='33' selectable
++++++++++++++[list item] name='34' selectable
++++++++++++++[list item] name='35' selectable
++++++++++++++[list item] name='36' selectable
++++++++++++++[list item] name='37' selectable
++++++++++++++[list item] name='38' selectable
++++++++++++++[list item] name='39' selectable
++++++++++++++[list item] name='40' selectable
++++++++++++++[list item] name='41' selectable
++++++++++++++[list item] name='42' selectable
++++++++++++++[list item] name='43' selectable
++++++++++++++[list item] name='44' selectable
++++++++++++++[list item] name='45' selectable
++++++++++++++[list item] name='46' selectable
++++++++++++++[list item] name='47' selectable
++++++++++++++[list item] name='48' selectable
++++++++++++++[list item] name='49' selectable
++++++++++++++[list item] name='50' selectable selected
++++++++++++++[list item] name='51' selectable
++++++++++++++[list item] name='52' selectable
++++++++++++++[list item] name='53' selectable
++++++++++++++[list item] name='54' selectable
++++++++++++++[list item] name='55' selectable
++++++++++++++[list item] name='56' selectable
++++++++++++++[list item] name='57' selectable
++++++++++++++[list item] name='58' selectable
++++++++++++++[list item] name='59' selectable
++++++++++++++[list item] name='00' selectable
++++++++++++[list box] name='Seconds'
++++++++++++++[list item] name='01' selectable
++++++++++++++[list item] name='02' selectable selected
++++++++++++++[list item] name='03' selectable
++++++++++++++[list item] name='04' selectable
++++++++++++++[list item] name='05' selectable
++++++++++++++[list item] name='06' selectable
++++++++++++++[list item] name='07' selectable
++++++++++++++[list item] name='08' selectable
++++++++++++++[list item] name='09' selectable
++++++++++++++[list item] name='10' selectable
++++++++++++++[list item] name='11' selectable
++++++++++++++[list item] name='12' selectable
++++++++++++++[list item] name='13' selectable
++++++++++++++[list item] name='14' selectable
++++++++++++++[list item] name='15' selectable
++++++++++++++[list item] name='16' selectable
++++++++++++++[list item] name='17' selectable
++++++++++++++[list item] name='18' selectable
++++++++++++++[list item] name='19' selectable
++++++++++++++[list item] name='20' selectable
++++++++++++++[list item] name='21' selectable
++++++++++++++[list item] name='22' selectable
++++++++++++++[list item] name='23' selectable
++++++++++++++[list item] name='24' selectable
++++++++++++++[list item] name='25' selectable
++++++++++++++[list item] name='26' selectable
++++++++++++++[list item] name='27' selectable
++++++++++++++[list item] name='28' selectable
++++++++++++++[list item] name='29' selectable
++++++++++++++[list item] name='30' selectable
++++++++++++++[list item] name='31' selectable
++++++++++++++[list item] name='32' selectable
++++++++++++++[list item] name='33' selectable
++++++++++++++[list item] name='34' selectable
++++++++++++++[list item] name='35' selectable
++++++++++++++[list item] name='36' selectable
++++++++++++++[list item] name='37' selectable
++++++++++++++[list item] name='38' selectable
++++++++++++++[list item] name='39' selectable
++++++++++++++[list item] name='40' selectable
++++++++++++++[list item] name='41' selectable
++++++++++++++[list item] name='42' selectable
++++++++++++++[list item] name='43' selectable
++++++++++++++[list item] name='44' selectable
++++++++++++++[list item] name='45' selectable
++++++++++++++[list item] name='46' selectable
++++++++++++++[list item] name='47' selectable
++++++++++++++[list item] name='48' selectable
++++++++++++++[list item] name='49' selectable
++++++++++++++[list item] name='50' selectable
++++++++++++++[list item] name='51' selectable
++++++++++++++[list item] name='52' selectable
++++++++++++++[list item] name='53' selectable
++++++++++++++[list item] name='54' selectable
++++++++++++++[list item] name='55' selectable
++++++++++++++[list item] name='56' selectable
++++++++++++++[list item] name='57' selectable
++++++++++++++[list item] name='58' selectable
++++++++++++++[list item] name='59' selectable
++++++++++++++[list item] name='00' selectable
++++++++++++[list box] name='Milliseconds'
++++++++++++++[list item] name='100' selectable
++++++++++++++[list item] name='200' selectable
++++++++++++++[list item] name='300' selectable
++++++++++++++[list item] name='400' selectable
++++++++++++++[list item] name='500' selectable
++++++++++++++[list item] name='600' selectable
++++++++++++++[list item] name='700' selectable
++++++++++++++[list item] name='800' selectable
++++++++++++++[list item] name='922' selectable selected
++++++++++++++[list item] name='000' selectable
++++++++++++[list box] name='AM/PM'
++++++++++++++[list item] name='PM' selectable selected
++++++++++++++[list item] name='AM' selectable
<!--
@BLINK-ALLOW:inputType=*
@MAC-ALLOW:AXRole*
@WIN-ALLOW:ia2_hypertext=*
@UIA-WIN-ALLOW:ControllerFor=*
@UIA-WIN-ALLOW:LocalizedControlType='time picker'
@DEFAULT-ACTION-ON:Show time picker
@WIN-ALLOW:localized_extended_role='time picker'
-->
<!DOCTYPE html>
<html>
<body>
<input type="time" value="13:50:02.922">
</body>
</html>
...@@ -170,6 +170,16 @@ void DateTimeChooserImpl::WriteDocument(SharedBuffer* data) { ...@@ -170,6 +170,16 @@ void DateTimeChooserImpl::WriteDocument(SharedBuffer* data) {
AddProperty("axShowPreviousMonth", AddProperty("axShowPreviousMonth",
GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_PREVIOUS_MONTH), GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_PREVIOUS_MONTH),
data); data);
AddProperty("axHourLabel", GetLocale().QueryString(IDS_AX_HOUR_FIELD_TEXT),
data);
AddProperty("axMinuteLabel",
GetLocale().QueryString(IDS_AX_MINUTE_FIELD_TEXT), data);
AddProperty("axSecondLabel",
GetLocale().QueryString(IDS_AX_SECOND_FIELD_TEXT), data);
AddProperty("axMillisecondLabel",
GetLocale().QueryString(IDS_AX_MILLISECOND_FIELD_TEXT), data);
AddProperty("axAmPmLabel", GetLocale().QueryString(IDS_AX_AM_PM_FIELD_TEXT),
data);
AddProperty("weekStartDay", locale_->FirstDayOfWeek(), data); AddProperty("weekStartDay", locale_->FirstDayOfWeek(), data);
AddProperty("shortMonthLabels", locale_->ShortMonthLabels(), data); AddProperty("shortMonthLabels", locale_->ShortMonthLabels(), data);
AddProperty("dayLabels", locale_->WeekDayShortLabels(), data); AddProperty("dayLabels", locale_->WeekDayShortLabels(), data);
......
...@@ -27,7 +27,6 @@ const TimeColumnType = { ...@@ -27,7 +27,6 @@ const TimeColumnType = {
AMPM: 5, AMPM: 5,
}; };
/** /**
* Supported label types. * Supported label types.
* @enum {number} * @enum {number}
...@@ -427,6 +426,19 @@ class TimeColumn extends HTMLUListElement { ...@@ -427,6 +426,19 @@ class TimeColumn extends HTMLUListElement {
this.className = TimeColumn.ClassName; this.className = TimeColumn.ClassName;
this.tabIndex = 0; this.tabIndex = 0;
this.columnType_ = columnType; this.columnType_ = columnType;
this.setAttribute('role', 'listbox');
if (this.columnType_ === TimeColumnType.HOUR) {
this.setAttribute('aria-label', global.params.axHourLabel);
} else if (this.columnType_ === TimeColumnType.MINUTE) {
this.setAttribute('aria-label', global.params.axMinuteLabel);
} else if (this.columnType_ === TimeColumnType.SECOND) {
this.setAttribute('aria-label', global.params.axSecondLabel);
} else if (this.columnType_ === TimeColumnType.MILLISECOND) {
this.setAttribute('aria-label', global.params.axMillisecondLabel);
} else {
this.setAttribute('aria-label', global.params.axAmPmLabel);
}
if (this.columnType_ == TimeColumnType.AMPM) { if (this.columnType_ == TimeColumnType.AMPM) {
this.createAndInitializeAMPMCells_(timePicker); this.createAndInitializeAMPMCells_(timePicker);
} else { } else {
...@@ -456,7 +468,7 @@ class TimeColumn extends HTMLUListElement { ...@@ -456,7 +468,7 @@ class TimeColumn extends HTMLUListElement {
(100 * Math.floor((Number(millisecondValue) + 50.0) / 100.0)) % 1000; (100 * Math.floor((Number(millisecondValue) + 50.0) / 100.0)) % 1000;
} }
let time = new Time(1, 1, 1, 0); let time = new Time(1, 1, 1, 100);
let cells = []; let cells = [];
let initialCellIndex = -1; let initialCellIndex = -1;
for (let i = 0; i < totalCells; i++) { for (let i = 0; i < totalCells; i++) {
...@@ -464,7 +476,7 @@ class TimeColumn extends HTMLUListElement { ...@@ -464,7 +476,7 @@ class TimeColumn extends HTMLUListElement {
if (this.columnType_ === TimeColumnType.MILLISECOND && if (this.columnType_ === TimeColumnType.MILLISECOND &&
Number(value) === roundedMillisecondValue) { Number(value) === roundedMillisecondValue) {
// Set this cell to the exat ms value of the in-page control // Set this cell to the exact ms value of the in-page control
value = value =
currentTime.value(TimeColumnType.MILLISECOND, timePicker.hasAMPM); currentTime.value(TimeColumnType.MILLISECOND, timePicker.hasAMPM);
initialCellIndex = i; initialCellIndex = i;
...@@ -691,9 +703,12 @@ class TimeColumn extends HTMLUListElement { ...@@ -691,9 +703,12 @@ class TimeColumn extends HTMLUListElement {
set selectedTimeCell(timeCell) { set selectedTimeCell(timeCell) {
if (this.selectedTimeCell_) { if (this.selectedTimeCell_) {
this.selectedTimeCell_.classList.remove('selected'); this.selectedTimeCell_.classList.remove('selected');
this.selectedTimeCell_.removeAttribute('aria-selected');
} }
this.selectedTimeCell_ = timeCell; this.selectedTimeCell_ = timeCell;
this.setAttribute('aria-activedescendant', timeCell.id);
this.selectedTimeCell_.classList.add('selected'); this.selectedTimeCell_.classList.add('selected');
this.selectedTimeCell_.setAttribute('aria-selected', 'true');
} }
resetToInitialValue = () => { resetToInitialValue = () => {
...@@ -721,7 +736,16 @@ class TimeCell extends HTMLLIElement { ...@@ -721,7 +736,16 @@ class TimeCell extends HTMLLIElement {
this.className = TimeCell.ClassName; this.className = TimeCell.ClassName;
this.textContent = localizedValue; this.textContent = localizedValue;
this.value = value; this.value = value;
this.setAttribute('role', 'option');
this.id = TimeCell.getNextUniqueId();
}; };
static getNextUniqueId() {
return `timeCell${TimeCell.idCount++}`;
}
static idCount = 0;
} }
TimeCell.ClassName = 'time-cell'; TimeCell.ClassName = 'time-cell';
window.customElements.define('time-cell', TimeCell, {extends: 'li'}); window.customElements.define('time-cell', TimeCell, {extends: 'li'});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment