opal-irb 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.gitignore +3 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +14 -0
  5. data/Gemfile.lock +113 -0
  6. data/Guardfile +5 -0
  7. data/LICENSE +21 -0
  8. data/README.md +175 -0
  9. data/Rakefile +65 -0
  10. data/Roadmap.org +17 -0
  11. data/app/assets/stylesheets/opal-irb/jqconsole.css +263 -0
  12. data/compiled/app-embeddable.js +39765 -0
  13. data/compiled/app-jqconsole.js +39767 -0
  14. data/compiled/application.js +27399 -0
  15. data/css/ansi.css +172 -0
  16. data/css/opal_irb_jqconsole.css +79 -0
  17. data/css/show-hint.css +38 -0
  18. data/doc/presentations/opal_irb_overview.html +678 -0
  19. data/doc/presentations/opal_irb_overview.org +448 -0
  20. data/examples/app-embeddable.rb +8 -0
  21. data/examples/app-jqconsole.rb +10 -0
  22. data/examples/application.rb +8 -0
  23. data/index-embeddable.html +29 -0
  24. data/index-homebrew.html +115 -0
  25. data/index-jq.html +80 -0
  26. data/js/anyword-hint.js +44 -0
  27. data/js/jqconsole.js +1583 -0
  28. data/js/nodeutil.js +546 -0
  29. data/js/ruby.js +285 -0
  30. data/js/show-hint.js +383 -0
  31. data/lib/opal-irb/rails_engine.rb +3 -0
  32. data/lib/opal-irb/version.rb +3 -0
  33. data/lib/opal-irb-rails.rb +2 -0
  34. data/lib/opal-irb.rb +44 -0
  35. data/opal/object_extensions.rb +20 -0
  36. data/opal/opal_irb/completion_engine.rb +202 -0
  37. data/opal/opal_irb/completion_formatter.rb +49 -0
  38. data/opal/opal_irb/completion_results.rb +88 -0
  39. data/opal/opal_irb.rb +88 -0
  40. data/opal/opal_irb_homebrew_console.rb +398 -0
  41. data/opal/opal_irb_jqconsole.rb +517 -0
  42. data/opal/opal_irb_jqconsole_css.rb +259 -0
  43. data/opal/opal_irb_log_redirector.rb +32 -0
  44. data/opal/opal_phantomjs.rb +49 -0
  45. data/opal-irb.gemspec +20 -0
  46. data/spec/code_link_handler_spec.rb +30 -0
  47. data/spec/jquery.js +5 -0
  48. data/spec/object_extensions_spec.rb +32 -0
  49. data/spec/opal_irb/completion_engine_spec.rb +204 -0
  50. data/spec/opal_irb/completion_results_spec.rb +32 -0
  51. data/spec/opal_irb_log_director_spec.rb +19 -0
  52. data/spec/opal_irb_spec.rb +19 -0
  53. data/spec/spec_helper.rb +1 -0
  54. metadata +151 -0
data/js/nodeutil.js ADDED
@@ -0,0 +1,546 @@
1
+ // Copyright Joyent, Inc. and other Node contributors.
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a
4
+ // copy of this software and associated documentation files (the
5
+ // "Software"), to deal in the Software without restriction, including
6
+ // without limitation the rights to use, copy, modify, merge, publish,
7
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
8
+ // persons to whom the Software is furnished to do so, subject to the
9
+ // following conditions:
10
+ //
11
+ // The above copyright notice and this permission notice shall be included
12
+ // in all copies or substantial portions of the Software.
13
+ //
14
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ // modified by Larry Ng
23
+ // remodified by Forrest Chang to not use require.js
24
+
25
+ var nodeutil = (function () {
26
+ var exports = {};
27
+
28
+ var formatRegExp = /%[sdj%]/g;
29
+ exports.format = function(f) {
30
+ if (typeof f !== 'string') {
31
+ var objects = [];
32
+ for (var i = 0; i < arguments.length; i++) {
33
+ objects.push(inspect(arguments[i]));
34
+ }
35
+ return objects.join(' ');
36
+ }
37
+
38
+ var i = 1;
39
+ var args = arguments;
40
+ var len = args.length;
41
+ var str = String(f).replace(formatRegExp, function(x) {
42
+ if (x === '%%') return '%';
43
+ if (i >= len) return x;
44
+ switch (x) {
45
+ case '%s': return String(args[i++]);
46
+ case '%d': return Number(args[i++]);
47
+ case '%j': return JSON.stringify(args[i++]);
48
+ default:
49
+ return x;
50
+ }
51
+ });
52
+ for (var x = args[i]; i < len; x = args[++i]) {
53
+ if (x === null || typeof x !== 'object') {
54
+ str += ' ' + x;
55
+ } else {
56
+ str += ' ' + inspect(x);
57
+ }
58
+ }
59
+ return str;
60
+ };
61
+
62
+
63
+ exports.print = function() {
64
+ for (var i = 0, len = arguments.length; i < len; ++i) {
65
+ process.stdout.write(String(arguments[i]));
66
+ }
67
+ };
68
+
69
+
70
+ exports.puts = function() {
71
+ for (var i = 0, len = arguments.length; i < len; ++i) {
72
+ process.stdout.write(arguments[i] + '\n');
73
+ }
74
+ };
75
+
76
+
77
+ exports.debug = function(x) {
78
+ process.stderr.write('DEBUG: ' + x + '\n');
79
+ };
80
+
81
+
82
+ var error = exports.error = function(x) {
83
+ for (var i = 0, len = arguments.length; i < len; ++i) {
84
+ process.stderr.write(arguments[i] + '\n');
85
+ }
86
+ };
87
+
88
+
89
+ /**
90
+ * Echos the value of a value. Trys to print the value out
91
+ * in the best way possible given the different types.
92
+ *
93
+ * @param {Object} obj The object to print out.
94
+ * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
95
+ * properties of objects.
96
+ * @param {Number} depth Depth in which to descend in object. Default is 2.
97
+ * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
98
+ * output. Default is false (no coloring).
99
+ */
100
+ function inspect(obj, showHidden, depth, colors) {
101
+ var ctx = {
102
+ showHidden: showHidden,
103
+ seen: [],
104
+ stylize: colors ? stylizeWithColor : stylizeNoColor
105
+ };
106
+ return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
107
+ }
108
+ exports.inspect = inspect;
109
+
110
+
111
+ // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
112
+ var colors = {
113
+ 'bold' : [1, 22],
114
+ 'italic' : [3, 23],
115
+ 'underline' : [4, 24],
116
+ 'inverse' : [7, 27],
117
+ 'white' : [37, 39],
118
+ 'grey' : [90, 39],
119
+ 'black' : [30, 39],
120
+ 'blue' : [34, 39],
121
+ 'cyan' : [36, 39],
122
+ 'green' : [32, 39],
123
+ 'magenta' : [35, 39],
124
+ 'red' : [31, 39],
125
+ 'yellow' : [33, 39]
126
+ };
127
+
128
+
129
+ // Don't use 'blue' not visible on cmd.exe
130
+ var styles = {
131
+ 'special': 'cyan',
132
+ 'number': 'yellow',
133
+ 'boolean': 'yellow',
134
+ 'undefined': 'grey',
135
+ 'null': 'bold',
136
+ 'string': 'green',
137
+ 'date': 'magenta',
138
+ // "name": intentionally not styling
139
+ 'regexp': 'red'
140
+ };
141
+
142
+ /*
143
+ function stylizeWithColor(str, styleType) {
144
+ var style = styles[styleType];
145
+
146
+ if (style) {
147
+ return '\033[' + colors[style][0] + 'm' + str +
148
+ '\033[' + colors[style][1] + 'm';
149
+ } else {
150
+ return str;
151
+ }
152
+ }
153
+ */
154
+
155
+
156
+ function stylizeWithColor(str, styleType) {
157
+ if (Object.keys(styles).indexOf(styleType) >= 0) {
158
+ return '<span class="s_' + styleType + '">' + str + '</span>';
159
+ } else {
160
+ return str;
161
+ }
162
+ }
163
+
164
+
165
+ function stylizeNoColor(str, styleType) {
166
+ return str;
167
+ }
168
+
169
+
170
+ function formatValue(ctx, value, recurseTimes) {
171
+ // Provide a hook for user-specified inspect functions.
172
+ // Check that value is an object with an inspect function on it
173
+ if (value && typeof value.inspect === 'function' &&
174
+ // Filter out the util module, it's inspect function is special
175
+ value.inspect !== exports.inspect &&
176
+ // Also filter out any prototype objects using the circular check.
177
+ !(value.constructor && value.constructor.prototype === value)) {
178
+ return String(value.inspect(recurseTimes));
179
+ }
180
+
181
+ // Primitive types cannot have properties
182
+ var primitive = formatPrimitive(ctx, value);
183
+ if (primitive) {
184
+ return primitive;
185
+ }
186
+
187
+ // Look up the keys of the object.
188
+ var visibleKeys = Object.keys(value);
189
+ var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys;
190
+
191
+ // Some type of object without properties can be shortcutted.
192
+ if (keys.length === 0) {
193
+ if (typeof value === 'function') {
194
+ var name = value.name ? ': ' + value.name : '';
195
+ return ctx.stylize('[Function' + name + ']', 'special');
196
+ }
197
+ if (isRegExp(value)) {
198
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
199
+ }
200
+ if (isDate(value)) {
201
+ return ctx.stylize(Date.prototype.toString.call(value), 'date');
202
+ }
203
+ if (isError(value)) {
204
+ return formatError(value);
205
+ }
206
+ }
207
+
208
+ var base = '', array = false, braces = ['{', '}'];
209
+
210
+ // Make Array say that they are Array
211
+ if (isArray(value)) {
212
+ array = true;
213
+ braces = ['[', ']'];
214
+ }
215
+
216
+ // Make functions say that they are functions
217
+ if (typeof value === 'function') {
218
+ var n = value.name ? ': ' + value.name : '';
219
+ base = ' [Function' + n + ']';
220
+ }
221
+
222
+ // Make RegExps say that they are RegExps
223
+ if (isRegExp(value)) {
224
+ base = ' ' + RegExp.prototype.toString.call(value);
225
+ }
226
+
227
+ // Make dates with properties first say the date
228
+ if (isDate(value)) {
229
+ base = ' ' + Date.prototype.toUTCString.call(value);
230
+ }
231
+
232
+ // Make error with message first say the error
233
+ if (isError(value)) {
234
+ base = ' ' + formatError(value);
235
+ }
236
+
237
+ if (keys.length === 0 && (!array || value.length == 0)) {
238
+ return braces[0] + base + braces[1];
239
+ }
240
+
241
+ if (recurseTimes < 0) {
242
+ if (isRegExp(value)) {
243
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
244
+ } else {
245
+ return ctx.stylize('[Object]', 'special');
246
+ }
247
+ }
248
+
249
+ ctx.seen.push(value);
250
+
251
+ var output;
252
+ if (array) {
253
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
254
+ } else {
255
+ output = keys.map(function(key) {
256
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
257
+ });
258
+ }
259
+
260
+ ctx.seen.pop();
261
+
262
+ return reduceToSingleString(output, base, braces);
263
+ }
264
+
265
+ function escapeHTML (s) {
266
+ return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
267
+ }
268
+
269
+ function formatPrimitive(ctx, value) {
270
+ switch (typeof value) {
271
+ case 'undefined':
272
+ return ctx.stylize('undefined', 'undefined');
273
+
274
+ case 'string':
275
+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
276
+ .replace(/'/g, "\\'")
277
+ .replace(/\\"/g, '"') + '\'';
278
+ return ctx.stylize(escapeHTML(simple), 'string');
279
+
280
+ case 'number':
281
+ return ctx.stylize('' + value, 'number');
282
+
283
+ case 'boolean':
284
+ return ctx.stylize('' + value, 'boolean');
285
+ }
286
+ // For some reason typeof null is "object", so special case here.
287
+ if (value === null) {
288
+ return ctx.stylize('null', 'null');
289
+ }
290
+ }
291
+
292
+
293
+ function formatError(value) {
294
+ return '[' + Error.prototype.toString.call(value) + ']';
295
+ }
296
+
297
+
298
+ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
299
+ var output = [];
300
+ for (var i = 0, l = value.length; i < l; ++i) {
301
+ if (Object.prototype.hasOwnProperty.call(value, String(i))) {
302
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
303
+ String(i), true));
304
+ } else {
305
+ output.push('');
306
+ }
307
+ }
308
+ keys.forEach(function(key) {
309
+ if (!key.match(/^\d+$/)) {
310
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
311
+ key, true));
312
+ }
313
+ });
314
+ return output;
315
+ }
316
+
317
+
318
+ function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
319
+ var name, str, desc;
320
+ desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
321
+ if (desc.get) {
322
+ if (desc.set) {
323
+ str = ctx.stylize('[Getter/Setter]', 'special');
324
+ } else {
325
+ str = ctx.stylize('[Getter]', 'special');
326
+ }
327
+ } else {
328
+ if (desc.set) {
329
+ str = ctx.stylize('[Setter]', 'special');
330
+ }
331
+ }
332
+ if (visibleKeys.indexOf(key) < 0) {
333
+ name = '[' + key + ']';
334
+ }
335
+ if (!str) {
336
+ if (ctx.seen.indexOf(desc.value) < 0) {
337
+ if (recurseTimes === null) {
338
+ str = formatValue(ctx, desc.value, null);
339
+ } else {
340
+ str = formatValue(ctx, desc.value, recurseTimes - 1);
341
+ }
342
+ if (str.indexOf('\n') > -1) {
343
+ if (array) {
344
+ str = str.split('\n').map(function(line) {
345
+ return ' ' + line;
346
+ }).join('\n').substr(2);
347
+ } else {
348
+ str = '\n' + str.split('\n').map(function(line) {
349
+ return ' ' + line;
350
+ }).join('\n');
351
+ }
352
+ }
353
+ } else {
354
+ str = ctx.stylize('[Circular]', 'special');
355
+ }
356
+ }
357
+ if (typeof name === 'undefined') {
358
+ if (array && key.match(/^\d+$/)) {
359
+ return str;
360
+ }
361
+ name = JSON.stringify('' + key);
362
+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
363
+ name = name.substr(1, name.length - 2);
364
+ name = ctx.stylize(name, 'name');
365
+ } else {
366
+ name = name.replace(/'/g, "\\'")
367
+ .replace(/\\"/g, '"')
368
+ .replace(/(^"|"$)/g, "'");
369
+ name = ctx.stylize(name, 'string');
370
+ }
371
+ }
372
+
373
+ return name + ': ' + str;
374
+ }
375
+
376
+
377
+ var spanpattern = /^<span .+?>(.*)<\/span>$/;
378
+ function reduceToSingleString(output, base, braces) {
379
+ var numLinesEst = 0;
380
+ var length = output.reduce(function(prev, cur) {
381
+ var m = cur.match(spanpattern);
382
+ var curlength = m ? m[1].length : cur.length;
383
+ numLinesEst++;
384
+ if (cur.indexOf('\n') >= 0) numLinesEst++;
385
+ return prev + curlength + 1;
386
+ }, 0);
387
+
388
+ if (length > 60) {
389
+ return braces[0] +
390
+ (base === '' ? '' : base + '\n ') +
391
+ ' ' +
392
+ output.join(',\n ') +
393
+ ' ' +
394
+ braces[1];
395
+ }
396
+
397
+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
398
+ }
399
+
400
+
401
+ // NOTE: These type checking functions intentionally don't use `instanceof`
402
+ // because it is fragile and can be easily faked with `Object.create()`.
403
+ function isArray(ar) {
404
+ return Array.isArray(ar) ||
405
+ (typeof ar === 'object' && objectToString(ar) === '[object Array]');
406
+ }
407
+ exports.isArray = isArray;
408
+
409
+
410
+ function isRegExp(re) {
411
+ return typeof re === 'object' && objectToString(re) === '[object RegExp]';
412
+ }
413
+ exports.isRegExp = isRegExp;
414
+
415
+
416
+ function isDate(d) {
417
+ return typeof d === 'object' && objectToString(d) === '[object Date]';
418
+ }
419
+ exports.isDate = isDate;
420
+
421
+
422
+ function isError(e) {
423
+ return typeof e === 'object' && objectToString(e) === '[object Error]';
424
+ }
425
+ exports.isError = isError;
426
+
427
+
428
+ function objectToString(o) {
429
+ return Object.prototype.toString.call(o);
430
+ }
431
+
432
+
433
+ exports.p = function() {
434
+ for (var i = 0, len = arguments.length; i < len; ++i) {
435
+ error(exports.inspect(arguments[i]));
436
+ }
437
+ };
438
+ // module.deprecate('p', 'Use `util.puts(util.inspect())` instead.');
439
+
440
+
441
+ function pad(n) {
442
+ return n < 10 ? '0' + n.toString(10) : n.toString(10);
443
+ }
444
+
445
+
446
+ var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
447
+ 'Oct', 'Nov', 'Dec'];
448
+
449
+ // 26 Feb 16:19:34
450
+ function timestamp() {
451
+ var d = new Date();
452
+ var time = [pad(d.getHours()),
453
+ pad(d.getMinutes()),
454
+ pad(d.getSeconds())].join(':');
455
+ return [d.getDate(), months[d.getMonth()], time].join(' ');
456
+ }
457
+
458
+
459
+ exports.log = function(msg) {
460
+ exports.puts(timestamp() + ' - ' + msg.toString());
461
+ };
462
+
463
+
464
+ exports.exec = function() {
465
+ return require('child_process').exec.apply(this, arguments);
466
+ };
467
+ // module.deprecate('exec', 'It is now called `child_process.exec`.');
468
+
469
+
470
+ exports.pump = function(readStream, writeStream, callback) {
471
+ var callbackCalled = false;
472
+
473
+ function call(a, b, c) {
474
+ if (callback && !callbackCalled) {
475
+ callback(a, b, c);
476
+ callbackCalled = true;
477
+ }
478
+ }
479
+
480
+ readStream.addListener('data', function(chunk) {
481
+ if (writeStream.write(chunk) === false) readStream.pause();
482
+ });
483
+
484
+ writeStream.addListener('drain', function() {
485
+ readStream.resume();
486
+ });
487
+
488
+ readStream.addListener('end', function() {
489
+ writeStream.end();
490
+ });
491
+
492
+ readStream.addListener('close', function() {
493
+ call();
494
+ });
495
+
496
+ readStream.addListener('error', function(err) {
497
+ writeStream.end();
498
+ call(err);
499
+ });
500
+
501
+ writeStream.addListener('error', function(err) {
502
+ readStream.destroy();
503
+ call(err);
504
+ });
505
+ };
506
+
507
+
508
+ /**
509
+ * Inherit the prototype methods from one constructor into another.
510
+ *
511
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
512
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
513
+ * during bootstrapping this function needs to be rewritten using some native
514
+ * functions as prototype setup using normal JavaScript does not work as
515
+ * expected during bootstrapping (see mirror.js in r114903).
516
+ *
517
+ * @param {function} ctor Constructor function which needs to inherit the
518
+ * prototype.
519
+ * @param {function} superCtor Constructor function to inherit prototype from.
520
+ */
521
+ exports.inherits = function(ctor, superCtor) {
522
+ ctor.super_ = superCtor;
523
+ ctor.prototype = Object.create(superCtor.prototype, {
524
+ constructor: {
525
+ value: ctor,
526
+ enumerable: false,
527
+ writable: true,
528
+ configurable: true
529
+ }
530
+ });
531
+ };
532
+
533
+ exports._extend = function(origin, add) {
534
+ // Don't do anything if add isn't an object
535
+ if (!add || typeof add !== 'object') return origin;
536
+
537
+ var keys = Object.keys(add);
538
+ var i = keys.length;
539
+ while (i--) {
540
+ origin[keys[i]] = add[keys[i]];
541
+ }
542
+ return origin;
543
+ };
544
+
545
+ return exports
546
+ })()