wide/static/js/tree.js

555 lines
20 KiB
JavaScript
Raw Normal View History

2015-01-01 05:06:33 +03:00
/*
2015-01-18 08:59:10 +03:00
* Copyright (c) 2014-2015, b3log.org
2015-01-01 05:06:33 +03:00
*
2014-11-12 18:13:14 +03:00
* 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
2015-01-01 05:06:33 +03:00
*
2014-11-12 18:13:14 +03:00
* http://www.apache.org/licenses/LICENSE-2.0
2015-01-01 05:06:33 +03:00
*
2014-11-12 18:13:14 +03:00
* 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.
2014-11-17 06:37:26 +03:00
*/
2014-11-12 18:13:14 +03:00
2014-08-18 17:45:43 +04:00
var tree = {
2014-09-25 07:04:17 +04:00
fileTree: undefined,
// 递归获取当前节点展开中的最后一个节点
2014-09-23 17:03:44 +04:00
getCurrentNodeLastNode: function (node) {
var returnNode = node.children[node.children.length - 1];
if (returnNode.open) {
return tree.getCurrentNodeLastNode(returnNode);
} else {
return returnNode;
}
},
// 按照树展现获取下一个节点
2014-09-23 17:03:44 +04:00
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();
}
},
2014-09-23 17:03:44 +04:00
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;
}
}
},
2014-09-23 17:03:44 +04:00
getTIdByPath: function (path) {
var nodes = tree.fileTree.transformToArray(tree.fileTree.getNodes());
2014-09-13 09:05:50 +04:00
for (var i = 0, ii = nodes.length; i < ii; i++) {
if (nodes[i].path === path) {
return nodes[i].tId;
}
}
2014-09-13 09:05:50 +04:00
return undefined;
},
2014-09-23 17:03:44 +04:00
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);
}
}
2014-09-23 18:29:53 +04:00
2014-09-23 17:03:44 +04:00
return paths;
},
2014-11-17 06:37:26 +03:00
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) {
2014-09-12 13:50:46 +04:00
var node = tree.fileTree.getNodeByTId(tId);
if (!node || !node.parentTId) {
return false;
} else {
var parentNode = tree.fileTree.getNodeByTId(node.parentTId);
if (node.path === parentPath) {
2014-09-12 13:50:46 +04:00
return true;
} else {
return tree.isParents(parentNode.tId, parentPath);
2014-09-12 13:50:46 +04:00
}
}
},
2014-11-06 10:47:05 +03:00
isDir: function () {
if (wide.curNode.iconSkin.indexOf("ico-ztree-dir") === 0) {
return true;
}
2014-12-18 11:46:38 +03:00
2014-11-06 10:47:05 +03:00
return false;
},
2014-11-06 11:51:59 +03:00
newFile: function (it) {
if ($(it).hasClass("disabled")) {
return false;
}
$("#dialogNewFilePrompt").dialog("open");
2014-08-18 17:45:43 +04:00
},
2014-11-06 16:46:20 +03:00
newDir: function (it) {
2014-11-06 11:51:59 +03:00
if ($(it).hasClass("disabled")) {
return false;
}
$("#dialogNewDirPrompt").dialog("open");
2014-08-18 17:45:43 +04:00
},
2014-11-06 10:47:05 +03:00
removeIt: function (it) {
if (it) {
if ($(it).hasClass("disabled")) {
return false;
}
} else {
2014-11-06 11:51:59 +03:00
if (!wide.curNode.removable) {
2014-11-06 10:47:05 +03:00
return false;
}
}
2014-12-18 11:46:38 +03:00
$("#dialogRemoveConfirm").dialog("open");
2014-08-18 17:45:43 +04:00
},
2014-11-07 18:11:37 +03:00
rename: function (it) {
if (it) {
if ($(it).hasClass("disabled")) {
return false;
}
}
2014-12-18 11:46:38 +03:00
2014-11-07 18:11:37 +03:00
$("#dialogRenamePrompt").dialog("open");
},
2014-12-18 13:04:12 +03:00
export: function () {
var request = newWideRequest(),
isSucc = false;
2014-11-24 12:20:43 +03:00
request.path = wide.curNode.path;
$.ajax({
async: false,
2014-11-24 12:20:43 +03:00
type: 'POST',
2014-12-11 10:32:24 +03:00
url: config.context + '/file/zip/new',
2014-11-24 12:20:43 +03:00
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
if (!data.succ) {
$("#dialogAlert").dialog("open", data.msg);
return false;
}
isSucc = true;
2014-11-24 12:20:43 +03:00
}
});
if (isSucc) {
window.open(config.context + '/file/zip?path=' + wide.curNode.path + ".zip");
}
2014-11-24 12:20:43 +03:00
},
2015-03-21 09:39:26 +03:00
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 (data) {
if (!data.succ) {
$("#dialogAlert").dialog("open", data.msg);
return false;
}
2015-04-12 03:15:28 +03:00
2015-03-22 07:59:25 +03:00
var dir = wide.curNode.getParentNode();
tree.fileTree.reAsyncChildNodes(dir, "refresh");
2015-03-21 09:39:26 +03:00
}
});
},
2014-11-25 09:20:45 +03:00
refresh: function (it) {
if (it) {
if ($(it).hasClass("disabled")) {
return false;
}
}
2014-12-07 05:06:46 +03:00
tree.fileTree.reAsyncChildNodes(wide.curNode, "refresh", true);
2014-11-25 09:20:45 +03:00
},
2015-03-07 12:51:28 +03:00
gitClone: function (it) {
if (it) {
if ($(it).hasClass("disabled")) {
return false;
}
}
2015-03-22 07:59:25 +03:00
2015-03-07 19:01:06 +03:00
$("#dialogGitClonePrompt").dialog('open');
2015-03-07 12:51:28 +03:00
},
2014-12-18 13:04:12 +03:00
import: function () {
2014-11-28 18:12:38 +03:00
var request = newWideRequest();
request.path = wide.curNode.path;
$('#importFileupload').fileupload({
url: "/file/upload?path=" + request.path,
dataType: 'json',
formData: request,
done: function (e, data) {
tree.fileTree.reAsyncChildNodes(wide.curNode, "refresh");
2014-12-18 13:04:12 +03:00
},
fail: function () {
console.log(arguments);
2014-11-28 18:12:38 +03:00
}
});
},
2014-09-23 17:03:44 +04:00
init: function () {
2014-11-06 10:04:33 +03:00
$("#file").click(function () {
$(this).focus();
});
2014-09-17 06:04:41 +04:00
var request = newWideRequest();
2014-08-18 17:45:43 +04:00
$.ajax({
2014-09-17 06:04:41 +04:00
type: 'POST',
2014-12-11 10:32:24 +03:00
url: config.context + '/files',
2014-09-17 06:04:41 +04:00
data: JSON.stringify(request),
2014-08-18 17:45:43 +04:00
dataType: "json",
2014-09-23 17:03:44 +04:00
success: function (data) {
2014-08-18 17:45:43 +04:00
if (data.succ) {
var $dirRMenu = $("#dirRMenu");
var $fileRMenu = $("#fileRMenu");
2014-08-18 17:45:43 +04:00
var setting = {
2014-11-05 16:31:19 +03:00
data: {
key: {
2014-11-07 18:11:37 +03:00
title: "path"
2014-11-05 16:31:19 +03:00
}
},
2014-08-18 17:45:43 +04:00
view: {
2014-11-05 16:31:19 +03:00
showTitle: true,
2014-08-18 17:45:43 +04:00
selectedMulti: false
},
2014-11-25 09:20:45 +03:00
async: {
enable: true,
2014-12-11 10:32:24 +03:00
url: config.context + "/file/refresh",
2014-11-25 09:20:45 +03:00
autoParam: ["path"]
},
2014-08-18 17:45:43 +04:00
callback: {
onDblClick: function (event, treeId, treeNode) {
if (treeNode) {
2014-10-09 17:55:09 +04:00
tree.openFile(treeNode);
}
},
2014-09-23 17:03:44 +04:00
onRightClick: function (event, treeId, treeNode) {
2014-12-25 11:34:35 +03:00
if (treeNode && !treeNode.isGOAPI) {
2015-03-10 09:37:58 +03:00
menu.undisabled(['import', 'export', 'git-clone']);
2014-12-18 11:46:38 +03:00
2014-08-19 11:44:30 +04:00
wide.curNode = treeNode;
tree.fileTree.selectNode(treeNode);
2015-03-21 09:39:26 +03:00
if (!tree.isDir()) { // if right click on a file
2014-11-06 11:51:59 +03:00
if (wide.curNode.removable) {
$fileRMenu.find(".remove").removeClass("disabled");
2014-11-06 11:51:59 +03:00
} else {
$fileRMenu.find(".remove").addClass("disabled");
2014-11-06 11:51:59 +03:00
}
2015-03-22 07:59:25 +03:00
2015-03-21 09:39:26 +03:00
if (wide.curNode.path.indexOf("zip", wide.curNode.path.length - "zip".length) === -1) { // !path.endsWith("zip")
$fileRMenu.find(".decompress").hide();
} else {
$fileRMenu.find(".decompress").show();
}
2014-11-07 18:11:37 +03:00
2014-12-18 11:56:21 +03:00
var top = event.clientY - 10;
if ($fileRMenu.height() + top > $('.content').height()) {
top = top - $fileRMenu.height() - 25;
}
$fileRMenu.css({
2014-12-18 11:56:21 +03:00
"top": top + "px",
2014-09-03 13:49:03 +04:00
"left": event.clientX + "px",
"display": "block"
}).show();
2015-03-22 07:59:25 +03:00
2015-03-07 19:01:06 +03:00
$dirRMenu.hide();
2014-12-18 11:46:38 +03:00
2015-03-10 09:37:58 +03:00
menu.disabled(['import', 'git-clone']);
2014-08-18 17:45:43 +04:00
} else { // 右击了目录
2014-11-06 11:51:59 +03:00
if (wide.curNode.removable) {
2014-12-13 15:08:35 +03:00
$dirRMenu.find(".remove").removeClass("disabled");
2014-11-06 11:51:59 +03:00
} else {
2014-12-13 15:08:35 +03:00
$dirRMenu.find(".remove").addClass("disabled");
2014-11-06 11:51:59 +03:00
}
if (wide.curNode.creatable) {
$dirRMenu.find(".create").removeClass("disabled");
2014-11-06 10:47:05 +03:00
} else {
$dirRMenu.find(".create").addClass("disabled");
2014-11-06 10:47:05 +03:00
}
2014-12-18 11:56:21 +03:00
var top = event.clientY - 10;
if ($dirRMenu.height() + top > $('.content').height()) {
top = top - $dirRMenu.height() - 25;
}
$dirRMenu.css({
2014-12-18 11:56:21 +03:00
"top": top + "px",
2014-09-12 13:50:46 +04:00
"left": event.clientX + "px",
2014-09-03 13:49:03 +04:00
"display": "block"
}).show();
2015-03-22 07:59:25 +03:00
2015-03-07 19:01:06 +03:00
$fileRMenu.hide();
2014-08-18 17:45:43 +04:00
}
$("#files").focus();
2014-08-18 17:45:43 +04:00
}
},
2014-09-23 17:03:44 +04:00
onClick: function (event, treeId, treeNode, clickFlag) {
if (treeNode) {
wide.curNode = treeNode;
tree.fileTree.selectNode(treeNode);
2014-12-18 11:46:38 +03:00
2015-03-10 09:37:58 +03:00
menu.undisabled(['import', 'export', 'git-clone']);
if (!tree.isDir()) {
menu.disabled(['import', 'git-clone']);
2014-12-18 11:46:38 +03:00
}
$("#files").focus();
}
2014-09-03 13:49:03 +04:00
}
}
};
tree.fileTree = $.fn.zTree.init($("#files"), setting, data.root.children);
2014-09-23 18:29:53 +04:00
session.restore();
2014-09-03 13:49:03 +04:00
}
}
});
2014-11-18 05:29:08 +03:00
2014-11-18 05:03:08 +03:00
this._initSearch();
2014-12-03 06:26:05 +03:00
this._initRename();
2014-09-03 13:49:03 +04:00
},
2014-11-18 05:51:26 +03:00
openFile: function (treeNode, cursor) {
2014-09-25 07:35:28 +04:00
wide.curNode = treeNode;
2014-11-18 05:51:26 +03:00
var tempCursor = cursor;
2014-09-25 07:35:28 +04:00
for (var i = 0, ii = editors.data.length; i < ii; i++) {
// 该节点文件已经打开
if (editors.data[i].id === treeNode.path) {
editors.tabs.setCurrent(treeNode.path);
2014-09-25 07:35:28 +04:00
wide.curEditor = editors.data[i].editor;
2014-11-18 05:51:26 +03:00
if (!tempCursor) {
tempCursor = wide.curEditor.getCursor();
}
$(".footer .cursor").text('| ' + (tempCursor.line + 1) + ':' + (tempCursor.ch + 1) + ' |');
wide.curEditor.setCursor(tempCursor);
2014-11-18 05:29:08 +03:00
var half = Math.floor(wide.curEditor.getScrollInfo().clientHeight / wide.curEditor.defaultTextHeight() / 2);
2014-11-18 05:51:26 +03:00
var cursorCoords = wide.curEditor.cursorCoords({line: tempCursor.line - half, ch: 0}, "local");
2014-11-18 05:29:08 +03:00
wide.curEditor.scrollTo(0, cursorCoords.top);
wide.curEditor.focus();
2015-01-02 13:14:58 +03:00
wide.refreshOutline();
2014-09-25 07:35:28 +04:00
return false;
2014-09-03 13:49:03 +04:00
}
}
2014-09-03 13:23:42 +04:00
2015-04-12 03:15:28 +03:00
if (!tree.isDir()) {
2014-09-17 06:04:41 +04:00
var request = newWideRequest();
request.path = treeNode.path;
2014-09-03 13:49:03 +04:00
$.ajax({
2014-09-23 18:29:53 +04:00
async: false,
2014-09-03 13:49:03 +04:00
type: 'POST',
2014-12-11 10:32:24 +03:00
url: config.context + '/file',
2014-09-03 13:49:03 +04:00
data: JSON.stringify(request),
dataType: "json",
2014-09-23 17:03:44 +04:00
success: function (data) {
2014-09-03 13:49:03 +04:00
if (!data.succ) {
2014-09-24 07:35:03 +04:00
$("#dialogAlert").dialog("open", data.msg);
2014-09-02 14:09:01 +04:00
2014-09-03 13:49:03 +04:00
return false;
}
2014-09-02 14:09:01 +04:00
2015-04-12 03:15:28 +03:00
if (!data.mode) {
var mode = CodeMirror.findModeByFileName(treeNode.path);
data.mode = mode.mime;
}
2015-07-23 11:31:37 +03:00
2015-04-12 03:15:28 +03:00
if (!data.mode) {
console.error("Can't find mode by file name [" + treeNode.path + "]");
}
2014-09-03 13:49:03 +04:00
if ("img" === data.mode) { // 是图片文件的话新建 tab 打开
// 最好是开 tab但这个最终取决于浏览器设置
2014-12-11 10:32:24 +03:00
var w = window.open(config.context + data.path);
2014-09-03 13:49:03 +04:00
return false;
}
2014-11-24 12:20:43 +03:00
2014-11-18 05:51:26 +03:00
if (!tempCursor) {
tempCursor = CodeMirror.Pos(0, 0);
}
2015-07-23 11:31:37 +03:00
2014-11-18 05:51:26 +03:00
editors.newEditor(data, tempCursor);
2015-01-02 13:14:58 +03:00
wide.refreshOutline();
2014-08-18 17:45:43 +04:00
}
2014-09-03 13:49:03 +04:00
});
}
2014-11-18 05:03:08 +03:00
},
_initSearch: function () {
2014-11-18 05:29:08 +03:00
$("#dialogSearchForm > input:eq(0)").keyup(function (event) {
2014-11-18 05:03:08 +03:00
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,
2014-12-05 12:59:42 +03:00
"height": 80,
2014-11-18 05:03:08 +03:00
"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();
2014-12-05 10:08:44 +03:00
if (!wide.curNode) {
request.dir = "";
} else {
request.dir = wide.curNode.path;
}
2014-11-18 05:03:08 +03:00
request.text = $("#dialogSearchForm > input:eq(0)").val();
request.extension = $("#dialogSearchForm > input:eq(1)").val();
$.ajax({
type: 'POST',
2014-12-11 10:32:24 +03:00
url: config.context + '/file/search/text',
2014-11-18 05:03:08 +03:00
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
if (!data.succ) {
return;
}
$("#dialogSearchForm").dialog("close");
editors.appendSearch(data.founds, 'founds', request.text);
}
});
}
});
2014-12-03 06:26:05 +03:00
},
_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;
2015-07-23 11:31:37 +03:00
request.newPath = wide.curNode.path.substring(0, wide.curNode.path.lastIndexOf("/")) + name;
2014-12-03 06:26:05 +03:00
$.ajax({
type: 'POST',
2014-12-11 10:32:24 +03:00
url: config.context + '/file/rename',
2014-12-03 06:26:05 +03:00
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
if (!data.succ) {
$("#dialogRenamePrompt").dialog("close");
bottomGroup.tabs.setCurrent("notification");
windows.flowBottom();
$(".bottom-window-group .notification").focus();
return false;
}
$("#dialogRenamePrompt").dialog("close");
// update tree node
2015-04-10 15:03:07 +03:00
var suffixIndex = name.lastIndexOf('.');
var suffix = name.substr(suffixIndex + 1);
2015-04-12 03:15:28 +03:00
2015-04-10 15:03:07 +03:00
var iconSkin = 'ico-ztree-dir ';
if ('f' === wide.curNode.type) {
iconSkin = wide.getClassBySuffix(suffix);
}
2015-04-12 03:15:28 +03:00
2014-12-03 06:26:05 +03:00
wide.curNode.name = name;
wide.curNode.title = request.newPath;
wide.curNode.path = request.newPath;
wide.curNode.iconSkin = iconSkin;
2015-04-10 15:03:07 +03:00
2014-12-03 06:26:05 +03:00
tree.fileTree.updateNode(wide.curNode);
// update open editor tab name
for (var i = 0, ii = editors.data.length; i < ii; i++) {
if (wide.curNode.path === editors.data[i].id) {
2015-04-10 15:03:07 +03:00
var mode = CodeMirror.findModeByExtension(suffix);
if (mode) {
editors.data[i].editor.setOption("mode", mode.mime);
2014-12-03 06:26:05 +03:00
}
var $currentSpan = $('.edit-panel .tabs > div[data-index="' + wide.curNode.path + '"] > span:eq(0)');
2014-12-03 06:26:05 +03:00
$currentSpan.attr("title", request.newPath);
$currentSpan.html('<span class="' + iconSkin + 'ico"></span>' + wide.curNode.name);
break;
}
}
}
});
}
});
2014-08-18 17:45:43 +04:00
}
};