Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
475d5a414f
|
@ -27,6 +27,8 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li>Ctrl+1:焦点切换到文件树</li>
|
<li>Ctrl+1:焦点切换到文件树</li>
|
||||||
<li>Ctrl+4:焦点切换到输出窗口</li>
|
<li>Ctrl+4:焦点切换到输出窗口</li>
|
||||||
|
<li>Ctrl+5:焦点切换到搜索窗口</li>
|
||||||
|
<li>Ctrl+6:焦点切换到通知窗口</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>运行</h2>
|
<h2>运行</h2>
|
||||||
|
|
8
main.go
8
main.go
|
@ -40,7 +40,7 @@ func init() {
|
||||||
// Wide 首页.
|
// Wide 首页.
|
||||||
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// 创建一个 Wide 会话
|
// 创建一个 Wide 会话
|
||||||
wideSession := user.NewSession()
|
wideSession := user.WideSessions.New()
|
||||||
|
|
||||||
i18n.Load()
|
i18n.Load()
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
name := conf.Wide.Users[0].Name
|
name := conf.Wide.Users[0].Name
|
||||||
|
|
||||||
httpSession.Values["username"] = name
|
httpSession.Values["username"] = name
|
||||||
httpSession.Values["id"] = strconv.Itoa(rand.Int())
|
httpSessionId := strconv.Itoa(rand.Int())
|
||||||
|
httpSession.Values["id"] = httpSessionId
|
||||||
// 一天过期
|
// 一天过期
|
||||||
httpSession.Options.MaxAge = 60 * 60 * 24
|
httpSession.Options.MaxAge = 60 * 60 * 24
|
||||||
|
|
||||||
|
@ -63,6 +64,9 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
httpSession.Save(r, w)
|
httpSession.Save(r, w)
|
||||||
|
|
||||||
|
// Wide 会话关联 HTTP 会话
|
||||||
|
wideSession.HTTPSessionId = httpSession.Values["id"].(string)
|
||||||
|
|
||||||
t, err := template.ParseFiles("view/index.html")
|
t, err := template.ParseFiles("view/index.html")
|
||||||
|
|
||||||
if nil != err {
|
if nil != err {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
var editors = {
|
var editors = {
|
||||||
data: [],
|
data: [],
|
||||||
init: function() {
|
init: function () {
|
||||||
editors._initAutocomplete();
|
editors._initAutocomplete();
|
||||||
editors.tabs = new Tabs({
|
editors.tabs = new Tabs({
|
||||||
id: ".edit-panel",
|
id: ".edit-panel",
|
||||||
clickAfter: function(id) {
|
clickAfter: function (id) {
|
||||||
// set tree node selected
|
// set tree node selected
|
||||||
var node = tree.fileTree.getNodeByTId(id);
|
var node = tree.fileTree.getNodeByTId(id);
|
||||||
tree.fileTree.selectNode(node);
|
tree.fileTree.selectNode(node);
|
||||||
|
@ -19,7 +19,7 @@ var editors = {
|
||||||
|
|
||||||
wide.curEditor.focus();
|
wide.curEditor.focus();
|
||||||
},
|
},
|
||||||
removeAfter: function(id, nextId) {
|
removeAfter: function (id, nextId) {
|
||||||
for (var i = 0, ii = editors.data.length; i < ii; i++) {
|
for (var i = 0, ii = editors.data.length; i < ii; i++) {
|
||||||
if (editors.data[i].id === id) {
|
if (editors.data[i].id === id) {
|
||||||
editors.data.splice(i, 1);
|
editors.data.splice(i, 1);
|
||||||
|
@ -57,16 +57,16 @@ var editors = {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$(".edit-header .tabs").on("dblclick", "div", function() {
|
$(".edit-header .tabs").on("dblclick", "div", function () {
|
||||||
editors.fullscreen();
|
editors.fullscreen();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
fullscreen: function() {
|
fullscreen: function () {
|
||||||
wide.curEditor.setOption("fullScreen", true);
|
wide.curEditor.setOption("fullScreen", true);
|
||||||
wide.curEditor.focus();
|
wide.curEditor.focus();
|
||||||
},
|
},
|
||||||
_initAutocomplete: function() {
|
_initAutocomplete: function () {
|
||||||
CodeMirror.registerHelper("hint", "go", function(editor) {
|
CodeMirror.registerHelper("hint", "go", function (editor) {
|
||||||
var word = /[\w$]+/;
|
var word = /[\w$]+/;
|
||||||
|
|
||||||
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
|
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
|
||||||
|
@ -79,12 +79,11 @@ var editors = {
|
||||||
--start;
|
--start;
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
path: $(".edit-header .current > span:eq(0)").attr("title"),
|
request.path = $(".edit-header .current > span:eq(0)").attr("title");
|
||||||
code: editor.getValue(),
|
request.code = editor.getValue();
|
||||||
cursorLine: cur.line,
|
request.cursorLine = cur.line;
|
||||||
cursorCh: cur.ch
|
request.cursorCh = cur.ch;
|
||||||
};
|
|
||||||
|
|
||||||
var autocompleteHints = [];
|
var autocompleteHints = [];
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ var editors = {
|
||||||
url: '/autocomplete',
|
url: '/autocomplete',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
var autocompleteArray = data[1];
|
var autocompleteArray = data[1];
|
||||||
|
|
||||||
if (autocompleteArray) {
|
if (autocompleteArray) {
|
||||||
|
@ -108,8 +107,8 @@ var editors = {
|
||||||
return {list: autocompleteHints, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
|
return {list: autocompleteHints, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
|
||||||
});
|
});
|
||||||
|
|
||||||
CodeMirror.commands.autocompleteAfterDot = function(cm) {
|
CodeMirror.commands.autocompleteAfterDot = function (cm) {
|
||||||
setTimeout(function() {
|
setTimeout(function () {
|
||||||
if (!cm.state.completionActive) {
|
if (!cm.state.completionActive) {
|
||||||
cm.showHint({hint: CodeMirror.hint.go, completeSingle: false});
|
cm.showHint({hint: CodeMirror.hint.go, completeSingle: false});
|
||||||
}
|
}
|
||||||
|
@ -118,35 +117,34 @@ var editors = {
|
||||||
return CodeMirror.Pass;
|
return CodeMirror.Pass;
|
||||||
};
|
};
|
||||||
|
|
||||||
CodeMirror.commands.autocompleteAnyWord = function(cm) {
|
CodeMirror.commands.autocompleteAnyWord = function (cm) {
|
||||||
cm.showHint({hint: CodeMirror.hint.auto});
|
cm.showHint({hint: CodeMirror.hint.auto});
|
||||||
};
|
};
|
||||||
|
|
||||||
CodeMirror.commands.gotoLine = function(cm) {
|
CodeMirror.commands.gotoLine = function (cm) {
|
||||||
var line = prompt("Go To Line: ", "0");
|
var line = prompt("Go To Line: ", "0");
|
||||||
|
|
||||||
cm.setCursor(CodeMirror.Pos(line - 1, 0));
|
cm.setCursor(CodeMirror.Pos(line - 1, 0));
|
||||||
};
|
};
|
||||||
|
|
||||||
CodeMirror.commands.doNothing = function(cm) {
|
CodeMirror.commands.doNothing = function (cm) {
|
||||||
};
|
};
|
||||||
|
|
||||||
CodeMirror.commands.jumpToDecl = function(cm) {
|
CodeMirror.commands.jumpToDecl = function (cm) {
|
||||||
var cur = wide.curEditor.getCursor();
|
var cur = wide.curEditor.getCursor();
|
||||||
|
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
path: $(".edit-header .current > span:eq(0)").attr("title"),
|
request.path = $(".edit-header .current > span:eq(0)").attr("title");
|
||||||
code: wide.curEditor.getValue(),
|
request.code = wide.curEditor.getValue();
|
||||||
cursorLine: cur.line,
|
request.cursorLine = cur.line;
|
||||||
cursorCh: cur.ch
|
request.cursorCh = cur.ch;
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/find/decl',
|
url: '/find/decl',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
if (!data.succ) {
|
if (!data.succ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -154,16 +152,15 @@ var editors = {
|
||||||
var cursorLine = data.cursorLine;
|
var cursorLine = data.cursorLine;
|
||||||
var cursorCh = data.cursorCh;
|
var cursorCh = data.cursorCh;
|
||||||
|
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
path: data.path
|
request.path = data.path;
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/file',
|
url: '/file',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
if (!data.succ) {
|
if (!data.succ) {
|
||||||
alert(data.msg);
|
alert(data.msg);
|
||||||
|
|
||||||
|
@ -183,22 +180,21 @@ var editors = {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
CodeMirror.commands.findUsages = function(cm) {
|
CodeMirror.commands.findUsages = function (cm) {
|
||||||
var cur = wide.curEditor.getCursor();
|
var cur = wide.curEditor.getCursor();
|
||||||
|
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
file: wide.curNode.path,
|
request.file = wide.curNode.path;
|
||||||
code: wide.curEditor.getValue(),
|
request.code = wide.curEditor.getValue();
|
||||||
cursorLine: cur.line,
|
request.cursorLine = cur.line;
|
||||||
cursorCh: cur.ch
|
request.cursorCh = cur.ch;
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/find/usages',
|
url: '/find/usages',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
if (!data.succ) {
|
if (!data.succ) {
|
||||||
|
@ -211,7 +207,7 @@ var editors = {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
// 新建一个编辑器 Tab,如果已经存在 Tab 则切换到该 Tab.
|
// 新建一个编辑器 Tab,如果已经存在 Tab 则切换到该 Tab.
|
||||||
newEditor: function(data) {
|
newEditor: function (data) {
|
||||||
$(".ico-fullscreen").show();
|
$(".ico-fullscreen").show();
|
||||||
var id = wide.curNode.tId;
|
var id = wide.curNode.tId;
|
||||||
|
|
||||||
|
@ -256,12 +252,12 @@ var editors = {
|
||||||
extraKeys: {
|
extraKeys: {
|
||||||
"Ctrl-\\": "autocompleteAnyWord",
|
"Ctrl-\\": "autocompleteAnyWord",
|
||||||
".": "autocompleteAfterDot",
|
".": "autocompleteAfterDot",
|
||||||
"Esc": function(cm) {
|
"Esc": function (cm) {
|
||||||
if (cm.getOption("fullScreen")) {
|
if (cm.getOption("fullScreen")) {
|
||||||
cm.setOption("fullScreen", false);
|
cm.setOption("fullScreen", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"F11": function(cm) {
|
"F11": function (cm) {
|
||||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||||
},
|
},
|
||||||
"Ctrl-G": "gotoLine",
|
"Ctrl-G": "gotoLine",
|
||||||
|
@ -269,16 +265,16 @@ var editors = {
|
||||||
"Ctrl-D": "doNothing", // 取消默认的 deleteLine
|
"Ctrl-D": "doNothing", // 取消默认的 deleteLine
|
||||||
"Ctrl-B": "jumpToDecl",
|
"Ctrl-B": "jumpToDecl",
|
||||||
"Ctrl-S": function () {
|
"Ctrl-S": function () {
|
||||||
wide.saveFile();
|
wide.saveFile();
|
||||||
},
|
},
|
||||||
"Shift-Alt-F": function () {
|
"Shift-Alt-F": function () {
|
||||||
wide.fmt();
|
wide.fmt();
|
||||||
},
|
},
|
||||||
"Alt-F7": "findUsages"
|
"Alt-F7": "findUsages"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.on('cursorActivity', function(cm) {
|
editor.on('cursorActivity', function (cm) {
|
||||||
var cursor = cm.getCursor();
|
var cursor = cm.getCursor();
|
||||||
|
|
||||||
$("#footer-cursor").text('| ' + (cursor.line + 1) + ':' + (cursor.ch + 1) + ' |');
|
$("#footer-cursor").text('| ' + (cursor.line + 1) + ':' + (cursor.ch + 1) + ' |');
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var tree = {
|
var tree = {
|
||||||
// 递归获取当前节点展开中的最后一个节点
|
// 递归获取当前节点展开中的最后一个节点
|
||||||
getCurrentNodeLastNode: function(node) {
|
getCurrentNodeLastNode: function (node) {
|
||||||
var returnNode = node.children[node.children.length - 1];
|
var returnNode = node.children[node.children.length - 1];
|
||||||
if (returnNode.open) {
|
if (returnNode.open) {
|
||||||
return tree.getCurrentNodeLastNode(returnNode);
|
return tree.getCurrentNodeLastNode(returnNode);
|
||||||
|
@ -9,7 +9,7 @@ var tree = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 按照树展现获取下一个节点
|
// 按照树展现获取下一个节点
|
||||||
getNextShowNode: function(node) {
|
getNextShowNode: function (node) {
|
||||||
if (node.level !== 0) {
|
if (node.level !== 0) {
|
||||||
if (node.getParentNode().getNextNode()) {
|
if (node.getParentNode().getNextNode()) {
|
||||||
return node.getParentNode().getNextNode();
|
return node.getParentNode().getNextNode();
|
||||||
|
@ -20,7 +20,7 @@ var tree = {
|
||||||
return node.getNextNode();
|
return node.getNextNode();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isBottomNode: function(node) {
|
isBottomNode: function (node) {
|
||||||
if (node.open) {
|
if (node.open) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ var tree = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTIdByPath: function(path) {
|
getTIdByPath: function (path) {
|
||||||
var nodes = tree.fileTree.transformToArray(tree.fileTree.getNodes());
|
var nodes = tree.fileTree.transformToArray(tree.fileTree.getNodes());
|
||||||
for (var i = 0, ii = nodes.length; i < ii; i++) {
|
for (var i = 0, ii = nodes.length; i < ii; i++) {
|
||||||
if (nodes[i].path === path) {
|
if (nodes[i].path === path) {
|
||||||
|
@ -50,7 +50,7 @@ var tree = {
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
fileTree: undefined,
|
fileTree: undefined,
|
||||||
_isParents: function(tId, parentTId) {
|
_isParents: function (tId, parentTId) {
|
||||||
var node = tree.fileTree.getNodeByTId(tId);
|
var node = tree.fileTree.getNodeByTId(tId);
|
||||||
if (!node || !node.parentTId) {
|
if (!node || !node.parentTId) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -62,23 +62,23 @@ var tree = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
newFile: function() {
|
newFile: function () {
|
||||||
$("#dirRMenu").hide();
|
$("#dirRMenu").hide();
|
||||||
var name = prompt("Name", "");
|
var name = prompt("Name", "");
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
path: wide.curNode.path + '\\' + name,
|
request.path = wide.curNode.path + '\\' + name;
|
||||||
fileType: "f"
|
request.fileType = "f";
|
||||||
};
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/file/new',
|
url: '/file/new',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
if (!data.succ) {
|
if (!data.succ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -126,23 +126,23 @@ var tree = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
newDir: function() {
|
newDir: function () {
|
||||||
$("#dirRMenu").hide();
|
$("#dirRMenu").hide();
|
||||||
var name = prompt("Name", "");
|
var name = prompt("Name", "");
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
path: wide.curNode.path + '\\' + name,
|
request.path = wide.curNode.path + '\\' + name;
|
||||||
fileType: "d"
|
request.fileType = "d";
|
||||||
};
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/file/new',
|
url: '/file/new',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
if (!data.succ) {
|
if (!data.succ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -154,22 +154,23 @@ var tree = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
removeIt: function() {
|
removeIt: function () {
|
||||||
$("#dirRMenu").hide();
|
$("#dirRMenu").hide();
|
||||||
$("#fileRMenu").hide();
|
$("#fileRMenu").hide();
|
||||||
|
|
||||||
if (!confirm("Remove it?")) {
|
if (!confirm("Remove it?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var request = {
|
|
||||||
path: wide.curNode.path
|
var request = newWideRequest();
|
||||||
};
|
request.path = wide.curNode.path;
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/file/remove',
|
url: '/file/remove',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
if (!data.succ) {
|
if (!data.succ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -196,12 +197,15 @@ var tree = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
init: function() {
|
init: function () {
|
||||||
|
var request = newWideRequest();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'POST',
|
||||||
url: '/files',
|
url: '/files',
|
||||||
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
if (data.succ) {
|
if (data.succ) {
|
||||||
var dirRMenu = $("#dirRMenu");
|
var dirRMenu = $("#dirRMenu");
|
||||||
var fileRMenu = $("#fileRMenu");
|
var fileRMenu = $("#fileRMenu");
|
||||||
|
@ -210,7 +214,7 @@ var tree = {
|
||||||
selectedMulti: false
|
selectedMulti: false
|
||||||
},
|
},
|
||||||
callback: {
|
callback: {
|
||||||
onRightClick: function(event, treeId, treeNode) {
|
onRightClick: function (event, treeId, treeNode) {
|
||||||
if (treeNode) {
|
if (treeNode) {
|
||||||
wide.curNode = treeNode;
|
wide.curNode = treeNode;
|
||||||
if ("ico-ztree-dir " !== treeNode.iconSkin) { // 如果右击了文件
|
if ("ico-ztree-dir " !== treeNode.iconSkin) { // 如果右击了文件
|
||||||
|
@ -230,7 +234,7 @@ var tree = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onClick: function(event, treeId, treeNode, clickFlag) {
|
onClick: function (event, treeId, treeNode, clickFlag) {
|
||||||
tree._onClick(treeNode);
|
tree._onClick(treeNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +244,7 @@ var tree = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
_onClick: function(treeNode) {
|
_onClick: function (treeNode) {
|
||||||
if (wide.curNode) {
|
if (wide.curNode) {
|
||||||
for (var i = 0, ii = editors.data.length; i < ii; i++) {
|
for (var i = 0, ii = editors.data.length; i < ii; i++) {
|
||||||
// 该节点文件已经打开
|
// 该节点文件已经打开
|
||||||
|
@ -256,15 +260,15 @@ var tree = {
|
||||||
wide.curNode = treeNode;
|
wide.curNode = treeNode;
|
||||||
|
|
||||||
if ("ico-ztree-dir " !== treeNode.iconSkin) { // 如果单击了文件
|
if ("ico-ztree-dir " !== treeNode.iconSkin) { // 如果单击了文件
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
path: treeNode.path
|
request.path = treeNode.path;
|
||||||
};
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/file',
|
url: '/file',
|
||||||
data: JSON.stringify(request),
|
data: JSON.stringify(request),
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function (data) {
|
||||||
if (!data.succ) {
|
if (!data.succ) {
|
||||||
alert(data.msg);
|
alert(data.msg);
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,8 @@ outputWS.onmessage = function(e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('run' === data.nextCmd) {
|
if ('run' === data.nextCmd) {
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
executable: data.executable
|
request.executable = data.executable;
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
|
@ -101,10 +100,10 @@ var wide = {
|
||||||
|
|
||||||
},
|
},
|
||||||
saveFile: function() {
|
saveFile: function() {
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
file: $(".edit-header .current span:eq(0)").attr("title"),
|
request.file = $(".edit-header .current span:eq(0)").attr("title");
|
||||||
code: wide.curEditor.getValue()
|
request.code = wide.curEditor.getValue();
|
||||||
};
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/file/save',
|
url: '/file/save',
|
||||||
|
@ -128,10 +127,9 @@ var wide = {
|
||||||
},
|
},
|
||||||
// 构建 & 运行.
|
// 构建 & 运行.
|
||||||
run: function() {
|
run: function() {
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
file: $(".edit-header .current span:eq(0)").attr("title"),
|
request.file = $(".edit-header .current span:eq(0)").attr("title");
|
||||||
code: wide.curEditor.getValue()
|
request.code = wide.curEditor.getValue();
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: 修改 [构建&运行] 图标状态为不可用状态
|
// TODO: 修改 [构建&运行] 图标状态为不可用状态
|
||||||
|
|
||||||
|
@ -148,9 +146,8 @@ var wide = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
goget: function() {
|
goget: function() {
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
file: $(".edit-header .current span:eq(0)").attr("title")
|
request.file = $(".edit-header .current span:eq(0)").attr("title");
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
|
@ -165,10 +162,9 @@ var wide = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
goinstall: function() {
|
goinstall: function() {
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
file: $(".edit-header .current span:eq(0)").attr("title"),
|
request.file = $(".edit-header .current span:eq(0)").attr("title");
|
||||||
code: wide.curEditor.getValue()
|
request.code = wide.curEditor.getValue();
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
|
@ -186,12 +182,11 @@ var wide = {
|
||||||
var path = $(".edit-header .current span:eq(0)").attr("title");
|
var path = $(".edit-header .current span:eq(0)").attr("title");
|
||||||
var mode = wide.curNode.mode;
|
var mode = wide.curNode.mode;
|
||||||
|
|
||||||
var request = {
|
var request = newWideRequest();
|
||||||
file: path,
|
request.file = path;
|
||||||
code: wide.curEditor.getValue(),
|
request.code = wide.curEditor.getValue();
|
||||||
cursorLine: wide.curEditor.getCursor().line,
|
request.cursorLine = wide.curEditor.getCursor().line;
|
||||||
cursorCh: wide.curEditor.getCursor().ch
|
request.cursorCh = wide.curEditor.getCursor().ch;
|
||||||
};
|
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "text/x-go":
|
case "text/x-go":
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,23 +18,55 @@ var Session = sessions.NewCookieStore([]byte("BEYOND"))
|
||||||
|
|
||||||
// Wide 会话,对应一个浏览器 tab.
|
// Wide 会话,对应一个浏览器 tab.
|
||||||
type WideSession struct {
|
type WideSession struct {
|
||||||
Id string // 唯一标识
|
Id string // 唯一标识
|
||||||
State int // 状态
|
HTTPSessionId string // HTTP 会话 id
|
||||||
Created time.Time // 创建时间
|
State int // 状态
|
||||||
Updated time.Time // 最近一次使用时间
|
Created time.Time // 创建时间
|
||||||
|
Updated time.Time // 最近一次使用时间
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Sessions []*WideSession
|
||||||
|
|
||||||
|
// 所有 Wide 会话集.
|
||||||
|
var WideSessions Sessions
|
||||||
|
|
||||||
// 创建一个 Wide 会话.
|
// 创建一个 Wide 会话.
|
||||||
func NewSession() *WideSession {
|
func (sessions *Sessions) New() *WideSession {
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
id := strconv.Itoa(rand.Int())
|
id := strconv.Itoa(rand.Int())
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
return &WideSession{
|
ret := &WideSession{
|
||||||
Id: id,
|
Id: id,
|
||||||
State: SessionStateActive,
|
State: SessionStateActive,
|
||||||
Created: now,
|
Created: now,
|
||||||
Updated: now,
|
Updated: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*sessions = append(*sessions, ret)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除 Wide 会话.
|
||||||
|
func (sessions *Sessions) Remove(sid string) {
|
||||||
|
for i, s := range *sessions {
|
||||||
|
if s.Id == sid {
|
||||||
|
*sessions = append((*sessions)[:i], (*sessions)[i+1:]...)
|
||||||
|
|
||||||
|
glog.V(3).Infof("Has [%d] wide sessions currently", len(*sessions))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除 HTTP 会话关联的所有 Wide 会话.
|
||||||
|
func (sessions *Sessions) RemoveByHTTPSid(httpSessionId string) {
|
||||||
|
for i, s := range *sessions {
|
||||||
|
if s.HTTPSessionId == httpSessionId {
|
||||||
|
*sessions = append((*sessions)[:i], (*sessions)[i+1:]...)
|
||||||
|
|
||||||
|
glog.V(3).Infof("Has [%d] wide sessions currently", len(*sessions))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>{{.i18n.wide}} - {{.session.Id}}</title>
|
<title>{{.i18n.wide}}</title>
|
||||||
<link rel="stylesheet" href="{{.conf.StaticServer}}/static/js/lib/codemirror-4.5/codemirror.css">
|
<link rel="stylesheet" href="{{.conf.StaticServer}}/static/js/lib/codemirror-4.5/codemirror.css">
|
||||||
<link rel="stylesheet" href="{{.conf.StaticServer}}/static/js/lib/codemirror-4.5/addon/hint/show-hint.css">
|
<link rel="stylesheet" href="{{.conf.StaticServer}}/static/js/lib/codemirror-4.5/addon/hint/show-hint.css">
|
||||||
<link rel="stylesheet" href="{{.conf.StaticServer}}/static/js/lib/codemirror-4.5/addon/lint/lint.css">
|
<link rel="stylesheet" href="{{.conf.StaticServer}}/static/js/lib/codemirror-4.5/addon/lint/lint.css">
|
||||||
|
@ -168,11 +168,22 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var config = {
|
var config = {
|
||||||
channel: {
|
channel: {
|
||||||
editor: '{{.conf.EditorChannel}}',
|
editor: {{.conf.EditorChannel}},
|
||||||
shell: '{{.conf.ShellChannel}}',
|
shell: {{.conf.ShellChannel}},
|
||||||
output: '{{.conf.OutputChannel}}'
|
output: {{.conf.OutputChannel}}
|
||||||
|
},
|
||||||
|
wideSessionId: {{.session.Id}}
|
||||||
|
};
|
||||||
|
// 发往 Wide 的所有 AJAX 请求需要使用该函数创建请求参数.
|
||||||
|
function newWideRequest() {
|
||||||
|
var ret = {
|
||||||
|
sid: config.wideSessionId
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
};</script>
|
|
||||||
|
</script>
|
||||||
<script type="text/javascript" src="{{.conf.StaticServer}}/static/js/lib/jquery-2.1.1.min.js"></script>
|
<script type="text/javascript" src="{{.conf.StaticServer}}/static/js/lib/jquery-2.1.1.min.js"></script>
|
||||||
<script type="text/javascript" src="{{.conf.StaticServer}}/static/js/lib/reconnecting-websocket.js"></script>
|
<script type="text/javascript" src="{{.conf.StaticServer}}/static/js/lib/reconnecting-websocket.js"></script>
|
||||||
<script type="text/javascript" src="{{.conf.StaticServer}}/static/js/lib/ztree/jquery.ztree.all-3.5.min.js"></script>
|
<script type="text/javascript" src="{{.conf.StaticServer}}/static/js/lib/ztree/jquery.ztree.all-3.5.min.js"></script>
|
||||||
|
|
Loading…
Reference in New Issue