{
  "version": 3,
  "sources": ["/cdn/shop/t/9/assets/pt-lang-menu.js?x=22895"],
  "sourcesContent": ["/**\n * Language menu with flags. It sits next to the native language <select>, which stays in the form as the real field:\n * choosing a language sets the select and fires its change event, so the theme's own localization form submits it.\n * Without JavaScript the native select stays visible.\n *\n * The menu itself is a native <details>: opening and closing needs no script (a tap on the summary just works on every phone).\n * The script only turns the menu on, sets the language, closes it on outside taps and Escape and adds the arrow keys.\n * Events are handled on the element and everything is looked up when needed, because the header drawer is filled in and morphed\n * after the page loaded (deferred hydration), which replaces the inner markup while the element stays. No dependencies.\n */\nclass PtLangMenu extends HTMLElement {\n  #abort = null;\n  #bound = false;\n\n  get details() {\n    return this.querySelector('[data-details]');\n  }\n\n  get options() {\n    return [...this.querySelectorAll('[role=\"option\"]')];\n  }\n\n  get select() {\n    return this.closest('form')?.querySelector('select[name=\"language_code\"]');\n  }\n\n  connectedCallback() {\n    this.setup();\n  }\n\n  /**\n   * The markup around the element is not always complete when it is connected (the module can run mid-parse, the drawer is\n   * filled in later). Until the details and the select of the form exist the menu stays a plain select; a page-level scan below\n   * keeps looking. A morph copies the attributes of fresh markup and drops data-ready: the listeners are still there then, so\n   * only the attribute is put back.\n   */\n  setup() {\n    if (!this.isConnected) return;\n    if (this.#bound) {\n      this.setAttribute('data-ready', '');\n      return;\n    }\n    if (!this.details || !this.select) return;\n    this.#bound = true;\n    this.#abort = new AbortController();\n    const { signal } = this.#abort;\n    this.addEventListener('click', (event) => this.#onClick(event), { signal });\n    this.addEventListener('keydown', (event) => this.#onKey(event), { signal });\n    // toggle does not bubble: the capture phase still sees it\n    this.addEventListener('toggle', () => this.#onToggle(), { capture: true, signal });\n    document.addEventListener('pointerdown', (event) => {\n      if (event.target instanceof Node && !this.contains(event.target)) this.#close();\n    }, { signal });\n    this.setAttribute('data-ready', '');\n  }\n\n  disconnectedCallback() {\n    this.#abort?.abort();\n    this.#bound = false;\n    this.removeAttribute('data-ready');\n  }\n\n  #close(restoreFocus = false) {\n    const details = this.details;\n    if (!details?.open) return;\n    details.open = false;\n    if (restoreFocus) details.querySelector('summary')?.focus();\n  }\n\n  #onToggle() {\n    const details = this.details;\n    if (!details?.open) return;\n    // inside the phone menu the list opens in the flow: make sure it is on screen\n    this.querySelector('[data-list]')?.scrollIntoView({ block: 'nearest' });\n    // a keyboard user lands on the current language\n    if (window.matchMedia('(pointer: fine)').matches) {\n      const options = this.options;\n      (options.find((o) => o.getAttribute('aria-selected') === 'true') ?? options[0])?.focus();\n    }\n  }\n\n  /** @param {MouseEvent} event */\n  #onClick(event) {\n    const option = event.target instanceof Element ? event.target.closest('[role=\"option\"]') : null;\n    if (!option) return;\n    const value = /** @type {HTMLElement} */ (option).dataset.value;\n    const select = this.select;\n    this.#close(true);\n    if (!value || !select || value === select.value) return;\n    select.value = value;\n    select.dispatchEvent(new Event('change', { bubbles: true }));\n  }\n\n  /** @param {KeyboardEvent} event */\n  #onKey(event) {\n    const target = event.target instanceof Element ? event.target : null;\n    if (!target) return;\n    const options = this.options;\n    if (target.closest('summary')) {\n      if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n        event.preventDefault();\n        if (this.details) this.details.open = true;\n        (options.find((o) => o.getAttribute('aria-selected') === 'true') ?? options[0])?.focus();\n      }\n      return;\n    }\n    if (!target.closest('[data-list]')) return;\n    const index = options.indexOf(/** @type {HTMLElement} */ (document.activeElement));\n    const move = (to) => {\n      event.preventDefault();\n      options[(to + options.length) % options.length]?.focus();\n    };\n    if (event.key === 'ArrowDown') move(index + 1);\n    else if (event.key === 'ArrowUp') move(index - 1);\n    else if (event.key === 'Home') move(0);\n    else if (event.key === 'End') move(options.length - 1);\n    else if (event.key === 'Escape') {\n      event.preventDefault();\n      this.#close(true);\n    } else if (event.key === 'Enter' || event.key === ' ') {\n      event.preventDefault();\n      if (index >= 0) /** @type {HTMLElement} */ (options[index]).click();\n    } else if (event.key === 'Tab') this.#close();\n  }\n}\n\nif (!customElements.get('pt-lang-menu')) customElements.define('pt-lang-menu', PtLangMenu);\n\n// A menu can be filled in or replaced after it was connected, without the element being connected again (its select can also\n// arrive after the menu, in the same form): look for menus that are not set up yet whenever the page changes, a frame at a time.\n// Once every menu is ready the observer does one cheap lookup per change and nothing else.\nlet scanning = false;\nnew MutationObserver(() => {\n  if (scanning || !document.querySelector('pt-lang-menu:not([data-ready])')) return;\n  scanning = true;\n  requestAnimationFrame(() => {\n    scanning = false;\n    document.querySelectorAll('pt-lang-menu:not([data-ready])').forEach((menu) => menu.setup?.());\n  });\n}).observe(document.documentElement, { childList: true, subtree: true });\n"],
  "mappings": "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",
  "names": []
}
