add context path support

This commit is contained in:
Liang Ding 2014-12-11 15:32:24 +08:00
parent c3a3862699
commit 56f3fa1cf6
14 changed files with 124 additions and 135 deletions

View File

@ -90,12 +90,10 @@ type Editor struct {
type conf struct { type conf struct {
IP string // server ip, ${ip} IP string // server ip, ${ip}
Port string // server port Port string // server port
Context string // server context
Server string // server host and port ({IP}:{Port}) Server string // server host and port ({IP}:{Port})
StaticServer string // static resources server scheme, host and port (http://{IP}:{Port}) StaticServer string // static resources server scheme, host and port (http://{IP}:{Port})
EditorChannel string // editor channel (ws://{IP}:{Port}) Channel string // channel (ws://{IP}:{Port})
OutputChannel string // output channel (ws://{IP}:{Port})
ShellChannel string // shell channel(ws://{IP}:{Port})
SessionChannel string // wide session channel (ws://{IP}:{Port})
HTTPSessionMaxAge int // HTTP session max age (in seciond) HTTPSessionMaxAge int // HTTP session max age (in seciond)
StaticResourceVersion string // version of static resources StaticResourceVersion string // version of static resources
MaxProcs int // Go max procs MaxProcs int // Go max procs
@ -251,7 +249,7 @@ func Save() bool {
} }
// Load loads the configurations from wide.json. // Load loads the configurations from wide.json.
func Load(confPath, confIP, confPort, confServer, confChannel string, confDocker bool) { func Load(confPath, confIP, confPort, confServer, confContext, confChannel string, confDocker bool) {
bytes, _ := ioutil.ReadFile(confPath) bytes, _ := ioutil.ReadFile(confPath)
err := json.Unmarshal(bytes, &Wide) err := json.Unmarshal(bytes, &Wide)
@ -301,34 +299,24 @@ func Load(confPath, confIP, confPort, confServer, confChannel string, confDocker
Wide.Server = confServer Wide.Server = confServer
} }
// Context
if "" != confContext {
Wide.Context = confContext
}
// Static Server // Static Server
Wide.StaticServer = strings.Replace(Wide.StaticServer, "{IP}", Wide.IP, 1) Wide.StaticServer = strings.Replace(Wide.StaticServer, "{IP}", Wide.IP, 1)
Wide.StaticResourceVersion = strings.Replace(Wide.StaticResourceVersion, "${time}", strconv.FormatInt(time.Now().UnixNano(), 10), 1) Wide.StaticResourceVersion = strings.Replace(Wide.StaticResourceVersion, "${time}", strconv.FormatInt(time.Now().UnixNano(), 10), 1)
// Channels // Channel
Wide.EditorChannel = strings.Replace(Wide.EditorChannel, "{IP}", Wide.IP, 1) Wide.Channel = strings.Replace(Wide.Channel, "{IP}", Wide.IP, 1)
Wide.Channel = strings.Replace(Wide.Channel, "{Port}", Wide.Port, 1)
if "" != confChannel { if "" != confChannel {
Wide.EditorChannel = confChannel Wide.Channel = confChannel
}
Wide.OutputChannel = strings.Replace(Wide.OutputChannel, "{IP}", Wide.IP, 1)
if "" != confChannel {
Wide.OutputChannel = confChannel
}
Wide.ShellChannel = strings.Replace(Wide.ShellChannel, "{IP}", Wide.IP, 1)
if "" != confChannel {
Wide.ShellChannel = confChannel
}
Wide.SessionChannel = strings.Replace(Wide.SessionChannel, "{IP}", Wide.IP, 1)
if "" != confChannel {
Wide.SessionChannel = confChannel
} }
Wide.Server = strings.Replace(Wide.Server, "{Port}", Wide.Port, 1) Wide.Server = strings.Replace(Wide.Server, "{Port}", Wide.Port, 1)
Wide.StaticServer = strings.Replace(Wide.StaticServer, "{Port}", Wide.Port, 1) Wide.StaticServer = strings.Replace(Wide.StaticServer, "{Port}", Wide.Port, 1)
Wide.EditorChannel = strings.Replace(Wide.EditorChannel, "{Port}", Wide.Port, 1)
Wide.OutputChannel = strings.Replace(Wide.OutputChannel, "{Port}", Wide.Port, 1)
Wide.ShellChannel = strings.Replace(Wide.ShellChannel, "{Port}", Wide.Port, 1)
Wide.SessionChannel = strings.Replace(Wide.SessionChannel, "{Port}", Wide.Port, 1)
glog.V(5).Info("Conf: \n" + string(bytes)) glog.V(5).Info("Conf: \n" + string(bytes))
@ -338,6 +326,7 @@ func Load(confPath, confIP, confPort, confServer, confChannel string, confDocker
// upgrade upgrades the wide.json. // upgrade upgrades the wide.json.
func upgrade() { func upgrade() {
// Users
for _, user := range Wide.Users { for _, user := range Wide.Users {
if "" == user.Theme { if "" == user.Theme {
user.Theme = "default" // since 1.1.0 user.Theme = "default" // since 1.1.0

View File

@ -1,12 +1,10 @@
{ {
"IP": "${ip}", "IP": "${ip}",
"Port": "7070", "Port": "7070",
"Context": "",
"Server": "{IP}:{Port}", "Server": "{IP}:{Port}",
"StaticServer": "", "StaticServer": "",
"EditorChannel": "ws://{IP}:{Port}", "Channel": "ws://{IP}:{Port}",
"OutputChannel": "ws://{IP}:{Port}",
"ShellChannel": "ws://{IP}:{Port}",
"SessionChannel": "ws://{IP}:{Port}",
"HTTPSessionMaxAge": 86400, "HTTPSessionMaxAge": 86400,
"StaticResourceVersion": "${time}", "StaticResourceVersion": "${time}",
"MaxProcs": 4, "MaxProcs": 4,
@ -32,7 +30,11 @@
"TabSize": "4" "TabSize": "4"
}, },
"LatestSessionContent": { "LatestSessionContent": {
"FileTree": [], "FileTree": [
"D:\\GoGoGo\\src",
"D:\\GoGoGo\\src\\demo",
"D:\\GoGoGo\\src\\hello"
],
"Files": [], "Files": [],
"CurrentFile": "" "CurrentFile": ""
} }

View File

@ -36,6 +36,7 @@ import (
) )
// WSHandler handles request of creating editor channel. // WSHandler handles request of creating editor channel.
// XXX: NOT used at present
func WSHandler(w http.ResponseWriter, r *http.Request) { func WSHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, "wide-session") httpSession, _ := session.HTTPSession.Get(r, "wide-session")
if httpSession.IsNew { if httpSession.IsNew {

97
main.go
View File

@ -47,6 +47,7 @@ func init() {
confIP := flag.String("ip", "", "ip to visit") confIP := flag.String("ip", "", "ip to visit")
confPort := flag.String("port", "", "port to visit") confPort := flag.String("port", "", "port to visit")
confServer := flag.String("server", "", "this will overwrite Wide.Server if specified") confServer := flag.String("server", "", "this will overwrite Wide.Server if specified")
confContext := flag.String("context", "", "this will overwrite Wide.Context if specified")
confChannel := flag.String("channel", "", "this will overwrite Wide.XXXChannel if specified") confChannel := flag.String("channel", "", "this will overwrite Wide.XXXChannel if specified")
confStat := flag.Bool("stat", false, "whether report statistics periodically") confStat := flag.Bool("stat", false, "whether report statistics periodically")
confDocker := flag.Bool("docker", false, "whether run in a docker container") confDocker := flag.Bool("docker", false, "whether run in a docker container")
@ -68,7 +69,7 @@ func init() {
event.Load() event.Load()
conf.Load(*confPath, *confIP, *confPort, *confServer, *confChannel, *confDocker) conf.Load(*confPath, *confIP, *confPort, *confServer, *confContext, *confChannel, *confDocker)
conf.FixedTimeCheckEnv() conf.FixedTimeCheckEnv()
conf.FixedTimeSave() conf.FixedTimeSave()
@ -84,7 +85,7 @@ func init() {
func indexHandler(w http.ResponseWriter, r *http.Request) { func indexHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, "wide-session") httpSession, _ := session.HTTPSession.Get(r, "wide-session")
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/login", http.StatusFound) http.Redirect(w, r, conf.Wide.Context+"login", http.StatusFound)
return return
} }
@ -102,7 +103,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
if nil == user { if nil == user {
glog.Warningf("Not found user [%s]", username) glog.Warningf("Not found user [%s]", username)
http.Redirect(w, r, "/login", http.StatusFound) http.Redirect(w, r, conf.Wide.Context+"login", http.StatusFound)
return return
} }
@ -141,7 +142,7 @@ func serveSingle(pattern string, filename string) {
func startHandler(w http.ResponseWriter, r *http.Request) { func startHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, "wide-session") httpSession, _ := session.HTTPSession.Get(r, "wide-session")
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/login", http.StatusFound) http.Redirect(w, r, conf.Wide.Context+"login", http.StatusFound)
return return
} }
@ -178,7 +179,7 @@ func startHandler(w http.ResponseWriter, r *http.Request) {
func keyboardShortcutsHandler(w http.ResponseWriter, r *http.Request) { func keyboardShortcutsHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, "wide-session") httpSession, _ := session.HTTPSession.Get(r, "wide-session")
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/login", http.StatusFound) http.Redirect(w, r, conf.Wide.Context+"login", http.StatusFound)
return return
} }
@ -207,7 +208,7 @@ func keyboardShortcutsHandler(w http.ResponseWriter, r *http.Request) {
func aboutHandler(w http.ResponseWriter, r *http.Request) { func aboutHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, "wide-session") httpSession, _ := session.HTTPSession.Get(r, "wide-session")
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/login", http.StatusFound) http.Redirect(w, r, conf.Wide.Context+"login", http.StatusFound)
return return
} }
@ -242,72 +243,72 @@ func main() {
defer glog.Flush() defer glog.Flush()
// IDE // IDE
http.HandleFunc("/", handlerGzWrapper(indexHandler)) http.HandleFunc(conf.Wide.Context+"/", handlerGzWrapper(indexHandler))
http.HandleFunc("/start", handlerWrapper(startHandler)) http.HandleFunc(conf.Wide.Context+"/start", handlerWrapper(startHandler))
http.HandleFunc("/about", handlerWrapper(aboutHandler)) http.HandleFunc(conf.Wide.Context+"/about", handlerWrapper(aboutHandler))
http.HandleFunc("/keyboard_shortcuts", handlerWrapper(keyboardShortcutsHandler)) http.HandleFunc(conf.Wide.Context+"/keyboard_shortcuts", handlerWrapper(keyboardShortcutsHandler))
// static resources // static resources
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) http.Handle(conf.Wide.Context+"/static/", http.StripPrefix(conf.Wide.Context+"/static/", http.FileServer(http.Dir("static"))))
serveSingle("/favicon.ico", "./static/favicon.ico") serveSingle("/favicon.ico", "./static/favicon.ico")
// workspaces // workspaces
for _, user := range conf.Wide.Users { for _, user := range conf.Wide.Users {
http.Handle("/workspace/"+user.Name+"/", http.Handle(conf.Wide.Context+"/workspace/"+user.Name+"/",
http.StripPrefix("/workspace/"+user.Name+"/", http.FileServer(http.Dir(user.GetWorkspace())))) http.StripPrefix(conf.Wide.Context+"/workspace/"+user.Name+"/", http.FileServer(http.Dir(user.GetWorkspace()))))
} }
// session // session
http.HandleFunc("/session/ws", handlerWrapper(session.WSHandler)) http.HandleFunc(conf.Wide.Context+"/session/ws", handlerWrapper(session.WSHandler))
http.HandleFunc("/session/save", handlerWrapper(session.SaveContent)) http.HandleFunc(conf.Wide.Context+"/session/save", handlerWrapper(session.SaveContent))
// run // run
http.HandleFunc("/build", handlerWrapper(output.BuildHandler)) http.HandleFunc(conf.Wide.Context+"/build", handlerWrapper(output.BuildHandler))
http.HandleFunc("/run", handlerWrapper(output.RunHandler)) http.HandleFunc(conf.Wide.Context+"/run", handlerWrapper(output.RunHandler))
http.HandleFunc("/stop", handlerWrapper(output.StopHandler)) http.HandleFunc(conf.Wide.Context+"/stop", handlerWrapper(output.StopHandler))
http.HandleFunc("/go/test", handlerWrapper(output.GoTestHandler)) http.HandleFunc(conf.Wide.Context+"/go/test", handlerWrapper(output.GoTestHandler))
http.HandleFunc("/go/get", handlerWrapper(output.GoGetHandler)) http.HandleFunc(conf.Wide.Context+"/go/get", handlerWrapper(output.GoGetHandler))
http.HandleFunc("/go/install", handlerWrapper(output.GoInstallHandler)) http.HandleFunc(conf.Wide.Context+"/go/install", handlerWrapper(output.GoInstallHandler))
http.HandleFunc("/output/ws", handlerWrapper(output.WSHandler)) http.HandleFunc(conf.Wide.Context+"/output/ws", handlerWrapper(output.WSHandler))
// file tree // file tree
http.HandleFunc("/files", handlerWrapper(file.GetFiles)) http.HandleFunc(conf.Wide.Context+"/files", handlerWrapper(file.GetFiles))
http.HandleFunc("/file/refresh", handlerWrapper(file.RefreshDirectory)) http.HandleFunc(conf.Wide.Context+"/file/refresh", handlerWrapper(file.RefreshDirectory))
http.HandleFunc("/file", handlerWrapper(file.GetFile)) http.HandleFunc(conf.Wide.Context+"/file", handlerWrapper(file.GetFile))
http.HandleFunc("/file/save", handlerWrapper(file.SaveFile)) http.HandleFunc(conf.Wide.Context+"/file/save", handlerWrapper(file.SaveFile))
http.HandleFunc("/file/new", handlerWrapper(file.NewFile)) http.HandleFunc(conf.Wide.Context+"/file/new", handlerWrapper(file.NewFile))
http.HandleFunc("/file/remove", handlerWrapper(file.RemoveFile)) http.HandleFunc(conf.Wide.Context+"/file/remove", handlerWrapper(file.RemoveFile))
http.HandleFunc("/file/rename", handlerWrapper(file.RenameFile)) http.HandleFunc(conf.Wide.Context+"/file/rename", handlerWrapper(file.RenameFile))
http.HandleFunc("/file/search/text", handlerWrapper(file.SearchText)) http.HandleFunc(conf.Wide.Context+"/file/search/text", handlerWrapper(file.SearchText))
http.HandleFunc("/file/find/name", handlerWrapper(file.Find)) http.HandleFunc(conf.Wide.Context+"/file/find/name", handlerWrapper(file.Find))
// file export/import // file export/import
http.HandleFunc("/file/zip/new", handlerWrapper(file.CreateZip)) http.HandleFunc(conf.Wide.Context+"/file/zip/new", handlerWrapper(file.CreateZip))
http.HandleFunc("/file/zip", handlerWrapper(file.GetZip)) http.HandleFunc(conf.Wide.Context+"/file/zip", handlerWrapper(file.GetZip))
http.HandleFunc("/file/upload", handlerWrapper(file.Upload)) http.HandleFunc(conf.Wide.Context+"/file/upload", handlerWrapper(file.Upload))
// editor // editor
http.HandleFunc("/editor/ws", handlerWrapper(editor.WSHandler)) http.HandleFunc(conf.Wide.Context+"/editor/ws", handlerWrapper(editor.WSHandler))
http.HandleFunc("/go/fmt", handlerWrapper(editor.GoFmtHandler)) http.HandleFunc(conf.Wide.Context+"/go/fmt", handlerWrapper(editor.GoFmtHandler))
http.HandleFunc("/autocomplete", handlerWrapper(editor.AutocompleteHandler)) http.HandleFunc(conf.Wide.Context+"/autocomplete", handlerWrapper(editor.AutocompleteHandler))
http.HandleFunc("/exprinfo", handlerWrapper(editor.GetExprInfoHandler)) http.HandleFunc(conf.Wide.Context+"/exprinfo", handlerWrapper(editor.GetExprInfoHandler))
http.HandleFunc("/find/decl", handlerWrapper(editor.FindDeclarationHandler)) http.HandleFunc(conf.Wide.Context+"/find/decl", handlerWrapper(editor.FindDeclarationHandler))
http.HandleFunc("/find/usages", handlerWrapper(editor.FindUsagesHandler)) http.HandleFunc(conf.Wide.Context+"/find/usages", handlerWrapper(editor.FindUsagesHandler))
// shell // shell
http.HandleFunc("/shell/ws", handlerWrapper(shell.WSHandler)) http.HandleFunc(conf.Wide.Context+"/shell/ws", handlerWrapper(shell.WSHandler))
http.HandleFunc("/shell", handlerWrapper(shell.IndexHandler)) http.HandleFunc(conf.Wide.Context+"/shell", handlerWrapper(shell.IndexHandler))
// notification // notification
http.HandleFunc("/notification/ws", handlerWrapper(notification.WSHandler)) http.HandleFunc(conf.Wide.Context+"/notification/ws", handlerWrapper(notification.WSHandler))
// user // user
http.HandleFunc("/login", handlerWrapper(session.LoginHandler)) http.HandleFunc(conf.Wide.Context+"/login", handlerWrapper(session.LoginHandler))
http.HandleFunc("/logout", handlerWrapper(session.LogoutHandler)) http.HandleFunc(conf.Wide.Context+"/logout", handlerWrapper(session.LogoutHandler))
http.HandleFunc("/signup", handlerWrapper(session.SignUpUser)) http.HandleFunc(conf.Wide.Context+"/signup", handlerWrapper(session.SignUpUser))
http.HandleFunc("/preference", handlerWrapper(session.PreferenceHandler)) http.HandleFunc(conf.Wide.Context+"/preference", handlerWrapper(session.PreferenceHandler))
glog.Infof("Wide is running [%s]", conf.Wide.Server) glog.Infof("Wide is running [%s]", conf.Wide.Server+conf.Wide.Context)
err := http.ListenAndServe(conf.Wide.Server, nil) err := http.ListenAndServe(conf.Wide.Server, nil)
if err != nil { if err != nil {

View File

@ -48,7 +48,7 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := HTTPSession.Get(r, "wide-session") httpSession, _ := HTTPSession.Get(r, "wide-session")
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/preference", http.StatusFound) http.Redirect(w, r, conf.Wide.Context+"login", http.StatusFound)
return return
} }

View File

@ -43,7 +43,7 @@ var ShellWS = map[string]*util.WSChannel{}
func IndexHandler(w http.ResponseWriter, r *http.Request) { func IndexHandler(w http.ResponseWriter, r *http.Request) {
httpSession, _ := session.HTTPSession.Get(r, "wide-session") httpSession, _ := session.HTTPSession.Get(r, "wide-session")
if httpSession.IsNew { if httpSession.IsNew {
http.Redirect(w, r, "/login", http.StatusFound) http.Redirect(w, r, conf.Wide.Context+"login", http.StatusFound)
return return
} }

View File

@ -260,7 +260,7 @@ var editors = {
title: '<span title="' + config.label.start_page + '">' + config.label.start_page + '</span>', title: '<span title="' + config.label.start_page + '">' + config.label.start_page + '</span>',
content: '<div id="startPage"></div>', content: '<div id="startPage"></div>',
after: function () { after: function () {
$("#startPage").load('/start?sid=' + config.wideSessionId); $("#startPage").load(config.context + '/start?sid=' + config.wideSessionId);
$.ajax({ $.ajax({
url: "http://symphony.b3log.org/apis/articles?tags=wide,golang&p=1&size=30", url: "http://symphony.b3log.org/apis/articles?tags=wide,golang&p=1&size=30",
type: "GET", type: "GET",
@ -334,7 +334,7 @@ var editors = {
$.ajax({ $.ajax({
async: false, // 同步执行 async: false, // 同步执行
type: 'POST', type: 'POST',
url: '/autocomplete', url: config.context + '/autocomplete',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -419,7 +419,7 @@ var editors = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/exprinfo', url: config.context + '/exprinfo',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -566,7 +566,7 @@ var editors = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/find/decl', url: config.context + '/find/decl',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -594,7 +594,7 @@ var editors = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/find/usages', url: config.context + '/find/usages',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {

View File

@ -27,7 +27,7 @@ var menu = {
}); });
}, },
_initAbout: function () { _initAbout: function () {
$("#dialogAbout").load('/about', function () { $("#dialogAbout").load(config.context + '/about', function () {
$("#dialogAbout").dialog({ $("#dialogAbout").dialog({
"modal": true, "modal": true,
"height": 460, "height": 460,
@ -121,7 +121,7 @@ var menu = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/logout', url: config.context + '/logout',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -151,7 +151,7 @@ var menu = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/go/get', url: config.context + '/go/get',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function (data) {
@ -178,7 +178,7 @@ var menu = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/go/install', url: config.context + '/go/install',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function (data) {
@ -206,7 +206,7 @@ var menu = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/go/test', url: config.context + '/go/test',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function (data) {
@ -241,7 +241,7 @@ var menu = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/build', url: config.context + '/build',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function (data) {
@ -273,7 +273,7 @@ var menu = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/build', url: config.context + '/build',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
beforeSend: function (data) { beforeSend: function (data) {
@ -284,7 +284,7 @@ var menu = {
}); });
}, },
_initPreference: function () { _initPreference: function () {
$("#dialogPreference").load('/preference', function () { $("#dialogPreference").load(config.context + '/preference', function () {
$("#dialogPreference input").keyup(function () { $("#dialogPreference input").keyup(function () {
var isChange = false, var isChange = false,
emptys = [], emptys = [],
@ -386,7 +386,7 @@ var menu = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/preference', url: config.context + '/preference',
data: JSON.stringify(request), data: JSON.stringify(request),
success: function (data, textStatus, jqXHR) { success: function (data, textStatus, jqXHR) {
if (!data.succ) { if (!data.succ) {

View File

@ -25,7 +25,7 @@ var notification = {
this._initWS(); this._initWS();
}, },
_initWS: function () { _initWS: function () {
var notificationWS = new ReconnectingWebSocket(config.channel.shell + '/notification/ws?sid=' + config.wideSessionId); var notificationWS = new ReconnectingWebSocket(config.channel + '/notification/ws?sid=' + config.wideSessionId);
notificationWS.onopen = function () { notificationWS.onopen = function () {
console.log('[notification onopen] connected'); console.log('[notification onopen] connected');

View File

@ -41,7 +41,7 @@ var session = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/session/save', url: config.context + '/session/save',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -112,7 +112,7 @@ var session = {
}, },
_initWS: function () { _initWS: function () {
// 用于保持会话,如果该通道断开,则服务器端会销毁会话状态,回收相关资源. // 用于保持会话,如果该通道断开,则服务器端会销毁会话状态,回收相关资源.
var sessionWS = new ReconnectingWebSocket(config.channel.session + '/session/ws?sid=' + config.wideSessionId); var sessionWS = new ReconnectingWebSocket(config.channel + '/session/ws?sid=' + config.wideSessionId);
sessionWS.onopen = function () { sessionWS.onopen = function () {
console.log('[session onopen] connected'); console.log('[session onopen] connected');

View File

@ -17,7 +17,7 @@
var shell = { var shell = {
_shellWS: undefined, _shellWS: undefined,
_initWS: function () { _initWS: function () {
shell.shellWS = new ReconnectingWebSocket(config.channel.shell + '/shell/ws?sid=' + config.wideSessionId); shell.shellWS = new ReconnectingWebSocket(config.channel + '/shell/ws?sid=' + config.wideSessionId);
shell.shellWS.onopen = function () { shell.shellWS.onopen = function () {
console.log('[shell onopen] connected'); console.log('[shell onopen] connected');
}; };

View File

@ -154,7 +154,7 @@ var tree = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/file/zip/new', url: config.context + '/file/zip/new',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -164,7 +164,7 @@ var tree = {
return false; return false;
} }
window.open('/file/zip?path=' + wide.curNode.path + '.zip'); window.open(config.context + '/file/zip?path=' + wide.curNode.path + '.zip');
} }
}); });
}, },
@ -205,7 +205,7 @@ var tree = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/files', url: config.context + '/files',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -224,7 +224,7 @@ var tree = {
}, },
async: { async: {
enable: true, enable: true,
url: "/file/refresh", url: config.context + "/file/refresh",
autoParam: ["path"] autoParam: ["path"]
}, },
callback: { callback: {
@ -323,7 +323,7 @@ var tree = {
$.ajax({ $.ajax({
async: false, async: false,
type: 'POST', type: 'POST',
url: '/file', url: config.context + '/file',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -335,7 +335,7 @@ var tree = {
if ("img" === data.mode) { // 是图片文件的话新建 tab 打开 if ("img" === data.mode) { // 是图片文件的话新建 tab 打开
// 最好是开 tab但这个最终取决于浏览器设置 // 最好是开 tab但这个最终取决于浏览器设置
var w = window.open(data.path); var w = window.open(config.context + data.path);
return false; return false;
} }
@ -394,7 +394,7 @@ var tree = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/file/search/text', url: config.context + '/file/search/text',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -433,7 +433,7 @@ var tree = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/file/rename', url: config.context + '/file/rename',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {

View File

@ -60,7 +60,7 @@ var wide = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/file/remove', url: config.context + '/file/remove',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -117,7 +117,7 @@ var wide = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/file/new', url: config.context + '/file/new',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -165,7 +165,7 @@ var wide = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/file/new', url: config.context + '/file/new',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -232,7 +232,7 @@ var wide = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/file/find/name', url: config.context + '/file/find/name',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -320,7 +320,7 @@ var wide = {
} }
}, },
_initWS: function () { _initWS: function () {
var outputWS = new ReconnectingWebSocket(config.channel.output + '/output/ws?sid=' + config.wideSessionId); var outputWS = new ReconnectingWebSocket(config.channel + '/output/ws?sid=' + config.wideSessionId);
outputWS.onopen = function () { outputWS.onopen = function () {
console.log('[output onopen] connected'); console.log('[output onopen] connected');
}; };
@ -339,7 +339,7 @@ var wide = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/run', url: config.context + '/run',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json" dataType: "json"
}); });
@ -468,7 +468,7 @@ var wide = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/file/save', url: config.context + '/file/save',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -518,7 +518,7 @@ var wide = {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '/stop', url: config.context + '/stop',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -540,7 +540,7 @@ var wide = {
$.ajax({ $.ajax({
async: false, // sync async: false, // sync
type: 'POST', type: 'POST',
url: '/go/fmt', url: config.context + '/go/fmt',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
@ -573,7 +573,7 @@ var wide = {
$.ajax({ $.ajax({
async: false, // sync async: false, // sync
type: 'POST', type: 'POST',
url: '/go/fmt', url: config.context + '/go/fmt',
data: JSON.stringify(request), data: JSON.stringify(request),
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {

View File

@ -60,12 +60,12 @@
<div class="frame"> <div class="frame">
<ul> <ul>
<li class="edit disabled" <li class="edit disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.undo();wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.undo(); wide.curEditor.focus()}">
<span>{{.i18n.undo}}</span> <span>{{.i18n.undo}}</span>
<span class="fn-right ft-small">Ctrl-Z</span> <span class="fn-right ft-small">Ctrl-Z</span>
</li> </li>
<li class="edit disabled" <li class="edit disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.redo();wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.redo(); wide.curEditor.focus()}">
<span>{{.i18n.redo}}</span> <span>{{.i18n.redo}}</span>
<span class="fn-right ft-small">Ctrl-Y</span> <span class="fn-right ft-small">Ctrl-Y</span>
</li> </li>
@ -81,7 +81,7 @@
</li> </li>
<li class="hr"></li> <li class="hr"></li>
<li class="edit disabled" <li class="edit disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('selectAll');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('selectAll'); wide.curEditor.focus()}">
<span>{{.i18n.select_all}}</span> <span>{{.i18n.select_all}}</span>
<span class="fn-right ft-small">Ctrl-A</span> <span class="fn-right ft-small">Ctrl-A</span>
</li> </li>
@ -95,28 +95,28 @@
<span class="fn-right ft-small">Ctrl-L</span> <span class="fn-right ft-small">Ctrl-L</span>
</li> </li>
<li class="edit disabled" <li class="edit disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('deleteLine');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('deleteLine'); wide.curEditor.focus()}">
<span>{{.i18n.delete_line}}</span> <span>{{.i18n.delete_line}}</span>
<span class="fn-right ft-small">Ctrl-E</span> <span class="fn-right ft-small">Ctrl-E</span>
</li> </li>
<li class="hr"></li> <li class="hr"></li>
<li class="edit disabled" <li class="edit disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('copyLinesUp');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('copyLinesUp'); wide.curEditor.focus()}">
<span>{{.i18n.copy_lines_up}}</span> <span>{{.i18n.copy_lines_up}}</span>
<span class="fn-right ft-small">Shift-Ctrl-Up</span> <span class="fn-right ft-small">Shift-Ctrl-Up</span>
</li> </li>
<li class="edit disabled" <li class="edit disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('copyLinesDown');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('copyLinesDown'); wide.curEditor.focus()}">
<span>{{.i18n.copy_lines_down}}</span> <span>{{.i18n.copy_lines_down}}</span>
<span class="fn-right ft-small">Shift-Ctrl-Down</span> <span class="fn-right ft-small">Shift-Ctrl-Down</span>
</li> </li>
<li class="edit disabled" <li class="edit disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('moveLinesUp');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('moveLinesUp'); wide.curEditor.focus()}">
<span>{{.i18n.move_lines_up}}</span> <span>{{.i18n.move_lines_up}}</span>
<span class="fn-right ft-small">Shift-Alt-Up</span> <span class="fn-right ft-small">Shift-Alt-Up</span>
</li> </li>
<li class="edit disabled" <li class="edit disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('moveLinesDown');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('moveLinesDown'); wide.curEditor.focus()}">
<span>{{.i18n.move_lines_down}}</span> <span>{{.i18n.move_lines_down}}</span>
<span class="fn-right ft-small">Shift-Alt-Down</span> <span class="fn-right ft-small">Shift-Alt-Down</span>
</li> </li>
@ -128,23 +128,23 @@
<div class="frame"> <div class="frame">
<ul> <ul>
<li class="format disabled" <li class="format disabled"
onclick="if (!$(this).hasClass('disabled')){wide.fmt(editors.getCurrentPath(), wide.curEditor);wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.fmt(editors.getCurrentPath(), wide.curEditor); wide.curEditor.focus()}">
<span>{{.i18n.format}}</span> <span>{{.i18n.format}}</span>
<span class="fn-right ft-small">Ctrl-Shift-F</span> <span class="fn-right ft-small">Ctrl-Shift-F</span>
</li> </li>
<li class="hr"></li> <li class="hr"></li>
<li class="autocomplete disabled" <li class="autocomplete disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('autocompleteAnyWord');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('autocompleteAnyWord'); wide.curEditor.focus()}">
<span>{{.i18n.autocomplete}}</span> <span>{{.i18n.autocomplete}}</span>
<span class="fn-right ft-small">Ctrl-\</span> <span class="fn-right ft-small">Ctrl-\</span>
</li> </li>
<li class="jump-to-decl disabled" <li class="jump-to-decl disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('jumpToDecl');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('jumpToDecl'); wide.curEditor.focus()}">
<span>{{.i18n.jump_to_decl}}</span> <span>{{.i18n.jump_to_decl}}</span>
<span class="fn-right ft-small">Ctrl-B</span> <span class="fn-right ft-small">Ctrl-B</span>
</li> </li>
<li class="expr-info disabled" <li class="expr-info disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('exprInfo');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('exprInfo'); wide.curEditor.focus()}">
<span>{{.i18n.show_expr_info}}</span> <span>{{.i18n.show_expr_info}}</span>
<span class="fn-right ft-small">Ctrl-I</span> <span class="fn-right ft-small">Ctrl-I</span>
</li> </li>
@ -155,7 +155,7 @@
</li> </li>
<li class="hr"></li> <li class="hr"></li>
<li class="toggle-comment disabled" <li class="toggle-comment disabled"
onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('toggleComment');wide.curEditor.focus()}"> onclick="if (!$(this).hasClass('disabled')){wide.curEditor.execCommand('toggleComment'); wide.curEditor.focus()}">
<span>{{.i18n.toggle_comment}}</span> <span>{{.i18n.toggle_comment}}</span>
<span class="fn-right ft-small">Ctrl-/</span> <span class="fn-right ft-small">Ctrl-/</span>
</li> </li>
@ -456,7 +456,8 @@
</div> </div>
<script> <script>
var config = { var config = {
"staticServer": "{{.conf.StaticServer}}", "context": {{.conf.Context}},
"staticServer": {{.conf.StaticServer}},
"pathSeparator": '{{.pathSeparator}}', "pathSeparator": '{{.pathSeparator}}',
"label": { "label": {
"restore_editor": "{{.i18n.restore_editor}}", "restore_editor": "{{.i18n.restore_editor}}",
@ -489,12 +490,7 @@
"apply": "{{.i18n.apply}}", "apply": "{{.i18n.apply}}",
"no_empty": "{{.i18n.no_empty}}" "no_empty": "{{.i18n.no_empty}}"
}, },
"channel": { "channel": {{.conf.Channel}},
"editor": '{{.conf.EditorChannel}}',
"shell": '{{.conf.ShellChannel}}',
"output": '{{.conf.OutputChannel}}',
"session": '{{.conf.SessionChannel}}'
},
"wideSessionId": '{{.session.ID}}', "wideSessionId": '{{.session.ID}}',
"editorTheme": '{{.user.Editor.Theme}}', "editorTheme": '{{.user.Editor.Theme}}',
"latestSessionContent": {{.latestSessionContent}}, "latestSessionContent": {{.latestSessionContent}},