Bug 1703172: Set role="alert" on Proton info bars. r=Jamie
authorJames Teh <jteh@mozilla.com>
Fri, 09 Apr 2021 16:08:53 +0000
changeset 575280 45b6eccfb1744b7bb16379ba7e18acd1e3a53b71
parent 575279 23dce8de054d323a641baa827314cb81fda7856a
child 575281 89a6a6b7c07ec789f30ce12ef6a36aef2ad0c995
push id140628
push usermstriemer@mozilla.com
push dateFri, 09 Apr 2021 17:48:01 +0000
treeherderautoland@45b6eccfb174 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJamie
bugs1703172
milestone89.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1703172: Set role="alert" on Proton info bars. r=Jamie This allows screen readers to report info bars automatically when they appear. It also allows the message text to be reported, which would normally be missed because it isn't focusable. Differential Revision: https://phabricator.services.mozilla.com/D111035
toolkit/content/widgets/notificationbox.js
--- a/toolkit/content/widgets/notificationbox.js
+++ b/toolkit/content/widgets/notificationbox.js
@@ -563,17 +563,21 @@
         this.persistence = 0;
         this.priority = 0;
         this.timeout = 0;
       }
 
       connectedCallback() {
         this.toggleAttribute("dismissable", true);
         this.closeButton.classList.add("notification-close");
-        this.shadowRoot.querySelector(".container").classList.add("infobar");
+
+        this.container = this.shadowRoot.querySelector(".container");
+        this.container.classList.add("infobar");
+        this.setAlertRole();
+
         let messageContent = this.shadowRoot.querySelector(".content");
         messageContent.classList.add("notification-content");
 
         // Remove the <slot>, API surface is `set label()` and `setButtons()`.
         messageContent.textContent = "";
 
         this.messageText = document.createElement("span");
         this.messageText.classList.add("notification-message");
@@ -598,16 +602,27 @@
 
       close() {
         if (!this.parentNode) {
           return;
         }
         this.control.removeNotification(this);
       }
 
+      setAlertRole() {
+        // Wait a little for this to render before setting the role for more
+        // consistent alerts to screen readers.
+        this.container.removeAttribute("role");
+        window.requestAnimationFrame(() => {
+          window.requestAnimationFrame(() => {
+            this.container.setAttribute("role", "alert");
+          });
+        });
+      }
+
       handleEvent(e) {
         if ("buttonInfo" in e.target) {
           let { buttonInfo } = e.target;
           let { callback, popup } = buttonInfo;
           if (popup) {
             document
               .getElementById(popup)
               .openPopup(
@@ -626,16 +641,17 @@
             }
             e.stopPropagation();
           }
         }
       }
 
       set label(value) {
         this.messageText.textContent = value;
+        this.setAlertRole();
       }
 
       setButtons(buttons) {
         this._buttons = buttons;
         for (let button of buttons) {
           let link = button.link;
           let localeId = button["l10n-id"];
           if (!link && button.supportPage) {