From bf33799377eab662f8f25365cf15f57cf6697947 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Thu, 05 Jun 2014 10:44:35 -0400
Subject: [PATCH] Navigate with arrow keys only in treelist widgets; fix keyboard event detection in IE; new text label to help screen readers

---
 program/js/treelist.js                |    8 +++++++-
 program/js/common.js                  |    7 ++++---
 program/localization/en_US/labels.inc |    1 +
 program/js/app.js                     |    3 +++
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/program/js/app.js b/program/js/app.js
index 6d66aa2..ddc7b2f 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -1669,6 +1669,9 @@
     var target = e.target || {},
       keyCode = rcube_event.get_keycode(e);
 
+    // save global reference for keyboard detection on click events in IE
+    rcube_event._last_keyboard_event = e;
+
     if (e.keyCode != 27 && (!this.menu_keyboard_active || target.nodeName == 'TEXTAREA' || target.nodeName == 'SELECT')) {
       return true;
     }
diff --git a/program/js/common.js b/program/js/common.js
index 5ac4feb..f4446c2 100644
--- a/program/js/common.js
+++ b/program/js/common.js
@@ -31,7 +31,6 @@
 var SHIFT_KEY = 2;
 var CONTROL_SHIFT_KEY = 3;
 
-
 /**
  * Default browser check class
  * @constructor
@@ -287,8 +286,10 @@
 is_keyboard: function(e)
 {
   return e && (
-      (e.mozInputSource && e.mozInputSource == e.MOZ_SOURCE_KEYBOARD) ||
-      (!e.pageX && (e.pageY || 0) <= 0 && !e.clientX && (e.clientY || 0) <= 0)
+      (e.pointerType !== undefined && e.pointerType !== 'mouse') ||       // IE 11+
+      (e.mozInputSource && e.mozInputSource == e.MOZ_SOURCE_KEYBOARD) ||  // Firefox
+      (!e.pageX && (e.pageY || 0) <= 0 && !e.clientX && (e.clientY || 0) <= 0) ||  // others
+      (bw.ie && rcube_event._last_keyboard_event && rcube_event._last_keyboard_event.target == e.target)  // hack for IE <= 10
     );
 },
 
diff --git a/program/js/treelist.js b/program/js/treelist.js
index 958ae81..cce4d17 100644
--- a/program/js/treelist.js
+++ b/program/js/treelist.js
@@ -747,10 +747,16 @@
         if (li.length) {
           id = dom2id(li);
           node = indexbyid[id];
-          if (node && node.children.length)
+          if (node && node.children.length && node.collapsed != (keyCode == 37))
             toggle(id, rcube_event.get_modifier(e) == SHIFT_KEY);  // toggle subtree
         }
         return false;
+
+      case 9:  // Tab
+        // jump to last/first item to move focus away from the treelist widget by tab
+        var limit = rcube_event.get_modifier(e) == SHIFT_KEY ? 'first' : 'last';
+        container.find('li[role=treeitem]:has(a)')[limit]().find('a:'+limit).focus();
+        break;
     }
 
     return true;
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index e7d385f..5a1f2fc 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -586,6 +586,7 @@
 $labels['arialabeltopnav'] = 'Window control';
 $labels['arialabeltasknav'] = 'Application tasks';
 $labels['arialabeltoolbar'] = 'Application toolbar';
+$labels['arialabelactivetask'] = 'Active task';
 $labels['arialabelmessagessearchfilter'] = 'Email listing filter';
 $labels['arialabelmailsearchform'] = 'Email message search form';
 $labels['arialabelcontactsearchform'] = 'Contacts search form';

--
Gitblit v1.9.1