/*
* Copyright (c) 2014-2019, b3log.org & hacpai.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @file tree.js
*
* @author Liyuan Li
* @author Liang Ding
* @version 1.0.1.1, Dec 15, 2015
*/
var tree = {
fileTree: undefined,
// 递归获取当前节点展开中的最后一个节点
getCurrentNodeLastNode: function (node) {
var returnNode = node.children[node.children.length - 1];
if (returnNode.open) {
return tree.getCurrentNodeLastNode(returnNode);
} else {
return returnNode;
}
},
// 按照树展现获取下一个节点
getNextShowNode: function (node) {
if (node.level !== 0) {
if (node.getParentNode().getNextNode()) {
return node.getParentNode().getNextNode();
} else {
return tree.getNextShowNode(node.getParentNode());
}
} else {
return node.getNextNode();
}
},
isBottomNode: function (node) {
if (node.open) {
return false;
}
if (node.getParentNode()) {
if (node.getParentNode().isLastNode) {
return tree.isBottomNode(node.getParentNode());
} else {
return false;
}
} else {
if (node.isLastNode) {
return true;
} else {
return false;
}
}
},
getTIdByPath: function (path) {
var nodes = tree.fileTree.transformToArray(tree.fileTree.getNodes());
for (var i = 0, ii = nodes.length; i < ii; i++) {
if (nodes[i].path === path) {
return nodes[i].tId;
}
}
return undefined;
},
getOpenPaths: function () {
var nodes = tree.fileTree.transformToArray(tree.fileTree.getNodes()),
paths = [];
for (var i = 0, ii = nodes.length; i < ii; i++) {
if (nodes[i].open) {
paths.push(nodes[i].path);
}
}
return paths;
},
getAllParents: function (node, parents) {
if (!parents) {
parents = [];
}
if (!node || !node.parentTId) {
return parents;
} else {
parents.push(node.getParentNode());
return tree.getAllParents(node.getParentNode(), parents);
}
},
isParents: function (tId, parentPath) {
var node = tree.fileTree.getNodeByTId(tId);
if (!node || !node.parentTId) {
return false;
} else {
var parentNode = tree.fileTree.getNodeByTId(node.parentTId);
if (node.path === parentPath) {
return true;
} else {
return tree.isParents(parentNode.tId, parentPath);
}
}
},
isDir: function () {
if (wide.curNode.iconSkin.indexOf("ico-ztree-dir") === 0) {
return true;
}
return false;
},
newFile: function (it) {
if ($(it).hasClass("disabled")) {
return false;
}
$("#dialogNewFilePrompt").dialog("open");
},
newDir: function (it) {
if ($(it).hasClass("disabled")) {
return false;
}
$("#dialogNewDirPrompt").dialog("open");
},
removeIt: function (it) {
if (it) {
if ($(it).hasClass("disabled")) {
return false;
}
} else {
if (!wide.curNode.removable) {
return false;
}
}
$("#dialogRemoveConfirm").dialog("open");
},
rename: function (it) {
if (it) {
if ($(it).hasClass("disabled")) {
return false;
}
}
$("#dialogRenamePrompt").dialog("open");
},
export: function () {
var request = newWideRequest(),
isSucc = false;
request.path = wide.curNode.path;
$.ajax({
async: false,
type: 'POST',
url: config.context + '/file/zip/new',
data: JSON.stringify(request),
dataType: "json",
success: function (result) {
if (!result.succ) {
$("#dialogAlert").dialog("open", result.msg);
return false;
}
isSucc = true;
}
});
if (isSucc) {
window.open(config.context + '/file/zip?path=' + wide.curNode.path + ".zip");
}
},
crossCompile: function (platform) {
var request = newWideRequest();
request.path = wide.curNode.path;
request.platform = platform;
$.ajax({
async: false,
type: 'POST',
url: config.context + '/cross',
data: JSON.stringify(request),
dataType: "json",
success: function (result) {
if (!result.succ) {
$("#dialogAlert").dialog("open", result.msg);
return false;
}
}
});
},
decompress: function () {
var request = newWideRequest();
request.path = wide.curNode.path;
$.ajax({
async: false,
type: 'POST',
url: config.context + '/file/decompress',
data: JSON.stringify(request),
dataType: "json",
success: function (result) {
if (!result.succ) {
$("#dialogAlert").dialog("open", result.msg);
return false;
}
var dir = wide.curNode.getParentNode();
tree.fileTree.reAsyncChildNodes(dir, "refresh");
}
});
},
refresh: function (it) {
if (it) {
if ($(it).hasClass("disabled")) {
return false;
}
}
tree.fileTree.reAsyncChildNodes(wide.curNode, "refresh", true);
},
gitClone: function (it) {
if (it) {
if ($(it).hasClass("disabled")) {
return false;
}
}
$("#dialogGitClonePrompt").dialog('open');
},
import: function () {
var request = newWideRequest();
request.path = wide.curNode.path;
$('#importFileupload').fileupload({
url: "/file/upload?path=" + request.path,
dataType: 'json',
formData: request,
done: function (e, result) {
tree.fileTree.reAsyncChildNodes(wide.curNode, "refresh");
},
fail: function () {
console.log(arguments);
}
});
},
init: function () {
$("#file").click(function () {
$(this).focus();
});
var request = newWideRequest();
$.ajax({
type: 'POST',
url: config.context + '/files',
data: JSON.stringify(request),
dataType: "json",
success: function (result) {
if (result.succ) {
var $dirRMenu = $("#dirRMenu");
var $fileRMenu = $("#fileRMenu");
var setting = {
data: {
key: {
title: "path"
}
},
view: {
showTitle: true,
selectedMulti: false
},
async: {
enable: true,
url: config.context + "/file/refresh",
autoParam: ["path"]
},
callback: {
onDblClick: function (event, treeId, treeNode) {
if (treeNode) {
tree.openFile(treeNode);
}
},
onRightClick: function (event, treeId, treeNode) {
if (treeNode && !treeNode.isGOAPI) {
menu.undisabled(['import', 'export', 'git-clone']);
wide.curNode = treeNode;
tree.fileTree.selectNode(treeNode);
if (!tree.isDir()) { // if right click on a file
if (wide.curNode.removable) {
$fileRMenu.find(".remove").removeClass("disabled");
} else {
$fileRMenu.find(".remove").addClass("disabled");
}
if (-1 === wide.curNode.path.indexOf("zip", wide.curNode.path.length - "zip".length)) { // !path.endsWith("zip")
$fileRMenu.find(".decompress").hide();
} else {
$fileRMenu.find(".decompress").show();
}
if (-1 === wide.curNode.path.indexOf("go", wide.curNode.path.length - "go".length)) { // !path.endsWith("go")
$fileRMenu.find(".linux64").hide();
} else {
$fileRMenu.find(".linux64").show();
}
var top = event.clientY - 10;
if ($fileRMenu.height() + top > $('.content').height()) {
top = top - $fileRMenu.height() - 25;
}
$fileRMenu.css({
"top": top + "px",
"left": event.clientX + "px",
"display": "block"
}).show();
$dirRMenu.hide();
menu.disabled(['import', 'git-clone']);
} else { // 右击了目录
if (wide.curNode.removable) {
$dirRMenu.find(".remove").removeClass("disabled");
} else {
$dirRMenu.find(".remove").addClass("disabled");
}
if (wide.curNode.creatable) {
$dirRMenu.find(".create").removeClass("disabled");
} else {
$dirRMenu.find(".create").addClass("disabled");
}
var top = event.clientY - 10;
if ($dirRMenu.height() + top > $('.content').height()) {
top = top - $dirRMenu.height() - 25;
}
$dirRMenu.css({
"top": top + "px",
"left": event.clientX + "px",
"display": "block"
}).show();
$fileRMenu.hide();
}
$("#files").focus();
}
},
onClick: function (event, treeId, treeNode, clickFlag) {
if (treeNode) {
wide.curNode = treeNode;
tree.fileTree.selectNode(treeNode);
menu.undisabled(['import', 'export', 'git-clone']);
if (!tree.isDir()) {
menu.disabled(['import', 'git-clone']);
}
$("#files").focus();
}
}
}
};
tree.fileTree = $.fn.zTree.init($("#files"), setting, result.data.children);
session.restore();
}
}
});
this._initSearch();
this._initRename();
},
openFile: function (treeNode, cursor) {
wide.curNode = treeNode;
var tempCursor = cursor;
for (var i = 0, ii = editors.data.length; i < ii; i++) {
// 该节点文件已经打开
if (editors.data[i].id === treeNode.path) {
editors.tabs.setCurrent(treeNode.path);
wide.curEditor = editors.data[i].editor;
if (!tempCursor) {
tempCursor = wide.curEditor.getCursor();
}
$(".footer .cursor").text('| ' + (tempCursor.line + 1) + ':' + (tempCursor.ch + 1) + ' |');
wide.curEditor.setCursor(tempCursor);
var half = Math.floor(wide.curEditor.getScrollInfo().clientHeight / wide.curEditor.defaultTextHeight() / 2);
var cursorCoords = wide.curEditor.cursorCoords({line: tempCursor.line - half, ch: 0}, "local");
wide.curEditor.scrollTo(0, cursorCoords.top);
wide.curEditor.focus();
wide.refreshOutline();
return false;
}
}
if (!tree.isDir()) {
var request = newWideRequest();
request.path = treeNode.path;
$.ajax({
async: false,
type: 'POST',
url: config.context + '/file',
data: JSON.stringify(request),
dataType: "json",
success: function (result) {
if (!result.succ) {
$("#dialogAlert").dialog("open", result.msg);
return false;
}
var data = result.data;
if (!data.mode) {
var mode = CodeMirror.findModeByFileName(treeNode.path);
if (mode) {
data.mode = mode.mime;
} else {
data.mode = 'text/plain';
}
}
if (!data.mode) {
console.error("Can't find mode by file name [" + treeNode.path + "]");
}
if ("img" === data.mode) { // 是图片文件的话新建 tab 打开
// 最好是开 tab,但这个最终取决于浏览器设置
var w = window.open(config.context + data.path);
return false;
}
if (!tempCursor) {
tempCursor = CodeMirror.Pos(0, 0);
}
editors.newEditor(data, tempCursor);
wide.refreshOutline();
}
});
}
},
_initSearch: function () {
$("#dialogSearchForm > input:eq(0)").keyup(function (event) {
var $okBtn = $(this).closest(".dialog-main").find(".dialog-footer > button:eq(0)");
if (event.which === 13 && !$okBtn.prop("disabled")) {
$okBtn.click();
}
if ($.trim($(this).val()) === "") {
$okBtn.prop("disabled", true);
} else {
$okBtn.prop("disabled", false);
}
});
$("#dialogSearchForm > input:eq(1)").keyup(function (event) {
var $okBtn = $(this).closest(".dialog-main").find(".dialog-footer > button:eq(0)");
if (event.which === 13 && !$okBtn.prop("disabled")) {
$okBtn.click();
}
});
$("#dialogSearchForm").dialog({
"modal": true,
"height": 80,
"width": 260,
"title": config.label.search,
"okText": config.label.search,
"cancelText": config.label.cancel,
"afterOpen": function () {
$("#dialogSearchForm > input:eq(0)").val('').focus();
$("#dialogSearchForm > input:eq(1)").val('');
$("#dialogSearchForm").closest(".dialog-main").find(".dialog-footer > button:eq(0)").prop("disabled", true);
},
"ok": function () {
var request = newWideRequest();
if (!wide.curNode) {
request.dir = "";
} else {
request.dir = wide.curNode.path;
}
request.text = $("#dialogSearchForm > input:eq(0)").val();
request.extension = $("#dialogSearchForm > input:eq(1)").val();
$.ajax({
type: 'POST',
url: config.context + '/file/search/text',
data: JSON.stringify(request),
dataType: "json",
success: function (result) {
if (!result.succ) {
return;
}
$("#dialogSearchForm").dialog("close");
editors.appendSearch(result.data, 'founds', request.text);
}
});
}
});
},
_initRename: function () {
$("#dialogRenamePrompt").dialog({
"modal": true,
"height": 52,
"width": 260,
"title": config.label.rename,
"okText": config.label.rename,
"cancelText": config.label.cancel,
"afterOpen": function () {
$("#dialogRenamePrompt").closest(".dialog-main").find(".dialog-footer > button:eq(0)").prop("disabled", true);
$("#dialogRenamePrompt > input").val(wide.curNode.name).select().focus();
},
"ok": function () {
var name = $("#dialogRenamePrompt > input").val(),
request = newWideRequest();
request.oldPath = wide.curNode.path;
request.newPath = wide.curNode.path.substring(0, wide.curNode.path.lastIndexOf("/") + 1) + name;
$.ajax({
type: 'POST',
url: config.context + '/file/rename',
data: JSON.stringify(request),
dataType: "json",
success: function (result) {
if (!result.succ) {
$("#dialogRenamePrompt").dialog("close");
bottomGroup.tabs.setCurrent("notification");
windows.flowBottom();
$(".bottom-window-group .notification").focus();
return false;
}
$("#dialogRenamePrompt").dialog("close");
}
});
}
});
}
};