use event.key, available since Chrome 51

This commit is contained in:
tophf 2020-10-13 10:42:36 +03:00
parent 130b011940
commit 1ebf2aa8a2
9 changed files with 75 additions and 106 deletions

View File

@ -408,7 +408,7 @@ function showHelp(title = '', body) {
!event ||
event.type === 'click' ||
(
event.which === 27 &&
event.key === 'Escape' &&
!event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey &&
!$('.CodeMirror-hints, #message-box') &&
(
@ -469,7 +469,7 @@ function showCodeMirrorPopup(title, html, options) {
popup.style.pointerEvents = 'auto';
const onKeyDown = event => {
if (event.which === 9 && !event.ctrlKey && !event.altKey && !event.metaKey) {
if (event.key === 'Tab' && !event.ctrlKey && !event.altKey && !event.metaKey) {
const search = $('#search-replace-dialog');
const area = search && search.contains(document.activeElement) ? search : popup;
moveFocus(area, event.shiftKey ? -1 : 1);

View File

@ -206,36 +206,32 @@ function createSection({
}
function handleKeydown(cm, event) {
const key = event.which;
if (key < 37 || key > 40 || event.shiftKey || event.altKey || event.metaKey) {
if (event.shiftKey || event.altKey || event.metaKey) {
return;
}
const {key} = event;
const {line, ch} = cm.getCursor();
switch (key) {
case 37:
// arrow Left
case 'ArrowLeft':
if (line || ch) {
return;
}
// fallthrough to arrow Up
case 38:
// arrow Up
// fallthrough
case 'ArrowUp':
cm = line === 0 && prevEditor(cm, false);
if (!cm) {
return;
}
event.preventDefault();
event.stopPropagation();
cm.setCursor(cm.doc.size - 1, key === 37 ? 1e20 : ch);
cm.setCursor(cm.doc.size - 1, key === 'ArrowLeft' ? 1e20 : ch);
break;
case 39:
// arrow Right
case 'ArrowRight':
if (line < cm.doc.size - 1 || ch < cm.getLine(line).length - 1) {
return;
}
// fallthrough to arrow Down
case 40:
// arrow Down
// fallthrough
case 'ArrowDown':
cm = line === cm.doc.size - 1 && nextEditor(cm, false);
if (!cm) {
return;
@ -245,13 +241,6 @@ function createSection({
cm.setCursor(0, 0);
break;
}
// FIXME: what is this?
// const animation = (cm.getSection().firstElementChild.getAnimations() || [])[0];
// if (animation) {
// animation.playbackRate = -1;
// animation.currentTime = 2000;
// animation.play();
// }
}
function showAppliesToHelp(event) {

View File

@ -20,6 +20,9 @@ for (const type of [NodeList, NamedNodeMap, HTMLCollection, HTMLAllCollection])
}
}
$.isTextLikeInput = el =>
el.localName === 'input' && /^(text|search|number)$/.test(el.type);
$.remove = (selector, base = document) => {
const el = selector && typeof selector === 'string' ? $(selector, base) : selector;
if (el) {
@ -354,10 +357,10 @@ function focusAccessibility() {
];
// try to find a focusable parent for this many parentElement jumps:
const GIVE_UP_DEPTH = 4;
const isOutlineAllowed = ({localName, type}) =>
!focusAccessibility.ELEMENTS.includes(localName) ||
// allow outline on text/search inputs in addition to textareas
localName === 'input' && /^(text|search|number)$/.test(type);
// allow outline on text/search inputs in addition to textareas
const isOutlineAllowed = el =>
!focusAccessibility.ELEMENTS.includes(el.localName) ||
$.isTextLikeInput(el);
addEventListener('mousedown', suppressOutlineOnClick, {passive: true});
addEventListener('keydown', keepOutlineOnTab, {passive: true});
@ -375,7 +378,7 @@ function focusAccessibility() {
}
function keepOutlineOnTab(event) {
if (event.which === 9) {
if (event.key === 'Tab') {
focusAccessibility.lastFocusedViaClick = false;
setTimeout(keepOutlineOnTab, 0, true);
return;

View File

@ -24,12 +24,12 @@ onDOMready().then(() => {
document.body.appendChild(input);
window.addEventListener('keydown', maybeRefocus, true);
function incrementalSearch({which}, immediately) {
function incrementalSearch({key}, immediately) {
if (!immediately) {
debounce(incrementalSearch, 100, {}, true);
return;
}
const direction = which === 38 ? -1 : which === 40 ? 1 : 0;
const direction = key === 'ArrowUp' ? -1 : key === 'ArrowDown' ? 1 : 0;
const text = input.value.toLocaleLowerCase();
if (!text.trim() || !direction && (text === prevText || focusedName.startsWith(text))) {
prevText = text;
@ -76,40 +76,31 @@ onDOMready().then(() => {
if (event.altKey || event.metaKey || $('#message-box')) {
return;
}
const inTextInput = event.target.matches('[type=text], [type=search], [type=number]');
const {which: k, key} = event;
// focus search field on "/" or Ctrl-F key
if (event.ctrlKey
? (event.code === 'KeyF' || !event.code && k === 70) && !event.shiftKey
: (key === '/' || !key && k === 191 && !event.shiftKey) && !inTextInput) {
const inTextInput = $.isTextLikeInput(event.target);
const {key, code, ctrlKey: ctrl} = event;
// `code` is independent of the current keyboard language
if ((code === 'KeyF' && ctrl && !event.shiftKey) ||
(code === 'Slash' || key === '/') && !ctrl && !inTextInput) {
// focus search field on "/" or Ctrl-F key
event.preventDefault();
$('#search').focus();
return;
}
if (event.ctrlKey || inTextInput) {
if (ctrl || inTextInput) {
return;
}
const time = performance.now();
if (
// 0-9
k >= 48 && k <= 57 ||
// a-z
k >= 65 && k <= 90 ||
// numpad keys
k >= 96 && k <= 111 ||
// marks
k >= 186
) {
if (key.length === 1) {
input.focus();
if (time - prevTime > 1000) {
input.value = '';
}
prevTime = time;
} else
if (k === 13 && focusedLink) {
if (key === 'Enter' && focusedLink) {
focusedLink.dispatchEvent(new MouseEvent('click', {bubbles: true}));
} else
if ((k === 38 || k === 40) && !event.shiftKey &&
if ((key === 'ArrowUp' || key === 'ArrowDown') && !event.shiftKey &&
time - prevTime < 5000 && incrementalSearch(event, true)) {
prevTime = time;
} else

View File

@ -62,28 +62,28 @@ function messageBox({
resolveWith({button: this.buttonIndex});
},
key(event) {
const {which, shiftKey, ctrlKey, altKey, metaKey, target} = event;
if (shiftKey && which !== 9 || ctrlKey || altKey || metaKey) {
const {key, shiftKey, ctrlKey, altKey, metaKey, target} = event;
if (shiftKey && key !== 'Tab' || ctrlKey || altKey || metaKey) {
return;
}
switch (which) {
case 13:
switch (key) {
case 'Enter':
if (target.closest(focusAccessibility.ELEMENTS.join(','))) {
return;
}
break;
case 27:
case 'Escape':
event.preventDefault();
event.stopPropagation();
break;
case 9:
case 'Tab':
moveFocus(messageBox.element, shiftKey ? -1 : 1);
event.preventDefault();
return;
default:
return;
}
resolveWith(which === 13 ? {enter: true} : {esc: true});
resolveWith(key === 'Enter' ? {enter: true} : {esc: true});
},
scroll() {
scrollTo(blockScroll.x, blockScroll.y);

View File

@ -298,7 +298,7 @@ function customizeHotkeys() {
}
window.onkeydown = event => {
if (event.keyCode === 27) {
if (event.key === 'Escape') {
top.dispatchEvent(new CustomEvent('closeOptions'));
}
};

View File

@ -37,40 +37,27 @@ const hotkeys = (() => {
return;
}
let entry;
const {which: k, key, code} = event;
let {key, code, shiftKey} = event;
if (code.startsWith('Digit') || code.startsWith('Numpad') && code.length === 7) {
if (key >= '0' && key <= '9') {
entry = entries[(Number(key) || 10) - 1];
} else if (code >= 'Digit0' && code <= 'Digit9') {
entry = entries[(Number(code.slice(-1)) || 10) - 1];
} else if (
code === 'Backquote' || code === 'NumpadMultiply' ||
key && (key === '`' || key === '*') ||
k === 192 || k === 106) {
} else if (key === '`' || key === '*' || code === 'Backquote' || code === 'NumpadMultiply') {
invertTogglables();
} else if (
code === 'NumpadSubtract' ||
key && key === '-' ||
k === 109) {
} else if (key === '-' || code === 'NumpadSubtract') {
toggleState(entries, 'enabled', false);
} else if (
code === 'NumpadAdd' ||
key && key === '+' ||
k === 107) {
} else if (key === '+' || code === 'NumpadAdd') {
toggleState(entries, 'disabled', true);
} else if (
// any single character
key && key.length === 1 ||
k >= 65 && k <= 90) {
const letter = new RegExp(key ? '^' + key : '^\\x' + k.toString(16), 'i');
entry = [...entries].find(entry => letter.test(entry.textContent));
} else if (key.length === 1) {
shiftKey = false; // typing ':' etc. needs Shift so we hide it here to avoid opening editor
key = key.toLocaleLowerCase();
entry = [...entries].find(e => e.innerText.toLocaleLowerCase().startsWith(key));
}
if (!entry) {
return;
}
const target = $(event.shiftKey ? '.style-edit-link' : '.checker', entry);
const target = $(shiftKey ? '.style-edit-link' : '.checker', entry);
target.dispatchEvent(new MouseEvent('click', {cancelable: true}));
}

View File

@ -507,16 +507,15 @@ Object.assign(handleEvent, {
window.onkeydown = event => {
const close = $('.menu-close', entry);
const checkbox = $('.exclude-by-domain-checkbox', entry);
const keyCode = event.keyCode || event.which;
if (document.activeElement === close && (keyCode === 9) && !event.shiftKey) {
if (document.activeElement === close && (event.key === 'Tab') && !event.shiftKey) {
event.preventDefault();
checkbox.focus();
}
if (document.activeElement === checkbox && (keyCode === 9) && event.shiftKey) {
if (document.activeElement === checkbox && (event.key === 'Tab') && event.shiftKey) {
event.preventDefault();
close.focus();
}
if (keyCode === 27) {
if (event.key === 'Escape') {
event.preventDefault();
close.click();
}
@ -542,20 +541,20 @@ Object.assign(handleEvent, {
const close = $('.menu-close', entry);
const checkbox = $('.exclude-by-domain-checkbox', entry);
const confirmActive = $('#confirm[data-display="true"]');
const keyCode = event.keyCode || event.which;
if (document.activeElement === cancel && (keyCode === 9)) {
const {key} = event;
if (document.activeElement === cancel && (key === 'Tab')) {
event.preventDefault();
affirm.focus();
}
if (document.activeElement === close && (keyCode === 9) && !event.shiftKey) {
if (document.activeElement === close && (key === 'Tab') && !event.shiftKey) {
event.preventDefault();
checkbox.focus();
}
if (document.activeElement === checkbox && (keyCode === 9) && event.shiftKey) {
if (document.activeElement === checkbox && (key === 'Tab') && event.shiftKey) {
event.preventDefault();
close.focus();
}
if (keyCode === 27) {
if (key === 'Escape') {
event.preventDefault();
if (confirmActive) {
box.dataset.display = false;

View File

@ -355,29 +355,29 @@
}
function setFromKeyboard(event) {
const {which, ctrlKey: ctrl, altKey: alt, shiftKey: shift, metaKey: meta} = event;
switch (which) {
case 9: // Tab
case 33: // PgUp
case 34: // PgDn
const {key, ctrlKey: ctrl, altKey: alt, shiftKey: shift, metaKey: meta} = event;
switch (key) {
case 'Tab':
case 'PageUp':
case 'PageDown':
if (!ctrl && !alt && !meta) {
const el = document.activeElement;
const inputs = $inputs[currentFormat];
const lastInput = inputs[inputs.length - 1];
if (which === 9 && shift && el === inputs[0]) {
if (key === 'Tab' && shift && el === inputs[0]) {
maybeFocus(lastInput);
} else if (which === 9 && !shift && el === lastInput) {
} else if (key === 'Tab' && !shift && el === lastInput) {
maybeFocus(inputs[0]);
} else if (which !== 9 && !shift) {
setFromFormatElement({shift: which === 33 || shift});
} else if (key !== 'Tab' && !shift) {
setFromFormatElement({shift: key === 'PageUp' || shift});
} else {
return;
}
event.preventDefault();
}
return;
case 38: // Up
case 40: // Down
case 'ArrowUp':
case 'ArrowDown':
if (!event.metaKey &&
document.activeElement.localName === 'input' &&
document.activeElement.checkValidity()) {
@ -389,8 +389,8 @@
function setFromKeyboardIncrement(event) {
const el = document.activeElement;
const {which, ctrlKey: ctrl, altKey: alt, shiftKey: shift} = event;
const dir = which === 38 ? 1 : -1;
const {key, ctrlKey: ctrl, altKey: alt, shiftKey: shift} = event;
const dir = key === 'ArrowUp' ? 1 : -1;
let value, newValue;
if (currentFormat === 'hex') {
value = el.value.trim();
@ -617,9 +617,9 @@
function onKeyDown(e) {
if (!e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
switch (e.which) {
case 13:
case 27:
switch (e.key) {
case 'Enter':
case 'Escape':
e.preventDefault();
e.stopPropagation();
hide();