|
|
|
$.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())
|
|
|
|
});
|