Skip to content

Commit 1f18c65

Browse files
authored
Merge pull request #101 from hmdne/hmdne/various-improvements
Various improvements of the codebase
2 parents e5dd9c0 + 3014b04 commit 1f18c65

File tree

4 files changed

+101
-41
lines changed

4 files changed

+101
-41
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
source 'https://rubygems.org'
22

3-
gem "opal", "~> 1.2"
3+
gem "opal", "~> 1.3a"
44
gem "opal-sprockets"
55
gem "opal-jquery", ">= 0.4.6"
66
gem "middleman"

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ GEM
9292
middleman-core (>= 3.2)
9393
rouge (~> 3.2)
9494
minitest (5.14.4)
95-
opal (1.2.0)
95+
opal (1.3.0.alpha1)
9696
ast (>= 2.3.0)
9797
parser (~> 3.0)
9898
opal-jquery (0.4.6)
@@ -157,7 +157,7 @@ DEPENDENCIES
157157
middleman-livereload
158158
middleman-sprockets
159159
middleman-syntax
160-
opal (~> 1.2)
160+
opal (~> 1.3a)
161161
opal-jquery (>= 0.4.6)
162162
opal-sprockets
163163
redcarpet

source/javascripts/try_ruby.js.rb

Lines changed: 90 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'opal'
2+
require 'opal/full'
23
require 'opal-parser'
34
require 'opal-jquery'
45

@@ -60,6 +61,10 @@ def mark_ok(line_from, line_to)
6061
def mark_error(line_from, line_to)
6162
`#@native.markText({line: line_from, ch: 0}, {line: line_to, ch: 99}, {className: "tryruby-output-red"})`
6263
end
64+
65+
def on(event, &block)
66+
`#@native.on(#{event}, #{block})`
67+
end
6368
end
6469

6570
# The TryRuby application
@@ -83,17 +88,34 @@ def initialize
8388

8489
# Create editors
8590
@output = Editor.new :output, lineNumbers: false, mode: 'text', readOnly: true, styleSelectedText: true
86-
@editor = Editor.new :editor, lineNumbers: false, mode: 'ruby', tabMode: 'shift', theme: 'tomorrow-night-eighties'
91+
@editor = Editor.new :editor, lineNumbers: false, mode: 'ruby', tabMode: 'shift', tabSize: 2, theme: 'tomorrow-night-eighties'
8792

8893
# Bind run button
8994
Element.find('#btn_run').on(:click) { do_run }
9095

91-
# Is this the playground ? If so -> exit
96+
# Is this the playground ? If so, run code specific
97+
# to the playground and exit before the tutorial buttons
98+
# are initialized.
9299
if Element.find('#tryruby-title').html.match(/playground/i)
93-
@editor.value = INITIAL_TRY_CODE.strip
100+
initialize_playground
94101
return
95102
end
96103

104+
initialize_tutorial
105+
end
106+
107+
def initialize_playground
108+
@playground = true
109+
110+
code = get_code_from_url
111+
@editor.value = code || INITIAL_TRY_CODE.strip
112+
113+
Element.find('#btn_copy_url').on(:click) { do_copy_url }
114+
Window.on('hashchange') { on_hash_change }
115+
@editor.on('change') { on_editor_change }
116+
end
117+
118+
def initialize_tutorial
97119
# Bind rest of buttons
98120
Element.find('#btn_copy').on(:click) { do_copy }
99121
Element.find('#btn_next').on(:click) { do_next }
@@ -247,8 +269,8 @@ def do_run
247269

248270
# Compile
249271
begin
250-
code = Opal.compile(source, :source_map_enabled => false)
251-
rescue => err
272+
code = Opal.compile(source)
273+
rescue Exception => err
252274
log_error err
253275
end
254276

@@ -291,6 +313,34 @@ def do_change_lang
291313
get_content_from_server(language)
292314
end
293315

316+
# Playground methods
317+
def get_code_from_url
318+
hash = $$.decodeURIComponent($$[:location][:hash].gsub('+', ' '))
319+
320+
hash['#code='.size..-1] if hash.start_with?('#code=')
321+
end
322+
323+
def do_copy_url
324+
$$.navigator.clipboard.writeText(gen_url)
325+
end
326+
327+
def gen_url
328+
prefix = $$[:document][:location].toString.split("#").first
329+
suffix = "#code=" + $$.encodeURIComponent(@editor.value)
330+
suffix = suffix.gsub("%20", "+")
331+
332+
prefix + suffix
333+
end
334+
335+
def on_hash_change
336+
@editor.value = get_code_from_url
337+
end
338+
339+
def on_editor_change
340+
$$[:window][:history].replaceState(nil, '', gen_url)
341+
end
342+
# End of playground methods
343+
294344
def get_code_fragment(str)
295345
# Let jQuery find the first code fragment in tryruby-content
296346
code = Element.find('#tryruby-content code').html.strip
@@ -322,37 +372,38 @@ def update_screen(item)
322372
# Code has already been compiled into js
323373
def eval_code(js_code)
324374
retval = nil
375+
error = nil
325376

326377
begin
327378
retval = `eval(js_code)`
328379
retval = retval ? retval.to_s : ''
329380
print_to_output(retval) if @output_buffer.length == 0 && !retval.empty?
330381
rescue => err
331-
retval = "#{err}"
332-
print_to_output(retval)
382+
error = err
383+
log_error(err)
333384
end
334385

335386
# Do not check the answer if there is no regexp matcher
336-
return if !@current_item || !@current_item.answer
337-
338-
# Get last line of output
339-
value_to_check = @output_buffer.length > 0 && !@output_buffer.last.empty? ? @output_buffer.last.chomp : ''
340-
341-
# Check if output matches the defined answer regexp
342-
# and print status message
343-
print_to_output("\n")
344-
from = count_lines
345-
346-
if !value_to_check.empty? && value_to_check.chomp.match(@current_item.answer)
347-
@current_item.ok.each do |line|
348-
print_to_output(line)
349-
end
350-
@output.mark_ok(from, count_lines)
351-
else
352-
@current_item.error.each do |line|
353-
print_to_output(line)
387+
if @current_item && @current_item.answer
388+
# Get last line of output
389+
value_to_check = @output_buffer.length > 0 && !@output_buffer.last.empty? ? @output_buffer.last.chomp : ''
390+
391+
# Check if output matches the defined answer regexp
392+
# and print status message
393+
print_to_output("\n")
394+
from = count_lines
395+
396+
if !value_to_check.empty? && value_to_check.chomp.match(@current_item.answer)
397+
@current_item.ok.each do |line|
398+
print_to_output(line)
399+
end
400+
@output.mark_ok(from, count_lines)
401+
else
402+
@current_item.error.each do |line|
403+
print_to_output(line)
404+
end
405+
@output.mark_error(from, count_lines)
354406
end
355-
@output.mark_error(from, count_lines)
356407
end
357408
end
358409

@@ -368,7 +419,16 @@ def count_lines
368419
end
369420

370421
def log_error(err)
371-
print_to_output "#{err}\n\n#{`err.stack`}"
422+
# Beautify the backtrace a little bit
423+
backtrace = err.backtrace
424+
backtrace = backtrace.select { |i| i.include? '<anonymous>' }
425+
backtrace = backtrace.map { |i| i.gsub(/.*(<anonymous>)/, '\1') }
426+
backtrace = ["(file)"] if backtrace.empty?
427+
err.set_backtrace(backtrace)
428+
429+
from = count_lines
430+
print_to_output err.full_message
431+
@output.mark_error(from, count_lines)
372432
end
373433

374434
def print_to_output(str, term = "\n")
@@ -378,15 +438,9 @@ def print_to_output(str, term = "\n")
378438
end
379439

380440
def start_tryruby
381-
# Bind puts and print methods. Make sure they return a string, not an array
382-
def $stdout.puts(*strs)
383-
strs.each { |str| TryRuby.instance.print_to_output str}
384-
strs.last
385-
end
386-
387-
def $stdout.print(*strs)
388-
strs.each { |str| TryRuby.instance.print_to_output(str, "")}
389-
strs.last
441+
# Bind puts and print methods.
442+
$stdout.write_proc = $stderr.write_proc = ->(str) do
443+
TryRuby.instance.print_to_output str, ""
390444
end
391445

392446
# Start TryRuby

source/playground.html.markdown

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,20 @@ description: Play around with Ruby programs
3030
<div id="editor" class="well" style="padding:0"></div>
3131

3232
<div class="row">
33-
<div class="col-md-12">
33+
<div class="col-md-8">
3434
<button type="button" id="btn_run" class="btn btn-primary btn-block">Run <span class="glyphicon glyphicon-play" aria-hidden="true"></span></button>
3535
</div>
36+
<div class="col-md-4">
37+
<button type="button" id="btn_copy_url" class="btn btn-default btn-block"><span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span> Copy URL</button>
38+
</div>
3639
</div>
3740
</div>
3841

3942
</div>
4043
</div>
4144
</div>
4245

43-
<script>Opal.load('try_ruby');</script>
46+
<script>
47+
Opal.loaded(OpalLoaded || []);
48+
Opal.require('try_ruby');
49+
</script>

0 commit comments

Comments
 (0)