Use fewer global variables in term* and softkb

cpsdqs/unified-input
cpsdqs 7 years ago
parent 8f0d6c7873
commit 5dab1c649f
Signed by untrusted user: cpsdqs
GPG Key ID: 3F59586BB7448DD1
  1. 54
      jssrc/soft_keyboard.js
  2. 30
      jssrc/term.js
  3. 10
      jssrc/term_conn.js
  4. 16
      jssrc/term_input.js
  5. 21
      jssrc/term_screen.js
  6. 14
      jssrc/term_upload.js

@ -1,6 +1,6 @@
window.initSoftKeyboard = function (screen) {
const input = qs('#softkb-input')
if (!input) return // abort, we're not on the terminal page
window.initSoftKeyboard = function (screen, input) {
const keyInput = qs('#softkb-input')
if (!keyInput) return // abort, we're not on the terminal page
let keyboardOpen = false
@ -8,97 +8,101 @@ window.initSoftKeyboard = function (screen) {
if (!keyboardOpen) return
let [x, y] = screen.gridToScreen(screen.cursor.x, screen.cursor.y, true)
input.style.transform = `translate(${x}px, ${y}px)`
keyInput.style.transform = `translate(${x}px, ${y}px)`
}
input.addEventListener('focus', () => {
keyInput.addEventListener('focus', () => {
keyboardOpen = true
updateInputPosition()
})
input.addEventListener('blur', () => (keyboardOpen = false))
keyInput.addEventListener('blur', () => (keyboardOpen = false))
screen.on('cursor-moved', updateInputPosition)
window.kbOpen = function openSoftKeyboard (open) {
keyboardOpen = open
updateInputPosition()
if (open) input.focus()
else input.blur()
if (open) keyInput.focus()
else keyInput.blur()
}
// Chrome for Android doesn't send proper keydown/keypress events with
// real key values instead of 229 “Unidentified,” so here's a workaround
// that deals with the input composition events.
let lastCompositionString = ''
let compositing = false
// sends the difference between the last and the new composition string
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))
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 -
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) +
input.sendString('\b'.repeat(lastCompositionString.length) +
newValue)
}
lastCompositionString = newValue
}
input.addEventListener('keydown', e => {
keyInput.addEventListener('keydown', e => {
if (e.key === 'Unidentified') return
input.value = ''
keyInput.value = ''
if (e.key === 'Backspace') {
e.preventDefault()
Input.sendString('\b')
input.sendString('\b')
} else if (e.key === 'Enter') {
e.preventDefault()
Input.sendString('\x0d')
input.sendString('\x0d')
}
})
input.addEventListener('keypress', e => {
keyInput.addEventListener('keypress', e => {
// prevent key duplication on iOS (because Safari *does* send proper events)
e.stopPropagation()
})
input.addEventListener('input', e => {
keyInput.addEventListener('input', e => {
e.stopPropagation()
if (e.isComposing) {
sendInputDelta(e.data)
} else {
if (e.inputType === 'insertCompositionText') Input.sendString(e.data)
if (e.inputType === 'insertCompositionText') input.sendString(e.data)
else if (e.inputType === 'deleteContentBackward') {
lastCompositionString = ''
sendInputDelta('')
} else if (e.inputType === 'insertText') {
Input.sendString(e.data)
input.sendString(e.data)
}
}
})
input.addEventListener('compositionstart', e => {
keyInput.addEventListener('compositionstart', e => {
lastCompositionString = ''
compositing = true
console.log('compositionstart')
})
input.addEventListener('compositionend', e => {
keyInput.addEventListener('compositionend', e => {
lastCompositionString = ''
compositing = false
input.value = ''
console.log('compositionend')
keyInput.value = ''
})
screen.on('open-soft-keyboard', () => input.focus())
screen.on('open-soft-keyboard', () => keyInput.focus())
}

@ -1,21 +1,15 @@
/** Init the terminal sub-module - called from HTML */
window.termInit = function (labels, theme) {
Conn.init()
Input.init()
TermUpl.init()
const screen = new window.TermScreen()
const conn = window.Conn(screen)
const input = window.Input(conn)
const termUpload = window.TermUpl(conn, input)
let didNotifyAboutScreen = false
Object.defineProperty(window, 'Screen', {
get () {
if (!didNotifyAboutScreen) {
console.warn('Use local variables instead of window.Screen')
didNotifyAboutScreen = true
}
return screen
}
})
screen.input = input
conn.init()
input.init()
termUpload.init()
qs('#screen').appendChild(screen.canvas)
screen.load(labels, theme) // load labels and theme
@ -43,8 +37,12 @@ window.termInit = function (labels, theme) {
}
}
window.initSoftKeyboard(screen)
window.initSoftKeyboard(screen, input)
if (window.attachDebugScreen) window.attachDebugScreen(screen)
window.termScreen = screen // for debugging
// for debugging
window.termScreen = screen
window.conn = conn
window.input = input
window.termUpl = termUpload
}

@ -1,5 +1,5 @@
/** Handle connections */
window.Conn = (function () {
window.Conn = function (screen) {
let ws
let heartbeatTout
let pingIv
@ -48,7 +48,7 @@ window.Conn = (function () {
break
default:
Screen.load(evt.data)
screen.load(evt.data)
if (!pageShown) {
showPage()
pageShown = true
@ -89,9 +89,9 @@ window.Conn = (function () {
}
function init () {
if (_demo) {
if (window._demo) {
console.log('Demo mode!')
Screen.load(_demo_screen)
screen.load(_demo_screen)
showPage()
return
}
@ -134,4 +134,4 @@ window.Conn = (function () {
send: doSend,
canSend: canSend // check flood control
}
})()
}

@ -14,7 +14,7 @@
* r - mb release
* m - mouse move
*/
window.Input = (function () {
window.Input = function (conn) {
let opts = {
np_alt: false,
cu_alt: false,
@ -27,12 +27,12 @@ window.Input = (function () {
/** Send a literal message */
function sendStrMsg (str) {
return Conn.send('s' + str)
return conn.send('s' + str)
}
/** Send a button event */
function sendBtnMsg (n) {
Conn.send('b' + Chr(n))
conn.send('b' + Chr(n))
}
/** Fn alt choice for key message */
@ -256,14 +256,14 @@ window.Input = (function () {
if (!opts.mt_move) return
const b = mb1 ? 1 : mb2 ? 2 : mb3 ? 3 : 0
const m = packModifiersForMouse()
Conn.send('m' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))
conn.send('m' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))
},
onMouseDown: function (x, y, b) {
if (!opts.mt_click) return
if (b > 3 || b < 1) return
const m = packModifiersForMouse()
Conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))
conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))
// console.log("B ",b," M ",m);
},
@ -271,7 +271,7 @@ window.Input = (function () {
if (!opts.mt_click) return
if (b > 3 || b < 1) return
const m = packModifiersForMouse()
Conn.send('r' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))
conn.send('r' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))
// console.log("B ",b," M ",m);
},
@ -281,7 +281,7 @@ window.Input = (function () {
// +1 ... btn 5 (towards user)
const m = packModifiersForMouse()
const b = (dir < 0 ? 4 : 5)
Conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))
conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))
// console.log("B ",b," M ",m);
},
@ -293,4 +293,4 @@ window.Input = (function () {
opts.no_keys = yes
}
}
})()
}

@ -79,6 +79,13 @@ window.TermScreen = class TermScreen {
console.warn('No AudioContext!')
}
// dummy
this.input = new Proxy({}, {
get () {
return () => console.warn('TermScreen#input not set!')
}
})
this.cursor = {
x: 0,
y: 0,
@ -200,7 +207,7 @@ window.TermScreen = class TermScreen {
if ((this.selection.selectable || e.altKey) && e.button === 0) {
selectStart(e.offsetX, e.offsetY)
} else {
Input.onMouseDown(...this.screenToGrid(e.offsetX, e.offsetY),
this.input.onMouseDown(...this.screenToGrid(e.offsetX, e.offsetY),
e.button + 1)
}
})
@ -306,20 +313,20 @@ window.TermScreen = class TermScreen {
this.canvas.addEventListener('mousemove', e => {
if (!selecting) {
Input.onMouseMove(...this.screenToGrid(e.offsetX, e.offsetY))
this.input.onMouseMove(...this.screenToGrid(e.offsetX, e.offsetY))
}
})
this.canvas.addEventListener('mouseup', e => {
if (!selecting) {
Input.onMouseUp(...this.screenToGrid(e.offsetX, e.offsetY),
this.input.onMouseUp(...this.screenToGrid(e.offsetX, e.offsetY),
e.button + 1)
}
})
this.canvas.addEventListener('wheel', e => {
if (this.mouseMode.clicks) {
Input.onMouseWheel(...this.screenToGrid(e.offsetX, e.offsetY),
this.input.onMouseWheel(...this.screenToGrid(e.offsetX, e.offsetY),
e.deltaY > 0 ? 1 : -1)
// prevent page scrolling
@ -1078,7 +1085,7 @@ window.TermScreen = class TermScreen {
this.cursor.visible = !!(attributes & 1)
this.cursor.hanging = !!(attributes & (1 << 1))
Input.setAlts(
this.input.setAlts(
!!(attributes & (1 << 2)), // cursors alt
!!(attributes & (1 << 3)), // numpad alt
!!(attributes & (1 << 4)), // fn keys alt
@ -1109,7 +1116,7 @@ window.TermScreen = class TermScreen {
this.resetCursorBlink()
}
Input.setMouseMode(trackMouseClicks, trackMouseMovement)
this.input.setMouseMode(trackMouseClicks, trackMouseMovement)
this.selection.selectable = !trackMouseMovement
$(this.canvas).toggleClass('selectable', !trackMouseMovement)
this.mouseMode = {
@ -1267,7 +1274,7 @@ window.TermScreen = class TermScreen {
load (str, theme = -1) {
const content = str.substr(1)
if (theme >= 0 && theme < themes.length) {
Screen.palette = themes[theme]
this.palette = themes[theme]
}
switch (str[0]) {

@ -1,5 +1,5 @@
/** File upload utility */
window.TermUpl = (function () {
window.TermUpl = function (conn, input) {
let lines, // array of lines without newlines
line_i, // current line index
fuTout, // timeout handle for line sending
@ -16,14 +16,14 @@ window.TermUpl = (function () {
fuStatus('Ready...')
Modal.show('#fu_modal', onClose)
$('#fu_form').toggleClass('busy', false)
Input.blockKeys(true)
input.blockKeys(true)
}
function onClose () {
console.log('Upload modal closed.')
clearTimeout(fuTout)
line_i = 0
Input.blockKeys(false)
input.blockKeys(false)
}
function fuStatus (msg) {
@ -65,7 +65,7 @@ window.TermUpl = (function () {
return
}
if (!Conn.canSend()) {
if (!conn.canSend()) {
// postpone
fuTout = setTimeout(fuSendLine, 1)
return
@ -84,7 +84,7 @@ window.TermUpl = (function () {
inline_pos += MAX_LINE_LEN
}
if (!Input.sendString(chunk)) {
if (!input.sendString(chunk)) {
fuStatus('FAILED!')
return
}
@ -101,7 +101,7 @@ window.TermUpl = (function () {
}
function closeWhenReady () {
if (!Conn.canSend()) {
if (!conn.canSend()) {
// stuck in XOFF still, wait to process...
fuStatus('Waiting for Tx buffer...')
setTimeout(closeWhenReady, 100)
@ -143,4 +143,4 @@ window.TermUpl = (function () {
start: fuSend,
open: fuOpen
}
})()
}

Loading…
Cancel
Save