$.ready(() => { const input = qs('#softkb-input'); if (!input) return; // abort, we're not on the terminal page let keyboardOpen = false; let updateInputPosition = function () { if (!keyboardOpen) return; let [x, y] = Screen.gridToScreen(Screen.cursor.x, Screen.cursor.y); input.style.transform = `translate(${x}px, ${y}px)` }; input.addEventListener('focus', () => { keyboardOpen = true; updateInputPosition() }); input.addEventListener('blur', () => (keyboardOpen = false)); Screen.on('cursor-moved', updateInputPosition); window.kbOpen = function openSoftKeyboard (open) { keyboardOpen = open; updateInputPosition(); if (open) input.focus(); else input.blur() }; let lastCompositionString = ''; let compositing = false; let sendInputDelta = function (newValue) { let resend = false; if (newValue.length > lastCompositionString.length) { if (newValue.startsWith(lastCompositionString)) { // characters have been added at the end Input.sendString(newValue.substr(lastCompositionString.length)) } else resend = true; } else if (newValue.length < lastCompositionString.length) { if (lastCompositionString.startsWith(newValue)) { // characters have been removed at the end Input.sendString('\b'.repeat(lastCompositionString.length - newValue.length)) } else resend = true; } else if (newValue !== lastCompositionString) resend = true; if (resend) { // the entire string changed; resend everything Input.sendString('\b'.repeat(lastCompositionString.length) + newValue) } lastCompositionString = newValue; }; input.addEventListener('keydown', e => { if (e.key === 'Unidentified') return; e.preventDefault(); input.value = ''; if (e.key === 'Backspace') Input.sendString('\b'); else if (e.key === 'Enter') Input.sendString('\x0d') }); input.addEventListener('input', e => { e.stopPropagation(); if (e.isComposing) { sendInputDelta(e.data); } else { if (e.data) Input.sendString(e.data); else if (e.inputType === 'deleteContentBackward') { lastCompositionString = ''; sendInputDelta(''); } } }); input.addEventListener('compositionstart', e => { lastCompositionString = ''; compositing = true; }); input.addEventListener('compositionend', e => { lastCompositionString = ''; compositing = false; input.value = ''; }); Screen.on('open-soft-keyboard', () => input.focus()) });