From 5dab1c649fa4c75ddc4db521e675da59ab552efd Mon Sep 17 00:00:00 2001 From: cpsdqs Date: Mon, 11 Sep 2017 15:27:02 +0200 Subject: [PATCH] Use fewer global variables in term* and softkb --- jssrc/soft_keyboard.js | 54 +++++++++++++++++++++++------------------- jssrc/term.js | 30 +++++++++++------------ jssrc/term_conn.js | 10 ++++---- jssrc/term_input.js | 16 ++++++------- jssrc/term_screen.js | 21 ++++++++++------ jssrc/term_upload.js | 14 +++++------ 6 files changed, 77 insertions(+), 68 deletions(-) diff --git a/jssrc/soft_keyboard.js b/jssrc/soft_keyboard.js index d3059d5..5519468 100644 --- a/jssrc/soft_keyboard.js +++ b/jssrc/soft_keyboard.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()) } diff --git a/jssrc/term.js b/jssrc/term.js index 6fd2f03..8a336aa 100644 --- a/jssrc/term.js +++ b/jssrc/term.js @@ -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 } diff --git a/jssrc/term_conn.js b/jssrc/term_conn.js index 3208028..4521e3d 100644 --- a/jssrc/term_conn.js +++ b/jssrc/term_conn.js @@ -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 } -})() +} diff --git a/jssrc/term_input.js b/jssrc/term_input.js index 2c8e257..3595f74 100644 --- a/jssrc/term_input.js +++ b/jssrc/term_input.js @@ -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 } } -})() +} diff --git a/jssrc/term_screen.js b/jssrc/term_screen.js index 94d4c35..2b1b05c 100644 --- a/jssrc/term_screen.js +++ b/jssrc/term_screen.js @@ -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]) { diff --git a/jssrc/term_upload.js b/jssrc/term_upload.js index bf940fa..0c188f2 100644 --- a/jssrc/term_upload.js +++ b/jssrc/term_upload.js @@ -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 } -})() +}