JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
parse in the client too, limit to 50fps
authorJason Woofenden <jason@jasonwoof.com>
Wed, 30 Jan 2013 21:42:11 +0000 (16:42 -0500)
committerJason Woofenden <jason@jasonwoof.com>
Wed, 30 Jan 2013 21:42:11 +0000 (16:42 -0500)
index.html
server.coffee
terminal.coffee

index e70dfc7..a38d705 100644 (file)
@@ -3,9 +3,11 @@
 <head>
        <title>Remote Terminal Viewer</title>
        <script src="/jquery.js"></script>
+       <script src="/terminal.js"></script>
        <script src="/socket.io/socket.io.js"></script>
        <script>
                $(function() {
+                       var term = null;
                        // 8-14 are bolded versions
                        var palette = [
                                '2e3436',
                                        index += 8;
                                }
                                return 'color: #' + palette[index] + '; ';
-                       }
+                       };
                        var bg_color_to_css = function(i) {
                                return 'background-' + color_to_css((i&0x10000) | ((i&0xff00) >> 8));
-                       }
+                       };
                        var stylize = function (txt, style) {
                                if (txt.length == 0 || style == 0) {
                                        return txt
                                }
                                css = ''
-                               if(style & 0x10000) css += 'font-weight: bold; ';
-                               if(style & 0x20000) css += 'text-decoration: underline; ';
-                               if(style & 0x40000) css += 'text-decoration: underline; '; // blink
-                               if(style & 0x80000) css += 'text-decoration: line-through; '; // invisible
-                               if(style & 0x000ff) css += color_to_css(style);
-                               if(style & 0x0ff00) css += bg_color_to_css(style);
+                               if (style & 0x10000) css += 'font-weight: bold; ';
+                               if (style & 0x20000) css += 'text-decoration: underline; ';
+                               if (style & 0x40000) css += 'text-decoration: underline; '; // blink
+                               if (style & 0x80000) css += 'text-decoration: line-through; '; // invisible
+                               if (style & 0x000ff) css += color_to_css(style);
+                               if (style & 0x0ff00) css += bg_color_to_css(style);
                                return $('<span style="'+css+'"></span>').text(txt);
-                       }
-                       socket.on('init', function (v) {
+                       };
+                       var redraw_wait = false;
+                       var redraw_again = false;
+                       var redraw_now = function () {
                                $body.children().remove();
-                               for(i in v.text) {
+                               for (i in term.text) {
                                        div = $('<div>');
                                        txt = ''
                                        a = 0;
-                                       for(j in v.text[i]) {
-                                               if(v.attributes[i][j] != a) {
-                                                       if(txt.length) {
+                                       for (j in term.text[i]) {
+                                               if (term.attributes[i][j] != a) {
+                                                       if (txt.length) {
                                                                div.append(stylize(txt, a));
                                                                txt = ''
                                                        }
-                                                       a = v.attributes[i][j]
+                                                       a = term.attributes[i][j]
                                                }
-                                               txt += v.text[i][j]
+                                               txt += term.text[i][j]
                                        }
                                        if(txt.length) {
                                                div.append(stylize(txt, a));
                                        }
                                        $body.append(div);
                                }
+                       }
+                       // limit to 50fps
+                       var redraw = function () {
+                               if (redraw_wait) {
+                                       redraw_again = true;
+                               } else {
+                                       redraw_now()
+                                       redraw_wait = true;
+                                       redraw_again = false;
+                                       setTimeout(function () {
+                                               redraw_wait = false;
+                                               if(redraw_again) {
+                                                       redraw_again = false;
+                                                       redraw();
+                                               }
+                                       }, 20);
+                               }
+                       }
+                       var update = function (data) {
+                               if (term) {
+                                       term.update(data);
+                                       redraw();
+                               }
+                       };
+
+                       socket.on('data', function (data) {
+                               update(data);
+                       });
+                       socket.on('init', function (v) {
+                               term = terminal.new(v.width, v.height);
+                               term.x = v.x;
+                               term.y = v.y;
+                               term.a = v.a;
+                               term.text = v.text;
+                               term.attributes = v.attributes;
+                               redraw();
                        });
                });
        </script>
index 1d0422b..32daeff 100644 (file)
@@ -1,7 +1,7 @@
 handler = (req, res) ->
-       err = (req, res) ->
-               res.writeHead(404, 'Content-Type': 'text/plain')
-               return res.end("Error loading #{req.url}")
+       reply_err = (req, res, msg) ->
+               res.writeHead(200, 'Content-Type': 'text/plain')
+               return res.end("Error loading #{req.url} \"#{msg}\"")
        switch req.url
                when '/', '/index.html'
                        filename = __dirname + '/index.html'
@@ -9,14 +9,24 @@ handler = (req, res) ->
                when '/jquery.js'
                        filename = '/usr/share/javascript/jquery/jquery.min.js'
                        type = 'text/javascript'
+               when '/terminal.js'
+                       filename = __dirname + '/terminal.coffee'
+                       type = 'text/javascript'
                else
-                       return err req, res
-       fs.readFile filename, (err, data) ->
-               return err req, res if err
+                       return reply_err req, res
+       fs.readFile filename, 'utf8', (err, data) ->
+               return reply_err req, res, err if err
+
+               if filename.substr(filename.length - 7) is '.coffee'
+                       try
+                               data = coffee.compile data
+                       catch e
+                               return reply_err req, res, "server faild to compile #{filename}: #{JSON.stringify(e)}"
 
                res.writeHead(200, 'Content-Type': type)
                res.end(data)
 
+coffee = require 'coffee-script'
 app = require('http').createServer(handler)
 io = require('socket.io').listen(app)
 fs = require('fs')
@@ -43,8 +53,7 @@ process.stdin.setEncoding 'utf8'
 
 process.stdin.on 'data', (data) ->
        term.update data
-       # FIXME send data, and have client parse it
        for s in sockets
-               s.emit 'init', width: term.width, height: term.height, x: term.x, y: term.y, a: term.a, text: term.text, attributes: term.attributes
+               s.emit 'data', data
 
 process.stdin.on 'end', -> process.exit()
index 34c7515..c7dbd7f 100644 (file)
@@ -1,5 +1,11 @@
-async = require 'async'
-fs = require 'fs'
+# this file is used by the client and server.
+
+# work around lack of module system in the browser:
+if exports?
+       my_exports = exports
+else
+       window.terminal = {}
+       my_exports = window.terminal
 
 class Terminal
        # public:
@@ -191,5 +197,5 @@ class Terminal
                return -1 unless parts?
                return parts[0].length
 
-exports.new = (width, height) ->
+my_exports.new = (width, height) ->
        return new Terminal width, height