Bug 1387057 - improved accessibliity of onboarding notification bar. r=mossop

MozReview-Commit-ID: Hx60C142g3u
This commit is contained in:
Yura Zenevich 2017-08-03 12:15:38 -04:00
Родитель b2ed131cbd
Коммит 62dc5614eb
3 изменённых файлов: 55 добавлений и 14 удалений

Просмотреть файл

@ -329,7 +329,8 @@
/* Keyboard focus specific outline */
.onboarding-tour-action-button:-moz-focusring,
#onboarding-tour-list .onboarding-tour-item:focus {
#onboarding-tour-list .onboarding-tour-item:focus,
#onboarding-notification-action-btn:-moz-focusring {
outline: 2px solid rgba(0,149,221,0.5);
outline-offset: 1px;
-moz-outline-radius: 2px;
@ -499,7 +500,7 @@
--height: 22px;
--vpadding: 3px;
position: absolute;
content: attr(data-tooltip);
content: attr(aria-label);
top: 0;
offset-inline-start: 73px;
line-height: calc(var(--height) - var(--vpadding) * 2);
@ -541,6 +542,7 @@
#onboarding-notification-tour-title {
margin: 0;
font-weight: bold;
}
#onboarding-notification-tour-icon {

Просмотреть файл

@ -929,17 +929,19 @@ class Onboarding {
}
_renderNotificationBar() {
let div = this._window.document.createElement("div");
div.id = "onboarding-notification-bar";
let footer = this._window.document.createElement("footer");
footer.id = "onboarding-notification-bar";
footer.setAttribute("aria-live", "polite");
footer.setAttribute("aria-labelledby", "onboarding-notification-icon")
// We use `innerHTML` for more friendly reading.
// The security should be fine because this is not from an external input.
div.innerHTML = `
<div id="onboarding-notification-icon"></div>
<section id="onboarding-notification-message-section">
<div id="onboarding-notification-tour-icon"></div>
<div id="onboarding-notification-body">
<h6 id="onboarding-notification-tour-title"></h6>
<span id="onboarding-notification-tour-message"></span>
footer.innerHTML = `
<div id="onboarding-notification-icon" role="presentation"></div>
<section id="onboarding-notification-message-section" role="presentation">
<div id="onboarding-notification-tour-icon" role="presentation"></div>
<div id="onboarding-notification-body" role="presentation">
<h1 id="onboarding-notification-tour-title"></h1>
<p id="onboarding-notification-tour-message"></p>
</div>
<button id="onboarding-notification-action-btn"></button>
</section>
@ -949,12 +951,15 @@ class Onboarding {
this._tourType === "new" ? "onboarding.notification-icon-tool-tip" :
"onboarding.notification-icon-tooltip-updated",
[BRAND_SHORT_NAME], 1);
div.querySelector("#onboarding-notification-icon").setAttribute("data-tooltip", toolTip);
let closeBtn = div.querySelector("#onboarding-notification-close-btn");
let icon = footer.querySelector("#onboarding-notification-icon");
icon.setAttribute("aria-label", toolTip);
icon.setAttribute("role", "presentation");
let closeBtn = footer.querySelector("#onboarding-notification-close-btn");
closeBtn.setAttribute("title",
this._bundle.GetStringFromName("onboarding.notification-close-button-tooltip"));
return div;
return footer;
}
hide() {

Просмотреть файл

@ -93,3 +93,37 @@ add_task(async function test_onboarding_overlay_dialog() {
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_onboarding_notification_bar() {
resetOnboardingDefaultState();
skipMuteNotificationOnFirstSession();
let tab = await openTab(ABOUT_NEWTAB_URL);
await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
await promiseTourNotificationOpened(tab.linkedBrowser);
info("Test accessibility and semantics of the notification bar");
await ContentTask.spawn(tab.linkedBrowser, {}, function() {
let doc = content.document;
let footer = doc.getElementById("onboarding-notification-bar");
let icon = doc.getElementById("onboarding-notification-icon")
is(footer.getAttribute("aria-live"), "polite",
"Notification bar should be a live region");
is(footer.getAttribute("aria-labelledby"), icon.id,
"Notification bar should be labelled by the notification icon text");
ok(icon.getAttribute("aria-label"),
"Notification icon should have a text alternative");
// Presentational elements
[
"onboarding-notification-icon",
"onboarding-notification-message-section",
"onboarding-notification-tour-icon",
"onboarding-notification-body"
].forEach(id =>
is(doc.getElementById(id).getAttribute("role"), "presentation",
"Element is only used for presentation"));
});
await BrowserTestUtils.removeTab(tab);
});