ESPTerm web interface submodule, separated to make testing and development easier
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
espterm-front-end/jssrc/soft_keyboard.js

88 lines
2.5 KiB

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