Improve keyboard shortcut handling

Use KeyboardEvent.key if available,
match both lower and upper case letters to keep previous behaviour

KeyboardEvent is a mess.

KeyboardEvent.which gives you, in theory, a decimal representation of the key pressed.
"r" or "R" gives you 82, which is "R", you can look at KeyboardEvent.shiftKey,
but you don't have access to capslock...

Maybe you want to use numbers, but of course NumPad will not give you the same than
"normal" numbers ...

Now if you use something else than letter, for exemple "?",
on a QWERTY keyboard "/" and "?" gives you 191,
on a AZERTY keyboard "," and "?" gives you 188, so we have to stick to letters.

This was for keydown and keyup events, keypressed event return the real char
(lower "a", "/", "?", ...) but it fails in some cases

The only non broken property is KeyboardEvent.key,
but it's only supported since Chrome 51, Opera 38, and not supported by Safari
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

A good reference & test:
http://unixpapa.com/js/testkey.html
http://unixpapa.com/js/key.html

Signed-off-by: Etienne CHAMPETIER <champetier.etienne@gmail.com>
This commit is contained in:
Etienne CHAMPETIER 2016-07-13 14:22:57 +02:00
parent 5b884806d2
commit 9a4cee1818
1 changed files with 52 additions and 28 deletions

View File

@ -3,67 +3,64 @@
var shortcuts = {};
function initShortcutHandlers() {
shortcuts = {
27: {
"ESCAPE": {
character: "Esc",
function: function() {
APP.UI.showKeyboardShortcutsPanel(false);
}
},
67: {
"C": {
character: "C",
id: "toggleChatPopover",
function: function() {
APP.UI.toggleChat();
}
},
68: {
"D": {
character: "D",
id: "toggleDesktopSharingPopover",
function: function () {
APP.conference.toggleScreenSharing();
}
},
70: {
"F": {
character: "F",
id: "filmstripPopover",
function: function() {
APP.UI.toggleFilmStrip();
}
},
77: {
"M": {
character: "M",
id: "mutePopover",
function: function() {
APP.conference.toggleAudioMuted();
}
},
82: {
"R": {
character: "R",
function: function() {
APP.conference.maybeToggleRaisedHand();
}
},
84: {
"T": {
character: "T",
function: function() {
APP.conference.muteAudio(true);
}
},
86: {
"V": {
character: "V",
id: "toggleVideoPopover",
function: function() {
APP.conference.toggleVideoMuted();
}
},
191: {
character: "/",
"?": {
character: "?",
function: function(e) {
// Only trigger on "?", not on "/".
if (e.shiftKey) {
APP.UI.toggleKeyboardShortcutsPanel();
}
APP.UI.toggleKeyboardShortcutsPanel();
}
}
};
@ -72,20 +69,21 @@ function initShortcutHandlers() {
var KeyboardShortcut = {
init: function () {
initShortcutHandlers();
var self = this;
window.onkeyup = function(e) {
var keycode = e.which;
var key = self.getKeyboardKey(e).toUpperCase();
var num = parseInt(key, 10);
if(!($(":focus").is("input[type=text]") ||
$(":focus").is("input[type=password]") ||
$(":focus").is("textarea"))) {
if (typeof shortcuts[keycode] === "object") {
shortcuts[keycode].function(e);
if (shortcuts.hasOwnProperty(key)) {
shortcuts[key].function(e);
}
else if (keycode >= "0".charCodeAt(0) &&
keycode <= "9".charCodeAt(0)) {
APP.UI.clickOnVideo(keycode - "0".charCodeAt(0) + 1);
else if (!isNaN(num) && num >= 0 && num <= 9) {
APP.UI.clickOnVideo(num + 1);
}
//esc while the smileys are visible hides them
} else if (keycode === 27 &&
//esc while the smileys are visible hides them
} else if (key === "ESCAPE" &&
$('#smileysContainer').is(':visible')) {
APP.UI.toggleSmileys();
}
@ -95,13 +93,13 @@ var KeyboardShortcut = {
if(!($(":focus").is("input[type=text]") ||
$(":focus").is("input[type=password]") ||
$(":focus").is("textarea"))) {
if(e.which === "T".charCodeAt(0)) {
var key = self.getKeyboardKey(e).toUpperCase();
if(key === "T") {
if(APP.conference.isLocalAudioMuted())
APP.conference.muteAudio(false);
}
}
};
var self = this;
$('body').popover({ selector: '[data-toggle=popover]',
trigger: 'click hover',
content: function() {
@ -116,14 +114,40 @@ var KeyboardShortcut = {
* @returns {string} the keyboard shortcut used for the id given
*/
getShortcut: function (id) {
for (var keycode in shortcuts) {
if (shortcuts.hasOwnProperty(keycode)) {
if (shortcuts[keycode].id === id) {
return " (" + shortcuts[keycode].character + ")";
for (var key in shortcuts) {
if (shortcuts.hasOwnProperty(key)) {
if (shortcuts[key].id === id) {
return " (" + shortcuts[key].character + ")";
}
}
}
return "";
},
/**
* @param e a KeyboardEvent
* @returns {string} e.key or something close if not supported
*/
getKeyboardKey: function (e) {
if (typeof e.key === "string") {
return e.key;
}
if (e.type === "keypress" && (
(e.which >= 32 && e.which <= 126) ||
(e.which >= 160 && e.which <= 255) )) {
return String.fromCharCode(e.which);
}
// try to fallback (0-9A-Za-z and QWERTY keyboard)
switch (e.which) {
case 27:
return "Escape";
case 191:
return e.shiftKey ? "?" : "/";
}
if (e.shiftKey || e.type === "keypress") {
return String.fromCharCode(e.which);
} else {
return String.fromCharCode(e.which).toLowerCase();
}
}
};