From 6c647deffce183bc37ac55e3b3ae35eb5922d428 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Wed, 18 Jun 2014 04:52:55 -0400
Subject: [PATCH] Option to disable cursor keyboard navigation on treelist widgets

---
 program/js/treelist.js |   28 +++++++++++++++++++++++++---
 1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/program/js/treelist.js b/program/js/treelist.js
index 958ae81..99d1dce 100644
--- a/program/js/treelist.js
+++ b/program/js/treelist.js
@@ -45,6 +45,7 @@
     scroll_step: 5,
     scroll_speed: 20,
     save_state: false,
+    keyboard: true,
     check_droptarget: function(node){ return !node.virtual }
   }, p || {});
 
@@ -735,11 +736,11 @@
       case 40:
       case 63232: // 'up', in safari keypress
       case 63233: // 'down', in safari keypress
-        var li = container.find(':focus').closest('li');
+        var li = p.keyboard ? container.find(':focus').closest('li') : [];
         if (li.length) {
           focus_next(li, (mod = keyCode == 38 || keyCode == 63232 ? -1 : 1));
         }
-        break;
+        return rcube_event.cancel(e);
 
       case 37: // Left arrow key
       case 39: // Right arrow key
@@ -747,10 +748,18 @@
         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
+        if (p.keyboard) {
+          // 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';
+          focus_noscroll(container.find('li[role=treeitem]:has(a)')[limit]().find('a:'+limit));
+        }
+        break;
     }
 
     return true;
@@ -782,6 +791,19 @@
     }
   }
 
+  /**
+   * Focus the given element without scrolling the list container
+   */
+  function focus_noscroll(elem)
+  {
+    if (elem.length) {
+      var frame = container.parent().get(0) || { scrollTop:0 },
+        y = frame.scrollTop || frame.scrollY;
+      elem.focus();
+      frame.scrollTop = y;
+    }
+  }
+
 
   ///// drag & drop support
 

--
Gitblit v1.9.1