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 {
IP string // server ip, ${ip}
Port string // server port
Context string // server context
Server string // server host and port ({IP}:{Port})
StaticServer string // static resources server scheme, host and port (http://{IP}:{Port})
EditorChannel string // editor 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})
Channel string // channel (ws://{IP}:{Port})
HTTPSessionMaxAge int // HTTP session max age (in seciond)
StaticResourceVersion string // version of static resources
MaxProcs int // Go max procs
@ -251,7 +249,7 @@ func Save() bool {
}
// 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)
err := json.Unmarshal(bytes, &Wide)
@ -301,34 +299,24 @@ func Load(confPath, confIP, confPort, confServer, confChannel string, confDocker
Wide.Server = confServer
}
// Context
if "" != confContext {
Wide.Context = confContext
}
// Static Server
Wide.StaticServer = strings.Replace(Wide.StaticServer, "{IP}", Wide.IP, 1)
Wide.StaticResourceVersion = strings.Replace(Wide.StaticResourceVersion, "${time}", strconv.FormatInt(time.Now().UnixNano(), 10), 1)
// Channels
Wide.EditorChannel = strings.Replace(Wide.EditorChannel, "{IP}", Wide.IP, 1)
// Channel
Wide.Channel = strings.Replace(Wide.Channel, "{IP}", Wide.IP, 1)
Wide.Channel = strings.Replace(Wide.Channel, "{Port}", Wide.Port, 1)
if "" != confChannel {
Wide.EditorChannel = 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.Channel = confChannel
}
Wide.Server = strings.Replace(Wide.Server, "{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))
@ -338,6 +326,7 @@ func Load(confPath, confIP, confPort, confServer, confChannel string, confDocker
// upgrade upgrades the wide.json.
func upgrade() {
// Users
for _, user := range Wide.Users {
if "" == user.Theme {
user.Theme = "default" // since 1.1.0

View File

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

View File

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

97
main.go
View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,7 @@ var notification = {
this._initWS();
},
_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 () {
console.log('[notification onopen] connected');

View File

@ -41,7 +41,7 @@ var session = {
$.ajax({
type: 'POST',
url: '/session/save',
url: config.context + '/session/save',
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
@ -112,7 +112,7 @@ var session = {
},
_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 () {
console.log('[session onopen] connected');

View File

@ -17,7 +17,7 @@
var shell = {
_shellWS: undefined,
_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 () {
console.log('[shell onopen] connected');
};

View File

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

View File

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

View File

@ -60,12 +60,12 @@
<div class="frame">
<ul>
<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 class="fn-right ft-small">Ctrl-Z</span>
</li>
<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 class="fn-right ft-small">Ctrl-Y</span>
</li>
@ -81,7 +81,7 @@
</li>
<li class="hr"></li>
<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 class="fn-right ft-small">Ctrl-A</span>
</li>
@ -95,28 +95,28 @@
<span class="fn-right ft-small">Ctrl-L</span>
</li>
<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 class="fn-right ft-small">Ctrl-E</span>
</li>
<li class="hr"></li>
<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 class="fn-right ft-small">Shift-Ctrl-Up</span>
</li>
<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 class="fn-right ft-small">Shift-Ctrl-Down</span>
</li>
<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 class="fn-right ft-small">Shift-Alt-Up</span>
</li>
<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 class="fn-right ft-small">Shift-Alt-Down</span>
</li>
@ -128,23 +128,23 @@
<div class="frame">
<ul>
<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 class="fn-right ft-small">Ctrl-Shift-F</span>
</li>
<li class="hr"></li>
<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 class="fn-right ft-small">Ctrl-\</span>
</li>
<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 class="fn-right ft-small">Ctrl-B</span>
</li>
<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 class="fn-right ft-small">Ctrl-I</span>
</li>
@ -155,7 +155,7 @@
</li>
<li class="hr"></li>
<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 class="fn-right ft-small">Ctrl-/</span>
</li>
@ -456,7 +456,8 @@
</div>
<script>
var config = {
"staticServer": "{{.conf.StaticServer}}",
"context": {{.conf.Context}},
"staticServer": {{.conf.StaticServer}},
"pathSeparator": '{{.pathSeparator}}',
"label": {
"restore_editor": "{{.i18n.restore_editor}}",
@ -489,12 +490,7 @@
"apply": "{{.i18n.apply}}",
"no_empty": "{{.i18n.no_empty}}"
},
"channel": {
"editor": '{{.conf.EditorChannel}}',
"shell": '{{.conf.ShellChannel}}',
"output": '{{.conf.OutputChannel}}',
"session": '{{.conf.SessionChannel}}'
},
"channel": {{.conf.Channel}},
"wideSessionId": '{{.session.ID}}',
"editorTheme": '{{.user.Editor.Theme}}',
"latestSessionContent": {{.latestSessionContent}},