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