async function keyDownHandler(e) { function isDialogChild(e) { while(e = e.parentElement) if(e.tagName == 'DIV' && e.classList.contains('dialog')) return true; return false; } var tag = document.activeElement.tagName; if((tag == 'INPUT' || (tag == 'TEXTAREA' && e.ctrlKey)) && e.key == 'Enter') { var element = document.activeElement; while(element = element.parentElement) { if(element.tagName == 'FORM') { element .querySelectorAll('input,textarea') .forEach(e => e.dispatchEvent(new Event('change'))); element.requestSubmit(); e.preventDefault(); return; } } } if((tag == 'INPUT' || tag == 'TEXTAREA') && e.key != 'Escape') return; var element = Array.from(document.querySelectorAll('div.dialog')) .filter(e => e.style.visibility == 'visible') .map(e => ({ element: e, zIndex: parseInt(e.style.zIndex) })) .sort((a, b) => b.zIndex - a.zIndex) .map(e => e.element)[0]; if(element) { await window.dialogObjects .find(d => d.element == element) .dialogObject .invokeMethodAsync('KeyHandler', e.key); e.preventDefault(); return; } var button = Array.from(document.getElementsByTagName('button')) .filter(b => typeof(b.dataset.keyboardShortcut) == 'string') .filter(b => !isDialogChild(b)) .find(b => b.dataset.keyboardShortcut == e.key); if(!e.ctrlKey && button) { button.click(); e.preventDefault(); return; } } window.onload = () => document.onkeydown = keyDownHandler;