class Opal::CliRunners::Safari
def prepare_files_in(dir)
def prepare_files_in(dir) # The safaridriver is very limited in capabilities, basically it can trigger visiting sites # and interact a bit with the page. So this runner starts its own server, overwrites the # console log, warn, error functions of the browser and triggers a request after execution # to exit. Certain exceptions cannot be caught that way and everything may fail in between, # thats why execution is timed out after EXECUTION_TIMEOUT (10 minutes). # As a side effect, console messages may arrive out of order and timing anything may be inaccurate. builder.build_str <<~RUBY, '(exit)', no_export: true %x{ var req = new XMLHttpRequest(); req.open("GET", '/exit'); req.send(); } RUBY js = builder.to_s map = builder.source_map.to_json ext = builder.output_extension module_type = ' type="module"' if builder.esm? File.binwrite("#{dir}/index.#{ext}", js) File.binwrite("#{dir}/index.map", map) File.binwrite("#{dir}/index.html", <<~HTML) <html><head> <meta charset='utf-8'> <link rel="icon" href="data:;base64,="> </head><body> <script> var orig_log = console.log; var orig_err = console.error; var orig_warn = console.warn; function send_log_request(args) { var req = new XMLHttpRequest(); req.open("POST", '/log'); req.setRequestHeader("Content-Type", "application/json"); req.send(JSON.stringify(args)); } console.log = function() { orig_log.apply(null, arguments); send_log_request(arguments); } console.error = function() { orig_err.apply(null, arguments); send_log_request(arguments); } console.warn = function() { orig_warn.apply(null, arguments); send_log_request(arguments); } </script> <script src='./index.#{ext}'#{module_type}></script> </body></html> HTML # <script src='./index.#{ext}'#{module_type}></script> end