bdcontract-web-ide/js/onlineide/leftmenu_en.js
2021-06-15 21:43:19 +08:00

748 lines
26 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var createProject = function () {
var body = "<div class='input-group mb-3'>";
body += "<div class='input-group-prepend'> <span class='input-group-text'>Project Name</span> </div>";
body += "<input type='text' id='newProjectNameInput' class='form-control' placeholder='Required'>";
body += "</div>";
body += "<div class='input-group mb-3'>";
body += "<div class='input-group-prepend'> <span class='input-group-text'>Project Template</span> </div>";
body += "<select class='custom-select ' id='selectProjectTemplate' aria-label='Example select with button addon' style='appearance: none'> <option selected>Empty Project</option> <option>Data Sharing Project</option> </select>";
body += "</div>";
body += "<div class='input-group mb-3'>";
body += "<div class='input-group-prepend'> <span class='input-group-text'>Project DOI</span> </div>";
body += "<input type='text' id='newProjectDOIInput' class='form-control' placeholder='OptionalA registered project DOI'>";
body += "</div>";
$("#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 += "<div class='headingDiv' id='headingDiv" + i + pad + "'>";
ret += " ";
ret += "<button style='text-align:left; border:0; box-shadow:none;' class='projectLine btn btn-outline-primary mt-1 btn-block collapsed' type='button' data-toggle='collapse' data-target='#collapseDiv"
+ i
+ pad
+ "' aria-expanded='false' aria-controls='collapseDiv"
+ i + pad + "' onclick=switchProject('" + i + "')>";
ret += "<img alt='Brand'";
ret += "class='trigimg mr-2' src='./images/onlineide/trigle.png' />";
ret += dataContent;
ret += "</button> </div>";
ret += "<div id='collapseDiv"
+ i
+ pad
+ "' class='collapse' aria-expanded='false' aria-labelledby='headingDiv"
+ i + pad + "' data-parent='#" + dataParent + "'>";
ret += "<div style='padding-left:15px; border-bottom: 1px solid #999; border-left: 1px solid #999; border-right: 1px solid #999;'>loading...</div></div>";
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 = "<div class='accordion " + clz + "' id='" + subLineID + "'>";
var dirIcon = "<img alt='Brand'";
dirIcon += "class='trigimg mr-1' src='./images/onlineide/trigle.png' />";
for (var i = 0; i < data.subFiles.length; i++) {
var obj = data.subFiles[i];
var divHtml = "";
var clickfun = "";
if (obj.subFiles == undefined) {
clickfun = "onclick = 'clickProjectFile(\"" + preFix + obj.name
+ "\")'" + " class='projectFileDiv' ";
} else {
clickfun = "onclick ='clickProjectDir(\"" + preFix + obj.name
+ "\")'" + " class='projectFileDiv' ";
}
if (obj.subFiles != undefined) {
divHtml = "<div class=' row ' "
+ clickfun
+ ">"
+ "<div class='col-sm-12 fileLine' data-toggle='collapse' data-target='#accrodionLine"
+ order
+ "_"
+ i
+ "' aria-expended='true' aria-controls='accrodionLine"
+ order
+ "_"
+ i
+ "' style='margin-left:"
+ extraPadding
+ "px; border-left:1px solid #999; padding:0;' id='headingSub"
+ order + "'>" + dirIcon + "<span >" + obj.name
+ "</span></div>";
divHtml += "<div id='accrodionLine" + order + "_" + i
+ "' class='collapse col-sm-12' aria-labeledby='headingSub"
+ order + "'>";
divHtml += getProjectTreeHtml2(obj, clz, preFix + obj.name + "/",
extraPadding + 12, order + "_" + i);
divHtml += "</div>";
divHtml += "</div>";
} else {
divHtml = "<div class='row ' " + clickfun + ">"
+ "<div class='col-sm-12 fileLine' style='margin-left:"
+ extraPadding + "px; border-left:1px solid #999;'><span>"
+ obj.name + "</span></div></div>";
}
ret += divHtml;
}
if (data.subFiles.length == 0) {
divHtml = "<div class='row ' onclick='clickEmpty(\"" + preFix + "\")'>"
+ "<div class='col-sm-12 fileLine' style='margin-left:"
+ extraPadding
+ "px; border-left:1px solid #999;'><span>当前目录为空"
+ "</span></div></div>";
ret += divHtml;
}
ret += "</div>";
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 = "<ul class='" + clz + "'>";
for (var i = 0; i < data.subFiles.length; i++) {
var obj = data.subFiles[i];
var clickfun = "";
if (obj.subFiles == undefined) {
clickfun = "onclick = 'clickProjectFile(\"" + preFix + obj.name
+ "\")'" + " class='projectFileDiv' ";
} else {
clickfun = "onclick ='clickProjectDir(\"" + preFix + obj.name
+ "\")'" + " class='projectFileDiv'";
}
ret += "<li><div " + clickfun + ">" + obj.name + "</div>";
if (obj.subFiles != undefined)
ret += getProjectTreeHtml(obj, "subFileTreeUl", preFix + obj.name
+ "/");
ret += "</li>"
}
return ret + "</ul>";
};
// context menu callbacks=======================
var showRename = function (projectName) {
var body = "<div class='input-group mb-3'>";
body += "<div class='input-group-prepend'>";
body += " <span class='input-group-text' >输入新名称</span>";
body += "</div> <input type='text' id='dialogInput' class='form-control' value='"
+ projectName + "'></div>";
$("#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 = "<div class='input-group mb-3'>";
body += " <span class='input-group-text' >请确认是否删除:" + projectName
+ "</span>";
body += " </div>";
$("#dialogBodyDiv").html(body);
showDialog("删除项目", function () {
global.projectName = projectName;
deleteFile();
});
};
var showCreateFile = function (projectName, isDir) {
var body = "<div class='input-group mb-3'>";
body += "<div class='input-group-prepend'>";
body += " <span class='input-group-text' >创建文件" + (isDir ? "夹" : "")
+ "</span>";
body += "</div> <input type='text' id='newProjectNameInput' class='form-control' placeholder='新文件"
+ (isDir ? "夹" : "") + "'></div>";
$("#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 = "<div class='input-group mb-3'>";
body += " <span class='input-group-text' id='progressTextDiv' ></span>";
body += "</div>";
body += "<div class='row'><div class='col-sm-12'><div class='progress'> <div id='progressDiv' class='progress-bar-animated progress-bar progress-bar-striped' role='progressbar' style='width: 5%' aria-valuenow='5' aria-valuemin='0' aria-valuemax='100'></div>";
body += "</div></div></div>";
$("#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 += "&timestamp=" + 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));
};