if RUBY_ENGINE=='opal' module Kernel def console(title: nil, context: nil) Hyperloop::Console.console(title: title, context: context) end end module Hyperloop module Console def self.console_id @console_id ||= ( `sessionStorage.getItem('Hyperloop::Console::MainWindowId')` || SecureRandom.uuid.tap { |id| `sessionStorage.setItem('Hyperloop::Console::MainWindowId', #{id})` } ) end def self.messenger(target_id, kind, m) Response.run(target_id: target_id, kind: kind, message: m.gsub(/\n$/, '')) end def self.console(title: nil, context: nil) title ||= context || 'Hyperloop Application Console' title = `encodeURIComponent(#{title})` context = `encodeURIComponent(#{context})` location = "/hyperloop/hyperloop-debug-console/#{console_id}?context=#{context}&title=#{title}" window_params = 'width=640,height=460,scrollbars=no,location=0' `window.open(#{location}, #{"window#{title}"}, #{window_params}).focus()` @__console_dispatcher__ ||= Evaluate.on_dispatch do |params| if params.target_id == console_id cwarn = `console.warn` clog = `console.log` cerror = `console.error` cinfo = `console.info` `console.warn = function(m) { #{messenger(params.sender_id, :warn, `m`)} }` `console.log = function(m) { #{messenger(params.sender_id, :log, `m`)} }` `console.error = function(m) { #{messenger(params.sender_id, :error, `m`)} }` `console.info = function(m) { #{messenger(params.sender_id, :info, `m`)} }` begin message = `eval(#{params.string})`.inspect Response.run(target_id: params.sender_id, kind: :result, message: message || '') rescue Exception => e Response.run(target_id: params.sender_id, kind: :exception, message: e.to_s) ensure `console.warn = cwarn` `console.log = clog` `console.error = cerror` `console.info = cinfo` nil end end end self end `window.hyperconsole = function() { Opal.Opal.$console() }` Hyperloop::Application::Boot.on_dispatch do @console ||= console if `window.HyperloopConsoleAutoStart` end end end else module Hyperloop define_setting :console_auto_start, true module Console class Config include React::IsomorphicHelpers prerender_footer do |controller| "<script type='text/javascript'>\n"\ "window.HyperloopConsoleAutoStart = #{!!Hyperloop.console_auto_start};\n"\ "</script>\n" end end end ::Hyperloop::Engine.routes.append do Hyperloop.initialize_policies HyperloopController.class_eval do def opal_debug_console console_params = { application_window_id: params[:application_window_id], context: params[:context], title: params[:title] } render inline: "<!DOCTYPE html>\n"\ "<html>\n"\ " <head>\n"\ " <title>Hyperloop Console Loading...</title>\n"\ " <%= csrf_meta_tags %>\n"\ " <%= stylesheet_link_tag 'hyper-console-client' %>\n"\ " <%= javascript_include_tag 'hyper-console-client.min.js' %>\n"\ " <%= javascript_include_tag 'action_cable' %>\n"\ " </head>\n"\ " <body>\n"\ " <%= react_component '::DebugConsole', #{console_params}, { prerender: false } %>\n"\ " </body>\n"\ "</html>\n" end end match 'hyperloop-debug-console/:application_window_id', to: 'hyperloop#opal_debug_console', via: :get end end end