11require 'opal'
2+ require 'opal/full'
23require 'opal-parser'
34require '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
6368end
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")
378438end
379439
380440def 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
0 commit comments