Переглянути джерело

Accessibility: Add a lot of ARIA attributes

Tested with macOS voiceover in Safari.

There's still a lot more to do, but it's a start.
Danilo Bargen 7 роки тому
батько
коміт
5b68e67218

+ 2 - 2
index.html

@@ -57,7 +57,7 @@
 </head>
 
 <body ng-controller="StatusController as ctrl" class="{{ ctrl.statusClass }}" ng-class="{expanded: ctrl.expandStatusBar}">
-    <img src="img/bg.jpg?v=1" id="background-image" draggable="false">
+    <img src="img/bg.jpg?v=1" alt="Background image: Blurred photo of a mountain" id="background-image" draggable="false">
 
     <noscript>
         <img id="logo-noscript" src="img/logo.svg?v=[[VERSION]]"/>
@@ -69,7 +69,7 @@
 
     <div id="main-wrapper" ng-cloak ng-class="{wide: ctrl.wide()}">
         <header>
-            <h1 id="title">
+            <h1 id="title" aria-label="Threema Web Logo">
                 <div id="logo" ng-include src="'img/logo.svg?v=[[VERSION]]'"></div>
             </h1>
         </header>

+ 2 - 1
public/i18n/de.json

@@ -182,7 +182,8 @@
         "MUTED_NONE": "Keine Benachrichtigungen",
         "MUTED_MENTION_ONLY": "Nur bei Erwähnung benachrichtigen",
         "MUTED_SILENT": "Stumme Benachrichtigungen",
-        "ALL": "Alle"
+        "ALL": "Alle",
+        "LOADING_MESSAGES": "Nachrichten werden geladen…"
     },
     "messageStates": {
         "WE_ACK": "Sie haben ein Daumen-Hoch gesendet",

+ 2 - 1
public/i18n/en.json

@@ -181,7 +181,8 @@
         "MUTED_NONE": "No notifications",
         "MUTED_MENTION_ONLY": "Only show notification when mentioned",
         "MUTED_SILENT": "Silent notifications",
-        "ALL": "All"
+        "ALL": "All",
+        "LOADING_MESSAGES": "Loading messages…"
     },
     "messageStates": {
         "WE_ACK": "You sent thumbs-up",

+ 4 - 2
src/directives/avatar.ts

@@ -68,7 +68,8 @@ export default [
 
                     this.highResolution = this.resolution === 'high';
                     this.isLoading = this.highResolution;
-                    this.backgroundColor = this.receiver.color;
+                    this.backgroundColor = (this.receiver as threema.Receiver).color;
+                    this.receiverName = (this.receiver as threema.Receiver).displayName;
                     this.avatarClass = () => {
                         return 'avatar-' + this.resolution + (this.isLoading ? ' is-loading' : '');
                     };
@@ -215,7 +216,8 @@ export default [
                          ng-class="ctrl.avatarClass()"
                          ng-style="{ 'background-color': ctrl.backgroundColor }"
                          ng-src="{{ ctrl.getAvatarUri() }}"
-                         in-view="ctrl.requestAvatar($inview)">
+                         in-view="ctrl.requestAvatar($inview)"
+                         aria-label="avatar {{ ctrl.receiverName }}">
                </div>
             `,
         };

+ 2 - 2
src/directives/battery.ts

@@ -60,10 +60,10 @@ export default [
             template: `
                 <div class="battery-status" ng-if="ctrl.available()"" ng-class="{'alert': ctrl.alert()}">
                     <md-icon
-                        aria-label="{{ ctrl.description() }}"
+                        aria-label="Battery status: {{ ctrl.description() }}"
                         title="{{ ctrl.description() }}"
                         class="material-icons md-light md-24">{{ ctrl.icon() }}</md-icon>
-                       <span class="battery-percent">{{ ctrl.percent() }}%</span>
+                    <span class="battery-percent" aria-hidden="true">{{ ctrl.percent() }}%</span>
                 </div>
             `,
         };

+ 8 - 1
src/directives/compose_area.ts

@@ -830,7 +830,14 @@ export default [
                         <i class="md-primary emoji-trigger trigger is-enabled material-icons" role="button" aria-label="emoji">tag_faces</i>
                     </div>
                     <div>
-                        <div class="compose" contenteditable translate translate-attr-data-placeholder="messenger.COMPOSE_MESSAGE" autofocus></div>
+                        <div
+                            class="compose"
+                            contenteditable
+                            autofocus
+                            translate
+                            translate-attr-data-placeholder="messenger.COMPOSE_MESSAGE"
+                            translate-attr-aria-label="messenger.COMPOSE_MESSAGE"
+                        ></div>
                     </div>
                     <div>
                         <i class="md-primary send-trigger trigger material-icons" role="button" aria-label="send">send</i>

+ 5 - 1
src/directives/message_state.ts

@@ -28,7 +28,11 @@ export default [
                 message: '=eeeMessage',
             },
             template: `
-                <i class="material-icons md-dark md-14 {{message.state}}" title="{{ message | messageStateTitleText | translate }}">{{ message | messageStateIcon }}</i>
+                <i
+                    class="material-icons md-dark md-14 {{message.state}}"
+                    title="{{ message | messageStateTitleText | translate }}"
+                    aria-label="icon {{ message | messageStateTitleText | translate }}"
+                >{{ message | messageStateIcon }}</i>
             `,
         };
     },

+ 1 - 1
src/partials/messenger.conversation.html

@@ -40,7 +40,7 @@
         <ul class="chat">
             <li in-view="$inview && !ctrl.locked && ctrl.topOfChat()" class="load-more">
                 <div ng-if="ctrl.hasMoreMessages()" class="loading">
-                    <img ng-src="img/spinner.gif" alt="...">
+                    <img ng-src="img/spinner.gif" alt="..." translate translate-attr-aria-label="messenger.LOADING_MESSAGES">
                 </div>
             </li>
             <li ng-repeat="message in ctrl.messages" id="message-{{message.id}}">

+ 12 - 10
src/partials/messenger.navigation.html

@@ -15,25 +15,25 @@
         <md-menu-content width="4">
             <md-menu-item>
                 <md-button ng-click="ctrl.closeSession()">
-                    <md-icon aria-label="Close session" class="material-icons md-24">exit_to_app</md-icon>
+                    <md-icon aria-hidden="true" class="material-icons md-24">exit_to_app</md-icon>
                     <span translate>common.SESSION_CLOSE</span>
                 </md-button>
             </md-menu-item>
             <md-menu-item ng-if="ctrl.isPersistent()">
                 <md-button ng-click="ctrl.deleteSession()">
-                    <md-icon aria-label="Delete session" class="material-icons md-24">delete</md-icon>
+                    <md-icon aria-hidden="true" class="material-icons md-24">delete</md-icon>
                     <span translate>common.SESSION_DELETE</span>
                 </md-button>
             </md-menu-item>
             <md-menu-item>
                 <md-button ng-click="ctrl.settings()">
-                    <md-icon aria-label="Settings" class="material-icons md-24">settings</md-icon>
+                    <md-icon aria-hidden="true" class="material-icons md-24">settings</md-icon>
                     <span translate>messenger.SETTINGS</span>
                 </md-button>
             </md-menu-item>
             <md-menu-item>
                 <md-button ng-click="ctrl.about()">
-                    <md-icon aria-label="About" class="material-icons md-24">info</md-icon>
+                    <md-icon aria-hidden="true" class="material-icons md-24">info</md-icon>
                     <span translate>messenger.ABOUT</span>
                 </md-button>
             </md-menu-item>
@@ -45,15 +45,15 @@
 <div id="navigation-header">
     <div class="main">
         <md-nav-bar md-no-ink md-selected-nav-item="ctrl.activeTab" nav-bar-aria-label="navigation links">
-            <md-nav-item md-nav-click="1" name="conversations">
+            <md-nav-item md-nav-click="1" name="conversations" aria-label="conversations">
                 <i class="material-icons md-dark md-24" translate translate-attr-title="messenger.CONVERSATIONS">speaker_notes</i>
             </md-nav-item>
-            <md-nav-item md-nav-click="1" name="contacts">
+            <md-nav-item md-nav-click="1" name="contacts" aria-label="contacts">
                 <i class="material-icons md-dark md-24" translate translate-attr-title="messenger.CONTACTS">person</i>
             </md-nav-item>
         </md-nav-bar>
         <span flex></span>
-        <md-button aria-label="Search" class="md-icon-button" ng-click="ctrl.toggleSearch()">
+        <md-button aria-label="search" class="md-icon-button" ng-click="ctrl.toggleSearch()">
             <i class="material-icons md-dark md-24" translate translate-attr-title="messenger.SEARCH">search</i>
         </md-button>
     </div>
@@ -69,21 +69,23 @@
         <li ng-repeat="conversation in ctrl.conversations() | filter:ctrl.searchConversation"
             ng-init="dndModeSimplified = ctrl.dndModeSimplified(conversation)"
             ui-sref="messenger.home.conversation({ type: conversation.type, id: conversation.id, initParams: null })"
-            class="conversation-wrapper" ng-if="ctrl.isVisible(conversation)">
+            aria-label="conversation with {{ conversation.receiver.displayName }}"
+            class="conversation-wrapper"
+            ng-if="ctrl.isVisible(conversation)">
 
             <div class="conversation"
                   ng-class="{'unread': conversation.unreadCount > 0,
                             'starred': conversation.isStarred,
                             'active': ctrl.isActive(conversation)}">
 
-                <section class="avatar-box">
+                <section class="avatar-box" role="button">
                     <eee-avatar eee-receiver="conversation.receiver"
                                 eee-resolution="'low'"></eee-avatar>
                 </section>
 
                 <section class="conversation-box">
                     <section class="receiver-box">
-                        <span class="title" ng-class="{'disabled': conversation.receiver.disabled === true}" ng-bind-html="conversation.receiver.displayName | escapeHtml | emojify">
+                        <span class="title" ng-class="{'disabled': conversation.receiver.disabled === true}" ng-bind-html="conversation.receiver.displayName | escapeHtml | emojify" role="button">
                         </span>
                         <span class="notification-settings" ng-if="dndModeSimplified === 'on'">
                             <img height="16" width="16" src="img/ic_dnd_total_silence.svg" translate translate-attr-title="messenger.MUTED_NONE">

+ 3 - 1
src/partials/welcome.html

@@ -46,7 +46,9 @@
                                    translate-attr="{'placeholder': 'welcome.PASSWORD', 'aria-label': 'welcome.PASSWORD'}"
                                    autocomplete="current-password">
                         </md-input-container>
-                        <md-button type="submit" class="md-raised md-primary"><span translate>welcome.BTN_RECONNECT</span></md-button>
+                        <md-button type="submit" class="md-raised md-primary" translate translate-attr-aria-label="welcome.BTN_RECONNECT">
+                            <span translate aria-hidden="true">welcome.BTN_RECONNECT</span>
+                        </md-button>
                     </form>
                     <p>
                         <span translate>welcome.ALTERNATIVELY</span>