فهرست منبع

Allow triggering buttons in compose area with keyboard

Danilo Bargen 7 سال پیش
والد
کامیت
7236f6ff24
3فایلهای تغییر یافته به همراه41 افزوده شده و 7 حذف شده
  1. 23 6
      src/directives/compose_area.ts
  2. 17 0
      src/helpers.ts
  3. 1 1
      src/partials/messenger.conversation.html

+ 23 - 6
src/directives/compose_area.ts

@@ -15,6 +15,7 @@
  * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  */
 
+import {isActionTrigger} from '../helpers';
 import {BrowserService} from '../services/browser';
 import {StringService} from '../services/string';
 
@@ -528,7 +529,7 @@ export default [
                 }
 
                 // Emoji trigger is clicked
-                function onEmojiTrigger(ev: MouseEvent): void {
+                function onEmojiTrigger(ev: UIEvent): void {
                     ev.stopPropagation();
                     // Toggle visibility of picker
                     if (emojiKeyboard.hasClass('active')) {
@@ -622,14 +623,14 @@ export default [
                 }
 
                 // File trigger is clicked
-                function onFileTrigger(ev: MouseEvent): void {
+                function onFileTrigger(ev: UIEvent): void {
                     ev.preventDefault();
                     ev.stopPropagation();
                     const input = element[0].querySelector('.file-input') as HTMLInputElement;
                     input.click();
                 }
 
-                function onSendTrigger(ev: MouseEvent): boolean {
+                function onSendTrigger(ev: UIEvent): boolean {
                     ev.preventDefault();
                     ev.stopPropagation();
                     return sendText();
@@ -788,15 +789,30 @@ export default [
 
                 // Handle click on emoji trigger
                 emojiTrigger.on('click', onEmojiTrigger);
+                emojiTrigger.on('keypress', (ev: KeyboardEvent) => {
+                    if (isActionTrigger(ev)) {
+                        onEmojiTrigger(ev);
+                    }
+                });
 
                 // Handle click on file trigger
                 fileTrigger.on('click', onFileTrigger);
+                fileTrigger.on('keypress', (ev: KeyboardEvent) => {
+                    if (isActionTrigger(ev)) {
+                        onFileTrigger(ev);
+                    }
+                });
 
                 // Handle file uploads
                 fileInput.on('change', onFileSelected);
 
                 // Handle click on send trigger
                 sendTrigger.on('click', onSendTrigger);
+                sendTrigger.on('keypress', (ev: KeyboardEvent) => {
+                    if (isActionTrigger(ev)) {
+                        onSendTrigger(ev);
+                    }
+                });
 
                 updateView();
 
@@ -827,7 +843,7 @@ export default [
             template: `
                 <div>
                     <div>
-                        <i class="md-primary emoji-trigger trigger is-enabled material-icons" role="button" aria-label="emoji">tag_faces</i>
+                        <i class="md-primary emoji-trigger trigger is-enabled material-icons" role="button" aria-label="emoji" tabindex="0">tag_faces</i>
                     </div>
                     <div>
                         <div
@@ -837,11 +853,12 @@ export default [
                             translate
                             translate-attr-data-placeholder="messenger.COMPOSE_MESSAGE"
                             translate-attr-aria-label="messenger.COMPOSE_MESSAGE"
+                            tabindex="0"
                         ></div>
                     </div>
                     <div>
-                        <i class="md-primary send-trigger trigger material-icons" role="button" aria-label="send">send</i>
-                        <i class="md-primary file-trigger trigger is-enabled material-icons" role="button" aria-label="attach file">attach_file</i>
+                        <i class="md-primary send-trigger trigger material-icons" role="button" aria-label="send" tabindex="0">send</i>
+                        <i class="md-primary file-trigger trigger is-enabled material-icons" role="button" aria-label="attach file" tabindex="0">attach_file</i>
                         <input class="file-input" type="file" style="visibility: hidden" multiple>
                     </div>
                 </div>

+ 17 - 0
src/helpers.ts

@@ -338,3 +338,20 @@ export function hasValue(val: any): boolean {
 export function sleep(ms: number): Promise<void> {
     return new Promise((resolve) => setTimeout(resolve, ms));
 }
+
+/**
+ * Return whether this key event should trigger a button.
+ * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
+ */
+export function isActionTrigger(ev: KeyboardEvent): boolean {
+    if (ev.key === undefined) {
+        return false;
+    }
+    switch (ev.key) {
+        case 'Enter':
+        case ' ':
+            return true;
+        default:
+            return false;
+    }
+}

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

@@ -62,7 +62,7 @@
     </div>
 
     <div id="scrolljump" ng-click="ctrl.scrollDown()" ng-if="ctrl.showScrollJump && !ctrl.receiver.locked"
-         translate translate-attr-title="messenger.SCROLL_DOWN">
+         translate translate-attr-title="messenger.SCROLL_DOWN" role="button" aria-label="scroll to bottom" tabindex="0">
         <svg x="0" y="0" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" width="100" height="100" style="fill: rgb(66, 66, 66);"><g fill="none" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="sans-serif" font-weight="normal" font-size="12" text-anchor="start" mix-blend-mode="normal"><g><g><path d="M0,50l0,-50l50,0l0,50z" fill="none"/><path d="M25,46.5c-11.87412,0 -21.5,-9.62588 -21.5,-21.5l0,0c0,-11.87412 9.62588,-21.5 21.5,-21.5l0,0c11.87412,0 21.5,9.62588 21.5,21.5l0,0c0,11.87412 -9.62588,21.5 -21.5,21.5z" fill="#ffffff"/><g fill="#424242"><path d="M25,0.16c-13.69656,0 -24.84,11.14344 -24.84,24.84c0,13.69764 11.14344,24.84 24.84,24.84c13.69764,0 24.84,-11.14236 24.84,-24.84c0,-13.69656 -11.14236,-24.84 -24.84,-24.84z M36.56356,22.52356l-10.8,10.8c-0.2106,0.2106 -0.48708,0.31644 -0.76356,0.31644c-0.27648,0 -0.55296,-0.10584 -0.76356,-0.31644l-10.8,-10.8c-0.42228,-0.42228 -0.42228,-1.10484 0,-1.52712c0.42228,-0.42228 1.10484,-0.42228 1.52712,0l10.03644,10.03644l10.03644,-10.03644c0.42228,-0.42228 1.10484,-0.42228 1.52712,0c0.42228,0.42228 0.42228,1.10484 0,1.52712z"/></g></g></g></g></svg>
     </div>