Source: LocaleDetection.js

import BaseCustomElement from "./BaseCustomElement"

/**
 * Send the locale and timezone from the browser to a configured endpoint on the server. This allows
 * the server to have access to a reasonable guess as to the website visitor's locale/timezone.
 *
 * Note that this will not contact the server if both `locale-from-server` and `timezone-from-server` are
 * set.  Further note that this will only contact the server once per page load, unless `url` is changed.
 *
 * @property {String} locale-from-server - omit this if the server doesn't know the visitor's locale. If both this and `timezone-from-server` are set, the server will not be contacted.
 * @property {String} timezone-from-server - omit this if the server doesn't know the visitor's timezone. If both this and `locale-from-server` are set, the server will not be contacted.
 * @property {URL} url - the url to send information to on the server.
 * @property {number} timeout-before-ping-ms - MS to wait until this element contacts the server. A value of 0 will contact the server immediately. The default is 1,000, meaning this element will wait 1 second before contacting the server.
 *
 * @example <caption>When no information about the visitor is known</caption>
 * <brut-locale-detection url="__brut/locale-detection"></brut-locale-detection>
 *
 * @example <caption>When all information about the visitor is known</caption>
 * <brut-locale-detection
 *   url="__brut/locale-detection"
 *   locale-from-server="en-US"
 *   timezone-from-server="America/New_York">
 * </brut-locale-detection>
 *
 * @customElement brut-locale-detection
 */
class LocaleDetection extends BaseCustomElement {
  static tagName = "brut-locale-detection"

  static observedAttributes = [
    "locale-from-server",
    "timezone-from-server",
    "url",
    "timeout-before-ping-ms",
    "show-warnings",
  ]

  #localeFromServer   = null
  #timezoneFromServer = null
  #reportingURL       = null
  #timeoutBeforePing  = 1000
  #serverContacted    = false

  localeFromServerChangedCallback({newValue}) {
    this.#localeFromServer = newValue
  }

  timezoneFromServerChangedCallback({newValue}) {
    this.#timezoneFromServer = newValue
  }

  urlChangedCallback({newValue}) {
    if (this.#serverContacted) {
      this.#serverContacted = false
    }
    this.#reportingURL = newValue
  }

  timeoutBeforePingMsChangedCallback({newValue}) {
    this.#timeoutBeforePing = newValue
  }

  update() {
    if (this.#timeoutBeforePing == 0) {
      this.#pingServerWithLocaleInfo()
    }
    else {
      setTimeout(this.#pingServerWithLocaleInfo.bind(this), this.#timeoutBeforePing)
    }
  }

  #pingServerWithLocaleInfo() {
    if (!this.#reportingURL) {
      this.logger.info("no url= set, so nowhere to report to")
      return
    }
    if (this.#localeFromServer && this.#timezoneFromServer) {
      this.logger.info("locale and timezone both set, not contacting server")
      return
    }

    if (this.#serverContacted) {
      this.logger.info("server has already been contacted at the given url, not doing it again")
      return
    }
    this.#serverContacted = true

    const formatOptions = Intl.DateTimeFormat().resolvedOptions()
    const request = new Request(
      this.#reportingURL,
      {
        headers: {
          "Content-Type": "application/json",
        },
        method: "POST",
        body: JSON.stringify({
          locale: formatOptions.locale,
          timeZone: formatOptions.timeZone,
        }),
      }
    )

    window.fetch(request).then( (response) => {
      if (response.ok) {
        this.logger.info("Server gave us the OK") 
      }
      else {
        console.warn(response)
      }
    }).catch( (e) => {
      console.warn(e)
    })
  }


}
export default LocaleDetection