parent
963bfce9cc
commit
036a58ce12
@ -1,189 +1,190 @@ |
||||
/** Global generic init */ |
||||
$.ready(function () { |
||||
// Checkbox UI (checkbox CSS and hidden input with int value)
|
||||
$('.Row.checkbox').forEach(function(x) { |
||||
var inp = x.querySelector('input'); |
||||
var box = x.querySelector('.box'); |
||||
|
||||
$(box).toggleClass('checked', inp.value); |
||||
|
||||
var hdl = function() { |
||||
inp.value = 1 - inp.value; |
||||
$(box).toggleClass('checked', inp.value) |
||||
}; |
||||
|
||||
$(x).on('click', hdl).on('keypress', cr(hdl)); |
||||
}); |
||||
|
||||
// Expanding boxes on mobile
|
||||
$('.Box.mobcol,.Box.fold').forEach(function(x) { |
||||
var h = x.querySelector('h2'); |
||||
|
||||
var hdl = function() { |
||||
$(x).toggleClass('expanded'); |
||||
}; |
||||
$(h).on('click', hdl).on('keypress', cr(hdl)); |
||||
}); |
||||
|
||||
$('form').forEach(function(x) { |
||||
$(x).on('keypress', function(e) { |
||||
if ((e.keyCode == 10 || e.keyCode == 13) && e.ctrlKey) { |
||||
x.submit(); |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
// loader dots...
|
||||
setInterval(function () { |
||||
$('.anim-dots').each(function (x) { |
||||
var $x = $(x); |
||||
var dots = $x.html() + '.'; |
||||
if (dots.length == 5) dots = '.'; |
||||
$x.html(dots); |
||||
}); |
||||
}, 1000); |
||||
|
||||
// flipping number boxes with the mouse wheel
|
||||
$('input[type=number]').on('mousewheel', function(e) { |
||||
var $this = $(this); |
||||
var val = +$this.val(); |
||||
if (isNaN(val)) val = 1; |
||||
|
||||
var step = +($this.attr('step') || 1); |
||||
var min = +$this.attr('min'); |
||||
var max = +$this.attr('max'); |
||||
if(e.wheelDelta > 0) { |
||||
val += step; |
||||
} else { |
||||
val -= step; |
||||
} |
||||
|
||||
if (typeof min != 'undefined') val = Math.max(val, +min); |
||||
if (typeof max != 'undefined') val = Math.min(val, +max); |
||||
$this.val(val); |
||||
|
||||
if ("createEvent" in document) { |
||||
var evt = document.createEvent("HTMLEvents"); |
||||
evt.initEvent("change", false, true); |
||||
$this[0].dispatchEvent(evt); |
||||
} else { |
||||
$this[0].fireEvent("onchange"); |
||||
} |
||||
|
||||
e.preventDefault(); |
||||
}); |
||||
|
||||
var errAt = location.search.indexOf('err='); |
||||
if (errAt !== -1 && qs('.Box.errors')) { |
||||
var errs = location.search.substr(errAt+4).split(','); |
||||
var hres = []; |
||||
errs.forEach(function(er) { |
||||
var lbl = qs('label[for="'+er+'"]'); |
||||
if (lbl) { |
||||
lbl.classList.add('error'); |
||||
hres.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, '')); |
||||
} else { |
||||
hres.push(er); |
||||
} |
||||
}); |
||||
|
||||
qs('.Box.errors .list').innerHTML = hres.join(', '); |
||||
qs('.Box.errors').classList.remove('hidden'); |
||||
} |
||||
|
||||
Modal.init(); |
||||
Notify.init(); |
||||
|
||||
// remove tabindixes from h2 if wide
|
||||
if (window.innerWidth > 550) { |
||||
$('.Box h2').forEach(function (x) { |
||||
x.removeAttribute('tabindex'); |
||||
}); |
||||
|
||||
// brand works as a link back to term in widescreen mode
|
||||
var br = qs('#brand'); |
||||
br && br.addEventListener('click', function() { |
||||
location.href='/'; // go to terminal
|
||||
}); |
||||
} |
||||
// Checkbox UI (checkbox CSS and hidden input with int value)
|
||||
$('.Row.checkbox').forEach(function (x) { |
||||
var inp = x.querySelector('input'); |
||||
var box = x.querySelector('.box'); |
||||
|
||||
$(box).toggleClass('checked', inp.value); |
||||
|
||||
var hdl = function () { |
||||
inp.value = 1 - inp.value; |
||||
$(box).toggleClass('checked', inp.value) |
||||
}; |
||||
|
||||
$(x).on('click', hdl).on('keypress', cr(hdl)); |
||||
}); |
||||
|
||||
// Expanding boxes on mobile
|
||||
$('.Box.mobcol,.Box.fold').forEach(function (x) { |
||||
var h = x.querySelector('h2'); |
||||
|
||||
var hdl = function () { |
||||
$(x).toggleClass('expanded'); |
||||
}; |
||||
$(h).on('click', hdl).on('keypress', cr(hdl)); |
||||
}); |
||||
|
||||
$('form').forEach(function (x) { |
||||
$(x).on('keypress', function (e) { |
||||
if ((e.keyCode == 10 || e.keyCode == 13) && e.ctrlKey) { |
||||
x.submit(); |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
// loader dots...
|
||||
setInterval(function () { |
||||
$('.anim-dots').each(function (x) { |
||||
var $x = $(x); |
||||
var dots = $x.html() + '.'; |
||||
if (dots.length == 5) dots = '.'; |
||||
$x.html(dots); |
||||
}); |
||||
}, 1000); |
||||
|
||||
// flipping number boxes with the mouse wheel
|
||||
$('input[type=number]').on('mousewheel', function (e) { |
||||
var $this = $(this); |
||||
var val = +$this.val(); |
||||
if (isNaN(val)) val = 1; |
||||
|
||||
var step = +($this.attr('step') || 1); |
||||
var min = +$this.attr('min'); |
||||
var max = +$this.attr('max'); |
||||
if (e.wheelDelta > 0) { |
||||
val += step; |
||||
} else { |
||||
val -= step; |
||||
} |
||||
|
||||
if (typeof min != 'undefined') val = Math.max(val, +min); |
||||
if (typeof max != 'undefined') val = Math.min(val, +max); |
||||
$this.val(val); |
||||
|
||||
if ("createEvent" in document) { |
||||
var evt = document.createEvent("HTMLEvents"); |
||||
evt.initEvent("change", false, true); |
||||
$this[0].dispatchEvent(evt); |
||||
} else { |
||||
$this[0].fireEvent("onchange"); |
||||
} |
||||
|
||||
e.preventDefault(); |
||||
}); |
||||
|
||||
var errAt = location.search.indexOf('err='); |
||||
if (errAt !== -1 && qs('.Box.errors')) { |
||||
var errs = location.search.substr(errAt + 4).split(','); |
||||
var hres = []; |
||||
errs.forEach(function (er) { |
||||
var lbl = qs('label[for="' + er + '"]'); |
||||
if (lbl) { |
||||
lbl.classList.add('error'); |
||||
hres.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, '')); |
||||
} else { |
||||
hres.push(er); |
||||
} |
||||
}); |
||||
|
||||
qs('.Box.errors .list').innerHTML = hres.join(', '); |
||||
qs('.Box.errors').classList.remove('hidden'); |
||||
} |
||||
|
||||
Modal.init(); |
||||
Notify.init(); |
||||
|
||||
// remove tabindixes from h2 if wide
|
||||
if (window.innerWidth > 550) { |
||||
$('.Box h2').forEach(function (x) { |
||||
x.removeAttribute('tabindex'); |
||||
}); |
||||
|
||||
// brand works as a link back to term in widescreen mode
|
||||
var br = qs('#brand'); |
||||
br && br.addEventListener('click', function () { |
||||
location.href = '/'; // go to terminal
|
||||
}); |
||||
} |
||||
}); |
||||
|
||||
$._loader = function(vis) { |
||||
$('#loader').toggleClass('show', vis); |
||||
$._loader = function (vis) { |
||||
$('#loader').toggleClass('show', vis); |
||||
}; |
||||
|
||||
function showPage() { |
||||
$('#content').addClass('load'); |
||||
$('#content').addClass('load'); |
||||
} |
||||
|
||||
$.ready(function() { |
||||
if (window.noAutoShow !== true) { |
||||
setTimeout(function () { |
||||
showPage(); |
||||
}, 1); |
||||
} |
||||
$.ready(function () { |
||||
if (window.noAutoShow !== true) { |
||||
setTimeout(function () { |
||||
showPage(); |
||||
}, 1); |
||||
} |
||||
}); |
||||
|
||||
|
||||
/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */ |
||||
if (!String.fromCodePoint) { |
||||
(function() { |
||||
var defineProperty = (function() { |
||||
// IE 8 only supports `Object.defineProperty` on DOM elements
|
||||
try { |
||||
var object = {}; |
||||
var $defineProperty = Object.defineProperty; |
||||
var result = $defineProperty(object, object, object) && $defineProperty; |
||||
} catch(error) {} |
||||
return result; |
||||
}()); |
||||
var stringFromCharCode = String.fromCharCode; |
||||
var floor = Math.floor; |
||||
var fromCodePoint = function() { |
||||
var MAX_SIZE = 0x4000; |
||||
var codeUnits = []; |
||||
var highSurrogate; |
||||
var lowSurrogate; |
||||
var index = -1; |
||||
var length = arguments.length; |
||||
if (!length) { |
||||
return ''; |
||||
} |
||||
var result = ''; |
||||
while (++index < length) { |
||||
var codePoint = Number(arguments[index]); |
||||
if ( |
||||
!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
|
||||
codePoint < 0 || // not a valid Unicode code point
|
||||
codePoint > 0x10FFFF || // not a valid Unicode code point
|
||||
floor(codePoint) != codePoint // not an integer
|
||||
) { |
||||
throw RangeError('Invalid code point: ' + codePoint); |
||||
} |
||||
if (codePoint <= 0xFFFF) { // BMP code point
|
||||
codeUnits.push(codePoint); |
||||
} else { // Astral code point; split in surrogate halves
|
||||
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||||
codePoint -= 0x10000; |
||||
highSurrogate = (codePoint >> 10) + 0xD800; |
||||
lowSurrogate = (codePoint % 0x400) + 0xDC00; |
||||
codeUnits.push(highSurrogate, lowSurrogate); |
||||
} |
||||
if (index + 1 == length || codeUnits.length > MAX_SIZE) { |
||||
result += stringFromCharCode.apply(null, codeUnits); |
||||
codeUnits.length = 0; |
||||
} |
||||
} |
||||
return result; |
||||
}; |
||||
if (defineProperty) { |
||||
defineProperty(String, 'fromCodePoint', { |
||||
'value': fromCodePoint, |
||||
'configurable': true, |
||||
'writable': true |
||||
}); |
||||
} else { |
||||
String.fromCodePoint = fromCodePoint; |
||||
} |
||||
}()); |
||||
(function () { |
||||
var defineProperty = (function () { |
||||
// IE 8 only supports `Object.defineProperty` on DOM elements
|
||||
try { |
||||
var object = {}; |
||||
var $defineProperty = Object.defineProperty; |
||||
var result = $defineProperty(object, object, object) && $defineProperty; |
||||
} catch (error) { |
||||
} |
||||
return result; |
||||
}()); |
||||
var stringFromCharCode = String.fromCharCode; |
||||
var floor = Math.floor; |
||||
var fromCodePoint = function () { |
||||
var MAX_SIZE = 0x4000; |
||||
var codeUnits = []; |
||||
var highSurrogate; |
||||
var lowSurrogate; |
||||
var index = -1; |
||||
var length = arguments.length; |
||||
if (!length) { |
||||
return ''; |
||||
} |
||||
var result = ''; |
||||
while (++index < length) { |
||||
var codePoint = Number(arguments[index]); |
||||
if ( |
||||
!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
|
||||
codePoint < 0 || // not a valid Unicode code point
|
||||
codePoint > 0x10FFFF || // not a valid Unicode code point
|
||||
floor(codePoint) != codePoint // not an integer
|
||||
) { |
||||
throw RangeError('Invalid code point: ' + codePoint); |
||||
} |
||||
if (codePoint <= 0xFFFF) { // BMP code point
|
||||
codeUnits.push(codePoint); |
||||
} else { // Astral code point; split in surrogate halves
|
||||
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||||
codePoint -= 0x10000; |
||||
highSurrogate = (codePoint >> 10) + 0xD800; |
||||
lowSurrogate = (codePoint % 0x400) + 0xDC00; |
||||
codeUnits.push(highSurrogate, lowSurrogate); |
||||
} |
||||
if (index + 1 == length || codeUnits.length > MAX_SIZE) { |
||||
result += stringFromCharCode.apply(null, codeUnits); |
||||
codeUnits.length = 0; |
||||
} |
||||
} |
||||
return result; |
||||
}; |
||||
if (defineProperty) { |
||||
defineProperty(String, 'fromCodePoint', { |
||||
'value': fromCodePoint, |
||||
'configurable': true, |
||||
'writable': true |
||||
}); |
||||
} else { |
||||
String.fromCodePoint = fromCodePoint; |
||||
} |
||||
}()); |
||||
} |
||||
|
@ -1,8 +1,8 @@ |
||||
// Generated from PHP locale file
|
||||
var _tr = { |
||||
"wifi.connected_ip_is": "Connected, IP is ", |
||||
"wifi.not_conn": "Not connected.", |
||||
"wifi.enter_passwd": "Enter password for \":ssid:\"" |
||||
"wifi.connected_ip_is": "Connected, IP is ", |
||||
"wifi.not_conn": "Not connected.", |
||||
"wifi.enter_passwd": "Enter password for \":ssid:\"" |
||||
}; |
||||
|
||||
function tr(key) { return _tr[key] || '?'+key+'?'; } |
||||
|
@ -1,44 +1,44 @@ |
||||
/** Module for toggling a modal overlay */ |
||||
(function () { |
||||
var modal = {}; |
||||
var curCloseCb = null; |
||||
var modal = {}; |
||||
var curCloseCb = null; |
||||
|
||||
modal.show = function (sel, closeCb) { |
||||
var $m = $(sel); |
||||
$m.removeClass('hidden visible'); |
||||
setTimeout(function () { |
||||
$m.addClass('visible'); |
||||
}, 1); |
||||
curCloseCb = closeCb; |
||||
}; |
||||
modal.show = function (sel, closeCb) { |
||||
var $m = $(sel); |
||||
$m.removeClass('hidden visible'); |
||||
setTimeout(function () { |
||||
$m.addClass('visible'); |
||||
}, 1); |
||||
curCloseCb = closeCb; |
||||
}; |
||||
|
||||
modal.hide = function (sel) { |
||||
var $m = $(sel); |
||||
$m.removeClass('visible'); |
||||
setTimeout(function () { |
||||
$m.addClass('hidden'); |
||||
if (curCloseCb) curCloseCb(); |
||||
}, 500); // transition time
|
||||
}; |
||||
modal.hide = function (sel) { |
||||
var $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; |
||||
window.Modal = modal; |
||||
})(); |
||||
|
@ -1,32 +1,32 @@ |
||||
(function (nt) { |
||||
var sel = '#notif'; |
||||
var sel = '#notif'; |
||||
|
||||
var hideTmeo1; // timeout to start hiding (transition)
|
||||
var hideTmeo2; // timeout to add the hidden class
|
||||
var hideTmeo1; // timeout to start hiding (transition)
|
||||
var hideTmeo2; // timeout to add the hidden class
|
||||
|
||||
nt.show = function (message, timeout) { |
||||
$(sel).html(message); |
||||
Modal.show(sel); |
||||
nt.show = function (message, timeout) { |
||||
$(sel).html(message); |
||||
Modal.show(sel); |
||||
|
||||
clearTimeout(hideTmeo1); |
||||
clearTimeout(hideTmeo2); |
||||
clearTimeout(hideTmeo1); |
||||
clearTimeout(hideTmeo2); |
||||
|
||||
if (undef(timeout)) timeout = 2500; |
||||
if (undef(timeout)) timeout = 2500; |
||||
|
||||
hideTmeo1 = setTimeout(nt.hide, timeout); |
||||
}; |
||||
hideTmeo1 = setTimeout(nt.hide, timeout); |
||||
}; |
||||
|
||||
nt.hide = function () { |
||||
var $m = $(sel); |
||||
$m.removeClass('visible'); |
||||
hideTmeo2 = setTimeout(function () { |
||||
$m.addClass('hidden'); |
||||
}, 250); // transition time
|
||||
}; |
||||
nt.hide = function () { |
||||
var $m = $(sel); |
||||
$m.removeClass('visible'); |
||||
hideTmeo2 = setTimeout(function () { |
||||
$m.addClass('hidden'); |
||||
}, 250); // transition time
|
||||
}; |
||||
|
||||
nt.init = function() { |
||||
$(sel).on('click', function() { |
||||
nt.hide(this); |
||||
}); |
||||
}; |
||||
nt.init = function () { |
||||
$(sel).on('click', function () { |
||||
nt.hide(this); |
||||
}); |
||||
}; |
||||
})(window.Notify = {}); |
||||
|
@ -1,146 +1,146 @@ |
||||
/** File upload utility */ |
||||
var TermUpl = (function() { |
||||
var lines, // array of lines without newlines
|
||||
line_i, // current line index
|
||||
fuTout, // timeout handle for line sending
|
||||
send_delay_ms, // delay between lines (ms)
|
||||
nl_str, // newline string to use
|
||||
curLine, // current line (when using fuOil)
|
||||
inline_pos; // Offset in line (for long lines)
|
||||
|
||||
// lines longer than this are split to chunks
|
||||
// sending a super-ling string through the socket is not a good idea
|
||||
var MAX_LINE_LEN = 128; |
||||
|
||||
function fuOpen() { |
||||
fuStatus("Ready..."); |
||||
Modal.show('#fu_modal', onClose); |
||||
$('#fu_form').toggleClass('busy', false); |
||||
Input.blockKeys(true); |
||||
} |
||||
|
||||
function onClose() { |
||||
console.log("Upload modal closed."); |
||||
clearTimeout(fuTout); |
||||
line_i = 0; |
||||
Input.blockKeys(false); |
||||
} |
||||
|
||||
function fuStatus(msg) { |
||||
qs('#fu_prog').textContent = msg; |
||||
} |
||||
|
||||
function fuSend() { |
||||
var v = qs('#fu_text').value; |
||||
if (!v.length) { |
||||
fuClose(); |
||||
return; |
||||
} |
||||
|
||||
lines = v.split('\n'); |
||||
line_i = 0; |
||||
inline_pos = 0; // offset in line
|
||||
send_delay_ms = qs('#fu_delay').value; |
||||
|
||||
// sanitize - 0 causes overflows
|
||||
if (send_delay_ms < 0) { |
||||
send_delay_ms = 0; |
||||
qs('#fu_delay').value = send_delay_ms; |
||||
} |
||||
|
||||
nl_str = { |
||||
'CR': '\r', |
||||
'LF': '\n', |
||||
'CRLF': '\r\n', |
||||
}[qs('#fu_crlf').value]; |
||||
|
||||
$('#fu_form').toggleClass('busy', true); |
||||
fuStatus("Starting..."); |
||||
fuSendLine(); |
||||
} |
||||
|
||||
function fuSendLine() { |
||||
if (!$('#fu_modal').hasClass('visible')) { |
||||
// Modal is closed, cancel
|
||||
return; |
||||
} |
||||
|
||||
if (!Conn.canSend()) { |
||||
// postpone
|
||||
fuTout = setTimeout(fuSendLine, 1); |
||||
return; |
||||
} |
||||
|
||||
if (inline_pos == 0) { |
||||
curLine = lines[line_i++] + nl_str; |
||||
} |
||||
|
||||
var chunk; |
||||
if ((curLine.length - inline_pos) <= MAX_LINE_LEN) { |
||||
chunk = curLine.substr(inline_pos, MAX_LINE_LEN); |
||||
inline_pos = 0; |
||||
} else { |
||||
chunk = curLine.substr(inline_pos, MAX_LINE_LEN); |
||||
inline_pos += MAX_LINE_LEN; |
||||
} |
||||
|
||||
if (!Input.sendString(chunk)) { |
||||
fuStatus("FAILED!"); |
||||
return; |
||||
} |
||||
|
||||
var all = lines.length; |
||||
|
||||
fuStatus(line_i+" / "+all+ " ("+(Math.round((line_i/all)*1000)/10)+"%)"); |
||||
|
||||
if (lines.length > line_i || inline_pos > 0) { |
||||
fuTout = setTimeout(fuSendLine, send_delay_ms); |
||||
} else { |
||||
closeWhenReady(); |
||||
} |
||||
} |
||||
|
||||
function closeWhenReady() { |
||||
if (!Conn.canSend()) { |
||||
// stuck in XOFF still, wait to process...
|
||||
fuStatus("Waiting for Tx buffer..."); |
||||
setTimeout(closeWhenReady, 100); |
||||
} else { |
||||
fuStatus("Done."); |
||||
// delay to show it
|
||||
setTimeout(function() { |
||||
fuClose(); |
||||
}, 100); |
||||
} |
||||
} |
||||
|
||||
function fuClose() { |
||||
Modal.hide('#fu_modal'); |
||||
} |
||||
|
||||
return { |
||||
init: function() { |
||||
qs('#fu_file').addEventListener('change', function (evt) { |
||||
var reader = new FileReader(); |
||||
var file = evt.target.files[0]; |
||||
console.log("Selected file type: "+file.type); |
||||
if (!file.type.match(/text\/.*|application\/(json|csv|.*xml.*|.*script.*)/)) { |
||||
// Deny load of blobs like img - can crash browser and will get corrupted anyway
|
||||
if (!confirm("This does not look like a text file: "+file.type+"\nReally load?")) { |
||||
qs('#fu_file').value = ''; |
||||
return; |
||||
} |
||||
} |
||||
reader.onload = function(e) { |
||||
var txt = e.target.result.replace(/[\r\n]+/,'\n'); |
||||
qs('#fu_text').value = txt; |
||||
}; |
||||
console.log("Loading file..."); |
||||
reader.readAsText(file); |
||||
}, false); |
||||
}, |
||||
close: fuClose, |
||||
start: fuSend, |
||||
open: fuOpen, |
||||
} |
||||
var TermUpl = (function () { |
||||
var lines, // array of lines without newlines
|
||||
line_i, // current line index
|
||||
fuTout, // timeout handle for line sending
|
||||
send_delay_ms, // delay between lines (ms)
|
||||
nl_str, // newline string to use
|
||||
curLine, // current line (when using fuOil)
|
||||
inline_pos; // Offset in line (for long lines)
|
||||
|
||||
// lines longer than this are split to chunks
|
||||
// sending a super-ling string through the socket is not a good idea
|
||||
var MAX_LINE_LEN = 128; |
||||
|
||||
function fuOpen() { |
||||
fuStatus("Ready..."); |
||||
Modal.show('#fu_modal', onClose); |
||||
$('#fu_form').toggleClass('busy', false); |
||||
Input.blockKeys(true); |
||||
} |
||||
|
||||
function onClose() { |
||||
console.log("Upload modal closed."); |
||||
clearTimeout(fuTout); |
||||
line_i = 0; |
||||
Input.blockKeys(false); |
||||
} |
||||
|
||||
function fuStatus(msg) { |
||||
qs('#fu_prog').textContent = msg; |
||||
} |
||||
|
||||
function fuSend() { |
||||
var v = qs('#fu_text').value; |
||||
if (!v.length) { |
||||
fuClose(); |
||||
return; |
||||
} |
||||
|
||||
lines = v.split('\n'); |
||||
line_i = 0; |
||||
inline_pos = 0; // offset in line
|
||||
send_delay_ms = qs('#fu_delay').value; |
||||
|
||||
// sanitize - 0 causes overflows
|
||||
if (send_delay_ms < 0) { |
||||
send_delay_ms = 0; |
||||
qs('#fu_delay').value = send_delay_ms; |
||||
} |
||||
|
||||
nl_str = { |
||||
'CR': '\r', |
||||
'LF': '\n', |
||||
'CRLF': '\r\n', |
||||
}[qs('#fu_crlf').value]; |
||||
|
||||
$('#fu_form').toggleClass('busy', true); |
||||
fuStatus("Starting..."); |
||||
fuSendLine(); |
||||
} |
||||
|
||||
function fuSendLine() { |
||||
if (!$('#fu_modal').hasClass('visible')) { |
||||
// Modal is closed, cancel
|
||||
return; |
||||
} |
||||
|
||||
if (!Conn.canSend()) { |
||||
// postpone
|
||||
fuTout = setTimeout(fuSendLine, 1); |
||||
return; |
||||
} |
||||
|
||||
if (inline_pos == 0) { |
||||
curLine = lines[line_i++] + nl_str; |
||||
} |
||||
|
||||
var chunk; |
||||
if ((curLine.length - inline_pos) <= MAX_LINE_LEN) { |
||||
chunk = curLine.substr(inline_pos, MAX_LINE_LEN); |
||||
inline_pos = 0; |
||||
} else { |
||||
chunk = curLine.substr(inline_pos, MAX_LINE_LEN); |
||||
inline_pos += MAX_LINE_LEN; |
||||
} |
||||
|
||||
if (!Input.sendString(chunk)) { |
||||
fuStatus("FAILED!"); |
||||
return; |
||||
} |
||||
|
||||
var all = lines.length; |
||||
|
||||
fuStatus(line_i + " / " + all + " (" + (Math.round((line_i / all) * 1000) / 10) + "%)"); |
||||
|
||||
if (lines.length > line_i || inline_pos > 0) { |
||||
fuTout = setTimeout(fuSendLine, send_delay_ms); |
||||
} else { |
||||
closeWhenReady(); |
||||
} |
||||
} |
||||
|
||||
function closeWhenReady() { |
||||
if (!Conn.canSend()) { |
||||
// stuck in XOFF still, wait to process...
|
||||
fuStatus("Waiting for Tx buffer..."); |
||||
setTimeout(closeWhenReady, 100); |
||||
} else { |
||||
fuStatus("Done."); |
||||
// delay to show it
|
||||
setTimeout(function () { |
||||
fuClose(); |
||||
}, 100); |
||||
} |
||||
} |
||||
|
||||
function fuClose() { |
||||
Modal.hide('#fu_modal'); |
||||
} |
||||
|
||||
return { |
||||
init: function () { |
||||
qs('#fu_file').addEventListener('change', function (evt) { |
||||
var reader = new FileReader(); |
||||
var file = evt.target.files[0]; |
||||
console.log("Selected file type: " + file.type); |
||||
if (!file.type.match(/text\/.*|application\/(json|csv|.*xml.*|.*script.*)/)) { |
||||
// Deny load of blobs like img - can crash browser and will get corrupted anyway
|
||||
if (!confirm("This does not look like a text file: " + file.type + "\nReally load?")) { |
||||
qs('#fu_file').value = ''; |
||||
return; |
||||
} |
||||
} |
||||
reader.onload = function (e) { |
||||
var txt = e.target.result.replace(/[\r\n]+/, '\n'); |
||||
qs('#fu_text').value = txt; |
||||
}; |
||||
console.log("Loading file..."); |
||||
reader.readAsText(file); |
||||
}, false); |
||||
}, |
||||
close: fuClose, |
||||
start: fuSend, |
||||
open: fuOpen, |
||||
} |
||||
})(); |
||||
|
@ -1,163 +1,163 @@ |
||||
(function(w) { |
||||
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2']; |
||||
var curSSID; |
||||
|
||||
// Get XX % for a slider input
|
||||
function rangePt(inp) { |
||||
return Math.round(((inp.value / inp.max)*100)) + '%'; |
||||
} |
||||
|
||||
// Display selected STA SSID etc
|
||||
function selectSta(name, password, ip) { |
||||
$('#sta_ssid').val(name); |
||||
$('#sta_password').val(password); |
||||
|
||||
$('#sta-nw').toggleClass('hidden', name.length == 0); |
||||
$('#sta-nw-nil').toggleClass('hidden', name.length > 0); |
||||
|
||||
$('#sta-nw .essid').html(e(name)); |
||||
var nopw = undef(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')); |
||||
} |
||||
|
||||
/** Update display for received response */ |
||||
function onScan(resp, status) { |
||||
//var ap_json = {
|
||||
// "result": {
|
||||
// "inProgress": "0",
|
||||
// "APs": [
|
||||
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
|
||||
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
|
||||
// ]
|
||||
// }
|
||||
//};
|
||||
|
||||
if (status != 200) { |
||||
// bad response
|
||||
rescan(5000); // wait 5sm then retry
|
||||
return; |
||||
} |
||||
|
||||
try { |
||||
resp = JSON.parse(resp); |
||||
} catch (e) { |
||||
console.log(e); |
||||
rescan(5000); |
||||
return; |
||||
} |
||||
|
||||
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0); |
||||
rescan(done ? 15000 : 1000); |
||||
if (!done) return; // no redraw yet
|
||||
|
||||
// clear the AP list
|
||||
var $list = $('#ap-list'); |
||||
// remove old APs
|
||||
$('#ap-list .AP').remove(); |
||||
|
||||
$list.toggleClass('hidden', !done); |
||||
$('#ap-loader').toggleClass('hidden', done); |
||||
|
||||
// scan done
|
||||
resp.result.APs.sort(function (a, b) { |
||||
return b.rssi - a.rssi; |
||||
}).forEach(function (ap) { |
||||
ap.enc = parseInt(ap.enc); |
||||
|
||||
if (ap.enc > 4) return; // hide unsupported auths
|
||||
|
||||
var item = mk('div'); |
||||
|
||||
var $item = $(item) |
||||
.data('ssid', ap.essid) |
||||
.data('pwd', ap.enc) |
||||
.attr('tabindex', 0) |
||||
.addClass('AP'); |
||||
|
||||
// mark current SSID
|
||||
if (ap.essid == curSSID) { |
||||
$item.addClass('selected'); |
||||
} |
||||
|
||||
var inner = mk('div'); |
||||
$(inner).addClass('inner') |
||||
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc)) |
||||
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format($.htmlEscape(ap.essid))) |
||||
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc])); |
||||
|
||||
$item.on('click', function () { |
||||
var $th = $(this); |
||||
|
||||
var conn_ssid = $th.data('ssid'); |
||||
var conn_pass = ''; |
||||
|
||||
if (+$th.data('pwd')) { |
||||
// this AP needs a password
|
||||
conn_pass = prompt(tr("wifi.enter_passwd").replace(":ssid:", conn_ssid)); |
||||
if (!conn_pass) return; |
||||
} |
||||
|
||||
$('#sta_password').val(conn_pass); |
||||
$('#sta_ssid').val(conn_ssid); |
||||
selectSta(conn_ssid, conn_pass, ''); |
||||
}); |
||||
|
||||
|
||||
item.appendChild(inner); |
||||
$list[0].appendChild(item); |
||||
}); |
||||
} |
||||
|
||||
function startScanning() { |
||||
$('#ap-loader').removeClass('hidden'); |
||||
$('#ap-scan').addClass('hidden'); |
||||
$('#ap-loader .anim-dots').html('.'); |
||||
|
||||
scanAPs(); |
||||
} |
||||
|
||||
/** Ask the CGI what APs are visible (async) */ |
||||
function scanAPs() { |
||||
if (_demo) { |
||||
onScan(_demo_aps, 200); |
||||
} else { |
||||
$.get('http://' + _root + '/cfg/wifi/scan', onScan); |
||||
} |
||||
} |
||||
|
||||
function rescan(time) { |
||||
setTimeout(scanAPs, time); |
||||
} |
||||
|
||||
/** Set up the WiFi page */ |
||||
function wifiInit(cfg) { |
||||
// Update slider value displays
|
||||
$('.Row.range').forEach(function(x) { |
||||
var inp = x.querySelector('input'); |
||||
var disp1 = x.querySelector('.x-disp1'); |
||||
var disp2 = x.querySelector('.x-disp2'); |
||||
var t = rangePt(inp); |
||||
$(disp1).html(t); |
||||
$(disp2).html(t); |
||||
$(inp).on('input', function() { |
||||
t = rangePt(inp); |
||||
$(disp1).html(t); |
||||
$(disp2).html(t); |
||||
}); |
||||
}); |
||||
|
||||
// Forget STA credentials
|
||||
$('#forget-sta').on('click', function() { |
||||
selectSta('', '', ''); |
||||
return false; |
||||
}); |
||||
|
||||
selectSta(cfg.sta_ssid, cfg.sta_password, cfg.sta_active_ip); |
||||
curSSID = cfg.sta_active_ssid; |
||||
} |
||||
|
||||
w.init = wifiInit; |
||||
w.startScanning = startScanning; |
||||
(function (w) { |
||||
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2']; |
||||
var curSSID; |
||||
|
||||
// Get XX % for a slider input
|
||||
function rangePt(inp) { |
||||
return Math.round(((inp.value / inp.max) * 100)) + '%'; |
||||
} |
||||
|
||||
// Display selected STA SSID etc
|
||||
function selectSta(name, password, ip) { |
||||
$('#sta_ssid').val(name); |
||||
$('#sta_password').val(password); |
||||
|
||||
$('#sta-nw').toggleClass('hidden', name.length == 0); |
||||
$('#sta-nw-nil').toggleClass('hidden', name.length > 0); |
||||
|
||||
$('#sta-nw .essid').html(e(name)); |
||||
var nopw = undef(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')); |
||||
} |
||||
|
||||
/** Update display for received response */ |
||||
function onScan(resp, status) { |
||||
//var ap_json = {
|
||||
// "result": {
|
||||
// "inProgress": "0",
|
||||
// "APs": [
|
||||
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
|
||||
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
|
||||
// ]
|
||||
// }
|
||||
//};
|
||||
|
||||
if (status != 200) { |
||||
// bad response
|
||||
rescan(5000); // wait 5sm then retry
|
||||
return; |
||||
} |
||||
|
||||
try { |
||||
resp = JSON.parse(resp); |
||||
} catch (e) { |
||||
console.log(e); |
||||
rescan(5000); |
||||
return; |
||||
} |
||||
|
||||
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0); |
||||
rescan(done ? 15000 : 1000); |
||||
if (!done) return; // no redraw yet
|
||||
|
||||
// clear the AP list
|
||||
var $list = $('#ap-list'); |
||||
// remove old APs
|
||||
$('#ap-list .AP').remove(); |
||||
|
||||
$list.toggleClass('hidden', !done); |
||||
$('#ap-loader').toggleClass('hidden', done); |
||||
|
||||
// scan done
|
||||
resp.result.APs.sort(function (a, b) { |
||||
return b.rssi - a.rssi; |
||||
}).forEach(function (ap) { |
||||
ap.enc = parseInt(ap.enc); |
||||
|
||||
if (ap.enc > 4) return; // hide unsupported auths
|
||||
|
||||
var item = mk('div'); |
||||
|
||||
var $item = $(item) |
||||
.data('ssid', ap.essid) |
||||
.data('pwd', ap.enc) |
||||
.attr('tabindex', 0) |
||||
.addClass('AP'); |
||||
|
||||
// mark current SSID
|
||||
if (ap.essid == curSSID) { |
||||
$item.addClass('selected'); |
||||
} |
||||
|
||||
var inner = mk('div'); |
||||
$(inner).addClass('inner') |
||||
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc)) |
||||
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format($.htmlEscape(ap.essid))) |
||||
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc])); |
||||
|
||||
$item.on('click', function () { |
||||
var $th = $(this); |
||||
|
||||
var conn_ssid = $th.data('ssid'); |
||||
var conn_pass = ''; |
||||
|
||||
if (+$th.data('pwd')) { |
||||
// this AP needs a password
|
||||
conn_pass = prompt(tr("wifi.enter_passwd").replace(":ssid:", conn_ssid)); |
||||
if (!conn_pass) return; |
||||
} |
||||
|
||||
$('#sta_password').val(conn_pass); |
||||
$('#sta_ssid').val(conn_ssid); |
||||
selectSta(conn_ssid, conn_pass, ''); |
||||
}); |
||||
|
||||
|
||||
item.appendChild(inner); |
||||
$list[0].appendChild(item); |
||||
}); |
||||
} |
||||
|
||||
function startScanning() { |
||||
$('#ap-loader').removeClass('hidden'); |
||||
$('#ap-scan').addClass('hidden'); |
||||
$('#ap-loader .anim-dots').html('.'); |
||||
|
||||
scanAPs(); |
||||
} |
||||
|
||||
/** Ask the CGI what APs are visible (async) */ |
||||
function scanAPs() { |
||||
if (_demo) { |
||||
onScan(_demo_aps, 200); |
||||
} else { |
||||
$.get('http://' + _root + '/cfg/wifi/scan', onScan); |
||||
} |
||||
} |
||||
|
||||
function rescan(time) { |
||||
setTimeout(scanAPs, time); |
||||
} |
||||
|
||||
/** Set up the WiFi page */ |
||||
function wifiInit(cfg) { |
||||
// Update slider value displays
|
||||
$('.Row.range').forEach(function (x) { |
||||
var inp = x.querySelector('input'); |
||||
var disp1 = x.querySelector('.x-disp1'); |
||||
var disp2 = x.querySelector('.x-disp2'); |
||||
var t = rangePt(inp); |
||||
$(disp1).html(t); |
||||
$(disp2).html(t); |
||||
$(inp).on('input', function () { |
||||
t = rangePt(inp); |
||||
$(disp1).html(t); |
||||
$(disp2).html(t); |
||||
}); |
||||
}); |
||||
|
||||
// Forget STA credentials
|
||||
$('#forget-sta').on('click', function () { |
||||
selectSta('', '', ''); |
||||
return false; |
||||
}); |
||||
|
||||
selectSta(cfg.sta_ssid, cfg.sta_password, cfg.sta_active_ip); |
||||
curSSID = cfg.sta_active_ssid; |
||||
} |
||||
|
||||
w.init = wifiInit; |
||||
w.startScanning = startScanning; |
||||
})(window.WiFi = {}); |
||||
|
Loading…
Reference in new issue