mirror of
https://github.com/NaitLee/Cat-Printer.git
synced 2025-05-16 15:20:12 -07:00
100 lines
3.5 KiB
JavaScript
100 lines
3.5 KiB
JavaScript
|
|
function isHidden(element) {
|
|
let parents = [element];
|
|
while (parents[0].parentElement)
|
|
parents.unshift(parents[0].parentElement);
|
|
return parents.some(e => {
|
|
let rect = e.getBoundingClientRect();
|
|
return (
|
|
e.classList.contains('hidden') ||
|
|
e.classList.contains('hard-hidden') ||
|
|
e.style.display == 'none' ||
|
|
rect.width == 0 || rect.height == 0 ||
|
|
rect.x < 0 || rect.y < 0 ||
|
|
e.style.visibility == 'none' ||
|
|
e.style.opacity == '0'
|
|
);
|
|
});
|
|
}
|
|
|
|
function toLocaleKey(key) {
|
|
const qwerty = '1234567890qwertyuiopasdfghjklzxcvbnm';
|
|
let keys, index;
|
|
if (
|
|
typeof i18n === 'undefined' ||
|
|
key.length !== 1 ||
|
|
(keys = i18n('KeyboardLayout')) === 'KeyboardLayout' ||
|
|
(index = qwerty.indexOf(key)) === -1
|
|
) return key;
|
|
return keys[index];
|
|
}
|
|
|
|
function initKeyboardShortcuts() {
|
|
const layer = document.getElementById('keyboard-shortcuts-layer');
|
|
const dialog = document.getElementById('dialog');
|
|
let key, keys = 'qwertyuiopasdfghjklzxcvbnm';
|
|
let focus, focusing = false, started = false;
|
|
let inputs, shortcuts = {};
|
|
const mark_keys = () => {
|
|
if (dialog.classList.contains('hidden'))
|
|
inputs = Array.from(document.querySelectorAll('*[data-key]'));
|
|
else inputs = Array.from(document.querySelectorAll('#dialog *[data-key]'));
|
|
/** @type {{ [key: string]: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement }} */
|
|
let key_index = 0;
|
|
shortcuts = {};
|
|
if (focusing) shortcuts = { ESC: focus };
|
|
else
|
|
for (let input of inputs) {
|
|
if (isHidden(input)) continue;
|
|
let key = toLocaleKey(input.getAttribute('data-key') || keys[key_index++]);
|
|
shortcuts[key] = input;
|
|
}
|
|
// Array.from(layer.children).forEach(e => e.remove());
|
|
for (let i = layer.children.length; i <= inputs.length; i++) {
|
|
let span = document.createElement('span');
|
|
layer.appendChild(span);
|
|
}
|
|
let index = 0;
|
|
for (let key in shortcuts) {
|
|
let span = layer.children[index++];
|
|
let input = shortcuts[key];
|
|
let position = input.getBoundingClientRect();
|
|
let text = key.toUpperCase().replace(' ', 'SPACE');
|
|
if (span.innerText !== text) span.innerText = text;
|
|
span.style.top = position.y + 'px';
|
|
span.style.left = position.x + 'px';
|
|
span.style.display = '';
|
|
}
|
|
for (let i = index; i < layer.children.length; i++) {
|
|
layer.children[i].style.display = 'none';
|
|
}
|
|
}
|
|
const start = () => setInterval(mark_keys, 1000);
|
|
const types_to_click = ['submit', 'file', 'checkbox', 'radio', 'A'];
|
|
document.body.addEventListener('keyup', (event) => {
|
|
key = event.key;
|
|
if (!started) {
|
|
if (key !== 'Tab') return;
|
|
mark_keys();
|
|
start();
|
|
started = true;
|
|
}
|
|
document.body.addEventListener('keyup', () =>
|
|
requestAnimationFrame(mark_keys)
|
|
, { once: true });
|
|
let input = shortcuts[key];
|
|
if (input) {
|
|
if (types_to_click.includes(input.type || input.tagName))
|
|
input.click();
|
|
else {
|
|
input.focus();
|
|
focusing = true;
|
|
}
|
|
focus = input;
|
|
} else if (key === 'Escape' && focus) {
|
|
focus.blur();
|
|
focusing = !focusing;
|
|
}
|
|
});
|
|
}
|