rack-webconsole-pry 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-webconsole-pry (0.1.7)
4
+ rack-webconsole-pry (0.1.8)
5
5
  json
6
6
  multi_json (>= 1.0.3)
7
7
  pry
@@ -2,6 +2,6 @@
2
2
  module Rack
3
3
  class Webconsole
4
4
  # rack-webconsole version number.
5
- VERSION = "0.1.7"
5
+ VERSION = "0.1.8"
6
6
  end
7
7
  end
data/public/webconsole.js CHANGED
@@ -1,5 +1,193 @@
1
1
  (function($) {
2
2
 
3
+ /* AnsiParse */
4
+ ansiparse = function (str) {
5
+ //
6
+ // I'm terrible at writing parsers.
7
+ //
8
+ var matchingControl = null,
9
+ matchingData = null,
10
+ matchingText = '',
11
+ ansiState = [],
12
+ result = [],
13
+ state = {},
14
+ eraseChar;
15
+
16
+ //
17
+ // General workflow for this thing is:
18
+ // \033\[33mText
19
+ // | | |
20
+ // | | matchingText
21
+ // | matchingData
22
+ // matchingControl
23
+ //
24
+ // In further steps we hope it's all going to be fine. It usually is.
25
+ //
26
+
27
+ //
28
+ // Erases a char from the output
29
+ //
30
+ eraseChar = function () {
31
+ var index, text;
32
+ if (matchingText.length) {
33
+ matchingText = matchingText.substr(0, matchingText.length - 1);
34
+ }
35
+ else if (result.length) {
36
+ index = result.length - 1;
37
+ text = result[index].text;
38
+ if (text.length === 1) {
39
+ //
40
+ // A result bit was fully deleted, pop it out to simplify the final output
41
+ //
42
+ result.pop();
43
+ }
44
+ else {
45
+ result[index].text = text.substr(0, text.length - 1);
46
+ }
47
+ }
48
+ };
49
+
50
+ for (var i = 0; i < str.length; i++) {
51
+ if (matchingControl != null) {
52
+ if (matchingControl == '\u001B' && str[i] == '\[') {
53
+ //
54
+ // We've matched full control code. Lets start matching formating data.
55
+ //
56
+
57
+ //
58
+ // "emit" matched text with correct state
59
+ //
60
+ if (matchingText) {
61
+ state.text = matchingText;
62
+ result.push(state);
63
+ state = {};
64
+ matchingText = "";
65
+ }
66
+
67
+ matchingControl = null;
68
+ matchingData = '';
69
+ }
70
+ else {
71
+ //
72
+ // We failed to match anything - most likely a bad control code. We
73
+ // go back to matching regular strings.
74
+ //
75
+ matchingText += matchingControl + str[i];
76
+ matchingControl = null;
77
+ }
78
+ continue;
79
+ }
80
+ else if (matchingData != null) {
81
+ if (str[i] == ';') {
82
+ //
83
+ // `;` separates many formatting codes, for example: `\033[33;43m`
84
+ // means that both `33` and `43` should be applied.
85
+ //
86
+ // TODO: this can be simplified by modifying state here.
87
+ //
88
+ ansiState.push(matchingData);
89
+ matchingData = '';
90
+ }
91
+ else if (str[i] == 'm') {
92
+ //
93
+ // `m` finished whole formatting code. We can proceed to matching
94
+ // formatted text.
95
+ //
96
+ ansiState.push(matchingData);
97
+ matchingData = null;
98
+ matchingText = '';
99
+
100
+ //
101
+ // Convert matched formatting data into user-friendly state object.
102
+ //
103
+ // TODO: DRY.
104
+ //
105
+ ansiState.forEach(function (ansiCode) {
106
+ if (ansiparse.foregroundColors[ansiCode]) {
107
+ state.foreground = ansiparse.foregroundColors[ansiCode];
108
+ }
109
+ else if (ansiparse.backgroundColors[ansiCode]) {
110
+ state.background = ansiparse.backgroundColors[ansiCode];
111
+ }
112
+ else if (ansiCode == 39) {
113
+ delete state.foreground;
114
+ }
115
+ else if (ansiCode == 49) {
116
+ delete state.background;
117
+ }
118
+ else if (ansiparse.styles[ansiCode]) {
119
+ state[ansiparse.styles[ansiCode]] = true;
120
+ }
121
+ else if (ansiCode == 22) {
122
+ state.bold = false;
123
+ }
124
+ else if (ansiCode == 23) {
125
+ state.italic = false;
126
+ }
127
+ else if (ansiCode == 24) {
128
+ state.underline = false;
129
+ }
130
+ });
131
+ ansiState = [];
132
+ }
133
+ else {
134
+ matchingData += str[i];
135
+ }
136
+ continue;
137
+ }
138
+
139
+ if (str[i] == '\u001B') {
140
+ matchingControl = str[i];
141
+ }
142
+ else if (str[i] == '\u0008') {
143
+ eraseChar();
144
+ }
145
+ else {
146
+ matchingText += str[i];
147
+ }
148
+ }
149
+
150
+ if (matchingText) {
151
+ state.text = matchingText + (matchingControl ? matchingControl : '');
152
+ result.push(state);
153
+ }
154
+ return result;
155
+ }
156
+
157
+ ansiparse.foregroundColors = {
158
+ '30': 'black',
159
+ '31': 'red',
160
+ '32': 'green',
161
+ '33': 'yellow',
162
+ '34': 'blue',
163
+ '35': 'magenta',
164
+ '36': 'cyan',
165
+ '37': 'white',
166
+ '90': 'grey'
167
+ };
168
+
169
+ ansiparse.backgroundColors = {
170
+ '40': 'black',
171
+ '41': 'red',
172
+ '42': 'green',
173
+ '43': 'yellow',
174
+ '44': 'blue',
175
+ '45': 'magenta',
176
+ '46': 'cyan',
177
+ '47': 'white'
178
+ };
179
+
180
+ ansiparse.styles = {
181
+ '1': 'bold',
182
+ '3': 'italic',
183
+ '4': 'underline'
184
+ };
185
+
186
+ if (typeof module == "object" && typeof window == "undefined") {
187
+ module.exports = ansiparse;
188
+ }
189
+
190
+ /* app */
3
191
  var webconsole = {
4
192
  history:[],
5
193
  pointer:0,
@@ -10,72 +198,59 @@
10
198
  e.preventDefault();
11
199
  });
12
200
 
13
- var prevStyle = {
14
- color: "#ffffff",
15
- bold: false,
16
- underline: false
17
- }
18
-
19
201
  // colors
20
202
  var colors = {
21
- 30: "#eeeeee",
22
- 31: "#ff6c60",
23
- 32: "#a8ff60",
24
- 33: "#ffffb6",
25
- 34: "#96cbfe",
26
- 35: "#ff73fd",
27
- 36: "#c6c5fe",
28
- 37: "#eeeeee"
203
+ 'black': "#eeeeee",
204
+ 'red': "#ff6c60",
205
+ 'green': "#a8ff60",
206
+ 'yellow': "#ffffb6",
207
+ 'blue': "#96cbfe",
208
+ 'magenta': "#ff73fd",
209
+ 'cyan': "#c6c5fe",
210
+ 'white': "#eeeeee"
29
211
  }
30
212
  var boldColors = {
31
- 30: "#7c7c7c",
32
- 31: "#ffb6b0",
33
- 32: "#ceffac",
34
- 33: "#ffffcb",
35
- 34: "#b5dcfe",
36
- 35: "#ff9cfe",
37
- 36: "#dfdffe",
38
- 37: "#ffffff"
213
+ 'black': "#7c7c7c",
214
+ 'red': "#ffb6b0",
215
+ 'green': "#ceffac",
216
+ 'yellow': "#ffffcb",
217
+ 'blue': "#b5dcfe",
218
+ 'magenta': "#ff9cfe",
219
+ 'cyan': "#dfdffe",
220
+ 'white': "#ffffff"
39
221
  }
40
222
 
41
- function resetBashStyle()
223
+ function subColor(color, elem)
42
224
  {
43
- prevStyle = {
44
- color: colors[37],
45
- bold: 'normal',
46
- underline: 'none'
47
- };
225
+ if (color == undefined) color = 'white';
226
+ if (elem.bold && boldColors[color] != undefined) {
227
+ color = boldColors[color];
228
+ } else if (!elem.bold && colors[color] != undefined) {
229
+ color = colors[color];
230
+ }
231
+ return color;
48
232
  }
49
- function bashColorToHtml(bcolor)
233
+ function parseBashString(str, into)
50
234
  {
51
- // set values
52
- var all = bcolor.split(/;/g)
53
- if (all.indexOf("0") > 0) // ignore anything before 0, since 0 resets
54
- all.splice(0, all.indexOf("0"));
55
- if (all.indexOf("0") >= 0)
56
- resetBashStyle();
57
- if (all.indexOf("1") >= 0)
58
- prevStyle['bold'] = 'bold';
59
- if (all.indexOf("4") >= 0)
60
- prevStyle['underline'] = 'underline';
61
- if (prevStyle['bold'] == 'bold')
62
- colorMap = boldColors;
63
- else
64
- colorMap = colors;
65
- $.each(all, function(idx, val) {
66
- var i = parseInt(val);
67
- if (i > 10 && colorMap[i] != undefined)
68
- prevStyle['color'] = colorMap[i];
235
+ $.each(ansiparse(str), function(idx, elem) {
236
+ if (elem.text.length == 1 && elem.text[0] == '\n') {
237
+ into.append("<br>");
238
+ return true;
239
+ }
240
+ var domElem = $('<span></span>');
241
+ domElem.text(elem.text);
242
+ domElem.html(domElem.text().replace(/\n/g, "<br>"));
243
+ domElem.css('color', subColor(elem.foreground, elem));
244
+ if (elem.bold)
245
+ domElem.css('font-weight', 'bold');
246
+ if (elem.italic)
247
+ domElem.css('font-style', 'italic');
248
+ if (elem.underline)
249
+ domElem.css('text-decoration', 'underline');
250
+ if (elem.background)
251
+ domElem.css('background-color', subColor(elem.background, elem));
252
+ into.append(domElem);
69
253
  });
70
- return 'color:'+prevStyle['color']+';font-weight:'+prevStyle['bold']+
71
- ';text-decoration:'+prevStyle['underline'];
72
- }
73
- function parseBashString(str)
74
- {
75
- str = str.replace(/\u001B\[([0-9;]+)m/g, function(fm, sm) {
76
- return '</span><span style="'+bashColorToHtml(sm)+'">';
77
- }).replace(/\n/g, "<br>");
78
- return '<span>'+str+'</span>';
79
254
  }
80
255
  $("#rack-webconsole form input").keyup(function(event) {
81
256
  function escapeHTML(string) {
@@ -97,10 +272,12 @@
97
272
  data: ({query: webconsole.query.val(), token: "$TOKEN"}),
98
273
  success: function (data) {
99
274
  var query_class = data.previous_multi_line ? 'query_multiline' : 'query';
100
- var result = "<div class='" + query_class + "'>" +
101
- parseBashString(escapeHTML(data.prompt)) + "</div>";
275
+ var result = $("<div class='" + query_class + "'></div>");
276
+ parseBashString(escapeHTML(data.prompt), result);
102
277
  if (!data.multi_line) {
103
- result += "<div class='result'>" + parseBashString(escapeHTML(data.result)) + "</div>";
278
+ var mresult = $("<div class='result'></div>");
279
+ parseBashString(escapeHTML(data.result), mresult);
280
+ result.append(mresult);
104
281
  }
105
282
  $("#rack-webconsole .results").append(result);
106
283
  $("#rack-webconsole .results_wrapper").scrollTop(
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-webconsole-pry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -203,7 +203,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
203
203
  version: '0'
204
204
  segments:
205
205
  - 0
206
- hash: -3970192323891586303
206
+ hash: 1992267155081239539
207
207
  required_rubygems_version: !ruby/object:Gem::Requirement
208
208
  none: false
209
209
  requirements:
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
212
  version: '0'
213
213
  segments:
214
214
  - 0
215
- hash: -3970192323891586303
215
+ hash: 1992267155081239539
216
216
  requirements: []
217
217
  rubyforge_project: rack-webconsole-pry
218
218
  rubygems_version: 1.8.24