diff --git a/demo/index.html b/demo/index.html index 60d0b376..264e50ae 100644 --- a/demo/index.html +++ b/demo/index.html @@ -22,6 +22,7 @@ +

xterm.js: xterm, in the browser

diff --git a/demo/main.js b/demo/main.js index f1245cb0..ee4dca70 100644 --- a/demo/main.js +++ b/demo/main.js @@ -138,19 +138,7 @@ function _hide_file_info() { } function _download(xfer, buffer) { - var uint8array = new Uint8Array(buffer); - var blob = new Blob([uint8array]); - var url = URL.createObjectURL(blob); - - var el = document.createElement("a"); - el.style.display = "none"; - el.href = url; - el.download = xfer.get_details().name; - document.body.appendChild(el); - - //It seems like a security problem that this actually works. - //But, hey. - el.click(); + return Zmodem.Browser.save_to_disk(buffer, xfer.get_details().name); } function _update_progress(xfer) { @@ -164,151 +152,118 @@ function _update_progress(xfer) { document.getElementById("percent_received").textContent = percent_received; } +var start_form = document.getElementById("zm_start"); + // END UI STUFF //---------------------------------------------------------------------- -var text_encoder = new TextEncoder(); -var zsentry = new Zmodem.Sentry(); +function _handle_receive_session(zsession) { + zsession.on("offer", function(xfer) { + _show_file_info(xfer); -var zsession; -function handleWSMessage(evt) { - var input = Array.prototype.slice.call( - new Uint8Array( - (typeof evt.data === "string") ? text_encoder.encode(evt.data) : evt.data - ) - ); + var offer_form = document.getElementById("zm_offer"); + offer_form.style.display = ""; + offer_form.onsubmit = function(e) { + offer_form.style.display = "none"; - if (zsession) { - zsession.consume(input); - if (zsession.has_ended()) { - if (zsession.type === "receive") { - input = zsession.get_trailing_bytes(); + //START + if (offer_form.zmaccept.value) { + 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 { - input = []; + _hide_file_info(); + xfer.skip(); } - zsession = null; - } - else input = []; //keep ZMODEM from going to the terminal + //END + }; + } ); + + zsession.start(); +} + +function _handle_send_session(zsession) { + 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 files_obj = file_el.files; + + Zmodem.Browser.send_files( + zsession, + files_obj, + { + on_offer_response(obj, xfer) { + console.log("offer", xfer ? "accepted" : "skipped"); + }, + on_file_complete(obj) { + console.log("COMPLETE", obj); + }, + } + ).then( + zsession.close.bind(zsession), + console.error.bind(console) + ); + }; +} + +var text_encoder = new TextEncoder(); +var zsentry = new Zmodem.Sentry( { + to_terminal(octets) { + term.write( + String.fromCharCode.apply(String, octets) + ); + }, + + sender(octets) { + socket.send( new Uint8Array(octets) ); + }, + + on_retract() { + start_form.style.display = "none"; + start_form.onsubmit = null; + }, + + on_detect(detection) { + start_form.style.display = ""; + start_form.onsubmit = function(e) { + start_form.style.display = "none"; + + //Aborted + if (!e.currentTarget.zmstart.value) { + return; + } + + var zsession = detection.confirm(); + + //HERE + if (zsession.type === "receive") { + _handle_receive_session(zsession); + } + else { + _handle_send_session(zsession); + } + }; + }, +} ); + +function handleWSMessage(evt) { + + //For some reason the first message from the server is text. + if (typeof evt.data === "string") { + term.write(evt.data); } else { - let termbytes; - [termbytes, zsession] = zsentry.parse(input); - input = termbytes; - - if (zsession) { - - zsession.set_sender( (octets) => { - socket.send( new Uint8Array(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) - ); + zsentry.consume(evt.data); } } diff --git a/demo/zmodemjs b/demo/zmodemjs index 7220230d..f19e3fcf 160000 --- a/demo/zmodemjs +++ b/demo/zmodemjs @@ -1 +1 @@ -Subproject commit 7220230d12ce5eb4c42c59442a5924d98abc1c1f +Subproject commit f19e3fcfc0bc80eaa25e4cbae1dedf26ca7d6b2b