2016-08-09 20:04:40 +00:00
|
|
|
/* global APP, $, JitsiMeetJS */
|
2016-06-20 21:13:17 +00:00
|
|
|
|
2016-11-01 21:48:29 +00:00
|
|
|
/**
|
|
|
|
* The reference to the shortcut dialogs when opened.
|
|
|
|
*/
|
|
|
|
let keyboardShortcutDialog = null;
|
|
|
|
|
2016-08-29 03:59:09 +00:00
|
|
|
/**
|
|
|
|
* Initialise global shortcuts.
|
|
|
|
* Global shortcuts are shortcuts for features that don't have a button or
|
|
|
|
* link associated with the action. In other words they represent actions
|
|
|
|
* triggered _only_ with a shortcut.
|
|
|
|
*/
|
|
|
|
function initGlobalShortcuts() {
|
|
|
|
|
|
|
|
KeyboardShortcut.registerShortcut("ESCAPE", null, function() {
|
2016-11-01 21:48:29 +00:00
|
|
|
showKeyboardShortcutsPanel(false);
|
2016-08-29 03:59:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
KeyboardShortcut.registerShortcut("?", null, function() {
|
|
|
|
JitsiMeetJS.analytics.sendEvent("shortcut.shortcut.help");
|
2016-11-01 21:48:29 +00:00
|
|
|
showKeyboardShortcutsPanel(true);
|
2016-08-29 03:59:09 +00:00
|
|
|
}, "keyboardShortcuts.toggleShortcuts");
|
|
|
|
|
2016-09-29 13:07:21 +00:00
|
|
|
// register SPACE shortcut in two steps to insure visibility of help message
|
|
|
|
KeyboardShortcut.registerShortcut(" ", null, function() {
|
2016-08-29 03:59:09 +00:00
|
|
|
JitsiMeetJS.analytics.sendEvent("shortcut.talk.clicked");
|
|
|
|
APP.conference.muteAudio(true);
|
2016-09-29 13:07:21 +00:00
|
|
|
});
|
|
|
|
KeyboardShortcut._addShortcutToHelp("SPACE","keyboardShortcuts.pushToTalk");
|
2016-08-29 03:59:09 +00:00
|
|
|
|
2016-08-29 20:47:24 +00:00
|
|
|
/**
|
|
|
|
* FIXME: Currently focus keys are directly implemented below in onkeyup.
|
|
|
|
* They should be moved to the SmallVideo instead.
|
|
|
|
*/
|
2016-08-29 03:59:09 +00:00
|
|
|
KeyboardShortcut._addShortcutToHelp("0", "keyboardShortcuts.focusLocal");
|
|
|
|
KeyboardShortcut._addShortcutToHelp("1-9", "keyboardShortcuts.focusRemote");
|
2015-07-02 21:33:06 +00:00
|
|
|
}
|
2015-01-22 16:26:05 +00:00
|
|
|
|
2016-11-01 21:48:29 +00:00
|
|
|
/**
|
|
|
|
* Shows or hides the keyboard shortcuts dialog.
|
|
|
|
* @param {boolean} show whether to show or hide the dialog
|
|
|
|
*/
|
|
|
|
function showKeyboardShortcutsPanel(show) {
|
|
|
|
if (show
|
|
|
|
&& !APP.UI.messageHandler.isDialogOpened()
|
|
|
|
&& keyboardShortcutDialog === null) {
|
|
|
|
|
|
|
|
let msg = $('#keyboard-shortcuts').html();
|
|
|
|
let buttons = { Close: true };
|
|
|
|
|
|
|
|
keyboardShortcutDialog = APP.UI.messageHandler.openDialog(
|
|
|
|
'keyboardShortcuts.keyboardShortcuts', msg, true, buttons);
|
|
|
|
} else {
|
|
|
|
if (keyboardShortcutDialog !== null) {
|
|
|
|
keyboardShortcutDialog.close();
|
|
|
|
keyboardShortcutDialog = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 03:59:09 +00:00
|
|
|
/**
|
|
|
|
* Map of shortcuts. When a shortcut is registered it enters the mapping.
|
|
|
|
* @type {{}}
|
|
|
|
*/
|
|
|
|
let _shortcuts = {};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Maps keycode to character, id of popover for given function and function.
|
|
|
|
*/
|
2015-01-22 16:26:05 +00:00
|
|
|
var KeyboardShortcut = {
|
|
|
|
init: function () {
|
2016-08-29 03:59:09 +00:00
|
|
|
initGlobalShortcuts();
|
|
|
|
|
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>
2016-07-13 12:22:57 +00:00
|
|
|
var self = this;
|
2015-01-22 16:26:05 +00:00
|
|
|
window.onkeyup = function(e) {
|
2016-08-29 03:59:09 +00:00
|
|
|
var key = self._getKeyboardKey(e).toUpperCase();
|
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>
2016-07-13 12:22:57 +00:00
|
|
|
var num = parseInt(key, 10);
|
2015-01-22 16:26:05 +00:00
|
|
|
if(!($(":focus").is("input[type=text]") ||
|
|
|
|
$(":focus").is("input[type=password]") ||
|
|
|
|
$(":focus").is("textarea"))) {
|
2016-08-29 03:59:09 +00:00
|
|
|
if (_shortcuts.hasOwnProperty(key)) {
|
|
|
|
_shortcuts[key].function(e);
|
2015-01-22 16:26:05 +00:00
|
|
|
}
|
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>
2016-07-13 12:22:57 +00:00
|
|
|
else if (!isNaN(num) && num >= 0 && num <= 9) {
|
|
|
|
APP.UI.clickOnVideo(num + 1);
|
2015-01-22 16:26:05 +00:00
|
|
|
}
|
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>
2016-07-13 12:22:57 +00:00
|
|
|
//esc while the smileys are visible hides them
|
|
|
|
} else if (key === "ESCAPE" &&
|
2015-09-11 02:42:15 +00:00
|
|
|
$('#smileysContainer').is(':visible')) {
|
2015-01-28 14:35:22 +00:00
|
|
|
APP.UI.toggleSmileys();
|
2015-01-22 16:26:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
window.onkeydown = function(e) {
|
|
|
|
if(!($(":focus").is("input[type=text]") ||
|
|
|
|
$(":focus").is("input[type=password]") ||
|
|
|
|
$(":focus").is("textarea"))) {
|
2016-08-29 03:59:09 +00:00
|
|
|
var key = self._getKeyboardKey(e).toUpperCase();
|
2016-09-29 13:07:21 +00:00
|
|
|
if(key === " ") {
|
2016-02-09 16:29:50 +00:00
|
|
|
if(APP.conference.isLocalAudioMuted())
|
|
|
|
APP.conference.muteAudio(false);
|
2015-01-22 16:26:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
2016-08-29 03:59:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Registers a new shortcut.
|
|
|
|
*
|
|
|
|
* @param shortcutChar the shortcut character triggering the action
|
|
|
|
* @param shortcutAttr the "shortcut" html element attribute mappring an
|
|
|
|
* element to this shortcut and used to show the shortcut character on the
|
|
|
|
* element tooltip
|
|
|
|
* @param exec the function to be executed when the shortcut is pressed
|
|
|
|
* @param helpDescription the description of the shortcut that would appear
|
|
|
|
* in the help menu
|
|
|
|
*/
|
|
|
|
registerShortcut: function( shortcutChar,
|
|
|
|
shortcutAttr,
|
|
|
|
exec,
|
|
|
|
helpDescription) {
|
|
|
|
_shortcuts[shortcutChar] = {
|
|
|
|
character: shortcutChar,
|
|
|
|
shortcutAttr: shortcutAttr,
|
|
|
|
function: exec
|
|
|
|
};
|
|
|
|
|
|
|
|
if (helpDescription)
|
|
|
|
this._addShortcutToHelp(shortcutChar, helpDescription);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unregisters a shortcut.
|
|
|
|
*
|
|
|
|
* @param shortcutChar unregisters the given shortcut, which means it will
|
|
|
|
* no longer be usable
|
|
|
|
*/
|
|
|
|
unregisterShortcut: function(shortcutChar) {
|
|
|
|
_shortcuts.remove(shortcutChar);
|
2016-08-29 20:47:24 +00:00
|
|
|
|
|
|
|
this._removeShortcutFromHelp(shortcutChar);
|
2016-08-29 03:59:09 +00:00
|
|
|
},
|
|
|
|
|
2015-01-22 16:26:05 +00:00
|
|
|
/**
|
2016-08-30 19:14:52 +00:00
|
|
|
* Returns the tooltip string for the given shortcut attribute.
|
2015-01-22 16:26:05 +00:00
|
|
|
*
|
2016-08-30 19:14:52 +00:00
|
|
|
* @param shortcutAttr indicates the popover associated with the shortcut
|
|
|
|
* @returns {string} the tooltip string to add to the given shortcut popover
|
|
|
|
* or an empty string if the shortcutAttr is null, an empty string or not
|
|
|
|
* found in the shortcut mapping
|
2015-01-22 16:26:05 +00:00
|
|
|
*/
|
2016-09-16 03:22:56 +00:00
|
|
|
getShortcutTooltip: function (shortcutAttr) {
|
2016-08-30 19:14:52 +00:00
|
|
|
if (typeof shortcutAttr === "string" && shortcutAttr.length > 0) {
|
|
|
|
for (var key in _shortcuts) {
|
|
|
|
if (_shortcuts.hasOwnProperty(key)
|
|
|
|
&& _shortcuts[key].shortcutAttr
|
|
|
|
&& _shortcuts[key].shortcutAttr === shortcutAttr) {
|
2016-08-29 03:59:09 +00:00
|
|
|
return " (" + _shortcuts[key].character + ")";
|
2015-01-22 16:26:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-08-30 19:14:52 +00:00
|
|
|
|
2015-01-22 16:26:05 +00:00
|
|
|
return "";
|
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>
2016-07-13 12:22:57 +00:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* @param e a KeyboardEvent
|
|
|
|
* @returns {string} e.key or something close if not supported
|
|
|
|
*/
|
2016-08-29 03:59:09 +00:00
|
|
|
_getKeyboardKey: function (e) {
|
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>
2016-07-13 12:22:57 +00:00
|
|
|
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();
|
|
|
|
}
|
2016-08-29 03:59:09 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds the given shortcut to the help dialog.
|
|
|
|
*
|
|
|
|
* @param shortcutChar the shortcut character
|
|
|
|
* @param shortcutDescriptionKey the description of the shortcut
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_addShortcutToHelp: function (shortcutChar, shortcutDescriptionKey) {
|
|
|
|
|
2016-10-12 00:08:24 +00:00
|
|
|
let listElement = document.createElement("li");
|
|
|
|
let itemClass = 'shortcuts-list__item';
|
|
|
|
listElement.className = itemClass;
|
2016-08-29 20:47:24 +00:00
|
|
|
listElement.id = shortcutChar;
|
2016-08-29 03:59:09 +00:00
|
|
|
|
2016-10-12 00:08:24 +00:00
|
|
|
let spanElement = document.createElement("span");
|
2016-08-29 03:59:09 +00:00
|
|
|
spanElement.className = "item-action";
|
|
|
|
|
2016-10-12 00:08:24 +00:00
|
|
|
let kbdElement = document.createElement("kbd");
|
|
|
|
let classes = 'aui-label regular-key';
|
|
|
|
kbdElement.className = classes;
|
2016-08-29 03:59:09 +00:00
|
|
|
kbdElement.innerHTML = shortcutChar;
|
|
|
|
spanElement.appendChild(kbdElement);
|
|
|
|
|
2016-10-12 00:08:24 +00:00
|
|
|
let descriptionElement = document.createElement("span");
|
|
|
|
let descriptionClass = "shortcuts-list__description";
|
|
|
|
descriptionElement.className = descriptionClass;
|
2016-08-29 03:59:09 +00:00
|
|
|
descriptionElement.setAttribute("data-i18n", shortcutDescriptionKey);
|
2016-10-21 17:11:22 +00:00
|
|
|
APP.translation.translateElement($(descriptionElement));
|
2016-08-29 03:59:09 +00:00
|
|
|
|
|
|
|
listElement.appendChild(spanElement);
|
|
|
|
listElement.appendChild(descriptionElement);
|
|
|
|
|
2016-10-12 00:08:24 +00:00
|
|
|
let parentListElement
|
2016-08-29 03:59:09 +00:00
|
|
|
= document.getElementById("keyboard-shortcuts-list");
|
|
|
|
|
|
|
|
if (parentListElement)
|
|
|
|
parentListElement.appendChild(listElement);
|
2016-08-29 20:47:24 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes the list element corresponding to the given shortcut from the
|
|
|
|
* help dialog
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_removeShortcutFromHelp: function (shortcutChar) {
|
|
|
|
var parentListElement
|
|
|
|
= document.getElementById("keyboard-shortcuts-list");
|
|
|
|
|
|
|
|
var shortcutElement = document.getElementById(shortcutChar);
|
|
|
|
|
|
|
|
if (shortcutElement)
|
|
|
|
parentListElement.removeChild(shortcutElement);
|
2015-01-22 16:26:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = KeyboardShortcut;
|