commit
b51a2d1b54
@ -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) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,14 @@ |
||||
require('./lib/polyfills') |
||||
require('./modal') |
||||
require('./notif') |
||||
require('./appcommon') |
||||
try { require('./demo') } catch (err) {} |
||||
require('./wifi') |
||||
|
||||
const $ = require('./lib/chibi') |
||||
const { qs } = require('./utils') |
||||
|
||||
/* Export stuff to the global scope for inline scripts */ |
||||
window.termInit = require('./term') |
||||
window.$ = $ |
||||
window.qs = qs |
@ -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 |
||||
|
@ -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 |
||||
|
@ -0,0 +1,57 @@ |
||||
|
||||
exports.themes = [ |
||||
[ // Tango
|
||||
'#111213', '#CC0000', '#4E9A06', '#C4A000', '#3465A4', '#75507B', '#06989A', '#D3D7CF', |
||||
'#555753', '#EF2929', '#8AE234', '#FCE94F', '#729FCF', '#AD7FA8', '#34E2E2', '#EEEEEC' |
||||
], |
||||
[ // Linux
|
||||
'#000000', '#aa0000', '#00aa00', '#aa5500', '#0000aa', '#aa00aa', '#00aaaa', '#aaaaaa', |
||||
'#555555', '#ff5555', '#55ff55', '#ffff55', '#5555ff', '#ff55ff', '#55ffff', '#ffffff' |
||||
], |
||||
[ // xterm
|
||||
'#000000', '#cd0000', '#00cd00', '#cdcd00', '#0000ee', '#cd00cd', '#00cdcd', '#e5e5e5', |
||||
'#7f7f7f', '#ff0000', '#00ff00', '#ffff00', '#5c5cff', '#ff00ff', '#00ffff', '#ffffff' |
||||
], |
||||
[ // rxvt
|
||||
'#000000', '#cd0000', '#00cd00', '#cdcd00', '#0000cd', '#cd00cd', '#00cdcd', '#faebd7', |
||||
'#404040', '#ff0000', '#00ff00', '#ffff00', '#0000ff', '#ff00ff', '#00ffff', '#ffffff' |
||||
], |
||||
[ // Ambience
|
||||
'#2e3436', '#cc0000', '#4e9a06', '#c4a000', '#3465a4', '#75507b', '#06989a', '#d3d7cf', |
||||
'#555753', '#ef2929', '#8ae234', '#fce94f', '#729fcf', '#ad7fa8', '#34e2e2', '#eeeeec' |
||||
], |
||||
[ // Solarized
|
||||
'#073642', '#dc322f', '#859900', '#b58900', '#268bd2', '#d33682', '#2aa198', '#eee8d5', |
||||
'#002b36', '#cb4b16', '#586e75', '#657b83', '#839496', '#6c71c4', '#93a1a1', '#fdf6e3' |
||||
] |
||||
] |
||||
|
||||
let colorTable256 = null |
||||
|
||||
exports.buildColorTable = function () { |
||||
if (colorTable256 !== null) return colorTable256 |
||||
|
||||
// 256color lookup table
|
||||
// should not be used to look up 0-15 (will return transparent)
|
||||
colorTable256 = new Array(16).fill('rgba(0, 0, 0, 0)') |
||||
|
||||
// fill color table
|
||||
// colors 16-231 are a 6x6x6 color cube
|
||||
for (let red = 0; red < 6; red++) { |
||||
for (let green = 0; green < 6; green++) { |
||||
for (let blue = 0; blue < 6; blue++) { |
||||
let redValue = red * 40 + (red ? 55 : 0) |
||||
let greenValue = green * 40 + (green ? 55 : 0) |
||||
let blueValue = blue * 40 + (blue ? 55 : 0) |
||||
colorTable256.push(`rgb(${redValue}, ${greenValue}, ${blueValue})`) |
||||
} |
||||
} |
||||
} |
||||
// colors 232-255 are a grayscale ramp, sans black and white
|
||||
for (let gray = 0; gray < 24; gray++) { |
||||
let value = gray * 10 + 8 |
||||
colorTable256.push(`rgb(${value}, ${value}, ${value})`) |
||||
} |
||||
|
||||
return colorTable256 |
||||
} |
@ -0,0 +1,37 @@ |
||||
const webpack = require('webpack') |
||||
const { execSync } = require('child_process') |
||||
const path = require('path') |
||||
|
||||
let hash = execSync('git rev-parse --short HEAD').toString().trim() |
||||
|
||||
let plugins = [new webpack.optimize.UglifyJsPlugin()] |
||||
let devtool = 'source-map' |
||||
|
||||
if (process.env.ESP_PROD) { |
||||
// ignore demo
|
||||
plugins.push(new webpack.IgnorePlugin(/\.\/demo(?:\.js)?$/)) |
||||
|
||||
// no source maps
|
||||
devtool = '' |
||||
} |
||||
|
||||
module.exports = { |
||||
entry: './js', |
||||
output: { |
||||
path: path.resolve(__dirname, 'out', 'js'), |
||||
filename: `app.${hash}.js` |
||||
}, |
||||
module: { |
||||
rules: [ |
||||
{ |
||||
test: /\.js$/, |
||||
exclude: [ |
||||
path.resolve(__dirname, 'node_modules') |
||||
], |
||||
loader: 'babel-loader' |
||||
} |
||||
] |
||||
}, |
||||
devtool, |
||||
plugins |
||||
} |
Loading…
Reference in new issue