function main(splash)
  splash.images_enabled = false
  splash.response_body_enabled = true

  local url = splash.args.url
  assert(splash:go(url))
  assert(splash:wait(5))

  local detectFunction = [[
    detect = function(){
      var rs = [];

      softwareData.forEach(function(s) {
        var matchers = s.matchers;

        for (var i in matchers) {
          if (eval(matchers[i].check)){
            var version = eval(matchers[i].version);
            if (version) {
              rs.push({'name': s.name, 'version': version});
            }
          }
        }

      });

      return rs;
    }
  ]]
  splash:runjs('softwareData = $js_data;')
  splash:runjs(detectFunction)
  local softwares = splash:evaljs('detect()')

  local scripts = splash:select_all('script')
  local sources = {}
  for _, s in ipairs(scripts) do
    sources[#sources+1] = s.node.innerHTML
  end

  return {
    har = splash:har(),
    softwares=softwares,
    scripts=sources,
  }
end


function main(splash)
  splash.images_enabled = false
  splash.response_body_enabled = true

  local url = splash.args.url
  assert(splash:go(url))
  assert(splash:wait(5))

  local detectFunction = [[
    detect = function(){
      var rs = [];

      softwareData.forEach(function(s) {
        var matchers = s.matchers;

        for (var i in matchers) {
          if (eval(matchers[i].check)){
            var version = eval(matchers[i].version);
            if (version) {
              rs.push({'name': s.name, 'version': version});
            }
          }
        }

      });

      return rs;
    }
  ]]
  splash:runjs('softwareData = $js_data;')
  splash:runjs(detectFunction)

  local softwares = {}
  local scripts = {}
  local errors = {}

  local ok, res = pcall(splash.evaljs, self, 'detect()')
  if ok then
    softwares = res
  else
    errors['evaljs'] = res
  end

  local ok, res = pcall(splash.select_all, self, 'script')
  if ok then
    if res then
      for _, s in ipairs(res) do
        scripts[#scripts+1] = s.node.innerHTML
      end
    end
  else
    errors['select_all'] = res
  end

  return {
    har = splash:har(),
    softwares=softwares,
    scripts=scripts,
    errors=errors,
  }
end


Handle errors when running JavaScript on the sites
Handle errors when running JavaScript on the sites

If the Content Security Policy directive is enabled in the site, then
the JavaScript detection function cannot be evaluated, and Splash will
fail with a Lua script error.

But even if the JavaScript matchers cannot be used, the HAR can still be
processed, so let Splash return the HAR normally in case of errors when
evaluating the JavaScript detection function.

The possible error messages are returned as parte of the output
dictionary, in case they are needed.
