From 26f5b0935ef4d8bc01e2b8581f7d7ed3c4508fc2 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Fri, 22 Aug 2008 06:37:48 -0400
Subject: [PATCH] Fix keyboard control of the list widgets and prevent Safari from scrolling (#1485279)

---
 program/js/list.js |   31 +++++++++++++++++++++----------
 1 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/program/js/list.js b/program/js/list.js
index 02c872f..a83a8af 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -86,8 +86,10 @@
     this.frame = this.list.parentNode;
 
     // set body events
-    if (this.keyboard)
-      rcube_event.add_listener({element:document, event:'keydown', object:this, method:'key_press'});
+    if (this.keyboard) {
+      rcube_event.add_listener({element:document, event:'keyup', object:this, method:'key_press'});
+      rcube_event.add_listener({element:document, event:'keydown', object:rcube_event, method:'cancel'});
+    }
   }
 },
 
@@ -172,7 +174,7 @@
   for (var n=0; n<this.selection.length; n++)
   {
     id = this.selection[n];
-    if (this.rows[id].obj)
+    if (this.rows[id] && this.rows[id].obj)
     {
       this.set_classname(this.rows[id].obj, 'selected', true);
       this.set_classname(this.rows[id].obj, 'unfocused', false);
@@ -398,6 +400,9 @@
  */
 shift_select: function(id, control)
 {
+  if (!this.rows[this.shift_start] || !this.selection.length)
+    this.shift_start = id;
+
   var from_rowIndex = this.rows[this.shift_start].obj.rowIndex;
   var to_rowIndex = this.rows[id].obj.rowIndex;
 
@@ -513,7 +518,7 @@
 {
   if (this.rows[id] && !multiple)
   {
-    if (!this.in_selection(id))
+    if (this.selection.length > 1 || !this.in_selection(id))
     {
       this.clear_selection();
       this.selection[0] = id;
@@ -545,18 +550,20 @@
  */
 key_press: function(e)
 {
-  if (this.focused != true) 
+  if (this.focused != true)
     return true;
 
-  var keyCode = document.layers ? e.which : document.all ? event.keyCode : document.getElementById ? e.keyCode : 0;
+  var keyCode = rcube_event.get_keycode(e);
   var mod_key = rcube_event.get_modifier(e);
   switch (keyCode)
   {
     case 40:
     case 38: 
+    case 63233: // "down", in safari keypress
+    case 63232: // "up", in safari keypress
+      // Stop propagation so that the browser doesn't scroll
+      rcube_event.cancel(e);
       return this.use_arrow_key(keyCode, mod_key);
-      break;
-
     default:
       this.shiftkey = e.shiftKey;
       this.key_pressed = keyCode;
@@ -573,9 +580,11 @@
 use_arrow_key: function(keyCode, mod_key)
 {
   var new_row;
-  if (keyCode == 40) // down arrow key pressed
+  // Safari uses the nonstandard keycodes 63232/63233 for up/down, if we're
+  // using the keypress event (but not the keydown or keyup event).
+  if (keyCode == 40 || keyCode == 63233) // down arrow key pressed
     new_row = this.get_next_row();
-  else if (keyCode == 38) // up arrow key pressed
+  else if (keyCode == 38 || keyCode == 63232) // up arrow key pressed
     new_row = this.get_prev_row();
 
   if (new_row)
@@ -689,6 +698,8 @@
   rcube_event.remove_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
   rcube_event.remove_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
 
+  this.focus();
+  
   return rcube_event.cancel(e);
 },
 

--
Gitblit v1.9.1