errors now appear in red in the browser

master
Jordan Orelli 12 years ago
parent 01d1a4e073
commit 28c989a603

@ -2,6 +2,7 @@ package main
import ( import (
"code.google.com/p/go.net/websocket" "code.google.com/p/go.net/websocket"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/jordanorelli/skeam/am" "github.com/jordanorelli/skeam/am"
@ -40,29 +41,59 @@ func getTemplate(relpath string) (*template.Template, error) {
return t, err return t, err
} }
type templateHandler string type templateHandler struct {
path string
context interface{}
}
func (t templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
tpl, err := getTemplate(string(t)) tpl, err := getTemplate(t.path)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
if err := tpl.Execute(w, nil); err != nil { if err := tpl.Execute(w, t.context); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
} }
} }
type wsMessage struct {
IsError bool `json:"is_error"`
Message string `json:"message"`
}
type wsWriter struct {
conn *websocket.Conn
}
func (w wsWriter) Write(b []byte) (int, error) {
out, err := json.Marshal(wsMessage{false, string(b)})
if err != nil {
return 0, err
}
return w.conn.Write(out)
}
type wsErrorWriter wsWriter
func (w wsErrorWriter) Write(b []byte) (int, error) {
out, err := json.Marshal(wsMessage{true, string(b)})
if err != nil {
return 0, err
}
return w.conn.Write(out)
}
func wsHandler(ws *websocket.Conn) { func wsHandler(ws *websocket.Conn) {
manager.Add(ws) manager.Add(ws)
defer manager.Remove(ws) defer manager.Remove(ws)
i := newInterpreter(ws, ws, ws) i := newInterpreter(ws, wsWriter{ws}, wsErrorWriter{ws})
i.run(universe) i.run(universe)
} }
func runHTTPServer() { func runHTTPServer() {
http.Handle("/", templateHandler("home.html")) http.Handle("/", &templateHandler{"home.html", map[string]interface{}{"ws_path": template.JS("/ws")}})
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(assets.AbsPath("static"))))) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(assets.AbsPath("static")))))
http.Handle("/ws", websocket.Handler(wsHandler)) http.Handle("/ws", websocket.Handler(wsHandler))
http.ListenAndServe(*httpAddr, nil) http.ListenAndServe(*httpAddr, nil)

@ -31,3 +31,7 @@ body {
.message { .message {
} }
.error {
color: red;
}

@ -39,9 +39,15 @@ InputHandler.prototype.clear = function() {
// connection handling // connection handling
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
var buildWsPath = function(wsPath) {
if (window.location.port) {
return "ws://" + window.location.hostname + ":" + window.location.port + wsPath;
}
return "ws://" + window.location.hostname + wsPath;
}
var ConnectionHandler = function(wsPath) { var ConnectionHandler = function(wsPath) {
this.path = wsPath; this.c = new WebSocket(buildWsPath(wsPath));
this.c = new WebSocket(wsPath);
this.c.onopen = _.bind(this.onopen, this); this.c.onopen = _.bind(this.onopen, this);
this.c.onclose = _.bind(this.onclose, this); this.c.onclose = _.bind(this.onclose, this);
this.c.onerror = _.bind(this.onerror, this); this.c.onerror = _.bind(this.onerror, this);
@ -79,19 +85,27 @@ ConnectionHandler.prototype.sendMsg = function(message) {
// response rendering // response rendering
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
var MessageDisplay = function(selector, templateSelector) { var MessageDisplay = function(selector, templateSelector, errorTemplateSelector) {
this.elem = $(selector); this.elem = $(selector);
this.renderMessage = _.template($(templateSelector).html()); this.renderMessage = _.template($(templateSelector).html());
this.renderError = _.template($(errorTemplateSelector).html());
} }
MessageDisplay.prototype.addMessage = function(message) { MessageDisplay.prototype.addMessage = function(rawmessage) {
var rendered = this.renderMessage({message: message}); var message = JSON.parse(rawmessage);
if (message.is_error) {
var rendered = this.renderError(message);
} else {
var rendered = this.renderMessage(message);
}
this.elem.append(rendered); this.elem.append(rendered);
}; };
var Skeam = function(config) { var Skeam = function(config) {
this.inputHandler = new InputHandler(config.inputSelector); this.inputHandler = new InputHandler(config.inputSelector);
this.messageDisplay = new MessageDisplay(config.outputSelector, config.messageTemplateSelector); this.messageDisplay = new MessageDisplay(config.outputSelector,
config.messageTemplateSelector,
config.errorTemplateSelector);
this.conn = new ConnectionHandler(config.wsPath); this.conn = new ConnectionHandler(config.wsPath);
document.addEventListener("sendMsg", _.bind(this.sendMsg, this), false); document.addEventListener("sendMsg", _.bind(this.sendMsg, this), false);
document.addEventListener("receiveResponse", _.bind(this.receiveResponse, this), false); document.addEventListener("receiveResponse", _.bind(this.receiveResponse, this), false);

@ -9,13 +9,19 @@
<pre><%= message %></pre> <pre><%= message %></pre>
</div> </div>
</script> </script>
<script type="application/template" id="error-template">
<div class="error">
<pre><%= message %></pre>
</div>
</script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
var skeam = new Skeam({ var skeam = new Skeam({
inputSelector: "#txt-repl", inputSelector: "#txt-repl",
outputSelector: "#responses", outputSelector: "#responses",
messageTemplateSelector: "#message-template", messageTemplateSelector: "#message-template",
wsPath: "ws://localhost:8000/ws" errorTemplateSelector: "#error-template",
wsPath: "{{.ws_path}}"
}); });
}); });
</script> </script>

Loading…
Cancel
Save