JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
1497d10c95eea8ffbb4dcab7b8d979a584ce07b4
[watch-my-terminal.git] / client.coffee
1 $ ->
2         timeout = (ms, f) -> setTimeout(f, ms)
3         term = null
4         palette = [
5                 # normal colours
6                 '2e3436',
7                 'cc0000',
8                 '4e9a06',
9                 'c4a000',
10                 '3465a4',
11                 '75507b',
12                 '06989a',
13                 'd3d7cf',
14
15                 # brighter versions (for bold, and 16-color sequences)
16                 '555753',
17                 'ef2929',
18                 '8ae234',
19                 'fce94f',
20                 '729fcf',
21                 'ad7fa8',
22                 '34e2e2',
23                 'eeeeec',
24
25                 # 256 colors
26                 '000000', '00005f', '000087', '0000af', '0000d7', '0000ff', '005f00', '005f5f',
27                 '005f87', '005faf', '005fd7', '005fff', '008700', '00875f', '008787', '0087af',
28                 '0087d7', '0087ff', '00af00', '00af5f', '00af87', '00afaf', '00afd7', '00afff',
29                 '00d700', '00d75f', '00d787', '00d7af', '00d7d7', '00d7ff', '00ff00', '00ff5f',
30                 '00ff87', '00ffaf', '00ffd7', '00ffff', '5f0000', '5f005f', '5f0087', '5f00af',
31                 '5f00d7', '5f00ff', '5f5f00', '5f5f5f', '5f5f87', '5f5faf', '5f5fd7', '5f5fff',
32                 '5f8700', '5f875f', '5f8787', '5f87af', '5f87d7', '5f87ff', '5faf00', '5faf5f',
33                 '5faf87', '5fafaf', '5fafd7', '5fafff', '5fd700', '5fd75f', '5fd787', '5fd7af',
34                 '5fd7d7', '5fd7ff', '5fff00', '5fff5f', '5fff87', '5fffaf', '5fffd7', '5fffff',
35                 '870000', '87005f', '870087', '8700af', '8700d7', '8700ff', '875f00', '875f5f',
36                 '875f87', '875faf', '875fd7', '875fff', '878700', '87875f', '878787', '8787af',
37                 '8787d7', '8787ff', '87af00', '87af5f', '87af87', '87afaf', '87afd7', '87afff',
38                 '87d700', '87d75f', '87d787', '87d7af', '87d7d7', '87d7ff', '87ff00', '87ff5f',
39                 '87ff87', '87ffaf', '87ffd7', '87ffff', 'af0000', 'af005f', 'af0087', 'af00af',
40                 'af00d7', 'af00ff', 'af5f00', 'af5f5f', 'af5f87', 'af5faf', 'af5fd7', 'af5fff',
41                 'af8700', 'af875f', 'af8787', 'af87af', 'af87d7', 'af87ff', 'afaf00', 'afaf5f',
42                 'afaf87', 'afafaf', 'afafd7', 'afafff', 'afd700', 'afd75f', 'afd787', 'afd7af',
43                 'afd7d7', 'afd7ff', 'afff00', 'afff5f', 'afff87', 'afffaf', 'afffd7', 'afffff',
44                 'd70000', 'd7005f', 'd70087', 'd700af', 'd700d7', 'd700ff', 'd75f00', 'd75f5f',
45                 'd75f87', 'd75faf', 'd75fd7', 'd75fff', 'd78700', 'd7875f', 'd78787', 'd787af',
46                 'd787d7', 'd787ff', 'd7af00', 'd7af5f', 'd7af87', 'd7afaf', 'd7afd7', 'd7afff',
47                 'd7d700', 'd7d75f', 'd7d787', 'd7d7af', 'd7d7d7', 'd7d7ff', 'd7ff00', 'd7ff5f',
48                 'd7ff87', 'd7ffaf', 'd7ffd7', 'd7ffff', 'ff0000', 'ff005f', 'ff0087', 'ff00af',
49                 'ff00d7', 'ff00ff', 'ff5f00', 'ff5f5f', 'ff5f87', 'ff5faf', 'ff5fd7', 'ff5fff',
50                 'ff8700', 'ff875f', 'ff8787', 'ff87af', 'ff87d7', 'ff87ff', 'ffaf00', 'ffaf5f',
51                 'ffaf87', 'ffafaf', 'ffafd7', 'ffafff', 'ffd700', 'ffd75f', 'ffd787', 'ffd7af',
52                 'ffd7d7', 'ffd7ff', 'ffff00', 'ffff5f', 'ffff87', 'ffffaf', 'ffffd7', 'ffffff',
53                 '080808', '121212', '1c1c1c', '262626', '303030', '3a3a3a', '444444', '4e4e4e',
54                 '585858', '626262', '6c6c6c', '767676', '808080', '8a8a8a', '949494', '9e9e9e',
55                 'a8a8a8', 'b2b2b2', 'bcbcbc', 'c6c6c6', 'd0d0d0', 'dadada', 'e4e4e4', 'eeeeee'
56         ]
57
58         $body = $('body')
59
60         socket = io.connect('http://localhost')
61
62         color_to_css = (i) ->
63                 index = 0xff & i
64                 # lighten the basic 8 colors when they're bold
65                 if ((i & 0x10000) and index < 8)
66                         index += 8
67                 return 'color: #' + palette[index] + '; '
68
69         bg_color_to_css = (i) ->
70                 return 'background-' + color_to_css((i & 0x10000) | ((i & 0xff00) >> 8))
71
72         stylize = (txt, style) ->
73                 if (txt.length == 0 or style == 0x000007)
74                         return txt
75                 css = ''
76                 css += 'font-weight: bold; ' if style & 0x10000
77                 css += 'text-decoration: underline; ' if style & 0x20000
78                 css += 'font-style: italic; ' if style & 0x40000 # blink
79                 css += 'text-decoration: line-through; ' if style & 0x80000 # invisible
80                 css += color_to_css(style) if style & 0x000ff
81                 css += bg_color_to_css(style) if style & 0x0ff00
82                 return $('<span style="'+css+'"></span>').text(txt)
83
84         redraw_wait = false
85         redraw_again = false
86         redraw_now = ->
87                 $body.children().remove()
88                 for i in [0...term.text.length]
89                         div = $('<div>')
90                         txt = ''
91                         a = 0x000007
92                         for j in [0...term.text[i].length]
93                                 if (term.attributes[i][j] isnt a)
94                                         if (txt.length)
95                                                 div.append(stylize(txt, a))
96                                                 txt = ''
97                                         a = term.attributes[i][j]
98                                 txt += term.text[i][j]
99                         if txt.length
100                                 div.append(stylize(txt, a))
101                         $body.append(div)
102
103         # limit to 50fps
104         redraw = ->
105                 if (redraw_wait)
106                         redraw_again = true
107                 else
108                         redraw_now()
109                         redraw_wait = true
110                         redraw_again = false
111                         timeout 20, ->
112                                 redraw_wait = false
113                                 if (redraw_again)
114                                         redraw_again = false
115                                         redraw()
116
117         update = (data) ->
118                 if (term)
119                         term.update(data)
120                         redraw()
121
122         socket.on 'data', (data) ->
123                 update(data)
124
125         socket.on 'init', (v) ->
126                 term = terminal.new(v.width, v.height)
127                 term.x = v.x
128                 term.y = v.y
129                 term.a = v.a
130                 term.text = v.text
131                 term.attributes = v.attributes
132                 redraw()