feat: init; from commit c3adcb2e6bc94b46f4f34c03bc62abcce6c7e1a0 of BDContract
This commit is contained in:
807
js/onlineide/leftmenu.js
Normal file
807
js/onlineide/leftmenu.js
Normal file
@@ -0,0 +1,807 @@
|
||||
var createProject = function() {
|
||||
var body = "<div class='input-group mb-3'>";
|
||||
body += "<div class='input-group-prepend'> <span class='input-group-text'>项目名称</span> </div>";
|
||||
body += "<input type='text' id='newProjectNameInput' class='form-control' placeholder='必填'>";
|
||||
body += "</div>";
|
||||
|
||||
body += "<div class='input-group mb-3'>";
|
||||
body += "<div class='input-group-prepend'> <span class='input-group-text'>项目模板</span> </div>";
|
||||
body += "<select class='custom-select ' id='selectProjectTemplate' aria-label='Example select with button addon' style='appearance:none;-webkit-appearance:none'> <option selected>空白项目</option> <option>数据共享项目</option> </select>";
|
||||
body += "</div>";
|
||||
|
||||
body += "<div class='input-group mb-3'>";
|
||||
body += "<div class='input-group-prepend'> <span class='input-group-text'>项目DOI</span> </div>";
|
||||
body += "<input type='text' id='newProjectDOIInput' class='form-control' placeholder='选填,已注册的合约项目DOI'>";
|
||||
body += "</div>";
|
||||
|
||||
$("#dialogBodyDiv").html(body);
|
||||
showDialog("创建新项目", sendCreateProject);
|
||||
};
|
||||
|
||||
var sendCreateProject = function() {
|
||||
var projectName = $("#newProjectNameInput")[0].value;
|
||||
if (projectName == undefined || projectName.length == 0) {
|
||||
setTimeout(function() {
|
||||
myToast("创建项目失败", "请输入项目名");
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
var projectTemplate = $("#selectProjectTemplate")[0].value;
|
||||
if (projectTemplate == undefined || projectName.length == 0) {
|
||||
setTimeout(function() {
|
||||
myToast("创建项目失败", "请选择项目模板");
|
||||
}, 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 : "下载项目",
|
||||
icon : "copy"
|
||||
},
|
||||
"Rename" : {
|
||||
name : "重命名",
|
||||
icon : "edit"
|
||||
},
|
||||
"Delete" : {
|
||||
name : "删除",
|
||||
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) {
|
||||
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 : "新建",
|
||||
icon : "add",
|
||||
items : {
|
||||
"Create File" : {
|
||||
name : "文件",
|
||||
icon : "copy"
|
||||
},
|
||||
"Create Folder" : {
|
||||
name : "文件夹",
|
||||
icon : "paste"
|
||||
},
|
||||
"Upload File" : {
|
||||
name : "上传文件",
|
||||
icon : "loading"
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
"Rename" : {
|
||||
name : "重命名",
|
||||
icon : "edit"
|
||||
},
|
||||
"Delete" : {
|
||||
name : "删除",
|
||||
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");
|
||||
}
|
||||
// console.log("clickTab:" + title);
|
||||
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);
|
||||
}
|
||||
// console.log("closeTab:" + 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) {
|
||||
console.log("showRename");
|
||||
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;
|
||||
}
|
||||
// console.log("[sendCreateProject] projectName:" + projectName
|
||||
// + " fileName:" + fileName);
|
||||
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;
|
||||
console.log(arg);
|
||||
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() {
|
||||
console.log("upload:" + global.uploadOrder + " total:" + global.chunks.length);
|
||||
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%";
|
||||
console.log("setTimeout uploadSingleFile");
|
||||
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;
|
||||
console.log(arg);
|
||||
var sign = sm2.doSignature(arg, global.sm2Key.privateKey,{hash:true,der:true});
|
||||
console.log(sign)
|
||||
arg += "&sign=" + sign;
|
||||
$.ajax({
|
||||
url : './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(){
|
||||
console.log("uploadSingleFile");
|
||||
console.log(global.uploadFiles[global.fileOrder]);
|
||||
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;
|
||||
console.log(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) {
|
||||
// console.log(window.location.href);
|
||||
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,{hash:true,der:true});
|
||||
arg += "&sign=" + sign;
|
||||
console.log(url + arg);
|
||||
window.open(url + arg);
|
||||
};
|
||||
|
||||
var staticVerifyNaive = 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));
|
||||
};
|
||||
|
||||
var compile = function() {
|
||||
var arg = {};
|
||||
arg.action = "compile";
|
||||
if (global.projects[global.lastClickedProjectId] == undefined) {
|
||||
myToast("提示", "请选择一个合约项目进行编译");
|
||||
return;
|
||||
}
|
||||
arg.path = global.projects[global.lastClickedProjectId];
|
||||
var privateTab = $("#privateprojecttab").hasClass("active");
|
||||
if (privateTab)
|
||||
arg.isPrivate = true;
|
||||
else
|
||||
arg.isPrivate = false;
|
||||
global.wssocket.send(JSON.stringify(arg));
|
||||
};
|
||||
|
||||
var registerDOI = function() {
|
||||
var arg = {};
|
||||
arg.action = "registerDOI";
|
||||
if (global.projects[global.lastClickedProjectId] == undefined) {
|
||||
myToast("提示", "请选择一个合约进行DOI注册");
|
||||
return;
|
||||
}
|
||||
arg.path = global.projects[global.lastClickedProjectId];
|
||||
var privateTab = $("#privateprojecttab").hasClass("active");
|
||||
if (privateTab)
|
||||
arg.isPrivate = true;
|
||||
else
|
||||
arg.isPrivate = false;
|
||||
|
||||
var body = "<div class='input-group mb-3'>";
|
||||
body += " <span class='input-group-text' >如果已经注册过,再次注册将导致之前的注册被覆盖." + "</span>";
|
||||
body += " </div>";
|
||||
$("#dialogBodyDiv").html(body);
|
||||
showDialog("请确认是否注册" + arg.path + "的DOI", function() {
|
||||
global.wssocket.send(JSON.stringify(arg));
|
||||
});
|
||||
};
|
||||
|
||||
var onCompile = function(obj) {
|
||||
myToast("提示",global.projects[global.lastClickedProjectId] + "项目编译结果:\n"+obj.result);
|
||||
};
|
||||
|
||||
var onRegisterDOI = function(obj) {
|
||||
myToast("提示",global.projects[global.lastClickedProjectId] + "项目注册DOI结果:\n"+obj.result);
|
||||
};
|
||||
745
js/onlineide/leftmenu_en.js
Normal file
745
js/onlineide/leftmenu_en.js
Normal file
@@ -0,0 +1,745 @@
|
||||
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='Optional,A 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 : './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 += "×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));
|
||||
};
|
||||
0
js/onlineide/projectman.js
Executable file
0
js/onlineide/projectman.js
Executable file
298
js/onlineide/rightmenu.js
Normal file
298
js/onlineide/rightmenu.js
Normal file
@@ -0,0 +1,298 @@
|
||||
var expandOrCollapse = function () {
|
||||
if ($("#outputNav").hasClass("col-2")) {
|
||||
$("#outputNav").removeClass("col-2").addClass("col-6");
|
||||
$("#mainBox").removeClass("col-8").addClass("col-4");
|
||||
$("#expand").html("收起");
|
||||
} else {
|
||||
$("#outputNav").removeClass("col-6").addClass("col-2");
|
||||
$("#mainBox").removeClass("col-4").addClass("col-8");
|
||||
$("#expand").html("展开");
|
||||
}
|
||||
};
|
||||
var listContracts = function () {
|
||||
var request = {};
|
||||
request.action = "listContractProcess";
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var startContract = function () {
|
||||
var key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
|
||||
var sm2Key = JSON.parse(key.sm2Key);
|
||||
var projectId = $("#selectedProject")[0].value;
|
||||
var project = global.projects[projectId];
|
||||
startResult.innerText = "正在启动合约:" + project;
|
||||
|
||||
var request = {};
|
||||
request.action = "startContract";
|
||||
request.isPrivate = $("#privateprojecttab").hasClass("active");
|
||||
|
||||
request.owner = sm2Key.publicKey;
|
||||
request.requestID = new Date().getTime() + "";
|
||||
// request.contractid = $("#tabdiv")[0].value;
|
||||
// request.script = global.scriptEditor.getValue();
|
||||
request.path = "/" + project + "/mainfest.json";
|
||||
localStorage.setItem("persisStatus", JSON.stringify(request));
|
||||
{
|
||||
request.signature = sm2.doSignature("Fixed|" + request.path + "|"
|
||||
+ sm2Key.publicKey, sm2Key.privateKey);
|
||||
request.script = "empty";
|
||||
}
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
|
||||
};
|
||||
|
||||
var startContractAsDebug = function () {
|
||||
var key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
|
||||
var sm2Key = JSON.parse(key.sm2Key);
|
||||
var projectId = $("#selectedProject")[0].value;
|
||||
var project = global.projects[projectId];
|
||||
startResult.innerText = "正在以调试模式启动合约:" + project;
|
||||
|
||||
var request = {};
|
||||
request.action = "startContractAsDebug";
|
||||
request.isPrivate = $("#privateprojecttab").hasClass("active");
|
||||
|
||||
request.owner = sm2Key.publicKey;
|
||||
request.requestID = new Date().getTime() + "";
|
||||
// request.contractid = $("#tabdiv")[0].value;
|
||||
// request.script = global.scriptEditor.getValue();
|
||||
request.path = "/" + project + "/mainfest.json";
|
||||
localStorage.setItem("persisStatus", JSON.stringify(request));
|
||||
{
|
||||
request.signature = sm2.doSignature("Fixed|" + request.path + "|"
|
||||
+ sm2Key.publicKey, sm2Key.privateKey);
|
||||
request.script = "empty";
|
||||
}
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
|
||||
};
|
||||
var stopContract = function () {
|
||||
var request = {};
|
||||
request.action = "killContractProcess";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
request.name = mainVue.contracts[selectedContract.value].name;
|
||||
request.id = mainVue.contracts[selectedContract.value].id;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var genReadme = function () {
|
||||
|
||||
var request = {};
|
||||
request.isPrivate = global.currentFile.isPrivate;
|
||||
request.path = global.currentFile.path;
|
||||
var tmpIndex = request.path.lastIndexOf('/');
|
||||
var yjsName = request.path.substring(tmpIndex + 1, request.path.length - 4);
|
||||
request.path = request.path.substring(0, tmpIndex);
|
||||
var key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
|
||||
var sm2Key = JSON.parse(key.sm2Key);
|
||||
|
||||
for (c of mainVue.contracts) {
|
||||
// 这里假设合约名同文件名
|
||||
if (yjsName == c.name) {
|
||||
var exportedFunction = c.exportedFunctions;
|
||||
ReadmeFunction = [];
|
||||
for (let f of exportedFunction) {
|
||||
let description = "暂无描述";
|
||||
let readmeFunc = {};
|
||||
readmeFunc.functionName = f.functionName;
|
||||
readmeFunc.description = description;
|
||||
for (let anno of f.annotations) {
|
||||
if (anno.type == 'Param') {
|
||||
readmeFunc.args = anno.args[0];
|
||||
}
|
||||
else if (anno.type == 'Description') {
|
||||
readmeFunc.description = anno.args[0];
|
||||
}
|
||||
else if (anno.type == 'Result') {
|
||||
readmeFunc.result = anno.args[0];
|
||||
}
|
||||
}
|
||||
ReadmeFunction.push(readmeFunc);
|
||||
}
|
||||
request.action = "generateReadme";
|
||||
|
||||
request.contractID = c.id;
|
||||
request.contractName = c.name;
|
||||
request.pubkey = sm2Key.publicKey;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
return;
|
||||
}
|
||||
}
|
||||
myToast("生成文档失败", "请启动合约并检查合约与文件名是否一致!");
|
||||
};
|
||||
|
||||
var genData = function () {
|
||||
var key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
|
||||
var sm2Key = JSON.parse(key.sm2Key);
|
||||
var value = selectedContract.value;
|
||||
if (value != undefined && value != "选择合约实例") {
|
||||
var request = {};
|
||||
request.action = "generateDataFromRM";
|
||||
request.requestID = new Date().getTime() + "_"
|
||||
+ Math.floor(Math.random() * 10000);
|
||||
var contract = mainVue.contracts[selectedContract.value];
|
||||
request.isPrivate = $("#privateprojecttab").hasClass("active");
|
||||
request.contractID = contract.id;
|
||||
request.contractName = mainVue.contracts[selectedContract.value].name;
|
||||
var arg = {};
|
||||
if ($('#gasLimit').val() == undefined || $('#gasLimit').val() == "") {
|
||||
arg.gasLimit = '1000';
|
||||
} else {
|
||||
arg.gasLimit =$('#gasLimit').val();
|
||||
}
|
||||
// console.log("[arg.gasLimit]"+arg.gasLimit);
|
||||
request.pubkey = sm2Key.publicKey;
|
||||
request.signature = sm2.doSignature(request.contractID + "|" + arg.action
|
||||
+ "|" + arg.arg + "|" + sm2Key.publicKey, sm2Key.privateKey);
|
||||
request.arg = JSON.stringify(arg);
|
||||
localStorage.setItem("persisArg", JSON.stringify(request));
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var queryContractInstanceDOI = function () {
|
||||
var request = {};
|
||||
request.action = "queryContractInstanceDOI";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
request.name = mainVue.contracts[selectedContract.value].name;
|
||||
request.id = mainVue.contracts[selectedContract.value].id;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var queryContractInstanceInfoByDOI = function () {
|
||||
var request = {};
|
||||
request.action = "queryContractInstanceInfoByDOI";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
request.doi = contractInstanceDOIInput.value;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var importContractInstanceCodeByDOI = function () {
|
||||
var request = {};
|
||||
request.action = "importContractInstanceCodeByDOI";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
request.doi = contractInstanceDOIInput.value;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var openinClient = function () {
|
||||
var path = document.location.pathname;
|
||||
path = path.replace("/SCIDE","");
|
||||
path = path.replace("/OnlineIDE.html","");
|
||||
var url = path + "/client/bdwareclient.html?self=true&contract="
|
||||
+ mainVue.contracts[selectedContract.value].id;
|
||||
window.open(url);
|
||||
};
|
||||
|
||||
var stopAllContract = function () {
|
||||
var request = {};
|
||||
request.action = "killAllContract";
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
var selectContractToExecute = function () {
|
||||
var value = selectedContractAtExecute.value;
|
||||
if (value != undefined && value != "选择实例") {
|
||||
var exportedFunction = mainVue.contracts[value].exportedFunctions;
|
||||
mainVue.contractFunctions = exportedFunction;
|
||||
|
||||
var pingObj = {};
|
||||
pingObj.action = "connectTo";
|
||||
pingObj.name = mainVue.contracts[value].name;
|
||||
pingObj.id = mainVue.contracts[value].id;
|
||||
global.wssocket.send(JSON.stringify(pingObj));
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
var executeContract = function () {
|
||||
if (selectedFunction.value == undefined) {
|
||||
myToast("调用合约失败", "请选择合约方法");
|
||||
return;
|
||||
}
|
||||
if (selectedContractAtExecute.value == undefined) {
|
||||
myToast("调用合约失败", "请选择合约");
|
||||
return;
|
||||
}
|
||||
var key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
|
||||
var sm2Key = JSON.parse(key.sm2Key);
|
||||
|
||||
var request = {};
|
||||
|
||||
|
||||
|
||||
request.action = "executeContract";
|
||||
request.requestID = new Date().getTime() + "_"
|
||||
+ Math.floor(Math.random() * 10000);
|
||||
var contract = mainVue.contracts[selectedContractAtExecute.value];
|
||||
|
||||
request.contractID = contract.id;
|
||||
var arg = {};
|
||||
arg.action = contract.exportedFunctions[selectedFunction.value].functionName;
|
||||
arg.arg = executeContractArgInput.value;
|
||||
if ($('#gasLimit').val() == undefined || $('#gasLimit').val() == "") {
|
||||
arg.gasLimit = '1000';
|
||||
} else {
|
||||
arg.gasLimit =$('#gasLimit').val();
|
||||
}
|
||||
// console.log("[arg.gasLimit]"+arg.gasLimit);
|
||||
request.pubkey = sm2Key.publicKey;
|
||||
request.signature = sm2.doSignature(request.contractID + "|" + arg.action
|
||||
+ "|" + arg.arg + "|" + sm2Key.publicKey, sm2Key.privateKey,{hash:true,der:true});
|
||||
request.arg = JSON.stringify(arg);
|
||||
|
||||
localStorage.setItem("persisArg", JSON.stringify(request));
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
var executeContractWithDynamicResult = function () {
|
||||
if (selectedFunction.value == undefined) {
|
||||
myToast("调用合约失败", "请选择合约方法");
|
||||
return;
|
||||
}
|
||||
if (selectedContractAtExecute.value == undefined) {
|
||||
myToast("调用合约失败", "请选择合约");
|
||||
return;
|
||||
}
|
||||
console.log("executeContractWithDynamicResult");
|
||||
var request = {};
|
||||
request.action = "executeContract";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
|
||||
var contract = mainVue.contracts[selectedContractAtExecute.value];
|
||||
request.contractName = contract.id;
|
||||
|
||||
var arg = {};
|
||||
arg.action = contract.exportedFunctions[selectedFunction.value].functionName;
|
||||
arg.arg = executeContractArgInput.value;
|
||||
|
||||
request.withDyanmicAnalysis = true;
|
||||
request.arg = "{\"action\":\"" + arg.action + "\",\"arg\":\"" + arg.arg
|
||||
+ "\"}";
|
||||
request.pubkey = global.sm2Key.publicKey;
|
||||
request.signature = sm2.doSignature(request.contractID + "|" + arg.action
|
||||
+ "|" + arg.arg + "|" + global.sm2Key.publicKey,
|
||||
global.sm2Key.privateKey,{hash:true,der:true});
|
||||
localStorage.setItem("persisArg", JSON.stringify(request));
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
var testEvaluates = function () {
|
||||
if (selectedFunction.value == undefined) {
|
||||
myToast("调用合约失败", "请选择合约方法");
|
||||
return;
|
||||
}
|
||||
if (selectedContractAtExecute.value == undefined) {
|
||||
myToast("调用合约失败", "请选择合约");
|
||||
return;
|
||||
}
|
||||
console.log("Evaluates");
|
||||
var contract = mainVue.contracts[selectedContractAtExecute.value];
|
||||
|
||||
var request = {};
|
||||
request.action = "evaluates";
|
||||
request.contractName = contract.id;
|
||||
request.functionName = contract.exportedFunctions[selectedFunction.value].functionName;
|
||||
request.args = executeContractArgInput.value;
|
||||
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
202
js/onlineide/rightmenu_en.js
Normal file
202
js/onlineide/rightmenu_en.js
Normal file
@@ -0,0 +1,202 @@
|
||||
var expandOrCollapse = function () {
|
||||
if ($("#outputNav").hasClass("col-2")) {
|
||||
$("#outputNav").removeClass("col-2").addClass("col-6");
|
||||
$("#mainBox").removeClass("col-8").addClass("col-4");
|
||||
$("#expand").html("Collapse");
|
||||
} else {
|
||||
$("#outputNav").removeClass("col-6").addClass("col-2");
|
||||
$("#mainBox").removeClass("col-4").addClass("col-8");
|
||||
$("#expand").html("Expand");
|
||||
}
|
||||
};
|
||||
var listContracts = function () {
|
||||
var request = {};
|
||||
request.action = "listContractProcess";
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var startContract = function () {
|
||||
var key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
|
||||
var sm2Key = JSON.parse(key.sm2Key);
|
||||
var projectId = $("#selectedProject")[0].value;
|
||||
var project = global.projects[projectId];
|
||||
startResult.innerText = "Starting:" + project;
|
||||
|
||||
var request = {};
|
||||
request.action = "startContract";
|
||||
request.isPrivate = $("#privateprojecttab").hasClass("active");
|
||||
|
||||
request.owner = sm2Key.publicKey;
|
||||
request.requestID = new Date().getTime() + "";
|
||||
// request.contractid = $("#tabdiv")[0].value;
|
||||
// request.script = global.scriptEditor.getValue();
|
||||
request.path = "/" + project + "/mainfest.json";
|
||||
localStorage.setItem("persisStatus", JSON.stringify(request));
|
||||
{
|
||||
request.signature = sm2.doSignature("Fixed|" + request.path + "|"
|
||||
+ sm2Key.publicKey, sm2Key.privateKey);
|
||||
request.script = "empty";
|
||||
}
|
||||
// console.log("path=" + request.path);
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
|
||||
};
|
||||
var stopContract = function () {
|
||||
var request = {};
|
||||
request.action = "killContractProcess";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
request.name = mainVue.contracts[selectedContract.value].name;
|
||||
request.id = mainVue.contracts[selectedContract.value].id;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var queryContractInstanceDOI = function () {
|
||||
var request = {};
|
||||
request.action = "queryContractInstanceDOI";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
request.name = mainVue.contracts[selectedContract.value].name;
|
||||
request.id = mainVue.contracts[selectedContract.value].id;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var queryContractInstanceInfoByDOI = function () {
|
||||
var request = {};
|
||||
request.action = "queryContractInstanceInfoByDOI";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
request.doi = contractInstanceDOIInput.value;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var importContractInstanceCodeByDOI = function () {
|
||||
var request = {};
|
||||
request.action = "importContractInstanceCodeByDOI";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
request.doi = contractInstanceDOIInput.value;
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
var openinClient = function () {
|
||||
var path = document.location.pathname;
|
||||
path = path.replace("/SCIDE","");
|
||||
path = path.replace("/OnlineIDE.html","");
|
||||
var url = path + "/client/bdwareclient.html?self=true&contract="
|
||||
+ mainVue.contracts[selectedContract.value].id;
|
||||
window.open(url);
|
||||
};
|
||||
|
||||
var stopAllContract = function () {
|
||||
var request = {};
|
||||
request.action = "killAllContract";
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
var selectContractToExecute = function () {
|
||||
var value = selectedContractAtExecute.value;
|
||||
if (value != undefined && value != "Select Instance") {
|
||||
var exportedFunction = mainVue.contracts[value].exportedFunctions;
|
||||
mainVue.contractFunctions = exportedFunction;
|
||||
|
||||
var pingObj = {};
|
||||
pingObj.action = "connectTo";
|
||||
pingObj.name = mainVue.contracts[value].name;
|
||||
pingObj.id = mainVue.contracts[value].id;
|
||||
global.wssocket.send(JSON.stringify(pingObj));
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
var executeContract = function () {
|
||||
if (selectedFunction.value == undefined) {
|
||||
myToast("Invoke Failed", "Please select a function.");
|
||||
return;
|
||||
}
|
||||
if (selectedContractAtExecute.value == undefined) {
|
||||
myToast("Invoke Failed", "Please select an instance.");
|
||||
return;
|
||||
}
|
||||
var key = pubkeyDialogVue.sm2KeyList[pubkeyDialogVue.selectedSM2Key];
|
||||
var sm2Key = JSON.parse(key.sm2Key);
|
||||
|
||||
var request = {};
|
||||
|
||||
|
||||
|
||||
request.action = "executeContract";
|
||||
request.requestID = new Date().getTime() + "_"
|
||||
+ Math.floor(Math.random() * 10000);
|
||||
var contract = mainVue.contracts[selectedContractAtExecute.value];
|
||||
|
||||
request.contractID = contract.id;
|
||||
var arg = {};
|
||||
arg.action = contract.exportedFunctions[selectedFunction.value].functionName;
|
||||
arg.arg = executeContractArgInput.value;
|
||||
//console.log("[global.withEvaluatesAnalysis]"+global.withEvaluatesAnalysis);
|
||||
//if (global.withEvaluatesAnalysis != undefined) {
|
||||
//console.log("test");
|
||||
if ($('#gasLimit').val() == undefined || $('#gasLimit').val() == "") {
|
||||
arg.gasLimit = '1000';
|
||||
} else {
|
||||
arg.gasLimit =$('#gasLimit').val();
|
||||
}
|
||||
console.log("[arg.gasLimit]"+arg.gasLimit);
|
||||
//request.withEvaluatesAnalysis = global.withEvaluatesAnalysis;
|
||||
//}
|
||||
request.pubkey = sm2Key.publicKey;
|
||||
request.signature = sm2.doSignature(request.contractID + "|" + arg.action
|
||||
+ "|" + arg.arg + "|" + sm2Key.publicKey, sm2Key.privateKey);
|
||||
request.arg = JSON.stringify(arg);
|
||||
|
||||
localStorage.setItem("persisArg", JSON.stringify(request));
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
var executeContractWithDynamicResult = function () {
|
||||
if (selectedFunction.value == undefined) {
|
||||
myToast("Invoke Failed", "Please select a function.");
|
||||
return;
|
||||
}
|
||||
if (selectedContractAtExecute.value == undefined) {
|
||||
myToast("Invoke Failed", "Please select an instance.");
|
||||
return;
|
||||
}
|
||||
console.log("executeContractWithDynamicResult");
|
||||
var request = {};
|
||||
request.action = "executeContract";
|
||||
request.requestID = new Date().getTime() + "";
|
||||
|
||||
var contract = mainVue.contracts[selectedContractAtExecute.value];
|
||||
request.contractName = contract.id;
|
||||
|
||||
var arg = {};
|
||||
arg.action = contract.exportedFunctions[selectedFunction.value].functionName;
|
||||
arg.arg = executeContractArgInput.value;
|
||||
|
||||
request.withDyanmicAnalysis = true;
|
||||
request.arg = "{\"action\":\"" + arg.action + "\",\"arg\":\"" + arg.arg
|
||||
+ "\"}";
|
||||
request.pubkey = global.sm2Key.publicKey;
|
||||
request.signature = sm2.doSignature(request.contractID + "|" + arg.action
|
||||
+ "|" + arg.arg + "|" + global.sm2Key.publicKey,
|
||||
global.sm2Key.privateKey);
|
||||
localStorage.setItem("persisArg", JSON.stringify(request));
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
var testEvaluates = function () {
|
||||
if (selectedFunction.value == undefined) {
|
||||
myToast("Invoke Failed", "Please select a function.");
|
||||
return;
|
||||
}
|
||||
if (selectedContractAtExecute.value == undefined) {
|
||||
myToast("Invoke Failed", "Please select an instance.");
|
||||
return;
|
||||
}
|
||||
console.log("Evaluates");
|
||||
var contract = mainVue.contracts[selectedContractAtExecute.value];
|
||||
|
||||
var request = {};
|
||||
request.action = "evaluates";
|
||||
request.contractName = contract.id;
|
||||
request.functionName = contract.exportedFunctions[selectedFunction.value].functionName;
|
||||
request.args = executeContractArgInput.value;
|
||||
|
||||
global.wssocket.send(JSON.stringify(request));
|
||||
};
|
||||
|
||||
234
js/onlineide/staticAnalysis.js
Normal file
234
js/onlineide/staticAnalysis.js
Normal file
@@ -0,0 +1,234 @@
|
||||
|
||||
var showAnalysis = function() {
|
||||
//console.log("showAnalysis test")
|
||||
var isAnalysis = document.getElementById("analysis").style.display;
|
||||
var isResize = document.getElementById("resize").style.display;
|
||||
//console.log(isAnalysis);
|
||||
var top = document.getElementById("contractCode");
|
||||
var down = document.getElementById("analysis");
|
||||
var box = document.getElementById("box");
|
||||
|
||||
if (isAnalysis == "none") {
|
||||
document.getElementById("analysis").style.display = "block";
|
||||
document.getElementById("resize").style.display = "block";
|
||||
var moveLen=300;
|
||||
top.style.height = moveLen + "px";
|
||||
$("#contractCode .CodeMirror").css("height",moveLen + "px");
|
||||
down.style.height = (box.clientHeight - moveLen - 10) + "px";
|
||||
staticAnalysis();
|
||||
} else {
|
||||
document.getElementById("analysis").style.display = "none";
|
||||
document.getElementById("resize").style.display = "none";
|
||||
top.style.height="100%";
|
||||
$("#contractCode .CodeMirror").css("height","100%");
|
||||
}
|
||||
//document.getElementById("analysis").style.display = "";
|
||||
};
|
||||
|
||||
var staticAnalysis = function() {
|
||||
var req = {};
|
||||
req.action = "getControlFlowByFileName";
|
||||
req.isPrivate = global.currentFile.isPrivate;
|
||||
var path = global.currentFile.path;
|
||||
if (path.startsWith("/"))
|
||||
path = path.substr(1);
|
||||
path = path.replace(/\/.*$/g,"");
|
||||
req.projectName = path;
|
||||
array = $("#form").serializeArray();
|
||||
req.formData=JSON.stringify(array);
|
||||
global.wssocket.send(JSON.stringify(req));
|
||||
};
|
||||
|
||||
window.onload = function(){
|
||||
var resize = document.getElementById("resize");
|
||||
var top = document.getElementById("contractCode");
|
||||
var down = document.getElementById("analysis");
|
||||
var box = document.getElementById("box");
|
||||
resize.onmousedown = function(e){
|
||||
var startY = e.clientY;
|
||||
resize.top = resize.offsetTop;
|
||||
|
||||
document.onmousemove = function(e){
|
||||
var endY = e.clientY;
|
||||
var moveLen = resize.top + (endY - startY);
|
||||
var maxT = box.clientHeight - resize.offsetHeight;
|
||||
if(moveLen<150) moveLen = 150;
|
||||
if(moveLen>maxT-150) moveLen = maxT-150;
|
||||
resize.style.top = moveLen;
|
||||
top.style.height = moveLen + "px";
|
||||
$("#contractCode .CodeMirror").css("height",top.style.height);
|
||||
down.style.height = (box.clientHeight - moveLen - 5) + "px";
|
||||
}
|
||||
document.onmouseup = function(evt){
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
resize.releaseCapture && resize.releaseCapture();
|
||||
}
|
||||
resize.setCapture && resize.setCapture();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var onGetControlFlow = function(obj) {
|
||||
var data = {};
|
||||
data.name = data.path = "/tmp/result_" + (new Date().getTime() % 1000)
|
||||
+ ".txt";
|
||||
obj = JSON.parse(obj.result);
|
||||
global.analysisResult = obj;
|
||||
$("#analysisFunction").html("<option value=''>选择方法</option>");
|
||||
for (var key in obj){
|
||||
$("#analysisFunction").append("<option value='"+key+"'>"+key+"</option>");
|
||||
};
|
||||
|
||||
|
||||
|
||||
data.val = JSON.stringify(obj, null, 4);
|
||||
mainVue.openedFiles.push(data);
|
||||
setTimeout(function() {
|
||||
clickTab(data.path);
|
||||
}, 100);
|
||||
}
|
||||
var showAnalysisResult = function(){
|
||||
var functionName = $("#analysisFunction")[0].value;
|
||||
if (global.analysisResult[functionName]!=undefined){
|
||||
drawMethod(global.analysisResult[functionName]);
|
||||
}
|
||||
};
|
||||
|
||||
var drawMethod = function(method) {
|
||||
var states = {};
|
||||
for (var i = 0; i < method.blocks.length; i++) {
|
||||
var block = method.blocks[i];
|
||||
var desp = {};
|
||||
desp.description = "字节码指令:"+"<br/>"+ stmt2Str(block.stmts);
|
||||
desp.description += "<br/><br/>" + "后续分析结果:" +"<br/>" + block.result;
|
||||
desp.description += "<br/><br/>" + "源码:"+"<br/>"+ block.original;
|
||||
desp.description += "<br/><br/>" + "数据依赖:"+"<br/>"+ block.blockDep;
|
||||
if (block.type != "Continuous")
|
||||
desp.fill = "#f77";
|
||||
states[block.name] = desp;
|
||||
}
|
||||
drawCFGraph(states, method.edges);
|
||||
var retDesp = "数据值传递依赖:";
|
||||
//retDesp += method.ret;
|
||||
var tmp1 = method.ret;
|
||||
retDesp += tmp1.split(":")[tmp1.split(',').length];
|
||||
retDesp += "\n";
|
||||
retDesp += "数据控制依赖:";
|
||||
var tmp2= method.blocks[method.blocks.length-1].blockDep;
|
||||
//retDesp += tmp.split(":")[tmp.split(',').length];
|
||||
retDesp += tmp2;
|
||||
retDesp += "\n";
|
||||
retDesp += method.finalRet;
|
||||
document.getElementById("ret").value = retDesp;
|
||||
};
|
||||
|
||||
var stmt2Str = function(l) {
|
||||
var str = "";
|
||||
for (var i = 0; i < l.length; i++)
|
||||
str += "<span style='text-overflow:ellipsis'>"
|
||||
+ l[i].replace(/\//g, ".") + "</span>" + "<br/>";
|
||||
return str;
|
||||
}
|
||||
|
||||
var drawCFGraph = function(states, edges) {
|
||||
var g = new dagreD3.graphlib.Graph().setGraph({});
|
||||
// Add states to the graph, set labels, and style
|
||||
Object.keys(states).forEach(function(state) {
|
||||
var value = states[state];
|
||||
value.label = state;
|
||||
value.rx = value.ry = 5;
|
||||
value.style = "fill:white;stroke:"+primaryColor;
|
||||
g.setNode(state, value);
|
||||
});
|
||||
for (var i = 0; i < edges.length; i++){
|
||||
edges[i].label.style= "fill:#fff;stroke:"+primaryColor+";stroke-width:2px";
|
||||
if (edges[i].label.label=='e')
|
||||
edges[i].label.label = "";
|
||||
g.setEdge(edges[i].from, edges[i].to,edges[i].label);
|
||||
}
|
||||
// Set up the edges
|
||||
|
||||
// Create the renderer
|
||||
var render = new dagreD3.render();
|
||||
$("svg").html("");
|
||||
// Set up an SVG group so that we can translate the final graph.
|
||||
var svg = d3.select("svg"), inner = svg.append("g");
|
||||
|
||||
// Set up zoom support
|
||||
var zoom = d3.zoom().on("zoom", function() {
|
||||
inner.attr("transform", d3.event.transform);
|
||||
});
|
||||
svg.call(zoom);
|
||||
|
||||
// Simple function to style the tooltip for the given node.
|
||||
var styleTooltip = function(name, description) {
|
||||
return "<p class='name'>" + name + "</p><p class='description'>"
|
||||
+ description + "</p>";
|
||||
};
|
||||
|
||||
// Run the renderer. This is what draws the final graph.
|
||||
render(inner, g);
|
||||
|
||||
inner.selectAll("g.node").attr("title", function(v) {
|
||||
return styleTooltip(v, g.node(v).description)
|
||||
}).each(function(v) {
|
||||
$(this).tipsy({
|
||||
gravity : "w",
|
||||
opacity : 1,
|
||||
html : true
|
||||
});
|
||||
});
|
||||
|
||||
// Center the graph
|
||||
var initialScale = 0.75;
|
||||
var width =$("#svgCanvas").css("width").replace("px","")/1;
|
||||
svg.call(zoom.transform, d3.zoomIdentity.translate(
|
||||
(width - g.graph().width * initialScale) / 2, 20)
|
||||
.scale(initialScale));
|
||||
svg.attr('height', g.graph().height * initialScale + 40);
|
||||
}
|
||||
|
||||
|
||||
var downloadAnalysis = function() {
|
||||
var pdf = new jsPDF('p', 'pt', 'a4');
|
||||
//page1
|
||||
/*
|
||||
pdf.addFont('NotoSansCJKtc-Regular.ttf', 'NotoSansCJKtc', 'normal');
|
||||
pdf.setFont('NotoSansCJKtc');
|
||||
*/
|
||||
pdf.text('Analysis Report', 10, 20);
|
||||
var res = document.getElementById("ret").value;
|
||||
pdf.text(res, 10, 20);
|
||||
//page2
|
||||
pdf.addPage();
|
||||
//method1:add text
|
||||
//get svg
|
||||
var svg = $("#svgCanvas")[0].outerHTML;
|
||||
if (svg)
|
||||
svg = svg.replace(/\r?\n|\r/g, '').trim();
|
||||
//change svg to canvas
|
||||
var canvas = document.createElement('canvas');
|
||||
ctx = canvas.getContext('2d');
|
||||
var v = canvg.Canvg.fromString(ctx, svg);
|
||||
|
||||
//create image
|
||||
var imgData = canvas.toDataURL('image/png');
|
||||
pdf.addImage(imgData, 'PNG', 0, 0, 595.28, 841.89);
|
||||
|
||||
/*
|
||||
//method2:add text to image
|
||||
var canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
var svg = document.getElementById('svg-container').innerHTML;
|
||||
var v = canvg.Canvg.fromString(ctx, svg);
|
||||
v.start();
|
||||
ctx.font="20px Georgia";
|
||||
ctx.fillText(res, 10, 20);
|
||||
var imgData = canvas.toDataURL('image/png');
|
||||
pdf.addImage(imgData, 'PNG', 0, 0, 595.28, 841.89);
|
||||
*/
|
||||
pdf.save('report.pdf');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user