From 9240c96339b26989f060c57c61a2677e2f1e502e Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Wed, 18 Jun 2014 08:35:48 -0400
Subject: [PATCH] Improve accessibility on attachments list: use custom tabindex attribute + add aria-label for meaningful voice output on delete icons

---
 program/js/app.js |   74 ++++++++++++++++++++-----------------
 1 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/program/js/app.js b/program/js/app.js
index 499e2a2..b4a2250 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -1677,7 +1677,7 @@
       case 63232: // "up", in safari keypress
       case 63233: // "down", in safari keypress
         focus_menu_item(keyCode == 38 || keyCode == 63232 ? -1 : 1);
-        break;
+        return rcube_event.cancel(e);
 
       case 9:   // tab
         if (this.focused_menu) {
@@ -3553,26 +3553,32 @@
         myprompt = $('<div class="prompt">').html('<div class="message">' + this.get_label('nosubjectwarning') + '</div>')
           .appendTo(document.body),
         prompt_value = $('<input>').attr({type: 'text', size: 30}).val(this.get_label('nosubject'))
-          .appendTo(myprompt);
+          .appendTo(myprompt),
+        save_func = function() {
+          input_subject.val(prompt_value.val());
+          myprompt.dialog('close');
+          ref.command(cmd, { nocheck:true });  // repeat command which triggered this
+        };
 
-      buttons[this.get_label('cancel')] = function(){
+      buttons[this.get_label('sendmessage')] = function() {
+        save_func($(this));
+      };
+      buttons[this.get_label('cancel')] = function() {
         input_subject.focus();
         $(this).dialog('close');
-      };
-      buttons[this.get_label('sendmessage')] = function(){
-        input_subject.val(prompt_value.val());
-        $(this).dialog('close');
-        ref.command(cmd, { nocheck:true });  // repeat command which triggered this
       };
 
       myprompt.dialog({
         modal: true,
         resizable: false,
         buttons: buttons,
-        close: function(event, ui) { $(this).remove() }
+        close: function(event, ui) { $(this).remove(); }
       });
 
-      prompt_value.select();
+      prompt_value.select().keydown(function(e) {
+        if (e.which == 13) save_func();
+      });
+
       return false;
     }
 
@@ -3650,7 +3656,7 @@
       $(this).dialog('close');
     };
 
-    this.show_popup_dialog(html, this.gettext('savenewresponse'), buttons);
+    this.show_popup_dialog(html, this.gettext('newresponse'), buttons);
 
     $('#ffresponsetext').val(text);
     $('#ffresponsename').select();
@@ -4064,7 +4070,7 @@
 
     if (!att.complete && att.frame)
       att.html = '<a title="'+this.get_label('cancel')+'" onclick="return rcmail.cancel_attachment_upload(\''+name+'\', \''+att.frame+'\');" href="#cancelupload" class="cancelupload">'
-        + (this.env.cancelicon ? '<img src="'+this.env.cancelicon+'" alt="" />' : this.get_label('cancel')) + '</a>' + att.html;
+        + (this.env.cancelicon ? '<img src="'+this.env.cancelicon+'" alt="'+this.get_label('cancel')+'" />' : this.get_label('cancel')) + '</a>' + att.html;
 
     var indicator, li = $('<li>');
 
@@ -4080,6 +4086,10 @@
     else { // add new li
       li.appendTo(this.gui_objects.attachmentlist);
     }
+
+    // set tabindex attribute
+    var tabindex = $(this.gui_objects.attachmentlist).attr('data-tabindex') || '0';
+    li.find('a').attr('tabindex', tabindex);
 
     if (upload_id && this.env.attachments[upload_id])
       delete this.env.attachments[upload_id];
@@ -4280,21 +4290,22 @@
     this.display_message(msg, type);
 
     if (this.env.extwin) {
-      var rc = this.opener();
       this.lock_form(this.gui_objects.messageform);
+
+      var rc = this.opener();
       if (rc) {
         rc.display_message(msg, type);
         // refresh the folder where sent message was saved or replied message comes from
         if (folders && rc.env.task == 'mail' && rc.env.action == '' && $.inArray(rc.env.mailbox, folders) >= 0) {
-          // @TODO: try with 'checkmail' here when #1485186 is fixed. See also #1489249.
-          rc.command('list');
+          rc.command('checkmail');
         }
       }
-      setTimeout(function(){ window.close() }, 1000);
+
+      setTimeout(function() { window.close(); }, 1000);
     }
     else {
       // before redirect we need to wait some time for Chrome (#1486177)
-      setTimeout(function(){ ref.list_mailbox(); }, 500);
+      setTimeout(function() { ref.list_mailbox(); }, 500);
     }
   };
 
@@ -7497,8 +7508,10 @@
   // post the given form to a hidden iframe
   this.async_upload_form = function(form, action, onload)
   {
-    var frame, ts = new Date().getTime(),
-      frame_name = 'rcmupload'+ts;
+    // create hidden iframe
+    var ts = new Date().getTime(),
+      frame_name = 'rcmupload' + ts,
+      frame = this.async_upload_form_frame(frame_name);
 
     // upload progress support
     if (this.env.upload_progress_name) {
@@ -7513,21 +7526,7 @@
       field.val(ts);
     }
 
-    // have to do it this way for IE
-    // otherwise the form will be posted to a new window
-    if (document.all) {
-      document.body.insertAdjacentHTML('BeforeEnd', '<iframe name="'+frame_name+'"'
-        + ' src="program/resources/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>');
-      frame = $('iframe[name="'+frame_name+'"]');
-    }
-    // for standards-compliant browsers
-    else {
-      frame = $('<iframe>').attr('name', frame_name)
-        .css({border: 'none', width: 0, height: 0, visibility: 'hidden'})
-        .appendTo(document.body);
-    }
-
-    // handle upload errors, parsing iframe content in onload
+    // handle upload errors by parsing iframe content in onload
     frame.bind('load', {ts:ts}, onload);
 
     $(form).attr({
@@ -7540,6 +7539,13 @@
     return frame_name;
   };
 
+  // create iframe element for files upload
+  this.async_upload_form_frame = function(name)
+  {
+    return $('<iframe>').attr({name: name, style: 'border: none; width: 0; height: 0; visibility: hidden'})
+      .appendTo(document.body);
+  };
+
   // html5 file-drop API
   this.document_drag_hover = function(e, over)
   {

--
Gitblit v1.9.1