Merge remote-tracking branch 'origin/master'

This commit is contained in:
Van 2014-09-17 10:18:41 +08:00
commit 475d5a414f
7 changed files with 162 additions and 117 deletions

View File

@ -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>

View File

@ -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 {

View File

@ -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 = [];
@ -134,12 +133,11 @@ var editors = {
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',
@ -154,9 +152,8 @@ 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',
@ -186,12 +183,11 @@ 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',

View File

@ -69,10 +69,10 @@ var tree = {
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',
@ -133,10 +133,10 @@ var tree = {
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',
@ -161,9 +161,10 @@ var tree = {
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',
@ -197,9 +198,12 @@ 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) {
@ -256,9 +260,9 @@ 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',

View File

@ -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":

View File

@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/golang/glog"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
) )
@ -18,22 +19,54 @@ var Session = sessions.NewCookieStore([]byte("BEYOND"))
// Wide 会话,对应一个浏览器 tab. // Wide 会话,对应一个浏览器 tab.
type WideSession struct { type WideSession struct {
Id string // 唯一标识 Id string // 唯一标识
HTTPSessionId string // HTTP 会话 id
State int // 状态 State int // 状态
Created time.Time // 创建时间 Created time.Time // 创建时间
Updated 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))
}
}
} }

View File

@ -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
} }
};</script>
return ret;
}
</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>