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