Use Left/Right Arrow keys to faster move over threaded messages list (#6399)

Fixed some inconsistencies in list widget expand/collapse code.

Made the arrow keys behavior like in Thunderbird, i.e.:
- Right Arrow expands thread or selects closest child if already expanded,
- Left Arrow collapses thread or jumps to closest parent,
- Left Arrow + Ctrl selects top-most parent,
- Up/Down Arrow keys behavior didn't change.
pull/6894/head
Aleksander Machniak 5 years ago
parent dc5be05a5f
commit 9a225bd3fe

@ -14,6 +14,7 @@ CHANGELOG Roundcube Webmail
- Added 'keyservers' option to define list of HKP servers for Enigma/Mailvelope (#6326)
- Added flag to disable server certificate validation via Mysql DSN argument (#6848)
- Select all records on the current list page with CTRL + A (#6813)
- Use Left/Right Arrow keys to faster move over threaded messages list (#6399)
- Changes in `display_next` setting (#6795):
- Move it to Preferences > User Interface > Main Options
- Make it apply to Contacts interface too

@ -732,25 +732,13 @@ expand_row: function(e, id)
{
var row = this.rows[id],
evtarget = rcube_event.get_target(e),
mod_key = rcube_event.get_modifier(e);
mod_key = rcube_event.get_modifier(e),
action = (row.expanded ? 'collapse' : 'expand') + (mod_key == CONTROL_KEY || this.multiexpand ? '_all' : '');
// Don't treat double click on the expando as double click on the message.
row.clicked = 0;
if (row.expanded) {
evtarget.className = 'collapsed';
if (mod_key == CONTROL_KEY || this.multiexpand)
this.collapse_all(row);
else
this.collapse(row);
}
else {
evtarget.className = 'expanded';
if (mod_key == CONTROL_KEY || this.multiexpand)
this.expand_all(row);
else
this.expand(row);
}
this[action](row);
},
collapse: function(row)
@ -759,6 +747,7 @@ collapse: function(row)
new_row = row ? row.obj.nextSibling : null;
row.expanded = false;
this.update_expando(row.id);
this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded, obj:row.obj });
while (new_row) {
@ -814,6 +803,7 @@ expand: function(row)
last_expanded_parent_depth = p.depth;
$(new_row).css('display', '');
r.expanded = true;
this.update_expando(r.id, true);
this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded, obj:new_row });
}
}
@ -828,6 +818,7 @@ expand: function(row)
this.resize();
this.triggerEvent('listupdate');
return false;
},
@ -860,18 +851,21 @@ collapse_all: function(row)
if (row || r.depth)
$(new_row).css('display', 'none');
if (r.has_children && r.expanded) {
if (r.expanded) {
r.expanded = false;
this.update_expando(r.id, false);
if (r.has_children) {
this.update_expando(r.id);
this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded, obj:new_row });
}
}
}
}
new_row = new_row.nextSibling;
}
this.resize();
this.triggerEvent('listupdate');
return false;
},
@ -899,18 +893,21 @@ expand_all: function(row)
break;
$(new_row).css('display', '');
if (r.has_children && !r.expanded) {
if (!r.expanded) {
r.expanded = true;
if (r.has_children) {
this.update_expando(r.id, true);
this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded, obj:new_row });
}
}
}
}
new_row = new_row.nextSibling;
}
this.resize();
this.triggerEvent('listupdate');
return false;
},
@ -1429,29 +1426,20 @@ key_press: function(e)
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
case 37: // Left arrow
case 39: // Right arrow
case 40: // Up arrow
case 38: // Down arrow
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);
case 32:
case 32: // Space
rcube_event.cancel(e);
return this.select_row(this.last_selected, mod_key, true);
case 37: // Left arrow
case 39: // Right arrow
// Stop propagation
rcube_event.cancel(e);
var ret = this.use_arrow_key(keyCode, mod_key);
this.key_pressed = keyCode;
this.modkey = mod_key;
this.triggerEvent('keypress');
this.modkey = 0;
return ret;
case 36: // Home
this.select_first(mod_key);
return rcube_event.cancel(e);
@ -1506,43 +1494,39 @@ key_press: function(e)
*/
use_arrow_key: function(keyCode, mod_key)
{
var new_row,
selected_row = this.rows[this.last_selected];
var new_row, selected_row = this.rows[this.last_selected];
// Safari uses the nonstandard keycodes 63232/63233 for up/down, if we're
if (!selected_row) {
// select the first row if none selected yet
this.select_first(CONTROL_KEY);
}
// Safari uses the non-standard 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
else if (keyCode == 40 || keyCode == 63233) // Down arrow
new_row = this.get_next_row();
else if (keyCode == 38 || keyCode == 63232) // up arrow key pressed
else if (keyCode == 38 || keyCode == 63232) // Up arrow
new_row = this.get_prev_row();
else {
if (!selected_row || !selected_row.has_children)
return;
// expand
if (keyCode == 39) {
if (selected_row.expanded)
return;
if (mod_key == CONTROL_KEY || this.multiexpand)
else if (keyCode == 39 && selected_row.has_children) { // Right arrow
if (!selected_row.expanded)
this.expand_all(selected_row);
else
this.expand(selected_row);
}
// collapse
else {
if (!selected_row.expanded)
return;
if (mod_key == CONTROL_KEY || this.multiexpand)
// jump to the first child
new_row = this.get_next_row();
mod_key = null;
}
}
else if (keyCode == 37) { // Left arrow
if (selected_row.expanded && selected_row.has_children && (!selected_row.parent_uid || !this.multiexpand))
this.collapse_all(selected_row);
else if (selected_row.parent_uid) {
// jump to the top-most or closest parent
if (mod_key == CONTROL_KEY)
new_row = this.rows[this.find_root(selected_row.uid)];
else
this.collapse(selected_row);
}
new_row = this.rows[selected_row.parent_uid];
this.update_expando(selected_row.id, selected_row.expanded);
return false;
mod_key = null;
}
}
if (new_row) {
@ -1553,10 +1537,6 @@ use_arrow_key: function(keyCode, mod_key)
this.select_row(new_row.uid, mod_key, false);
this.scrollto(new_row.uid);
}
else if (!new_row && !selected_row) {
// select the first row if none selected yet
this.select_first(CONTROL_KEY);
}
return false;
},

Loading…
Cancel
Save