import { cspNonce } from “./csp” import { CSRFProtection } from “./csrf”

const AcceptHeaders = {

"*": "*/*",
text: "text/plain",
html: "text/html",
xml: "application/xml, text/xml",
json: "application/json, text/javascript",
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"

}

const ajax = (options) => {

options = prepareOptions(options)
var xhr = createXHR(options, function() {
  const response = processResponse(xhr.response != null ? xhr.response : xhr.responseText, xhr.getResponseHeader("Content-Type"))
  if (Math.floor(xhr.status / 100) === 2) {
    if (typeof options.success === "function") {
      options.success(response, xhr.statusText, xhr)
    }
  } else {
    if (typeof options.error === "function") {
      options.error(response, xhr.statusText, xhr)
    }
  }
  return (typeof options.complete === "function" ? options.complete(xhr, xhr.statusText) : undefined)
})

if (options.beforeSend && !options.beforeSend(xhr, options)) {
  return false
}

if (xhr.readyState === XMLHttpRequest.OPENED) {
  return xhr.send(options.data)
}

}

var prepareOptions = function(options) {

options.url = options.url || location.href
options.type = options.type.toUpperCase()
// append data to url if it's a GET request
if ((options.type === "GET") && options.data) {
  if (options.url.indexOf("?") < 0) {
    options.url += "?" + options.data
  } else {
    options.url += "&" + options.data
  }
}
// Use "*" as default dataType
if (!(options.dataType in AcceptHeaders)) { options.dataType = "*" }
options.accept = AcceptHeaders[options.dataType]
if (options.dataType !== "*") { options.accept += ", */*; q=0.01" }
return options

}

var createXHR = function(options, done) {

const xhr = new XMLHttpRequest()
// Open and set up xhr
xhr.open(options.type, options.url, true)
xhr.setRequestHeader("Accept", options.accept)
// Set Content-Type only when sending a string
// Sending FormData will automatically set Content-Type to multipart/form-data
if (typeof options.data === "string") {
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
}
if (!options.crossDomain) {
  xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
  // Add X-CSRF-Token
  CSRFProtection(xhr)
}
xhr.withCredentials = !!options.withCredentials
xhr.onreadystatechange = function() {
  if (xhr.readyState === XMLHttpRequest.DONE) { return done(xhr) }
}
return xhr

}

var processResponse = function(response, type) {

if ((typeof response === "string") && (typeof type === "string")) {
  if (type.match(/\bjson\b/)) {
    try { response = JSON.parse(response) } catch (error) { /* do nothing */ }
  } else if (type.match(/\b(?:java|ecma)script\b/)) {
    const script = document.createElement("script")
    script.setAttribute("nonce", cspNonce())
    script.text = response
    document.head.appendChild(script).parentNode.removeChild(script)
  } else if (type.match(/\b(xml|html|svg)\b/)) {
    const parser = new DOMParser()
    type = type.replace(/;.+/, "") // remove something like ';charset=utf-8'
    try { response = parser.parseFromString(response, type) } catch (error1) { /* do nothing */ }
  }
}
return response

}

// Default way to get an element’s href. May be overridden at Rails.href. const href = element => element.href

// Determines if the request is a cross domain request. const isCrossDomain = function(url) {

const originAnchor = document.createElement("a")
originAnchor.href = location.href
const urlAnchor = document.createElement("a")
try {
  urlAnchor.href = url
  // If URL protocol is false or is a string containing a single colon
  // *and* host are false, assume it is not a cross-domain request
  // (should only be the case for IE7 and IE compatibility mode).
  // Otherwise, evaluate protocol and host of the URL against the origin
  // protocol and host.
  return !(((!urlAnchor.protocol || (urlAnchor.protocol === ":")) && !urlAnchor.host) ||
    ((originAnchor.protocol + "//" + originAnchor.host) === (urlAnchor.protocol + "//" + urlAnchor.host)))
} catch (e) {
  // If there is an error parsing the URL, assume it is crossDomain.
  return true
}

}

export { ajax, href, isCrossDomain }