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 | 72 +++++++++++++++++++++++++----------- 1 files changed, 50 insertions(+), 22 deletions(-) diff --git a/program/js/list.js b/program/js/list.js index 565d1b7..a83a8af 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -3,7 +3,7 @@ | RoundCube List Widget | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2006, RoundCube Dev, - Switzerland | + | Copyright (C) 2006-2008, RoundCube Dev, - Switzerland | | Licensed under the GNU GPL | | | +-----------------------------------------------------------------------+ @@ -32,9 +32,10 @@ this.rows = []; this.selection = []; + this.subject_col = -1; this.shiftkey = false; - this.multiselect = false; + this.multi_selecting = false; this.draggable = false; this.keyboard = false; this.toggleselect = false; @@ -85,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'}); + } } }, @@ -171,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); @@ -207,11 +210,12 @@ */ drag_row: function(e, id) { - this.in_selection_before = this.in_selection(id) ? id : false; - // don't do anything (another action processed before) - if (this.dont_select) + var evtarget = rcube_event.get_target(e); + if (this.dont_select || (evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG'))) return false; + + this.in_selection_before = this.in_selection(id) ? id : false; // selects currently unselected row if (!this.in_selection_before) @@ -239,7 +243,11 @@ { var now = new Date().getTime(); var mod_key = rcube_event.get_modifier(e); - + var evtarget = rcube_event.get_target(e); + + if ((evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG'))) + return false; + // don't do anything (another action processed before) if (this.dont_select) { @@ -314,6 +322,7 @@ { this.shift_start = id; this.highlight_row(id, false); + this.multi_selecting = false; } else { @@ -336,6 +345,7 @@ this.highlight_row(id, false); break; } + this.multi_selecting = true; } // trigger event if selection changed @@ -390,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; @@ -451,6 +464,8 @@ if (this.selection.join(',') != select_before) this.trigger_event('select'); + this.focus(); + return true; }, @@ -503,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; @@ -535,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; @@ -563,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) @@ -613,7 +632,7 @@ // get subjects of selectedd messages var names = ''; - var c, node, subject, obj; + var c, i, node, subject, obj; for(var n=0; n<this.selection.length; n++) { if (n>12) // only show 12 lines @@ -627,13 +646,20 @@ obj = this.rows[this.selection[n]].obj; subject = ''; - for(c=0; c<obj.childNodes.length; c++) - if (obj.childNodes[c].nodeName=='TD' && (node = obj.childNodes[c].firstChild) && (node.nodeType==3 || node.nodeName=='A')) + for(c=0, i=0; i<obj.childNodes.length; i++) + { + if (obj.childNodes[i].nodeName == 'TD') { - subject = node.nodeType==3 ? node.data : node.innerHTML; - names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />'; - break; + if (((node = obj.childNodes[i].firstChild) && (node.nodeType==3 || node.nodeName=='A')) && + (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c))) + { + subject = node.nodeType==3 ? node.data : node.innerHTML; + names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />'; + break; + } + c++; } + } } } @@ -672,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