maglev-webtools 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/LICENSE.txt +25 -0
  2. data/README.rdoc +121 -0
  3. data/bin/webtools +15 -0
  4. data/lib/web_tools/#debugger.rb# +212 -0
  5. data/lib/web_tools/browser.rb +45 -0
  6. data/lib/web_tools/debugger.rb +219 -0
  7. data/lib/web_tools/info.rb +29 -0
  8. data/lib/web_tools/middleware/debugger.rb +118 -0
  9. data/lib/web_tools/support/app_model.rb +117 -0
  10. data/lib/web_tools/support/code_browser.rb +109 -0
  11. data/lib/web_tools/support/ruby.rb +132 -0
  12. data/lib/web_tools/support/service_helper.rb +22 -0
  13. data/lib/web_tools/support/smalltalk_extensions.rb +65 -0
  14. data/lib/web_tools/support/smalltalk_tools.rb +16 -0
  15. data/lib/web_tools/ui.rb +67 -0
  16. data/lib/web_tools.rb +10 -0
  17. data/public/images/favicon.ico +0 -0
  18. data/public/javascript/CodeMirror/LICENSE +23 -0
  19. data/public/javascript/CodeMirror/css/Smalltalk.css +34 -0
  20. data/public/javascript/CodeMirror/js/codemirror.js +582 -0
  21. data/public/javascript/CodeMirror/js/editor.js +1671 -0
  22. data/public/javascript/CodeMirror/js/highlight.js +68 -0
  23. data/public/javascript/CodeMirror/js/parseSmalltalk.js +126 -0
  24. data/public/javascript/CodeMirror/js/parsedummy.js +32 -0
  25. data/public/javascript/CodeMirror/js/select.js +699 -0
  26. data/public/javascript/CodeMirror/js/stringstream.js +159 -0
  27. data/public/javascript/CodeMirror/js/tokenize.js +57 -0
  28. data/public/javascript/CodeMirror/js/undo.js +413 -0
  29. data/public/javascript/CodeMirror/js/util.js +133 -0
  30. data/public/javascript/CodeMirror/testSmalltalkParser.html +116 -0
  31. data/public/javascript/ace/ace-uncompressed.js +17299 -0
  32. data/public/javascript/ace/ace.js +1 -0
  33. data/public/javascript/ace/keybinding-emacs.js +1 -0
  34. data/public/javascript/ace/keybinding-vim.js +1 -0
  35. data/public/javascript/ace/mode-c_cpp.js +1 -0
  36. data/public/javascript/ace/mode-clojure.js +1 -0
  37. data/public/javascript/ace/mode-coffee.js +1 -0
  38. data/public/javascript/ace/mode-csharp.js +1 -0
  39. data/public/javascript/ace/mode-css.js +1 -0
  40. data/public/javascript/ace/mode-groovy.js +1 -0
  41. data/public/javascript/ace/mode-html.js +1 -0
  42. data/public/javascript/ace/mode-java.js +1 -0
  43. data/public/javascript/ace/mode-javascript.js +1 -0
  44. data/public/javascript/ace/mode-json.js +1 -0
  45. data/public/javascript/ace/mode-lua.js +1 -0
  46. data/public/javascript/ace/mode-markdown.js +1 -0
  47. data/public/javascript/ace/mode-ocaml.js +1 -0
  48. data/public/javascript/ace/mode-perl.js +1 -0
  49. data/public/javascript/ace/mode-php.js +1 -0
  50. data/public/javascript/ace/mode-python.js +1 -0
  51. data/public/javascript/ace/mode-ruby.js +1 -0
  52. data/public/javascript/ace/mode-scad.js +1 -0
  53. data/public/javascript/ace/mode-scala.js +1 -0
  54. data/public/javascript/ace/mode-scss.js +1 -0
  55. data/public/javascript/ace/mode-svg.js +1 -0
  56. data/public/javascript/ace/mode-textile.js +1 -0
  57. data/public/javascript/ace/mode-xml.js +1 -0
  58. data/public/javascript/ace/theme-clouds.js +1 -0
  59. data/public/javascript/ace/theme-clouds_midnight.js +1 -0
  60. data/public/javascript/ace/theme-cobalt.js +1 -0
  61. data/public/javascript/ace/theme-crimson_editor.js +1 -0
  62. data/public/javascript/ace/theme-dawn.js +1 -0
  63. data/public/javascript/ace/theme-eclipse.js +1 -0
  64. data/public/javascript/ace/theme-idle_fingers.js +1 -0
  65. data/public/javascript/ace/theme-kr_theme.js +1 -0
  66. data/public/javascript/ace/theme-merbivore.js +1 -0
  67. data/public/javascript/ace/theme-merbivore_soft.js +1 -0
  68. data/public/javascript/ace/theme-mono_industrial.js +1 -0
  69. data/public/javascript/ace/theme-monokai.js +1 -0
  70. data/public/javascript/ace/theme-pastel_on_dark.js +1 -0
  71. data/public/javascript/ace/theme-solarized_dark.js +1 -0
  72. data/public/javascript/ace/theme-solarized_light.js +1 -0
  73. data/public/javascript/ace/theme-textmate.js +1 -0
  74. data/public/javascript/ace/theme-twilight.js +1 -0
  75. data/public/javascript/ace/theme-vibrant_ink.js +1 -0
  76. data/public/javascript/ace/worker-coffee.js +1 -0
  77. data/public/javascript/ace/worker-css.js +1 -0
  78. data/public/javascript/ace/worker-javascript.js +1 -0
  79. data/public/javascript/webtools/#debugger.coffee# +253 -0
  80. data/public/javascript/webtools/browser.js +260 -0
  81. data/public/javascript/webtools/debugger.coffee +286 -0
  82. data/public/javascript/webtools/debugger.js +366 -0
  83. data/public/javascript/webtools/sessions.coffee +17 -0
  84. data/public/javascript/webtools/sessions.js +27 -0
  85. data/public/javascript/webtools/version.coffee +14 -0
  86. data/public/javascript/webtools/version.js +20 -0
  87. data/public/stylesheets/base/images/ui-anim_basic_16x16.gif +0 -0
  88. data/public/stylesheets/base/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  89. data/public/stylesheets/base/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  90. data/public/stylesheets/base/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  91. data/public/stylesheets/base/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  92. data/public/stylesheets/base/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  93. data/public/stylesheets/base/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  94. data/public/stylesheets/base/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  95. data/public/stylesheets/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  96. data/public/stylesheets/base/images/ui-icons_222222_256x240.png +0 -0
  97. data/public/stylesheets/base/images/ui-icons_2e83ff_256x240.png +0 -0
  98. data/public/stylesheets/base/images/ui-icons_454545_256x240.png +0 -0
  99. data/public/stylesheets/base/images/ui-icons_888888_256x240.png +0 -0
  100. data/public/stylesheets/base/images/ui-icons_cd0a0a_256x240.png +0 -0
  101. data/public/stylesheets/base/jquery.ui.accordion.css +12 -0
  102. data/public/stylesheets/base/jquery.ui.all.css +2 -0
  103. data/public/stylesheets/base/jquery.ui.autocomplete.css +39 -0
  104. data/public/stylesheets/base/jquery.ui.base.css +11 -0
  105. data/public/stylesheets/base/jquery.ui.button.css +35 -0
  106. data/public/stylesheets/base/jquery.ui.core.css +37 -0
  107. data/public/stylesheets/base/jquery.ui.datepicker.css +61 -0
  108. data/public/stylesheets/base/jquery.ui.dialog.css +13 -0
  109. data/public/stylesheets/base/jquery.ui.progressbar.css +4 -0
  110. data/public/stylesheets/base/jquery.ui.resizable.css +13 -0
  111. data/public/stylesheets/base/jquery.ui.selectable.css +3 -0
  112. data/public/stylesheets/base/jquery.ui.slider.css +17 -0
  113. data/public/stylesheets/base/jquery.ui.tabs.css +11 -0
  114. data/public/stylesheets/base/jquery.ui.theme.css +247 -0
  115. data/public/stylesheets/jquery.contextMenu.css +62 -0
  116. data/public/stylesheets/reset.css +18 -0
  117. data/public/stylesheets/webtools.css +53 -0
  118. data/public/test.html +47 -0
  119. data/views/browser.rhtml +63 -0
  120. data/views/debugger.rhtml +59 -0
  121. data/views/index.rhtml +8 -0
  122. data/views/layout.rhtml +24 -0
  123. data/views/sessions.rhtml +12 -0
  124. data/views/version.rhtml +10 -0
  125. metadata +316 -0
@@ -0,0 +1,286 @@
1
+ window.escapeHTML = (str) ->
2
+ str = "" unless str?
3
+ str += str unless typeof str == "string"
4
+ $("<i></i>").text(str).html()
5
+
6
+ class Frame
7
+ constructor: (@server, @pid, @frame_idx, @container) ->
8
+
9
+ update_detail_view: (objectInfo) ->
10
+ @inspector.hide()
11
+ @inspector.find('.objInfoClass').text(objectInfo['class'])
12
+ @inspector.find('.objInfoValue').text(objectInfo['inspect'])
13
+ this.renderTableData @inspector.children('.objInstVars'),
14
+ objectInfo.instance_variables,
15
+ (idx, data) ->
16
+ $("<tr><td>#{idx}</td><td>#{data}</td></tr>")
17
+ @inspector.show()
18
+
19
+ renderTableData: (table, object, formatFn) ->
20
+ ui = table.children('tbody')
21
+ ui.empty()
22
+ $.each object, (key, value) ->
23
+ if key.indexOf("@") == 0
24
+ ui.append(formatFn(key, value))
25
+
26
+ create_detail_view: ->
27
+ @inspector = $('#objectInspector').clone()
28
+ @inspector.removeAttr('id')
29
+ @inspector.removeClass('hidden')
30
+ @container.append(@inspector)
31
+
32
+ create_source_code_holder: () ->
33
+ @container.prepend(window.editorDiv)
34
+ window.editor.save_url = "#{@server}/process/#{@pid}/frames/#{@frame_idx}"
35
+ window.editorDiv.show()
36
+
37
+ create_inspector: (object, index, path) ->
38
+ index = 0 unless index?
39
+ path = "#{@server}/process/#{@pid}/frames/#{@frame_idx}" unless path?
40
+ options = $([])
41
+ if object.instance_variables?
42
+ $.each object.instance_variables, (key, value) ->
43
+ options.push("#{key}")
44
+ else
45
+ $.each object, (key, value) ->
46
+ options.push("#{key}")
47
+ if not @inspector_div?
48
+ @inspector_div = $(document.createElement("div"))
49
+ @inspector_div.addClass("inspectors")
50
+ @container.prepend(@inspector_div)
51
+ if @inspectors[index]?
52
+ inspector = @inspectors[index]
53
+ else
54
+ @inspectors[index] = (inspector = $(document.createElement("select")))
55
+ @inspector_div.append(inspector)
56
+ inspector.attr
57
+ multiple: true
58
+ class: 'inspector'
59
+ inspector.html("")
60
+ $(options).each (idx, o) =>
61
+ inspector.append("<option value=#{idx}>#{escapeHTML(o)}</option>")
62
+ this.create_evaluator(path)
63
+ inspector.bind "change", =>
64
+ value = options[inspector.val()]
65
+ url = "#{path}/objects/#{value}"
66
+ for i in @inspectors.slice(index + 1)
67
+ i.html("")
68
+ $.get url, (object) =>
69
+ this.create_inspector(object.instance_variables, index + 1, url)
70
+ this.update_detail_view(object)
71
+ , 'json'
72
+
73
+ create_evaluator: (path) ->
74
+ unless @evaluator?
75
+ @evaluator = $(document.createElement("input"))
76
+ @evaluator.attr
77
+ type: "text"
78
+ name: "#{@frame_idx}_evaluator"
79
+ id: "#{@frame_idx}_evaluator"
80
+ class: "ui-widget-content ui-corner-all"
81
+ style: 'width: 100%;'
82
+ @container.prepend(@evaluator)
83
+ @evaluator.bind "focus", =>
84
+
85
+ @evaluator.unbind("keypress")
86
+ @evaluator.bind "keypress", (e) =>
87
+ code = e.keyCode if e.keyCode?
88
+ code = e.which unless code
89
+ if code == 13 # RETURN
90
+ $.ajax
91
+ url: path
92
+ data:
93
+ "do-it": @evaluator.val()
94
+ success: (data) =>
95
+ result = data["do-it-result"]
96
+ @evaluator.val("#{@evaluator.val()} => #{result['inspect']}")
97
+ this.update_detail_view(result)
98
+ @evaluator.select()
99
+ dataType: 'json'
100
+ type: 'PUT'
101
+
102
+ render: ->
103
+ @container.html("")
104
+ @inspectors = []
105
+ this.create_source_code_holder()
106
+ $.get "#{@server}/process/#{@pid}/frames/#{@frame_idx}", (frame) =>
107
+ editor.getSession().setValue(frame.debug_info.source)
108
+ this.create_inspector(frame.debug_info.context)
109
+ this.create_detail_view()
110
+ , 'json'
111
+
112
+ class Process
113
+ constructor: (@server, @pid, @tab) ->
114
+ @info_div = $("##{@tab} .info-bar")
115
+ @stack_div = $("##{@tab} .frame-list")
116
+
117
+ render: ->
118
+ this.render_info()
119
+ this.render_stack()
120
+
121
+ render_info: ->
122
+ request = $.get "#{@server}/process/#{@pid}", (data) =>
123
+ @info_div.text("#{data.label} (#{data.timestamp})")
124
+ , 'json'
125
+
126
+ render_stack: ->
127
+ @stack_div.html("")
128
+ request = $.get "#{@server}/process/#{@pid}/frames", (framelist) =>
129
+ $(framelist).each (idx, f) =>
130
+ header = $(document.createElement("h3"))
131
+ link = $(document.createElement("a"))
132
+ link.attr
133
+ href: '#'
134
+ data_idx: idx
135
+ link.text("#{f.class}##{f.method_name}")
136
+ link.append("<small>#{escapeHTML(f.source_location)}</small>")
137
+ header.append(link)
138
+ restartLink = $('<a href="#">Restart frame</a>')
139
+ restartLink.bind "click", (e) =>
140
+ $.ajax
141
+ url: "#{@server}/process/#{@pid}/frames/#{idx}",
142
+ type: 'DELETE'
143
+ success: =>
144
+ this.render()
145
+ e.preventDefault()
146
+ header.append(restartLink)
147
+ div = document.createElement("div")
148
+ $(div).text("Waiting for data...")
149
+ @stack_div.append(header)
150
+ @stack_div.append(div)
151
+ if idx == 0
152
+ @selected_frame = new Frame(@server, @pid, 0, $(div))
153
+ @selected_frame.render()
154
+ @stack_div.accordion( "destroy" )
155
+ @stack_div.accordion
156
+ clearStyle: true
157
+ collapsible: true
158
+ changestart: (event, ui) =>
159
+ frame_idx = ui.newHeader.children("a").attr("data_idx")
160
+ if frame_idx?
161
+ @selected_frame = new Frame(@server, @pid, frame_idx, ui.newContent)
162
+ @selected_frame.render()
163
+ , 'json'
164
+
165
+ class Debugger
166
+ constructor: (@server) ->
167
+ @tab_content_template = $("#tab_content_template")
168
+
169
+ toString: ->
170
+ "Debugger on #{server}"
171
+
172
+ server_alive: () ->
173
+ request = $.ajax
174
+ url: "#{@server}/process"
175
+ async: false
176
+ request.status == 200
177
+
178
+ clone_template: () ->
179
+ @content = @tab_content_template.clone()
180
+ @content.show()
181
+ @content.removeAttr("id")
182
+
183
+ fill_process_selector: () ->
184
+ @process_box = @content.children("select[name='process-select-box']")
185
+ $.getJSON "#{@server}/process", (errors) =>
186
+ $(errors).each (idx, e) =>
187
+ @process_box.append("<option value='#{e.process_id}'>#{e.process_id}: #{escapeHTML(e.label)}</option>")
188
+ @process_box.bind "change", =>
189
+ @process = new Process(@server, @process_box.val(), @tab)
190
+ @process.render()
191
+ refreshButton = @content.children(".reload-button")
192
+ refreshButton.bind "click", (e) =>
193
+ e.preventDefault()
194
+ @process = new Process(@server, @process_box.val(), @tab)
195
+ @process.render()
196
+
197
+ content_for: (ui_panel) ->
198
+ if not @content?
199
+ @tab = $(ui_panel).attr("id")
200
+ return "<p>The URL " + url + " could not be reached</p>" unless this.server_alive()
201
+ this.clone_template()
202
+ this.fill_process_selector()
203
+ ui_panel.append(@content)
204
+ @content
205
+
206
+ DebuggerApp =
207
+ setup: ->
208
+ debuggers = []
209
+ tab_server_input = $("#tab_server")
210
+ tab_counter = 2
211
+
212
+ # actual addTab function: adds new tab using the title input
213
+ # from the form above
214
+ add_tab = ->
215
+ tab_server = tab_server_input.val()
216
+ tabs.tabs("add", "#tabs-#{tab_counter}", tab_server)
217
+ tab_counter++
218
+
219
+ # tabs init with a custom tab template and an "add" callback
220
+ # filling in the content
221
+ tabs = $("#tabs").tabs
222
+ tabTemplate: '<li><a href=\'#{href}\'>#{label}</a>' +
223
+ "<span class='ui-icon ui-icon-close'>Remove Tab</span></li>"
224
+ add: (event, ui) ->
225
+ new_debugger = new Debugger(tab_server_input.val())
226
+ debuggers.push(new_debugger)
227
+ new_debugger.content_for($(ui.panel))
228
+
229
+ # modal dialog init: custom buttons and a "close" callback
230
+ # reseting the form inside
231
+ dialog = $("#dialog").dialog
232
+ autoOpen: false
233
+ modal: true
234
+ buttons:
235
+ Add: ->
236
+ add_tab()
237
+ dialog.dialog("close")
238
+ Cancel: ->
239
+ dialog.dialog("close")
240
+ open: ->
241
+ tab_server_input.focus()
242
+ close: ->
243
+ form[0].reset()
244
+
245
+ # addTab form: calls addTab function on submit and closes the
246
+ # dialog
247
+ form = $("form", this.dialog).submit ->
248
+ add_tab()
249
+ dialog.dialog("close")
250
+ false
251
+
252
+ # addTab button: just opens the dialog
253
+ $("#add_tab").button().click ->
254
+ dialog.dialog("open");
255
+
256
+ # close icon: removing the tab on click
257
+ $("#tabs span.ui-icon-close").live "click", ->
258
+ index = $("li", tabs).index($(this).parent())
259
+ tabs.tabs("remove", index);
260
+
261
+ $(document).ready ->
262
+ DebuggerApp.setup()
263
+ window.RubyMode = require("ace/mode/ruby").Mode
264
+ window.canon = require('pilot/canon')
265
+ window.editorDiv = $("#editor")
266
+ window.editor = ace.edit('editor')
267
+ window.editor.getSession().setUseSoftTabs(true)
268
+ window.editor.getSession().setMode(new RubyMode())
269
+ canon.addCommand
270
+ name: "save",
271
+ bindKey:
272
+ win: "Ctrl-S",
273
+ mac: "Command-S",
274
+ sender: "editor"
275
+ exec: ->
276
+ $.ajax
277
+ url: window.editor.save_url
278
+ type: 'PUT'
279
+ data:
280
+ debug_info:
281
+ source: window.editor.getSession().getValue()
282
+ success: ->
283
+ alert('Save successful. The stack has been reset to the new method.')
284
+ $("#tabs").select(".reload-button").filter(':visible').click()
285
+
286
+
@@ -0,0 +1,366 @@
1
+ var Debugger, DebuggerApp, Frame, Process;
2
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
3
+ window.escapeHTML = function(str) {
4
+ if (str == null) {
5
+ str = "";
6
+ }
7
+ if (typeof str !== "string") {
8
+ str += str;
9
+ }
10
+ return $("<i></i>").text(str).html();
11
+ };
12
+ Frame = (function() {
13
+ function Frame(server, pid, frame_idx, container) {
14
+ this.server = server;
15
+ this.pid = pid;
16
+ this.frame_idx = frame_idx;
17
+ this.container = container;
18
+ }
19
+ Frame.prototype.update_detail_view = function(objectInfo) {
20
+ this.inspector.hide();
21
+ this.inspector.find('.objInfoClass').text(objectInfo['class']);
22
+ this.inspector.find('.objInfoValue').text(objectInfo['inspect']);
23
+ this.renderTableData(this.inspector.children('.objInstVars'), objectInfo.instance_variables, function(idx, data) {
24
+ return $("<tr><td>" + idx + "</td><td>" + data + "</td></tr>");
25
+ });
26
+ return this.inspector.show();
27
+ };
28
+ Frame.prototype.renderTableData = function(table, object, formatFn) {
29
+ var ui;
30
+ ui = table.children('tbody');
31
+ ui.empty();
32
+ return $.each(object, function(key, value) {
33
+ if (key.indexOf("@") === 0) {
34
+ return ui.append(formatFn(key, value));
35
+ }
36
+ });
37
+ };
38
+ Frame.prototype.create_detail_view = function() {
39
+ this.inspector = $('#objectInspector').clone();
40
+ this.inspector.removeAttr('id');
41
+ this.inspector.removeClass('hidden');
42
+ return this.container.append(this.inspector);
43
+ };
44
+ Frame.prototype.create_source_code_holder = function() {
45
+ this.container.prepend(window.editorDiv);
46
+ window.editor.save_url = "" + this.server + "/process/" + this.pid + "/frames/" + this.frame_idx;
47
+ return window.editorDiv.show();
48
+ };
49
+ Frame.prototype.create_inspector = function(object, index, path) {
50
+ var inspector, options;
51
+ if (index == null) {
52
+ index = 0;
53
+ }
54
+ if (path == null) {
55
+ path = "" + this.server + "/process/" + this.pid + "/frames/" + this.frame_idx;
56
+ }
57
+ options = $([]);
58
+ if (object.instance_variables != null) {
59
+ $.each(object.instance_variables, function(key, value) {
60
+ return options.push("" + key);
61
+ });
62
+ } else {
63
+ $.each(object, function(key, value) {
64
+ return options.push("" + key);
65
+ });
66
+ }
67
+ if (!(this.inspector_div != null)) {
68
+ this.inspector_div = $(document.createElement("div"));
69
+ this.inspector_div.addClass("inspectors");
70
+ this.container.prepend(this.inspector_div);
71
+ }
72
+ if (this.inspectors[index] != null) {
73
+ inspector = this.inspectors[index];
74
+ } else {
75
+ this.inspectors[index] = (inspector = $(document.createElement("select")));
76
+ this.inspector_div.append(inspector);
77
+ inspector.attr({
78
+ multiple: true,
79
+ "class": 'inspector'
80
+ });
81
+ }
82
+ inspector.html("");
83
+ $(options).each(__bind(function(idx, o) {
84
+ return inspector.append("<option value=" + idx + ">" + (escapeHTML(o)) + "</option>");
85
+ }, this));
86
+ this.create_evaluator(path);
87
+ return inspector.bind("change", __bind(function() {
88
+ var i, url, value, _i, _len, _ref;
89
+ value = options[inspector.val()];
90
+ url = "" + path + "/objects/" + value;
91
+ _ref = this.inspectors.slice(index + 1);
92
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
93
+ i = _ref[_i];
94
+ i.html("");
95
+ }
96
+ return $.get(url, __bind(function(object) {
97
+ this.create_inspector(object.instance_variables, index + 1, url);
98
+ return this.update_detail_view(object);
99
+ }, this), 'json');
100
+ }, this));
101
+ };
102
+ Frame.prototype.create_evaluator = function(path) {
103
+ if (this.evaluator == null) {
104
+ this.evaluator = $(document.createElement("input"));
105
+ this.evaluator.attr({
106
+ type: "text",
107
+ name: "" + this.frame_idx + "_evaluator",
108
+ id: "" + this.frame_idx + "_evaluator",
109
+ "class": "ui-widget-content ui-corner-all",
110
+ style: 'width: 100%;'
111
+ });
112
+ this.container.prepend(this.evaluator);
113
+ }
114
+ this.evaluator.bind("focus", __bind(function() {}, this));
115
+ this.evaluator.unbind("keypress");
116
+ return this.evaluator.bind("keypress", __bind(function(e) {
117
+ var code;
118
+ if (e.keyCode != null) {
119
+ code = e.keyCode;
120
+ }
121
+ if (!code) {
122
+ code = e.which;
123
+ }
124
+ if (code === 13) {
125
+ return $.ajax({
126
+ url: path,
127
+ data: {
128
+ "do-it": this.evaluator.val()
129
+ },
130
+ success: __bind(function(data) {
131
+ var result;
132
+ result = data["do-it-result"];
133
+ this.evaluator.val("" + (this.evaluator.val()) + " => " + result['inspect']);
134
+ this.update_detail_view(result);
135
+ return this.evaluator.select();
136
+ }, this),
137
+ dataType: 'json',
138
+ type: 'PUT'
139
+ });
140
+ }
141
+ }, this));
142
+ };
143
+ Frame.prototype.render = function() {
144
+ this.container.html("");
145
+ this.inspectors = [];
146
+ this.create_source_code_holder();
147
+ return $.get("" + this.server + "/process/" + this.pid + "/frames/" + this.frame_idx, __bind(function(frame) {
148
+ editor.getSession().setValue(frame.debug_info.source);
149
+ this.create_inspector(frame.debug_info.context);
150
+ return this.create_detail_view();
151
+ }, this), 'json');
152
+ };
153
+ return Frame;
154
+ })();
155
+ Process = (function() {
156
+ function Process(server, pid, tab) {
157
+ this.server = server;
158
+ this.pid = pid;
159
+ this.tab = tab;
160
+ this.info_div = $("#" + this.tab + " .info-bar");
161
+ this.stack_div = $("#" + this.tab + " .frame-list");
162
+ }
163
+ Process.prototype.render = function() {
164
+ this.render_info();
165
+ return this.render_stack();
166
+ };
167
+ Process.prototype.render_info = function() {
168
+ var request;
169
+ return request = $.get("" + this.server + "/process/" + this.pid, __bind(function(data) {
170
+ return this.info_div.text("" + data.label + " (" + data.timestamp + ")");
171
+ }, this), 'json');
172
+ };
173
+ Process.prototype.render_stack = function() {
174
+ var request;
175
+ this.stack_div.html("");
176
+ return request = $.get("" + this.server + "/process/" + this.pid + "/frames", __bind(function(framelist) {
177
+ $(framelist).each(__bind(function(idx, f) {
178
+ var div, header, link, restartLink;
179
+ header = $(document.createElement("h3"));
180
+ link = $(document.createElement("a"));
181
+ link.attr({
182
+ href: '#',
183
+ data_idx: idx
184
+ });
185
+ link.text("" + f["class"] + "#" + f.method_name);
186
+ link.append("<small>" + (escapeHTML(f.source_location)) + "</small>");
187
+ header.append(link);
188
+ restartLink = $('<a href="#">Restart frame</a>');
189
+ restartLink.bind("click", __bind(function(e) {
190
+ $.ajax({
191
+ url: "" + this.server + "/process/" + this.pid + "/frames/" + idx,
192
+ type: 'DELETE',
193
+ success: __bind(function() {
194
+ return this.render();
195
+ }, this)
196
+ });
197
+ return e.preventDefault();
198
+ }, this));
199
+ header.append(restartLink);
200
+ div = document.createElement("div");
201
+ $(div).text("Waiting for data...");
202
+ this.stack_div.append(header);
203
+ this.stack_div.append(div);
204
+ if (idx === 0) {
205
+ this.selected_frame = new Frame(this.server, this.pid, 0, $(div));
206
+ return this.selected_frame.render();
207
+ }
208
+ }, this));
209
+ this.stack_div.accordion("destroy");
210
+ return this.stack_div.accordion({
211
+ clearStyle: true,
212
+ collapsible: true,
213
+ changestart: __bind(function(event, ui) {
214
+ var frame_idx;
215
+ frame_idx = ui.newHeader.children("a").attr("data_idx");
216
+ if (frame_idx != null) {
217
+ this.selected_frame = new Frame(this.server, this.pid, frame_idx, ui.newContent);
218
+ return this.selected_frame.render();
219
+ }
220
+ }, this)
221
+ });
222
+ }, this), 'json');
223
+ };
224
+ return Process;
225
+ })();
226
+ Debugger = (function() {
227
+ function Debugger(server) {
228
+ this.server = server;
229
+ this.tab_content_template = $("#tab_content_template");
230
+ }
231
+ Debugger.prototype.toString = function() {
232
+ return "Debugger on " + server;
233
+ };
234
+ Debugger.prototype.server_alive = function() {
235
+ var request;
236
+ request = $.ajax({
237
+ url: "" + this.server + "/process",
238
+ async: false
239
+ });
240
+ return request.status === 200;
241
+ };
242
+ Debugger.prototype.clone_template = function() {
243
+ this.content = this.tab_content_template.clone();
244
+ this.content.show();
245
+ return this.content.removeAttr("id");
246
+ };
247
+ Debugger.prototype.fill_process_selector = function() {
248
+ var refreshButton;
249
+ this.process_box = this.content.children("select[name='process-select-box']");
250
+ $.getJSON("" + this.server + "/process", __bind(function(errors) {
251
+ return $(errors).each(__bind(function(idx, e) {
252
+ return this.process_box.append("<option value='" + e.process_id + "'>" + e.process_id + ": " + (escapeHTML(e.label)) + "</option>");
253
+ }, this));
254
+ }, this));
255
+ this.process_box.bind("change", __bind(function() {
256
+ this.process = new Process(this.server, this.process_box.val(), this.tab);
257
+ return this.process.render();
258
+ }, this));
259
+ refreshButton = this.content.children(".reload-button");
260
+ return refreshButton.bind("click", __bind(function(e) {
261
+ e.preventDefault();
262
+ this.process = new Process(this.server, this.process_box.val(), this.tab);
263
+ return this.process.render();
264
+ }, this));
265
+ };
266
+ Debugger.prototype.content_for = function(ui_panel) {
267
+ if (!(this.content != null)) {
268
+ this.tab = $(ui_panel).attr("id");
269
+ if (!this.server_alive()) {
270
+ return "<p>The URL " + url + " could not be reached</p>";
271
+ }
272
+ this.clone_template();
273
+ this.fill_process_selector();
274
+ ui_panel.append(this.content);
275
+ }
276
+ return this.content;
277
+ };
278
+ return Debugger;
279
+ })();
280
+ DebuggerApp = {
281
+ setup: function() {
282
+ var add_tab, debuggers, dialog, form, tab_counter, tab_server_input, tabs;
283
+ debuggers = [];
284
+ tab_server_input = $("#tab_server");
285
+ tab_counter = 2;
286
+ add_tab = function() {
287
+ var tab_server;
288
+ tab_server = tab_server_input.val();
289
+ tabs.tabs("add", "#tabs-" + tab_counter, tab_server);
290
+ return tab_counter++;
291
+ };
292
+ tabs = $("#tabs").tabs({
293
+ tabTemplate: '<li><a href=\'#{href}\'>#{label}</a>' + "<span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
294
+ add: function(event, ui) {
295
+ var new_debugger;
296
+ new_debugger = new Debugger(tab_server_input.val());
297
+ debuggers.push(new_debugger);
298
+ return new_debugger.content_for($(ui.panel));
299
+ }
300
+ });
301
+ dialog = $("#dialog").dialog({
302
+ autoOpen: false,
303
+ modal: true,
304
+ buttons: {
305
+ Add: function() {
306
+ add_tab();
307
+ return dialog.dialog("close");
308
+ },
309
+ Cancel: function() {
310
+ return dialog.dialog("close");
311
+ }
312
+ },
313
+ open: function() {
314
+ return tab_server_input.focus();
315
+ },
316
+ close: function() {
317
+ return form[0].reset();
318
+ }
319
+ });
320
+ form = $("form", this.dialog).submit(function() {
321
+ add_tab();
322
+ dialog.dialog("close");
323
+ return false;
324
+ });
325
+ $("#add_tab").button().click(function() {
326
+ return dialog.dialog("open");
327
+ });
328
+ return $("#tabs span.ui-icon-close").live("click", function() {
329
+ var index;
330
+ index = $("li", tabs).index($(this).parent());
331
+ return tabs.tabs("remove", index);
332
+ });
333
+ }
334
+ };
335
+ $(document).ready(function() {
336
+ DebuggerApp.setup();
337
+ window.RubyMode = require("ace/mode/ruby").Mode;
338
+ window.canon = require('pilot/canon');
339
+ window.editorDiv = $("#editor");
340
+ window.editor = ace.edit('editor');
341
+ window.editor.getSession().setUseSoftTabs(true);
342
+ window.editor.getSession().setMode(new RubyMode());
343
+ return canon.addCommand({
344
+ name: "save",
345
+ bindKey: {
346
+ win: "Ctrl-S",
347
+ mac: "Command-S",
348
+ sender: "editor"
349
+ },
350
+ exec: function() {
351
+ return $.ajax({
352
+ url: window.editor.save_url,
353
+ type: 'PUT',
354
+ data: {
355
+ debug_info: {
356
+ source: window.editor.getSession().getValue()
357
+ }
358
+ },
359
+ success: function() {
360
+ alert('Save successful. The stack has been reset to the new method.');
361
+ return $("#tabs").select(".reload-button").filter(':visible').click();
362
+ }
363
+ });
364
+ }
365
+ });
366
+ });
@@ -0,0 +1,17 @@
1
+ $(document).ready ->
2
+ $.getJSON "#{WebTools.location}/sessions", (data) ->
3
+ error = data['_error']
4
+ if error?
5
+ console.log(data)
6
+ alert(error + ' (see console log for stack)')
7
+ else
8
+ thead = $('#sessionHeaders').children("tr")
9
+ $(data.headers).each (idx, element) ->
10
+ thead.append("<th title='#{element[1]}'>#{element[0]}</th>")
11
+ tbody = $('#sessionTable')
12
+ for session in data.report
13
+ row = $('<tr>')
14
+ for field in session
15
+ row.append("<td>#{field}</td>")
16
+ tbody.append(row)
17
+ $('.timestamp').html("Report generated #{data.timestamp}")
@@ -0,0 +1,27 @@
1
+ $(document).ready(function() {
2
+ return $.getJSON("" + WebTools.location + "/sessions", function(data) {
3
+ var error, field, row, session, tbody, thead, _i, _j, _len, _len2, _ref;
4
+ error = data['_error'];
5
+ if (error != null) {
6
+ console.log(data);
7
+ return alert(error + ' (see console log for stack)');
8
+ } else {
9
+ thead = $('#sessionHeaders').children("tr");
10
+ $(data.headers).each(function(idx, element) {
11
+ return thead.append("<th title='" + element[1] + "'>" + element[0] + "</th>");
12
+ });
13
+ tbody = $('#sessionTable');
14
+ _ref = data.report;
15
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
16
+ session = _ref[_i];
17
+ row = $('<tr>');
18
+ for (_j = 0, _len2 = session.length; _j < _len2; _j++) {
19
+ field = session[_j];
20
+ row.append("<td>" + field + "</td>");
21
+ }
22
+ tbody.append(row);
23
+ }
24
+ return $('.timestamp').html("Report generated " + data.timestamp);
25
+ }
26
+ });
27
+ });