diff --git a/.eslintrc b/.eslintrc index a8e79a4..b6aeb27 100644 --- a/.eslintrc +++ b/.eslintrc @@ -135,7 +135,7 @@ "no-unsafe-finally": "error", "no-unsafe-negation": "error", "no-unused-expressions": ["warn", { "allowShortCircuit": true, "allowTernary": true, "allowTaggedTemplates": true }], - "no-unused-vars": ["error", { "vars": "local", "args": "none", "ignoreRestSiblings": true }], + "no-unused-vars": ["warn", { "vars": "local", "args": "none", "ignoreRestSiblings": true }], "no-use-before-define": ["error", { "functions": false, "classes": false, "variables": false }], "no-useless-call": "error", "no-useless-computed-key": "error", diff --git a/_build_js.sh b/_build_js.sh index 912feea..104de65 100755 --- a/_build_js.sh +++ b/_build_js.sh @@ -6,6 +6,9 @@ echo 'Generating lang.js...' php ./dump_js_lang.php echo 'Processing JS...' +npm run webpack +exit + if [[ $ESP_PROD ]]; then smarg= demofile= diff --git a/dump_js_lang.php b/dump_js_lang.php index 2639eea..d577f16 100755 --- a/dump_js_lang.php +++ b/dump_js_lang.php @@ -18,5 +18,5 @@ foreach ($selected as $key) { file_put_contents(__DIR__. '/js/lang.js', "// Generated from PHP locale file\n" . 'let _tr = ' . json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE) . ";\n\n" . - "function tr (key) { return _tr[key] || '?' + key + '?' }\n" + "module.exports = function tr (key) { return _tr[key] || '?' + key + '?' }\n" ); diff --git a/js/appcommon.js b/js/appcommon.js index 60a8b2a..e8226d9 100644 --- a/js/appcommon.js +++ b/js/appcommon.js @@ -1,4 +1,20 @@ const $ = require('./lib/chibi') +const { mk, qs } = require('./utils') +const modal = require('./modal') +const notify = require('./notif') + +/** + * Filter 'spacebar' and 'return' from keypress handler, + * and when they're pressed, fire the callback. + * use $(...).on('keypress', cr(handler)) + */ +function cr (hdl) { + return function (e) { + if (e.which === 10 || e.which === 13 || e.which === 32) { + hdl() + } + } +} /** Global generic init */ $.ready(function () { @@ -60,8 +76,8 @@ $.ready(function () { val -= step } - if (undef(min)) val = Math.max(val, +min) - if (undef(max)) val = Math.min(val, +max) + if (!Number.isFinite(min)) val = Math.max(val, +min) + if (!Number.isFinite(max)) val = Math.min(val, +max) $this.val(val) if ('createEvent' in document) { @@ -96,8 +112,8 @@ $.ready(function () { qs('.Box.errors').classList.remove('hidden') } - Modal.init() - Notify.init() + modal.init() + notify.init() // remove tabindices from h2 if wide if (window.innerWidth > 550) { @@ -108,7 +124,7 @@ $.ready(function () { // brand works as a link back to term in widescreen mode let br = qs('#brand') br && br.addEventListener('click', function () { - location.href = '/' // go to terminal + window.location.href = '/' // go to terminal }) } }) @@ -124,6 +140,8 @@ function showPage () { pageShown = true $('#content').addClass('load') } +// HACKITY HACK: fix this later +window.showPage = showPage // Auto reveal pages other than the terminal (sets window.noAutoShow) $.ready(function () { diff --git a/js/debug_screen.js b/js/debug_screen.js index 06df806..e03e291 100644 --- a/js/debug_screen.js +++ b/js/debug_screen.js @@ -1,4 +1,6 @@ -window.attachDebugScreen = function (screen) { +const { mk } = require('./utils') + +module.exports = function attachDebugScreen (screen) { const debugCanvas = mk('canvas') const ctx = debugCanvas.getContext('2d') @@ -73,7 +75,7 @@ window.attachDebugScreen = function (screen) { let isDrawing = false let drawLoop = function () { - if (isDrawing) requestAnimationFrame(drawLoop) + if (isDrawing) window.requestAnimationFrame(drawLoop) let { devicePixelRatio, width, height } = screen.window let { width: cellWidth, height: cellHeight } = screen.getCellSize() diff --git a/js/demo.js b/js/demo.js index bb1d0a3..22c0f76 100644 --- a/js/demo.js +++ b/js/demo.js @@ -1,3 +1,6 @@ +const EventEmitter = require('events') +const { encode2B, encode3B, parse2B } = require('./utils') + class ANSIParser { constructor (handler) { this.reset() diff --git a/js/event_emitter.js b/js/event_emitter.js deleted file mode 100644 index 88d6db7..0000000 --- a/js/event_emitter.js +++ /dev/null @@ -1,70 +0,0 @@ -if (!('EventEmitter' in window)) { - window.EventEmitter = class EventEmitter { - constructor () { - this._listeners = {} - } - - /** - * Bind an event listener to an event - * @param {string} event - the event name - * @param {Function} listener - the event listener - */ - on (event, listener) { - if (!this._listeners[event]) this._listeners[event] = [] - this._listeners[event].push({ listener }) - } - - /** - * Bind an event listener to be run only once the next time the event fires - * @param {string} event - the event name - * @param {Function} listener - the event listener - */ - once (event, listener) { - if (!this._listeners[event]) this._listeners[event] = [] - this._listeners[event].push({ listener, once: true }) - } - - /** - * Remove an event listener - * @param {string} event - the event name - * @param {Function} listener - the event listener - */ - off (event, listener) { - let listeners = this._listeners[event] - if (listeners) { - for (let i in listeners) { - if (listeners[i].listener === listener) { - listeners.splice(i, 1) - break - } - } - } - } - - /** - * Emits an event - * @param {string} event - the event name - * @param {...any} args - arguments passed to all listeners - */ - emit (event, ...args) { - let listeners = this._listeners[event] - if (listeners) { - let remove = [] - for (let listener of listeners) { - try { - listener.listener(...args) - if (listener.once) remove.push(listener) - } catch (err) { - console.error(err) - } - } - - // this needs to be done in this roundabout way because for loops - // do not like arrays with changing lengths - for (let listener of remove) { - listeners.splice(listeners.indexOf(listener), 1) - } - } - } - } -} diff --git a/js/index.js b/js/index.js index 23cf5a9..060d5fc 100644 --- a/js/index.js +++ b/js/index.js @@ -1,17 +1,7 @@ -require('./lib/chibi') require('./lib/polyfills') -require('./event_emitter') -require('./utils') require('./modal') require('./notif') require('./appcommon') require('./demo') -require('./lang') require('./wifi') -require('./term_conn') -require('./term_input') -require('./term_screen') -require('./term_upload') -require('./debug_screen') -require('./soft_keyboard') -require('./term') +window.termInit = require('./term') diff --git a/js/lang.js b/js/lang.js index bce4adb..31117a3 100644 --- a/js/lang.js +++ b/js/lang.js @@ -5,4 +5,4 @@ let _tr = { "wifi.enter_passwd": "Enter password for \":ssid:\"" }; -function tr (key) { return _tr[key] || '?' + key + '?' } +module.exports = function tr (key) { return _tr[key] || '?' + key + '?' } diff --git a/js/modal.js b/js/modal.js index fabc1a7..e4e9cab 100644 --- a/js/modal.js +++ b/js/modal.js @@ -1,44 +1,44 @@ +const $ = require('./lib/chibi') + /** Module for toggling a modal overlay */ -(function () { - let modal = {} - let curCloseCb = null +let modal = {} +let curCloseCb = null - modal.show = function (sel, closeCb) { - let $m = $(sel) - $m.removeClass('hidden visible') - setTimeout(function () { - $m.addClass('visible') - }, 1) - curCloseCb = closeCb - } +modal.show = function (sel, closeCb) { + let $m = $(sel) + $m.removeClass('hidden visible') + setTimeout(function () { + $m.addClass('visible') + }, 1) + curCloseCb = closeCb +} - modal.hide = function (sel) { - let $m = $(sel) - $m.removeClass('visible') - setTimeout(function () { - $m.addClass('hidden') - if (curCloseCb) curCloseCb() - }, 500) // transition time - } +modal.hide = function (sel) { + let $m = $(sel) + $m.removeClass('visible') + setTimeout(function () { + $m.addClass('hidden') + if (curCloseCb) curCloseCb() + }, 500) // transition time +} - modal.init = function () { - // close modal by click outside the dialog - $('.Modal').on('click', function () { - if ($(this).hasClass('no-close')) return // this is a no-close modal - modal.hide(this) - }) +modal.init = function () { + // close modal by click outside the dialog + $('.Modal').on('click', function () { + if ($(this).hasClass('no-close')) return // this is a no-close modal + modal.hide(this) + }) - $('.Dialog').on('click', function (e) { - e.stopImmediatePropagation() - }) + $('.Dialog').on('click', function (e) { + e.stopImmediatePropagation() + }) - // Hide all modals on esc - $(window).on('keydown', function (e) { - if (e.which === 27) { - modal.hide('.Modal') - } - }) - } + // Hide all modals on esc + $(window).on('keydown', function (e) { + if (e.which === 27) { + modal.hide('.Modal') + } + }) +} - window.Modal = modal -})() +module.exports = modal diff --git a/js/notif.js b/js/notif.js index 38cbd4e..fa78e3a 100644 --- a/js/notif.js +++ b/js/notif.js @@ -1,65 +1,65 @@ -window.Notify = (function () { - let nt = {} - const sel = '#notif' - let $balloon +const $ = require('./lib/chibi') +const modal = require('./modal') - let timerHideBegin // timeout to start hiding (transition) - let timerHideEnd // timeout to add the hidden class - let timerCanCancel - let canCancel = false +let nt = {} +const sel = '#notif' +let $balloon - let stopTimeouts = function () { - clearTimeout(timerHideBegin) - clearTimeout(timerHideEnd) - } - - nt.show = function (message, timeout, isError) { - $balloon.toggleClass('error', isError === true) - $balloon.html(message) - Modal.show($balloon) - stopTimeouts() +let timerHideBegin // timeout to start hiding (transition) +let timerHideEnd // timeout to add the hidden class +let canCancel = false - if (undef(timeout) || timeout === null || timeout <= 0) { - timeout = 2500 - } +let stopTimeouts = function () { + clearTimeout(timerHideBegin) + clearTimeout(timerHideEnd) +} - timerHideBegin = setTimeout(nt.hide, timeout) +nt.show = function (message, timeout, isError) { + $balloon.toggleClass('error', isError === true) + $balloon.html(message) + modal.show($balloon) + stopTimeouts() - canCancel = false - timerCanCancel = setTimeout(function () { - canCancel = true - }, 500) + if (!timeout || timeout <= 0) { + timeout = 2500 } - nt.hide = function () { - let $m = $(sel) - $m.removeClass('visible') - timerHideEnd = setTimeout(function () { - $m.addClass('hidden') - }, 250) // transition time - } + timerHideBegin = setTimeout(nt.hide, timeout) - nt.init = function () { - $balloon = $(sel) + canCancel = false + setTimeout(() => { + canCancel = true + }, 500) +} - // close by click outside - $(document).on('click', function () { - if (!canCancel) return - nt.hide(this) - }) +nt.hide = function () { + let $m = $(sel) + $m.removeClass('visible') + timerHideEnd = setTimeout(function () { + $m.addClass('hidden') + }, 250) // transition time +} - // click caused by selecting, prevent it from bubbling - $balloon.on('click', function (e) { - e.stopImmediatePropagation() - return false - }) +nt.init = function () { + $balloon = $(sel) - // stop fading if moused - $balloon.on('mouseenter', function () { - stopTimeouts() - $balloon.removeClass('hidden').addClass('visible') - }) - } + // close by click outside + $(document).on('click', function () { + if (!canCancel) return + nt.hide(this) + }) + + // click caused by selecting, prevent it from bubbling + $balloon.on('click', function (e) { + e.stopImmediatePropagation() + return false + }) + + // stop fading if moused + $balloon.on('mouseenter', function () { + stopTimeouts() + $balloon.removeClass('hidden').addClass('visible') + }) +} - return nt -})() +module.exports = nt diff --git a/js/soft_keyboard.js b/js/soft_keyboard.js index 7921e5d..2acfebe 100644 --- a/js/soft_keyboard.js +++ b/js/soft_keyboard.js @@ -1,4 +1,6 @@ -window.initSoftKeyboard = function (screen, input) { +const { qs } = require('./utils') + +module.exports = function (screen, input) { const keyInput = qs('#softkb-input') if (!keyInput) return // abort, we're not on the terminal page @@ -33,7 +35,6 @@ window.initSoftKeyboard = function (screen, input) { // 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) { @@ -96,12 +97,10 @@ window.initSoftKeyboard = function (screen, input) { keyInput.addEventListener('compositionstart', e => { lastCompositionString = '' - compositing = true }) keyInput.addEventListener('compositionend', e => { lastCompositionString = '' - compositing = false keyInput.value = '' }) diff --git a/js/term.js b/js/term.js index c6bb03a..46ecab9 100644 --- a/js/term.js +++ b/js/term.js @@ -1,9 +1,18 @@ +const { qs, mk } = require('./utils') +const Notify = require('./notif') +const TermScreen = require('./term_screen') +const TermConnection = require('./term_conn') +const TermInput = require('./term_input') +const TermUpload = require('./term_upload') +const initSoftKeyboard = require('./soft_keyboard') +const attachDebugScreen = require('./debug_screen') + /** Init the terminal sub-module - called from HTML */ -window.termInit = function ({ labels, theme, allFn }) { +module.exports = function ({ labels, theme, allFn }) { const screen = new TermScreen() - const conn = new Conn(screen) - const input = Input(conn, screen) - const termUpload = TermUpl(conn, input, screen) + const conn = new TermConnection(screen) + const input = TermInput(conn, screen) + const termUpload = TermUpload(conn, input, screen) screen.input = input input.termUpload = termUpload @@ -39,8 +48,8 @@ window.termInit = function ({ labels, theme, allFn }) { qs('#screen').appendChild(screen.canvas) screen.load(labels, theme) // load labels and theme - window.initSoftKeyboard(screen, input) - if (window.attachDebugScreen) window.attachDebugScreen(screen) + initSoftKeyboard(screen, input) + if (attachDebugScreen) attachDebugScreen(screen) let isFullscreen = false let fitScreen = false @@ -75,10 +84,10 @@ window.termInit = function ({ labels, theme, allFn }) { }) // add fullscreen mode & button - if (Element.prototype.requestFullscreen || Element.prototype.webkitRequestFullscreen) { + if (window.Element.prototype.requestFullscreen || window.Element.prototype.webkitRequestFullscreen) { let checkForFullscreen = function () { // document.fullscreenElement is not really supported yet, so here's a hack - if (isFullscreen && (innerWidth !== window.screen.width || innerHeight !== window.screen.height)) { + if (isFullscreen && (window.innerWidth !== window.screen.width || window.innerHeight !== window.screen.height)) { isFullscreen = false fitScreenIfNeeded() } diff --git a/js/term_conn.js b/js/term_conn.js index b5fb962..dc186f2 100644 --- a/js/term_conn.js +++ b/js/term_conn.js @@ -1,5 +1,9 @@ +const EventEmitter = require('events') +const $ = require('./lib/chibi') +const demo = require('./demo') + /** Handle connections */ -window.Conn = class TermConnection extends EventEmitter { +module.exports = class TermConnection extends EventEmitter { constructor (screen) { super() @@ -94,7 +98,7 @@ window.Conn = class TermConnection extends EventEmitter { send (message) { if (window._demo) { if (typeof window.demoInterface !== 'undefined') { - demoInterface.input(message) + demo.input(message) } else { console.log(`TX: ${JSON.stringify(message)}`) } @@ -130,9 +134,9 @@ window.Conn = class TermConnection extends EventEmitter { init () { if (window._demo) { if (typeof window.demoInterface === 'undefined') { - alert('Demoing non-demo build!') // this will catch mistakes when deploying to the website + window.alert('Demoing non-demo build!') // this will catch mistakes when deploying to the website } else { - demoInterface.init(this.screen) + demo.init(this.screen) showPage() } return @@ -143,7 +147,7 @@ window.Conn = class TermConnection extends EventEmitter { this.closeSocket() - this.ws = new WebSocket('ws://' + _root + '/term/update.ws') + this.ws = new window.WebSocket('ws://' + window._root + '/term/update.ws') this.ws.addEventListener('open', (...args) => this.onWSOpen(...args)) this.ws.addEventListener('close', (...args) => this.onWSClose(...args)) this.ws.addEventListener('message', (...args) => this.onWSMessage(...args)) @@ -167,7 +171,7 @@ window.Conn = class TermConnection extends EventEmitter { this.pingInterval = setInterval(() => { console.log('> ping') this.emit('ping') - $.get('http://' + _root + '/system/ping', (resp, status) => { + $.get('http://' + window._root + '/system/ping', (resp, status) => { if (status === 200) { clearInterval(this.pingInterval) console.info('Server ready, opening socket…') diff --git a/js/term_input.js b/js/term_input.js index b465401..bef567c 100644 --- a/js/term_input.js +++ b/js/term_input.js @@ -1,3 +1,6 @@ +const $ = require('./lib/chibi') +const { encode2B } = require('./utils') + /** * User input * @@ -14,7 +17,7 @@ * r - mb release * m - mouse move */ -window.Input = function (conn, screen) { +module.exports = function (conn, screen) { // handle for input object let input diff --git a/js/term_screen.js b/js/term_screen.js index d406739..4ab3efb 100644 --- a/js/term_screen.js +++ b/js/term_screen.js @@ -1,3 +1,8 @@ +const EventEmitter = require('events') +const $ = require('./lib/chibi') +const { mk, qs, parse2B, parse3B } = require('./utils') +const notify = require('./notif') + // constants for decoding the update blob const SEQ_REPEAT = 2 const SEQ_SET_COLORS = 3 @@ -8,7 +13,7 @@ const SEQ_SET_BG = 6 const SELECTION_BG = '#b2d7fe' const SELECTION_FG = '#333' -window.TermScreen = class TermScreen extends EventEmitter { +module.exports = class TermScreen extends EventEmitter { constructor () { super() @@ -472,8 +477,6 @@ window.TermScreen = class TermScreen extends EventEmitter { const { width, height, - gridScaleX, - gridScaleY, fitIntoWidth, fitIntoHeight } = this.window @@ -632,9 +635,9 @@ window.TermScreen = class TermScreen extends EventEmitter { textarea.value = selectedText textarea.select() if (document.execCommand('copy')) { - Notify.show('Copied to clipboard') + notify.show('Copied to clipboard') } else { - Notify.show('Failed to copy') + notify.show('Failed to copy') } document.body.removeChild(textarea) } @@ -899,8 +902,6 @@ window.TermScreen = class TermScreen extends EventEmitter { width, height, devicePixelRatio, - gridScaleX, - gridScaleY, statusScreen } = this.window @@ -913,8 +914,6 @@ window.TermScreen = class TermScreen extends EventEmitter { const charSize = this.getCharSize() const { width: cellWidth, height: cellHeight } = this.getCellSize() - const screenWidth = width * cellWidth - const screenHeight = height * cellHeight const screenLength = width * height ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0) @@ -1042,7 +1041,7 @@ window.TermScreen = class TermScreen extends EventEmitter { // pass 1: backgrounds for (let font of fontGroups.keys()) { for (let data of fontGroups.get(font)) { - let [cell, x, y, text, fg, bg, attrs, isCursor] = data + let [cell, x, y, text, , bg] = data if (redrawMap.get(cell)) { this.drawBackground({ x, y, cellWidth, cellHeight, bg }) @@ -1128,7 +1127,8 @@ window.TermScreen = class TermScreen extends EventEmitter { const { fontFamily, width, - height + height, + devicePixelRatio } = this.window // reset drawnScreen to force redraw when statusScreen is disabled @@ -1185,7 +1185,7 @@ window.TermScreen = class TermScreen extends EventEmitter { drawTimerLoop (threadID) { if (!threadID || threadID !== this._drawTimerThread) return - requestAnimationFrame(() => this.drawTimerLoop(threadID)) + window.requestAnimationFrame(() => this.drawTimerLoop(threadID)) this.draw('draw-loop') } @@ -1296,7 +1296,7 @@ window.TermScreen = class TermScreen extends EventEmitter { this.screenAttrs = new Array(screenLength).fill(' ') } - let strArray = !undef(Array.from) ? Array.from(str) : str.split('') + let strArray = Array.from ? Array.from(str) : str.split('') const MASK_LINE_ATTR = 0xC8 const MASK_BLINK = 1 << 4 @@ -1392,7 +1392,7 @@ window.TermScreen = class TermScreen extends EventEmitter { let label = pieces[i + 1].trim() // if empty string, use the "dim" effect and put nbsp instead to // stretch the button vertically - button.innerHTML = label ? esc(label) : ' ' + button.innerHTML = label ? $.htmlEscape(label) : ' ' button.style.opacity = label ? 1 : 0.2 }) } @@ -1403,17 +1403,17 @@ window.TermScreen = class TermScreen extends EventEmitter { */ showNotification (text) { console.info(`Notification: ${text}`) - if (Notification && Notification.permission === 'granted') { - let notification = new Notification('ESPTerm', { + if (window.Notification && window.Notification.permission === 'granted') { + let notification = new window.Notification('ESPTerm', { body: text }) notification.addEventListener('click', () => window.focus()) } else { - if (Notification && Notification.permission !== 'denied') { - Notification.requestPermission() + if (window.Notification && window.Notification.permission !== 'denied') { + window.Notification.requestPermission() } else { // Fallback using the built-in notification balloon - Notify.show(text) + notify.show(text) } } } @@ -1500,7 +1500,7 @@ window.TermScreen = class TermScreen extends EventEmitter { surrOsc.stop(startTime + 0.8) let loop = function () { - if (audioCtx.currentTime < startTime + 0.8) requestAnimationFrame(loop) + if (audioCtx.currentTime < startTime + 0.8) window.requestAnimationFrame(loop) mainGain.gain.value *= 0.8 surrGain.gain.value *= 0.8 } diff --git a/js/term_upload.js b/js/term_upload.js index 1ff6752..fabd795 100644 --- a/js/term_upload.js +++ b/js/term_upload.js @@ -1,5 +1,9 @@ +const $ = require('./lib/chibi') +const { qs } = require('./utils') +const modal = require('./modal') + /** File upload utility */ -window.TermUpl = function (conn, input, screen) { +module.exports = function (conn, input, screen) { let lines, // array of lines without newlines line_i, // current line index fuTout, // timeout handle for line sending @@ -14,7 +18,7 @@ window.TermUpl = function (conn, input, screen) { function openUploadDialog () { updateStatus('Ready...') - Modal.show('#fu_modal', onDialogClose) + modal.show('#fu_modal', onDialogClose) $('#fu_form').toggleClass('busy', false) input.blockKeys(true) } @@ -125,19 +129,19 @@ window.TermUpl = function (conn, input, screen) { } function fuClose () { - Modal.hide('#fu_modal') + modal.hide('#fu_modal') } return { init: function () { qs('#fu_file').addEventListener('change', function (evt) { - let reader = new FileReader() + let reader = new window.FileReader() let file = evt.target.files[0] let ftype = file.type || 'application/octet-stream' console.log('Selected file type: ' + ftype) if (!ftype.match(/text\/.*|application\/(json|csv|.*xml.*|.*script.*|x-php)/)) { // Deny load of blobs like img - can crash browser and will get corrupted anyway - if (!confirm(`This does not look like a text file: ${ftype}\nReally load?`)) { + if (!window.confirm(`This does not look like a text file: ${ftype}\nReally load?`)) { qs('#fu_file').value = '' return } diff --git a/js/utils.js b/js/utils.js index 9a5049c..428a6cb 100755 --- a/js/utils.js +++ b/js/utils.js @@ -1,48 +1,25 @@ /** Make a node */ -function mk (e) { +exports.mk = function mk (e) { return document.createElement(e) } /** Find one by query */ -function qs (s) { +exports.qs = function qs (s) { return document.querySelector(s) } /** Find all by query */ -function qsa (s) { +exports.qsa = function qsa (s) { return document.querySelectorAll(s) } /** Convert any to bool safely */ -function bool (x) { +exports.bool = function bool (x) { return (x === 1 || x === '1' || x === true || x === 'true') } -/** - * Filter 'spacebar' and 'return' from keypress handler, - * and when they're pressed, fire the callback. - * use $(...).on('keypress', cr(handler)) - */ -function cr (hdl) { - return function (e) { - if (e.which === 10 || e.which === 13 || e.which === 32) { - hdl() - } - } -} - -/** HTML escape */ -function esc (str) { - return $.htmlEscape(str) -} - -/** Check for undefined */ -function undef (x) { - return typeof x == 'undefined' -} - /** Safe json parse */ -function jsp (str) { +exports.jsp = function jsp (str) { try { return JSON.parse(str) } catch (e) { @@ -51,33 +28,28 @@ function jsp (str) { } } -/** Create a character from ASCII code */ -function Chr (n) { - return String.fromCharCode(n) -} - /** Decode number from 2B encoding */ -function parse2B (s, i = 0) { +exports.parse2B = function parse2B (s, i = 0) { return (s.charCodeAt(i++) - 1) + (s.charCodeAt(i) - 1) * 127 } /** Decode number from 3B encoding */ -function parse3B (s, i = 0) { +exports.parse3B = function parse3B (s, i = 0) { return (s.charCodeAt(i) - 1) + (s.charCodeAt(i + 1) - 1) * 127 + (s.charCodeAt(i + 2) - 1) * 127 * 127 } /** Encode using 2B encoding, returns string. */ -function encode2B (n) { +exports.encode2B = function encode2B (n) { let lsb, msb lsb = (n % 127) n = ((n - lsb) / 127) lsb += 1 msb = (n + 1) - return Chr(lsb) + Chr(msb) + return String.fromCharCode(lsb) + String.fromCharCode(msb) } /** Encode using 3B encoding, returns string. */ -function encode3B (n) { +exports.encode3B = function encode3B (n) { let lsb, msb, xsb lsb = (n % 127) n = (n - lsb) / 127 @@ -86,5 +58,5 @@ function encode3B (n) { n = (n - msb) / 127 msb += 1 xsb = (n + 1) - return Chr(lsb) + Chr(msb) + Chr(xsb) + return String.fromCharCode(lsb) + String.fromCharCode(msb) + String.fromCharCode(xsb) } diff --git a/js/wifi.js b/js/wifi.js index 8e90328..40d8020 100644 --- a/js/wifi.js +++ b/js/wifi.js @@ -1,4 +1,8 @@ -(function (w) { +const $ = require('./lib/chibi') +const { mk, bool } = require('./utils') +const tr = require('./lang') + +;(function (w) { const authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'] let curSSID @@ -15,8 +19,8 @@ $('#sta-nw').toggleClass('hidden', name.length === 0) $('#sta-nw-nil').toggleClass('hidden', name.length > 0) - $('#sta-nw .essid').html(esc(name)) - const nopw = undef(password) || password.length === 0 + $('#sta-nw .essid').html($.htmlEscape(name)) + const nopw = !password || password.length === 0 $('#sta-nw .passwd').toggleClass('hidden', nopw) $('#sta-nw .nopasswd').toggleClass('hidden', !nopw) $('#sta-nw .ip').html(ip.length > 0 ? tr('wifi.connected_ip_is') + ip : tr('wifi.not_conn')) @@ -96,7 +100,7 @@ if (+$th.data('pwd')) { // this AP needs a password - conn_pass = prompt(tr('wifi.enter_passwd').replace(':ssid:', conn_ssid)) + conn_pass = window.prompt(tr('wifi.enter_passwd').replace(':ssid:', conn_ssid)) if (!conn_pass) return } @@ -120,10 +124,10 @@ /** Ask the CGI what APs are visible (async) */ function scanAPs () { - if (_demo) { - onScan(_demo_aps, 200) + if (window._demo) { + onScan(window._demo_aps, 200) } else { - $.get('http://' + _root + '/cfg/wifi/scan', onScan) + $.get('http://' + window._root + '/cfg/wifi/scan', onScan) } } diff --git a/package.json b/package.json index 580acd6..9dc416e 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,7 @@ "webpack": "^3.6.0" }, "scripts": { - "babel": "babel $@", - "minify": "babel-minify $@", + "webpack": "webpack $@", "sass": "node-sass $@" } } diff --git a/pages/term.php b/pages/term.php index bbf97cd..101e7be 100644 --- a/pages/term.php +++ b/pages/term.php @@ -2,9 +2,9 @@