handle keyboard in dropdowns

master
Vitaliy Filippov 2016-06-18 01:33:42 +03:00
parent 910e806e77
commit 506164791e
2 changed files with 52 additions and 3 deletions

View File

@ -210,7 +210,7 @@ div
position: relative;
}
.dropdown .item:hover
.dropdown .item.over
{
background: rgba(0, 0, 0, 0.08);
border-color: #b7b0ac #cec8c6 #e6e3e2 #cec8c6;
@ -227,7 +227,7 @@ div
opacity: 0.45;
}
.dropdown .item.disabled:hover
.dropdown .item.disabled.over
{
background: transparent;
border-color: transparent;
@ -880,6 +880,11 @@ div
border-bottom: 0;
}
.message-list .listview .day-list.collapsed
{
display: none;
}
.message-list .listview .day-list:last-child .message:last-child
{
border-bottom: 1px solid #dadce0;

View File

@ -685,7 +685,6 @@
<!--
// TODO: virtual scroll
// TODO: expand/collapse days, handle up/down (switch messages -> days -> messages -> scroll), pgup/pgdown, home/end keys
// TODO: keyboard navigation in dropdowns
// TODO: message multiselect in list (with ctrl, shift and keyboard)
// TODO: space=read
// TODO: quick reply
@ -846,12 +845,53 @@ function addAttachments()
}
e = document.querySelectorAll('.dropdown');
for (var i = 0; i < e.length; i++)
{
e[i].addEventListener('click', stopHidingDropdowns);
if (e[i].className.indexOf(' window') < 0)
{
e[i].addEventListener('keydown', dropdownKbNav);
e[i].addEventListener('mouseover', dropdownMouseNav);
}
}
document.body.addEventListener('click', hideAllDropdowns);
function stopHidingDropdowns(ev)
{
ev.stopPropagation();
}
function dropdownKbNav(ev)
{
if (ev.keyCode == 40 || ev.keyCode == 38)
{
var es = this.querySelectorAll('.item');
var cur = this._sel;
if (cur)
{
cur.className = cur.className.replace(/ over/, '');
for (var i = 0; i < es.length && cur != es[i]; i++) {}
cur = i;
}
else
cur = -1;
var a = ev.keyCode == 40 ? 1 : es.length-1;
cur = (cur+a) % es.length;
es[cur].className += ' over';
this._sel = es[cur];
}
else if ((ev.keyCode == 10 || ev.keyCode == 13) && this._sel)
this._sel.click();
}
function dropdownMouseNav(ev)
{
var el = ev.target||ev.srcElement;
while (el && !/(^|\s)item($|\s)/.exec(el.className))
el = el.parentNode;
if (!el || / over/.exec(el.className))
return;
if (this._sel)
this._sel.className = this._sel.className.replace(/ over/, '');
el.className += ' over';
this._sel = el;
}
function getOffset(elem)
{
if (elem.getBoundingClientRect)
@ -913,6 +953,10 @@ function addAttachments()
}
if (y + m.offsetHeight > wh)
m.style.left = (wh-m.offsetHeight)+'px';
m.focus();
if (m._sel)
m._sel.className = m._sel.className.replace(/ over/, '');
m._sel = null;
}
else
hideDropdown.apply(b);