require 'envjs' module Envjs::Runtime def self.extended object object.instance_eval do @outer = {} # ||= new_split_global_outer @inner = {} # ||= new_split_global_inner( @outer ) @inner["Johnson"] = global["Johnson"] @inner["Ruby"] = global["Ruby"] evaluate <<'EOJS' print = function() { var l = arguments.length for( var i = 0; i < l; i++ ) { var s; if ( arguments[i] === null ) { s = "null"; } else if ( arguments[i] === undefined ) { s = "undefined" } else { s = arguments[i].toString(); } Ruby.print(s); if( i < l-1 ) { Ruby.print(" "); } } Ruby.print("\n"); }; EOJS @inner["print"] = global["print"] ( class << self; self; end ).send :define_method, :evaluate do |*args| ( script, file, line, global, scope ) = *args g ||= @inner s ||= @inner p "super" super( script, file, line, g, s ) end # self.global = outer return evaluate <<'EOJS' print = function() { var l = arguments.length for( var i = 0; i < l; i++ ) { var s; if ( arguments[i] === null ) { s = "null"; } else if ( arguments[i] === undefined ) { s = "undefined" } else { s = arguments[i].toString(); } Ruby.print(s); if( i < l-1 ) { Ruby.print(" "); } } Ruby.print("\n"); }; EOJS master = global["$master"] = evaluate("new Object") master.symbols = [ "Johnson", "Ruby", "print", "load", "whichInterpreter", "multiwindow" ] # master.symbols = [ "Johnson", "whichInterpreter" ] master.symbols.each { |symbol| master[symbol] = global[symbol] } master.whichInterpreter = "Johnson" if true master.multiwindow = true master.load = lambda { |*files| load *files } master.evaluate = lambda { |script| return evaluate(script, nil, nil, master["inner"], master["inner"]) } master.global = lambda { global } master.new_global = lambda { new_global } master.set_global = lambda { |target, s| self.global = target } master._new_proxy = lambda { |target| new_proxy target } master._set_proxy_target = lambda { |proxy, target| set_proxy_target proxy, target } master.new_split_global_outer = lambda { new_split_global_outer } master.new_split_global_inner = lambda { |outer,_| new_split_global_inner outer } end # create an proto window object and proxy outer = master["outer"] = new_split_global_outer window = inner = master["inner"] = new_split_global_inner( outer ) master.symbols.each do |symbol| window[symbol] = master[symbol] end master.first_script_window = window window["$master"] = master self.global = outer ( class << self; self; end ).send :define_method, :wait do master["finalize"] && master.finalize.call end ( class << self; self; end ).send :define_method, :evaluate do |*args| ( script, file, line, global, scope ) = *args global ||= inner scope ||= inner p "super" super( script, file, line, global, scope ) end end end end