var term; var webreplws; var connected = false; var binary_state = 0; var put_file_name = null; var put_file_data = null; var get_file_name = null; var get_file_data = null; var _filename; sendfile = function () { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } var _codetext = blockpy.components.editor.codeMirror.getValue(); var _arr = blockpy.components.editor.codeMirror.getValue().split("\n"); // _arr.unshift("import gc"); // for (var i = 0; i < _arr.length; i++) { // if (_arr[i].indexOf("import") == -1) { // _arr.splice(i, 0, "gc.enable()"); // _arr.splice(i + 1, 0, "gc.collect()"); // break; // } // } _codetext = _arr.join("\n"); if (pythonnewcode || Blockly.Python.workspaceToCode(this.blockly)) { _codetext = pythonnewcode || Blockly.Python.workspaceToCode(this.blockly); } //web repl 上传 if ($(".select-connected")[0].selectedIndex) { _filename = "python" + Math.round(Math.random() * 100000); $('#runCode')[0].innerHTML = CCB.str_group.uploading; $('#runCode')[0].style.backgroundColor = "d9d9d9"; put_file_data = stringToUint8Array(_codetext); // stringToUint8Array($("#text")[0].innerHTML); put_file_name = _filename + ".py"; put_file(); } //有线上传 else { $('#runCode')[0].innerHTML = CCB.str_group.uploading;//CCB.str_group.uploading; // $('#runCode')[0].style.backgroundColor = "d9d9d9"; // $('#runCode')[0].style.backgroundColor = "#508cf0"; $('#send_file').addClass("disabled"); $('#uploadpy').addClass("disabled"); $('#qiehuanbtn').addClass("disabled"); $('#send_string').addClass("disabled"); $('#resetMainUIBtn').addClass("disabled"); $('#send_file').attr("disabled", true); $('#uploadpy').attr("disabled", true); $('#qiehuanbtn').attr("disabled", true); $('#send_string').attr("disabled", true); $('#resetMainUIBtn').attr("disabled", true); //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythonupload`, { method: 'POST', data: { comname: $("#ports")[0].value, code: _codetext, sid: CCB.socket.id, type: $("#mode")[0].selectedIndex == 1 }, complete: (data) => { setTimeout(function () { //成功之后去除上传中的提示,改成上传成功 if (CCB.iaboratory && _codetext.indexOf('# modal') != -1) { $(CCB.iaboratory).modal('open') } $('#runCode')[0].innerHTML = CCB.str_group.run_code; $('#send_file').removeClass("disabled"); $('#uploadpy').removeClass("disabled"); $('#qiehuanbtn').removeClass("disabled"); $('#send_string').removeClass("disabled"); $('#resetMainUIBtn').removeClass("disabled"); $('#send_file').attr("disabled", false); $('#uploadpy').attr("disabled", false); $('#qiehuanbtn').attr("disabled", false); $('#send_string').attr("disabled", false); $('#resetMainUIBtn').attr("disabled", false); }, 2000); }, error: function (error) { $('#runCode')[0].innerHTML = CCB.str_group.run_code; } }); } } sendstring = function () { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } if ($(".select-connected")[0].selectedIndex) { webreplws.send(data + "/r"); } else { $('#resetDevice')[0].innerHTML = CCB.str_group.reseting; // $('#resetDevice')[0].style.backgroundColor = "d9d9d9"; // $('#resetDevice')[0].style.backgroundColor = "#508cf0"; $('#send_file').addClass("disabled"); $('#uploadpy').addClass("disabled"); $('#qiehuanbtn').addClass("disabled"); $('#send_string').addClass("disabled"); $('#resetMainUIBtn').addClass("disabled"); $('#send_file').attr("disabled", true); $('#uploadpy').attr("disabled", true); $('#qiehuanbtn').attr("disabled", true); $('#send_string').attr("disabled", true); $('#resetMainUIBtn').attr("disabled", true); //上传中的处理 // $.ajax(`${CCB.socket.io.uri}/pythonreset`, { // method: 'POST', // data: { comname: $("#ports")[0].value, sid: CCB.socket.id }, $.ajax(`${CCB.socket.io.uri}/pythonreset`, { method: 'POST', data: { comname: $("#ports")[0].value, sid: CCB.socket.id }, complete: (data) => { //成功之后去除上传中的提示,改成上传成功 setTimeout(function () { eproxy.emit('progress-response', 'upload-success'); $('#resetDevice')[0].innerHTML = CCB.str_group.reset_device; $('#send_file').removeClass("disabled"); $('#uploadpy').removeClass("disabled"); $('#qiehuanbtn').removeClass("disabled"); $('#send_string').removeClass("disabled"); $('#resetMainUIBtn').removeClass("disabled"); $('#send_file').attr("disabled", false); $('#uploadpy').attr("disabled", false); $('#qiehuanbtn').attr("disabled", false); $('#send_string').attr("disabled", false); $('#resetMainUIBtn').attr("disabled", false); }, 2000); }, error: function (error) { $('#resetDevice')[0].innerHTML = CCB.str_group.reset_device; // $('#resetDevice')[0].style.backgroundColor = "#508cf0"; } }); } } sendcontent = function (data) { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } if ($(".select-connected")[0].selectedIndex) { webreplws.send(data); } else { //上传中的处理 $.ajax(`${CCB.socket.io.uri}/sendcontent`, { method: 'POST', data: { content: data, sid: CCB.socket.id }, complete: (data) => { }, error: function (error) { } }); } } uploadpyfile = function () { $('#error-btn').css('display', 'none'); var _codetext = blockpy.components.editor.codeMirror.getValue(); $('#uploadFiles')[0].innerHTML = CCB.str_group.uploading; // $('#runCuploadFilesode')[0].style.backgroundColor = "d9d9d9"; // $('#uploadFiles')[0].style.backgroundColor = "#508cf0"; $('#send_file').addClass("disabled"); $('#uploadpy').addClass("disabled"); $('#qiehuanbtn').addClass("disabled"); $('#send_string').addClass("disabled"); $('#resetMainUIBtn').addClass("disabled"); $('#send_file').attr("disabled", true); $('#uploadpy').attr("disabled", true); $('#qiehuanbtn').attr("disabled", true); $('#send_string').attr("disabled", true); $('#resetMainUIBtn').attr("disabled", true); var path = $("#mode")[0].selectedIndex == 1 ? "sd/user_latest_code.py" : "user_latest_code.py"; if ($(".select-connected")[0].selectedIndex) { } else { // console.log(CCB.iaboratory, _codetext.indexOf('# modal')) //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythonuploadfile`, { method: 'POST', data: { comname: $("#ports")[0].value, code: _codetext, sid: CCB.socket.id, name: path }, complete: (data) => { //成功之后去除上传中的提示,改成上传成功 setTimeout(function () { $('#uploadFiles')[0].innerHTML = Ardublockly.LOCALISED_TEXT.uploadFiles; $('#send_file').removeClass("disabled"); $('#uploadpy').removeClass("disabled"); $('#qiehuanbtn').removeClass("disabled"); $('#send_string').removeClass("disabled"); $('#resetMainUIBtn').removeClass("disabled"); $('#send_file').attr("disabled", false); $('#uploadpy').attr("disabled", false); $('#qiehuanbtn').attr("disabled", false); $('#send_string').attr("disabled", false); $('#resetMainUIBtn').attr("disabled", false); }, 2000); }, error: function (error) { $('#uploadFiles')[0].innerHTML = Ardublockly.LOCALISED_TEXT.uploadFiles; // $('#uploadFiles')[0].style.backgroundColor = "#508cf0"; } }); } } uploadfile = function (type) { $('#error-btn').css('display', 'none'); //var name = $("#mode")[0].selectedIndex == 1 ? "AI" : "IoT"; //var path = name + (type ? "模組_開機啓動可視化菜單界面" : "模組_開機運行上次的程式"); //readTxt("src/python/" + path + ".py", function (txt) { var _codetext = type ? "load_last_code_on_boot = 0" : "load_last_code_on_boot = 1"; //无限模式 if ($(".select-connected")[0].selectedIndex) { } else { //path = $("#mode")[0].selectedIndex == 1 ? "sd/main.py" : "boot.py"; path = "sd/config.cfg"; var _title = $('#runCuploadFilesode')[0].innerHTML; $('#runCuploadFilesode')[0].innerHTML = CCB.str_group.uploading; // $('#runCuploadFilesode')[0].style.backgroundColor = "d9d9d9"; // $('#runCuploadFilesode')[0].style.backgroundColor = "#508cf0"; $('#send_file').addClass("disabled"); $('#uploadpy').addClass("disabled"); $('#qiehuanbtn').addClass("disabled"); $('#send_string').addClass("disabled"); $('#resetMainUIBtn').addClass("disabled"); $('#send_file').attr("disabled", true); $('#uploadpy').attr("disabled", true); $('#qiehuanbtn').attr("disabled", true); $('#send_string').attr("disabled", true); $('#resetMainUIBtn').attr("disabled", true); //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythonuploadfile`, { method: 'POST', data: { comname: $("#ports")[0].value, code: _codetext, sid: CCB.socket.id, name: path }, complete: (data) => { setTimeout(function () { //成功之后去除上传中的提示,改成上传成功 $('#runCuploadFilesode')[0].innerHTML = _title; $('#send_file').removeClass("disabled"); $('#uploadpy').removeClass("disabled"); $('#qiehuanbtn').removeClass("disabled"); $('#send_string').removeClass("disabled"); $('#resetMainUIBtn').removeClass("disabled"); $('#send_file').attr("disabled", false); $('#uploadpy').attr("disabled", false); $('#qiehuanbtn').attr("disabled", false); $('#send_string').attr("disabled", false); $('#resetMainUIBtn').attr("disabled", false); }, 2000); }, error: function (error) { $('#runCuploadFilesode')[0].innerHTML = _title; // $('#runCuploadFilesode')[0].style.backgroundColor = "#508cf0"; } }); } } resetmainUI = function () { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } //web repl 上传 if ($(".select-connected")[0].selectedIndex) { _filename = "python" + Math.round(Math.random() * 100000); $('#resetMainUI')[0].innerHTML = CCB.str_group.uploading; $('#resetMainUI')[0].style.backgroundColor = "d9d9d9"; put_file_data = stringToUint8Array(_codetext); // stringToUint8Array($("#text")[0].innerHTML); put_file_name = _filename + ".py"; put_file(); } //有线上传 else { $('#resetMainUI')[0].innerHTML = CCB.str_group.uploading;//CCB.str_group.uploading; // $('#runCode')[0].style.backgroundColor = "d9d9d9"; // $('#runCode')[0].style.backgroundColor = "#508cf0"; $('#send_file').addClass("disabled"); $('#uploadpy').addClass("disabled"); $('#qiehuanbtn').addClass("disabled"); $('#send_string').addClass("disabled"); $('#resetMainUIBtn').addClass("disabled"); $('#send_file').attr("disabled", true); $('#uploadpy').attr("disabled", true); $('#qiehuanbtn').attr("disabled", true); $('#send_string').attr("disabled", true); $('#resetMainUIBtn').attr("disabled", true); //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythonupload`, { method: 'POST', data: { comname: $("#ports")[0].value, code: `def _CREATE_TEXT_FILE(_path): f = open(_path, 'w') f.close() _CREATE_TEXT_FILE("/sd/main.py")`, sid: CCB.socket.id, type: $("#mode")[0].selectedIndex == 1 }, complete: (data) => { $.ajax(`${CCB.socket.io.uri}/pythoncmd`, { method: 'POST', data: { comname: $("#ports")[0].value, code: `import machine machine.reset()`, sid: CCB.socket.id }, complete: (data) => { setTimeout(function () { //成功之后去除上传中的提示,改成上传成功 $('#resetMainUI')[0].innerHTML = CCB.str_group.reset_main_UI; $('#send_file').removeClass("disabled"); $('#uploadpy').removeClass("disabled"); $('#qiehuanbtn').removeClass("disabled"); $('#send_string').removeClass("disabled"); $('#resetMainUIBtn').removeClass("disabled"); $('#send_file').attr("disabled", false); $('#uploadpy').attr("disabled", false); $('#qiehuanbtn').attr("disabled", false); $('#send_string').attr("disabled", false); $('#resetMainUIBtn').attr("disabled", false); }, 2000); }, error: function (error) { } }); }, error: function (error) { $('#resetMainUI')[0].innerHTML = CCB.str_group.reset_main_UI; } }); } } //获取指定目录所有的文件 function pythoncmdselect(path, cb) { pythoncmd(` import os for filename in os.listdir("${path}"): print(filename)`, cb); } //删除指定的路径文件 function pythoncmddel(path, cb) { pythoncmd(` def ForceRMDir(DirName): try: os.remove(DirName) except OSError as e: try: for i in os.listdir(DirName + "/"): ForceRMDir(DirName + "/"+i) os.remove(DirName) except OSError as e: return "" ForceRMDir("${path}") for filename in os.listdir("${path.split("/").slice(0, -1).join("/") + '/'}"): print(filename) `, cb); } //创建指定文件夹 function pythoncmdcreate(path, cb) { pythoncmd(` import os os.mkdir("${path}") for filename in os.listdir("${path.split("/").slice(0, -1).join("/") + '/'}"): print(filename) `, cb); } //在指定目录上传文件 function pythoncmduploadfile(path, name, content, cb) { path = path + "/" + name; $.ajax(`${CCB.socket.io.uri}/pythonuploadfile`, { method: 'POST', data: { comname: $("#ports")[0].value, code: content, sid: CCB.socket.id, name: path }, complete: (data) => { cb(data) }, error: function (error) { cb(error) } }); } //在指定目录上传文件 function pythonuploadfilebyfile(path, name, file, cb) { path = path + "/" + name; var fm = new FormData(); fm.append('comname', $("#ports")[0].value); fm.append('sid', CCB.socket.id); fm.append('name', path); fm.append('img', file); $.ajax({ url: `${CCB.socket.io.uri}/pythonuploadfilebyfile`, type: 'post', method: 'POST', data: fm, contentType: false, processData: false, complete: (data) => { cb(data) }, error: function (error) { cb(error) } }); // var fordata = new FormData(); # 生成文件对象 // fordata.append('name',$('#name').val()); # 添加值 // fordata.append('myfiles',$('#myfiles')[0].files[0]); # 添加文件流 // $.ajax({ // url:'/ajaxfiles/', # 路由 // type:'post', # 请求的形式 // processData:false, # 不指定编码方式(默认指定编码 urlencode) // contentType:false, # 不处理数据(默认处理数据:name=lxx &age=18) // data:fordata, # 传文件的数据 // success:function (data) { # 请求成功回调函数 // alert(data) // } // }) } function pythoncmd(codetext, cb) { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythoncmd`, { method: 'POST', data: { comname: $("#ports")[0].value, code: codetext, sid: CCB.socket.id }, complete: (data) => { cb(data); }, error: function (error) { cb(error); } }); } function stringToUint8Array(str) { var arr = []; for (var i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); } var tmpUint8Array = new Uint8Array(arr); return tmpUint8Array } function calculate_size(win) { var cols = Math.floor(win.offsetWidth / 12) - 1; var rows = Math.floor(win.offsetHeight / 14); //var cols = Math.max(30, Math.min(30, (win.innerWidth - 280) / 7)) | 0; ///var rows = Math.max(24, Math.min(80, (win.innerHeight - 180) / 12)) | 0; return [cols, rows]; } (function () { window.onload = function () { /* var url = window.location.hash.substring(1); if (url) { document.getElementById('ipAddress').value = 'ws://' + url; } var size = calculate_size($("#term")[0]); term = new Terminal({ cols: size[0], rows: size[1], useStyle: true, screenKeys: true, cursorBlink: false }); term.open(document.getElementById("term")); show_https_warning(); */ }; window.addEventListener('resize', function () { /* var size = calculate_size(self); term.resize(size[0], size[1]); */ }); }).call(this); function show_https_warning() { if (window.location.protocol == 'https:') { var warningDiv = document.createElement('div'); warningDiv.style.cssText = 'background:#f99;padding:5px;margin-bottom:10px;line-height:1.5em;text-align:center'; warningDiv.innerHTML = [ 'At this time, the WebREPL client cannot be accessed over HTTPS connections.', 'Use a HTTP connection, eg. http://micropython.org/webrepl/.', 'Alternatively, download the files from GitHub and run them locally.' ].join('
'); document.body.insertBefore(warningDiv, document.body.childNodes[0]); term.resize(term.cols, term.rows - 7); } } function button_click() { if (connected) { connected = false; prepare_for_connect(); webreplws.close(); } else if (document.getElementById('ipAddress').value) { document.getElementById('ConnectBtn').innerHTML = CCB.str_group.run_code; $('#ConnectBtn')[0].style.backgroundColor = "#508cf0"; document.getElementById('ConnectBtn').innerHTML = CCB.str_group.connection; connect("ws://" + document.getElementById('ipAddress').value + ":8266"); document.getElementById('ipAddress').disabled = true; connected = true; } } function prepare_for_connect() { document.getElementById('ipAddress').disabled = false; document.getElementById('ConnectBtn').style.backgroundColor = "#508cf0"; document.getElementById('ConnectBtn').innerHTML = CCB.str_group.connect; } function update_file_status(s) { console.log(s); //document.getElementById('file-status').innerHTML = s; } function is_news() { } /** * 创建对话框 */ function Alert(c, t) { !t ? t = 3000 : ""; var div = document.createElement("div") div.style.cssText = "padding: 12px 25px 12px 25px;font-size: 16px;max-width:300px;min-width:100px;color: rgba(255,255,255,1);background: rgba(0,0,0,0.75);border-radius: 10px;position: fixed;top:20%;left:0px;right:0px;margin:0px auto;text-align:center; word-break: break-word;z-index:999; "; div.innerHTML = c; document.body.appendChild(div); setTimeout(function () { div.parentNode.removeChild(div); }, t); } function connect(url) { window.location.hash = url.substring(5); webreplws = new WebSocket(url); webreplws.binaryType = 'arraybuffer'; webreplws.onopen = function () { term.removeAllListeners('data'); term.on('data', function (data) { // Pasted data from clipboard will likely contain // LF as EOL chars. data = data.replace(/\n/g, "\r"); webreplws.send(data); }); term.on('title', function (title) { document.title = title; }); term.focus(); term.element.focus(); term.write('\x1b[31mWelcome to MicroPython!\x1b[m\r\n'); webreplws.onmessage = function (event) { if (event.data instanceof ArrayBuffer) { var data = new Uint8Array(event.data); switch (binary_state) { case 11: // first response for put if (decode_resp(data) == 0) { // send file data in chunks for (var offset = 0; offset < put_file_data.length; offset += 1024) { webreplws.send(put_file_data.slice(offset, offset + 1024)); } binary_state = 12; } break; case 12: $('#runCode')[0].innerHTML = CCB.str_group.run_code; $('#runCode')[0].style.backgroundColor = "#508cf0"; // final response for put if (decode_resp(data) == 0) { webreplws.send("import " + _filename); webreplws.send("\r"); update_file_status('Sent ' + put_file_name + ', ' + put_file_data.length + ' bytes'); Alert("上传成功"); } else { update_file_status('Failed sending ' + put_file_name); } binary_state = 0; break; case 21: // first response for get if (decode_resp(data) == 0) { binary_state = 22; var rec = new Uint8Array(1); rec[0] = 0; webreplws.send(rec); } break; case 22: { // file data var sz = data[0] | (data[1] << 8); if (data.length == 2 + sz) { // we assume that the data comes in single chunks if (sz == 0) { // end of file binary_state = 23; } else { // accumulate incoming data to get_file_data var new_buf = new Uint8Array(get_file_data.length + sz); new_buf.set(get_file_data); new_buf.set(data.slice(2), get_file_data.length); get_file_data = new_buf; update_file_status('Getting ' + get_file_name + ', ' + get_file_data.length + ' bytes'); var rec = new Uint8Array(1); rec[0] = 0; webreplws.send(rec); } } else { binary_state = 0; } break; } case 23: // final response if (decode_resp(data) == 0) { update_file_status('Got ' + get_file_name + ', ' + get_file_data.length + ' bytes'); saveAs(new Blob([get_file_data], { type: "application/octet-stream" }), get_file_name); } else { update_file_status('Failed getting ' + get_file_name); } binary_state = 0; break; case 31: // first (and last) response for GET_VER console.log('GET_VER', data); binary_state = 0; break; } } term.write(event.data); if (event.data == "Password: ") { webreplws.send("cocorobo\r"); document.getElementById('ConnectBtn').style.backgroundColor = "#f0505f"; document.getElementById('ConnectBtn').innerHTML = CCB.str_group.disconnect; } }; }; webreplws.onclose = function () { connected = false; if (term) { term.write('\x1b[31mDisconnected\x1b[m\r\n'); } term.off('data'); prepare_for_connect(); } } function decode_resp(data) { if (data[0] == 'W'.charCodeAt(0) && data[1] == 'B'.charCodeAt(0)) { var code = data[2] | (data[3] << 8); return code; } else { return -1; } } function put_file() { var dest_fname = put_file_name; var dest_fsize = put_file_data.length; // WEBREPL_FILE = "<2sBBQLH64s" var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64); rec[0] = 'W'.charCodeAt(0); rec[1] = 'A'.charCodeAt(0); rec[2] = 1; // put rec[3] = 0; rec[4] = 0; rec[5] = 0; rec[6] = 0; rec[7] = 0; rec[8] = 0; rec[9] = 0; rec[10] = 0; rec[11] = 0; rec[12] = dest_fsize & 0xff; rec[13] = (dest_fsize >> 8) & 0xff; rec[14] = (dest_fsize >> 16) & 0xff; rec[15] = (dest_fsize >> 24) & 0xff; rec[16] = dest_fname.length & 0xff; rec[17] = (dest_fname.length >> 8) & 0xff; for (var i = 0; i < 64; ++i) { if (i < dest_fname.length) { rec[18 + i] = dest_fname.charCodeAt(i); } else { rec[18 + i] = 0; } } // initiate put binary_state = 11; update_file_status('Sending ' + put_file_name + '...'); webreplws.send(rec); } function get_file(name) { var src_fname = name; //document.getElementById('get_filename').value; // WEBREPL_FILE = "<2sBBQLH64s" var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64); rec[0] = 'W'.charCodeAt(0); rec[1] = 'A'.charCodeAt(0); rec[2] = 2; // get rec[3] = 0; rec[4] = 0; rec[5] = 0; rec[6] = 0; rec[7] = 0; rec[8] = 0; rec[9] = 0; rec[10] = 0; rec[11] = 0; rec[12] = 0; rec[13] = 0; rec[14] = 0; rec[15] = 0; rec[16] = src_fname.length & 0xff; rec[17] = (src_fname.length >> 8) & 0xff; for (var i = 0; i < 64; ++i) { if (i < src_fname.length) { rec[18 + i] = src_fname.charCodeAt(i); } else { rec[18 + i] = 0; } } // initiate get binary_state = 21; get_file_name = src_fname; get_file_data = new Uint8Array(0); update_file_status('Getting ' + get_file_name + '...'); webreplws.send(rec); } function get_ver() { // WEBREPL_REQ_S = "<2sBBQLH64s" var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64); rec[0] = 'W'.charCodeAt(0); rec[1] = 'A'.charCodeAt(0); rec[2] = 3; // GET_VER // rest of "rec" is zero // initiate GET_VER binary_state = 31; webreplws.send(rec); } function handle_put_file_select(evt) { // The event holds a FileList object which is a list of File objects, // but we only support single file selection at the moment. var files = evt.target.files; // Get the file info and load its data. var f = files[0]; put_file_name = f.name; var reader = new FileReader(); reader.onload = function (e) { put_file_data = new Uint8Array(e.target.result); document.getElementById('put-file-list').innerHTML = '' + escape(put_file_name) + ' - ' + put_file_data.length + ' bytes'; document.getElementById('put-file-button').disabled = false; }; reader.readAsArrayBuffer(f); } /* document.getElementById('put-file-select').addEventListener('click', function () { this.value = null; }, false); document.getElementById('put-file-select').addEventListener('change', handle_put_file_select, false); document.getElementById('put-file-button').disabled = true; */