var createProject = function () { var body = "
"; body += "
Project Name
"; body += ""; body += "
"; body += "
"; body += "
Project Template
"; body += ""; body += "
"; body += "
"; body += "
Project DOI
"; body += ""; body += "
"; $("#dialogBodyDiv").html(body); showDialog("Create New Project", sendCreateProject); }; var sendCreateProject = function () { var projectName = $("#newProjectNameInput")[0].value; if (projectName == undefined || projectName.length == 0) { setTimeout(function () { myToast("Create Failed", "Please input the project name."); }, 1000); return; } var projectTemplate = $("#selectProjectTemplate")[0].value; if (projectTemplate == undefined || projectName.length == 0) { setTimeout(function () { myToast("Create Failed", "Please select the project template."); }, 1000); return; } var projectDOI = $("#newProjectDOIInput")[0].value; // console.log("[sendCreateProject] projectName:" + projectName + ", projectTemplate:" + projectTemplate + ", projectDOI:" + projectDOI); var arg = {}; var privateTab = $("#privateprojecttab").hasClass("active"); if (privateTab) arg.isPrivate = true; else arg.isPrivate = false; arg.dir = "./"; arg.action = "createFile"; arg.isFolder = true; arg.name = projectName; arg.projectTemplate = projectTemplate; if (arg.dir.indexOf("..") != -1) { console.log(arg.dir); myToast("项目名称不符合规范!", "请勿包含 . .. / \\"); return; } if (arg.name.indexOf(".") != -1 || arg.name.indexOf("..") != -1 || arg.name.indexOf("/") != -1 || arg.name.indexOf("\\") != -1) { console.log(arg.name); myToast("项目名称不符合规范!", "请勿包含 . .. / \\"); return; } if (!(projectDOI == undefined || projectDOI.length == 0)) arg.projectDOI = projectDOI; global.filewssocket.send(JSON.stringify(arg)); } var listFiles = function () { global.wssocket.send("{\"action\":\"listProjects\",\"isPrivate\":false}"); global.wssocket.send("{\"action\":\"listProjects\",\"isPrivate\":true}"); }; var updateGlobalProject = function () { setTimeout(updateGlobalProjectInternal, 100); }; var updateGlobalProjectInternal = function () { var isPublic = $("#publicprojecttab").hasClass("active"); // console.log("updateGlobalProject, isPublic:" + isPublic); if (isPublic) global.projects = global.publicProjects; else global.projects = global.privateProjects; mainVue.projects = global.projects; }; // ==========WSHandler callbacks========= var onListProjects = function (obj) { global.filewssocket = global.wssocket; var data = JSON.parse(obj.data); var projectDiv = "publicprojectAccordion"; var publicTab = $("#publicprojecttab").hasClass("active"); var pad = ""; if (obj.isPrivate != undefined && obj.isPrivate) { pad = "_p"; global.privateProjects = data; projectDiv = "privateprojectAccordion"; if (!publicTab) global.projects = data; global.privateProjects = data; } else { if (publicTab) { global.projects = data; } global.publicProjects = data; } mainVue.projects = global.projects; var html = ""; for (var i = 0; i < data.length; i++) { var dataContent = data[i]; if (dataContent.length > 40) { dataContent = dataContent.substr(0, 40) + "..." } html += getProjectLineHtml(i, dataContent, projectDiv, obj.isPrivate); } $("#" + projectDiv).html(html); $.contextMenu({ selector: '#' + projectDiv + '> .headingDiv', zIndex: 10, callback: function (key, options) { var projectID = this[0].id.replace("headingDiv", "").replace("_p", ""); var projectName = global.projects[projectID]; global.projectName = projectName; if (key == "Rename") { showRename(projectName); } else if (key == "Delete") { showDelete(projectName); } else if (key == "Export") { downloadContract(projectName); } }, items: { "Export": { name: "Download Project", icon: "copy" }, "Rename": { name: "Rename Project", icon: "edit" }, "Delete": { name: "Delete Project", icon: "delete" } } }); }; var onListProject = function (obj) { var pad = ""; if (obj.isPrivate != undefined && obj.isPrivate) { pad = "_p"; } var data = JSON.parse(obj.data); var title = global.projects[global.lastClickedProjectId]; if (!data.isDir) { console.log("TODO dipslay fileContent"); } else { var listDiv = $("#collapseDiv" + global.lastClickedProjectId + pad); listDiv.html(getProjectTreeHtml2(data, "projectTreeUl", "/" + title + "/", 24, global.lastClickedProjectId + pad)); $.contextMenu({ selector: '.fileLine', zIndex: 10, callback: function (key, options) { // console.log(this); // console.log(key); // console.log(this[0]); var projectName = this[0].parentElement.onclick + ""; projectName = projectName.split("\n")[1]; projectName = projectName.replace(/^[^"]*"/g, "").replace( /".*$/g, ""); global.projectName = projectName; if (key == "Rename") { showRename(projectName); } else if (key == "Delete") { showDelete(projectName); } else if (key == "Create File") { showCreateFile(projectName, false); } else if (key == "Create Folder") { showCreateFile(projectName, true); } else if (key == "Upload File") { global.lastClickProjectName = projectName; $("#uploadFileInput").click(); } }, items: { "New": { name: "New", icon: "add", items: { "Create File": { name: "File", icon: "copy" }, "Create Folder": { name: "Folder", icon: "paste" }, "Upload File": { name: "Upload File", icon: "loading" } } }, "Rename": { name: "Rename", icon: "edit" }, "Delete": { name: "Delete", icon: "delete" } } }); } } // ==========WSHandler done===================== // projectbutton callbacks====================== var getProjectLineHtml = function (i, dataContent, dataParent, isPrivate) { var ret = ""; var pad = ""; if (isPrivate) { pad = "_p"; } ret += "
"; ret += " "; ret += "
"; return ret; }; var switchProject = function (i) { var pingObj = {}; pingObj.action = "listProject"; pingObj.project = global.projects[i]; var isPrivate = $("#privateprojecttab").hasClass("active"); pingObj.isPrivate = isPrivate; global.lastClickedProjectId = i; // if (global.fileContentMap.has(pingObj.project)) { // clickTab(pingObj.project); // } else // console.log(pingObj.project); // console.log(global.lastClickedProjectId); global.filewssocket.send(JSON.stringify(pingObj)); }; var getProjectTreeHtml2 = function (data, clz, preFix, extraPadding, order) { if (data == undefined || data.subFiles == undefined) return ""; var subLineID = "accrodionLine" + order; var ret = "
"; var dirIcon = "Brand" + "
" + dirIcon + "" + obj.name + "
"; divHtml += "
"; divHtml += getProjectTreeHtml2(obj, clz, preFix + obj.name + "/", extraPadding + 12, order + "_" + i); divHtml += "
"; divHtml += "
"; } else { divHtml = "
" + "
" + obj.name + "
"; } ret += divHtml; } if (data.subFiles.length == 0) { divHtml = "
" + "
当前目录为空" + "
"; ret += divHtml; } ret += ""; return ret; }; // Tab related handlers============ var onListFile = function (obj) { var data = JSON.parse(obj.data); data.name = "..."; data.changed = false; // .replace(/.*\//g,""); data.isPrivate = obj.isPrivate; mainVue.openedFiles.push(data); setTimeout(function () { clickTab(data.path); }, 100); }; var onStaticVerify = function (obj) { var data = {}; data.name = data.path = "/tmp/result_" + (new Date().getTime() % 1000) + ".txt"; obj = JSON.parse(obj.data); obj.result = JSON.parse(obj.result); data.val = JSON.stringify(obj, null, 4); mainVue.openedFiles.push(data); setTimeout(function () { clickTab(data.path); }, 100); } var clickProjectDir = function () { }; var clickProjectFile = function (tar) { var pingObj = {}; pingObj.action = "listFile"; pingObj.path = tar; pingObj.isPrivate = $("#privateprojecttab").hasClass("active"); for (var i = 0; i < mainVue.openedFiles.length; i++) { var file = mainVue.openedFiles[i]; if (file.path == tar) { clickTab(tar); return; } } global.filewssocket.send(JSON.stringify(pingObj)); }; var formatScriptEditor = function () { var from = global.scriptEditor.getCursor(true); var to = global.scriptEditor.getCursor(false); if (from == to) { from = { line: 0, ch: 0 }; to = { line: global.scriptEditor.lastLine() + 1, ch: 1 }; } global.scriptEditor.autoFormatRange(from, to); } var adjustFileName = function (title) { if (mainVue.openedFiles.length < 2) return; var totalLen = 90; var average = (totalLen - title.length - 6) / (mainVue.openedFiles.length - 1); average -= 4; for (var i = 0; i < mainVue.openedFiles.length; i++) { var file = mainVue.openedFiles[i]; if (file.path == title) file.name = file.path; else { if (file.path.length > average + 5) file.name = file.path.substr(0, average) + " ..."; else file.name = file.path; } if (file.changed) { file.name = "* " + file.name; } } }; var clickTab = function (title) { if (title.getAttribute != undefined) { title = title.getAttribute("path"); } if (global.currentFile != undefined && global.currentFile.val != undefined) { var val = global.scriptEditor.getValue(); if (global.currentFile.val != val) { global.currentFile.changed = true; } global.currentFile.val = val; } for (var i = 0; i < mainVue.openedFiles.length; i++) { var file = mainVue.openedFiles[i]; if (file.path == title) { if (file.val != undefined) { global.scriptEditor.setOption("mode", "application/javascript"); if (file.path.endsWith(".css")) { global.scriptEditor.setOption("mode", "text/css"); } if (file.path.endsWith(".html")) { global.scriptEditor.setOption("mode", "text/html"); } if (file.path.endsWith(".js")) { global.scriptEditor.setOption("mode", "application/javascript"); } global.scriptEditor.setValue(file.val); } else { global.scriptEditor.setValue("not text file!"); } $("#myFileTab a").removeClass("active"); $("#myFileTab a")[i].classList.add("active"); global.currentFile = file; adjustFileName(title); return; } } // it is Hello if (title == "Hello") { $("#myFileTab a")[0].classList.add("active"); global.scriptEditor.setValue("Hello Page"); adjustFileName(title); } }; var closeTab = function (ele) { var path = ele.getAttribute("path"); var newList = []; var pos = 0; for (var i = 0; i < mainVue.openedFiles.length; i++) { var file = mainVue.openedFiles[i]; if (file.path == global.currentFile.path) { pos = i; } if (file.path == path) { continue; } newList.push(file); } mainVue.openedFiles = newList; if (pos < mainVue.openedFiles.length) { clickTab(mainVue.openedFiles[pos].path); } else { pos--; if (pos >= 0) clickTab(mainVue.openedFiles[pos].path); } }; // Tab related handlers============ var getProjectTreeHtml = function (data, clz, preFix) { if (data == undefined || data.subFiles == undefined) return ""; var ret = ""; }; // context menu callbacks======================= var showRename = function (projectName) { var body = "
"; body += "
"; body += " 输入新名称"; body += "
"; $("#dialogBodyDiv").html(body); showDialog("重命名项目", function () { var pingObj = {}; var newVal = $("#dialogInput")[0].value; if (newVal == undefined || newVal.length == 0 || newVal.indexOf("..") != -1 || newVal.indexOf("\\") != -1) { setTimeout(function () { myToast("重命名失败", "新文件名不符合规范"); }, 1000); return; } pingObj.newFile = newVal; pingObj.action = "renameFile"; pingObj.oldFile = projectName; pingObj.isPrivate = $("#privateprojecttab").hasClass("active"); global.filewssocket.send(JSON.stringify(pingObj)); }); }; var showDelete = function (projectName) { var body = "
"; body += " 请确认是否删除:" + projectName + ""; body += "
"; $("#dialogBodyDiv").html(body); showDialog("删除项目", function () { global.projectName = projectName; deleteFile(); }); }; var showCreateFile = function (projectName, isDir) { var body = "
"; body += "
"; body += " 创建文件" + (isDir ? "夹" : "") + ""; body += "
"; $("#dialogBodyDiv").html(body); showDialog("创建新文件", function () { var fileName = $("#newProjectNameInput")[0].value; if (fileName == undefined || fileName.length == 0) { setTimeout(function () { myToast("新建文件失败", "请输入文件名"); }, 1000); return; } var arg = {}; var privateTab = $("#privateprojecttab").hasClass("active"); if (privateTab) arg.isPrivate = true; else arg.isPrivate = false; arg.dir = projectName; arg.action = "createFile"; arg.isFolder = isDir; arg.name = fileName; global.filewssocket.send(JSON.stringify(arg)); }); } var deleteFile = function () { var pingObj = {}; pingObj.file = global.projectName; pingObj.action = "deleteFile"; pingObj.isPrivate = $("#privateprojecttab").hasClass("active"); global.filewssocket.send(JSON.stringify(pingObj)); }; var saveFile = function () { var pingObj = {}; pingObj.isAppend = false; pingObj.isPrivate = global.currentFile.isPrivate; pingObj.path = global.currentFile.path; pingObj.action = "saveFile"; pingObj.content = global.scriptEditor.getValue(); if (pingObj.path == "Hello") { myToast("保存出错", "不能保存Hello"); return; } global.filewssocket.send(JSON.stringify(pingObj)); global.currentFile.changed = false; adjustFileName(global.currentFile.path); }; var sliceFile = function (file) { let piece = 1024 * 50; let totalSize = file.size; // 文件总大小 let start = 0; // 每次上传的开始字节 let end = start + piece; // 每次上传的结尾字节 let chunks = [] while (start < totalSize) { // 根据长度截取每次需要上传的数据 // File对象继承自Blob对象,因此包含slice方法 let blob = file.slice(start, end); chunks.push(blob) start = end; end = start + piece; } return chunks; }; var uploadInternal = function () { var isAppend = true; if (global.uploadOrder == 0) isAppend = false; if (global.uploadOrder >= global.chunks.length) { progressTextDiv.innerText = global.uploadFiles[global.fileOrder - 1].name + "上传已完成"; progressDiv.style.width = "100%"; setTimeout(uploadSingleFile, 500); return; } var num = global.uploadOrder * 100 / global.chunks.length; progressDiv.style.width = num.toFixed(2) + "%"; var chunk = global.chunks[global.uploadOrder]; let fd = new FormData(); fd.append("file", chunk); var isPrivate = $("#privateprojecttab").hasClass("active"); var arg = "path=" + global.lastClickProjectName; arg += "&fileName=" + global.uploadFileName; arg += "&isPrivate=" + isPrivate; arg += "&order=" + global.uploadOrder; arg += "&count=" + global.chunks.length; arg += "&pubKey=" + global.sm2Key.publicKey; var sign = sm2.doSignature(arg, global.sm2Key.privateKey, {hash: true, der: true}); arg += "&sign=" + sign; $.ajax({ url: `${global.urlparam ? (location.href.startsWith('https') ? 'https://' : 'http://') + global.urlparam.nodeAddr : '.'}/Upload?${arg}`, type: 'POST', data: fd, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success: function (data) { uploadInternal(); }, error: function (data) { console.log("[uploadFile] error!"); alert("Upload failed!"); } }); global.uploadOrder++; return; var pingObj = {}; pingObj.isAppend = false; pingObj.isPrivate = $("#privateprojecttab").hasClass("active"); pingObj.path = global.lastClickProjectName; pingObj.fileName = global.uploadFileName; pingObj.action = "uploadFile"; var text = btoa(new Uint8Array(chunk.arrayBuffer)); pingObj.content = text; global.filewssocket.send(JSON.stringify(pingObj)); } var uploadFile = function (obj) { console.log("uploadFile : "); global.uploadFiles = $("#uploadFileInput")[0].files; global.fileOrder = 0; var body = "
"; body += " "; body += "
"; body += "
"; body += "
"; $("#dialogBodyDiv").html(body); uploadSingleFile(); showDialog("正在上传文件", function () { cancelUpload(); }, function () { cancelUpload(); }); }; var uploadSingleFile = function () { var file = global.uploadFiles[global.fileOrder]; global.fileOrder++; if (file == undefined) { progressTextDiv.innerHTML = global.uploadFiles.length + "个文件全部上传完毕"; return; } else { progressTextDiv.innerHTML = "上传第(" + (global.fileOrder) + "/" + global.uploadFiles.length + ")个文件:" + file.name; } global.uploadFile = file; global.chunks = sliceFile(file); global.uploadOrder = 0; global.uploadFileName = file.name; uploadInternal(); }; var cancelUpload = function () { global.uploadOrder = global.chunks.length + 1; global.fileOrder = global.uploadFiles.length + 1; } var downloadContract = function (projectName) { var url; if (window.location.href.indexOf("/SCIDE") != -1) url = window.location.href.replace("/OnlineIDE.html", "/CMManager?"); else url = window.location.href.replace("/OnlineIDE.html", "/SCIDE/CMManager?"); var arg = "action=downloadContract&projectName=" arg += projectName; var isPrivate = $("#privateprojecttab").hasClass("active"); arg += "&isPrivate=" + isPrivate; arg += "&pubKey=" + global.sm2Key.publicKey; arg += "×tamp=" + new Date().getTime(); var sign = sm2.doSignature(arg, global.sm2Key.privateKey); arg += "&sign=" + sign; window.open(url + arg); }; var staticVerify = function () { var arg = {}; arg.action = "staticVerifyContract"; arg.contractid = "-"; arg.script = "-"; if (global.currentFile == undefined) { myToast("提示", "请打开一个文件以静态分析该项目"); return; } var p = global.currentFile.path; p = p.substr(0, p.indexOf("/", 1) + 1); arg.path = p; var privateTab = $("#privateprojecttab").hasClass("active"); if (privateTab) arg.isPrivate = true; else arg.isPrivate = false; global.wssocket.send(JSON.stringify(arg)); };