diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..b4a5a6c1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "zmodemjs"] + path = demo/zmodemjs + url = https://github.com/FGasper/zmodemjs.git diff --git a/demo/app.js b/demo/app.js index 8637dad8..089ccf6e 100644 --- a/demo/app.js +++ b/demo/app.js @@ -21,6 +21,10 @@ app.get('/main.js', function(req, res){ res.sendFile(__dirname + '/main.js'); }); +app.get('/zmodemjs/*.js', function(req, res){ + res.sendFile(__dirname + req.url); +}); + app.post('/terminals', function (req, res) { var cols = parseInt(req.query.cols), rows = parseInt(req.query.rows), @@ -59,6 +63,7 @@ app.ws('/terminals/:pid', function (ws, req) { ws.send(logs[term.pid]); term.on('data', function(data) { +console.log("From PTY: ", escape(data) ); try { ws.send(data); } catch (ex) { diff --git a/demo/index.html b/demo/index.html index daa60b6f..60d0b376 100644 --- a/demo/index.html +++ b/demo/index.html @@ -12,9 +12,57 @@ + + + + + + + + + +

xterm.js: xterm, in the browser

+ +
+ + + + + + + + + +
+

Actions

diff --git a/demo/main.js b/demo/main.js index f4fb0a2a..c1d4d4e9 100644 --- a/demo/main.js +++ b/demo/main.js @@ -90,7 +90,7 @@ function createTerminal() { socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/'; term.open(terminalContainer); - term.fit(); + //term.fit(); // fit is called within a setTimeout, cols and rows need this. setTimeout(() => { @@ -109,13 +109,160 @@ function createTerminal() { socket.onopen = runRealTerminal; socket.onclose = runFakeTerminal; socket.onerror = runFakeTerminal; + + socket.addEventListener("message", handleWSMessage); }); }); }, 0); } +var text_encoder = new TextEncoder(); +var zsentry = new Zmodem.Sentry(); + +var zsession; +function handleWSMessage(evt) { + var binary = text_encoder.encode(evt.data); + var input = Array.prototype.slice.call( new Uint8Array(binary) ); +console.log("from WS", evt.data, input, evt.data.charCodeAt( evt.data.length - 2 )); + + if (zsession) { + zsession.consume(input); + if (zsession.has_ended()) { + input = zsession.get_trailing_bytes(); + zsession = null; + } + } + else { + let termbytes; + [termbytes, zsession] = zsentry.parse(input); + input = termbytes; + + if (zsession) { + + zsession.set_sender( (octets) => { + socket.send( String.fromCharCode.apply(String, octets) ); + } ); + + var start_form = document.getElementById("zm_start"); + start_form.style.display = ""; + start_form.onsubmit = function(e) { + start_form.style.display = "none"; + + if (zsession.type === "receive") { + zsession.on("offer", function(xfer) { + _show_file_info(xfer); + + var offer_form = document.getElementById("zm_offer"); + offer_form.style.display = ""; + offer_form.onsubmit = function(e) { + offer_form.style.display = "none"; + + if (offer_form.zmaccept) { + var FILE_BUFFER = []; + xfer.on("input", (payload) => { + _update_progress(xfer); + FILE_BUFFER.push.apply(FILE_BUFFER, payload); + }); + xfer.accept().then( () => { + _download(xfer, FILE_BUFFER); + _hide_file_info(); + } ); + } + else { + _hide_file_info(); + xfer.skip(); + } + }; + } ); + + zsession.start(); + } + else { + var choose_form = document.getElementById("zm_choose"); + choose_form.style.display = ""; + choose_form.onsubmit = function(e) { + choose_form.style.display = "none"; + + var file_el = document.getElementById("zm_files"); + var batch = []; + var total_size = 0; + for (var f=0; f { + if (xfer === undefined) { + return promise_callback(); //skipped + } + + return new Promise( (res) => { + var reader = new FileReader(); + reader.onerror = function(e) { + console.error("file read error", e); + throw("File read error: " + e); + }; + + var offset = xfer.get_offset(); + reader.onprogress = function(e) { + xfer.send( + new Uint8Array(e.target.result, offset) + ); + offset = e.loaded; + }; + + reader.onload = function(e) { + xfer.end( + new Uint8Array(e.target.result, offset) + ).then(res).then(promise_callback); + }; + + reader.readAsArrayBuffer(cur_b.obj); + } ); + } ) + } + else { + zsession.close(); + choose_form.style.display = "none"; + } + } + + promise_callback(); + }; + + } + }; + } + } + + if (input.length) { + term.write( + String.fromCharCode.apply(String, input) + ); + } +} + +//var text_encoder = new TextEncoder(); + function runRealTerminal() { - term.attach(socket); + //term.attach(socket); + + term.on("data", (d) => { + //socket.send( text_encoder.encode(d) ); + socket.send(d); + }); + term._initialized = true; } diff --git a/demo/zmodemjs b/demo/zmodemjs new file mode 160000 index 00000000..eefc61c2 --- /dev/null +++ b/demo/zmodemjs @@ -0,0 +1 @@ +Subproject commit eefc61c2c4cbad743dea53b417a4948a08b7b652