{
  "version": 3,
  "sources": ["../src/tomselect-init.js"],
  "sourcesContent": [
    "/**\n * Auto-initialise TomSelect on data-tomselect-prefilled attribute on <select> and <input>\n * Relies on window.TomSelect being loaded by django-tomselect middleware.\n *\n * Example usage:\n  * <select data-tomselect-prefilled='{\"placeholder\": \"Select an option\", \"maxItems\": 3, \"plugins\": [\"clear_button\"]}'>\n  *   <option value=\"1\">Option 1</option>\n  *   <option value=\"2\">Option 2</option>\n  * </select>\n */\n(function () {\n  /** Default render templates — DaisyUI badge items for multi-select */\n  /* Make sure it is kept in sync with templates/django_tomselect/render/item.html */\n  // escape() skips ', so spots only in text or \"double-quoted\" attrs\n  function fillTemplate(template, data, escape) {\n    return template.replace(/\\$\\{data\\.(\\w+)\\}/g, (_, field) =>\n      escape(data[field] ?? \"\"),\n    );\n  }\n\n  var defaultRender = {\n    item: function (data, escape) {\n      const safeText = escape(data.text);\n      if (this.settings.maxItems !== 1) {\n        return `<div class=\"badge badge-secondary badge-soft\" role=\"option\" title=\"${safeText}\"><span>${safeText}</span></div>`;\n      }\n      var template = this.settings.itemTemplate;\n      if (template) return fillTemplate(template, data, escape);\n      return `<div role=\"option\" title=\"${safeText}\">${safeText}</div>`;\n    },\n    option: function (data, escape) {\n      var template = this.settings.optionTemplate;\n      if (!template) return `<div>${escape(data.text)}</div>`;\n      return fillTemplate(template, data, escape);\n    },\n  };\n\n  /** Plugin-level defaults that require JS functions */\n  /* Make sure it is kept in sync with templates/django_tomselect/render/clear_button.html */\n  var pluginDefaults = {\n    clear_button: {\n      html: function (data) {\n        return `<div class=\"ts-clear-button-wrapper tooltip tooltip-top\" data-tip=\"${data.title}\">\n          <button type=\"button\" class=\"${data.className}\" title=\"${data.title}\" aria-label=\"${data.title}\"></button>\n        </div>`;\n      },\n      get title() {\n        return gettext(\"Clear selection\");\n      },\n      className:\n        \"ts-clear-button btn btn-xs btn-circle btn-ghost btn-info outline-primary -outline-offset-4 hover:bg-transparent hover:border-transparent hover:outline-2 focus-visible:outline-2 focus-visible:border-transparent\",\n    },\n    remove_button: {\n      label: \"\",\n    },\n  };\n\n  /**\n   * Build the final TomSelect config from the raw JSON attribute value.\n   * - Render: defaultRender provides fallbacks; user config takes precedence.\n   * - Plugins: normalises array form [\"remove_button\", …] to the expected form.\n   * - Null-safe: null is valid JSON so any field could be null; normalise to {}\n   *   so Object.assign merges are always safe and TomSelect never receives null.\n   */\n  function buildConfig(raw) {\n    if (raw === null || typeof raw !== \"object\") raw = {};\n\n    var render = Object.assign({}, defaultRender, raw.render || {});\n\n    var plugins = raw.plugins;\n    if (Array.isArray(plugins)) {\n      var obj = {};\n      plugins.forEach(function (p) {\n        obj[p] = {};\n      });\n      plugins = obj;\n    }\n    if (plugins && typeof plugins === \"object\") {\n      Object.keys(plugins).forEach(function (name) {\n        if (pluginDefaults[name]) {\n          plugins[name] = Object.assign(\n            {},\n            pluginDefaults[name],\n            plugins[name] || {},\n          );\n        }\n      });\n    } else {\n      plugins = undefined;\n    }\n\n    return Object.assign(\n      {},\n      raw,\n      { render: render },\n      plugins ? { plugins: plugins } : {},\n    );\n  }\n\n  function applyMultiOverflowCount(ts) {\n    var control = ts.control;\n    if (!control) return;\n\n    var selectedItems = control.querySelectorAll('.item[data-value]');\n    var overflowCount = control.querySelector('.ts-overflow-count');\n    var count = selectedItems.length;\n\n    selectedItems.forEach(function (item, index) {\n      item.style.display = index === 0 ? '' : 'none';\n    });\n\n    if (count <= 1) {\n      if (overflowCount) overflowCount.remove();\n      return;\n    }\n\n    if (!overflowCount) {\n      overflowCount = document.createElement('span');\n      overflowCount.className = 'ts-overflow-count badge badge-soft badge-secondary';\n      control.appendChild(overflowCount);\n    }\n\n    overflowCount.textContent = '+ ' + (count - 1);\n  }\n\n  function setupMultiOverflowCount(ts, rawConfig) {\n    if (!rawConfig || !rawConfig.overflowCount) return;\n    if (!ts.settings || ts.settings.maxItems === 1) return;\n\n    ts.wrapper.classList.add(\"plugin-overflow_count\");\n\n    var refreshOverflowCount = function () {\n      applyMultiOverflowCount(ts);\n    };\n\n    ts.on('initialize', refreshOverflowCount);\n    ts.on('clear', refreshOverflowCount);\n    ts.on('change', refreshOverflowCount);\n\n    refreshOverflowCount();\n  }\n\n  var canFloat =\n    !!HTMLElement.prototype.showPopover && CSS.supports(\"anchor-scope: all\");\n\n  /* Show the dropdown in the top layer, so no overflow or modal can clip it.\n     tom-select.css anchors it to the field. */\n  function floatDropdown(ts) {\n    ts.dropdown.popover = \"manual\";\n    ts.on(\"dropdown_open\", function () {\n      ts.dropdown.showPopover();\n    });\n    ts.on(\"dropdown_close\", function () {\n      ts.dropdown.hidePopover();\n    });\n    // Field scrolled out of view: close, or the list floats on its own\n    var observer = new IntersectionObserver(function (entries) {\n      if (ts.isOpen && !entries.at(-1).isIntersecting) ts.close();\n    });\n    observer.observe(ts.control);\n    ts.on(\"destroy\", () => observer.disconnect());\n  }\n\n  /* Browsers without canFloat: inside a <dialog>, hang the dropdown on the\n     dialog itself, so the modal-box's scroll can't clip it. */\n  function attachToDialog(ts) {\n    var dialog = ts.wrapper.closest(\"dialog\");\n    if (!dialog) return;\n    dialog.append(ts.dropdown);\n    dialog.addEventListener(\"close\", () => ts.dropdown.remove(), { once: true });\n    ts.positionDropdown = function () {\n      var rect = ts.control.getBoundingClientRect();\n      Object.assign(ts.dropdown.style, {\n        position: \"fixed\",\n        top: `${rect.bottom}px`,\n        left: `${rect.left}px`,\n        width: `${rect.width}px`,\n      });\n    };\n  }\n\n  function initTomSelects(root) {\n    if (!window.TomSelect) return;\n    var selects = (root || document).querySelectorAll(\n      \"select[data-tomselect-prefilled], input[data-tomselect-prefilled]\",\n    );\n    selects.forEach(function (el) {\n      if (el.tomselect) return; // already initialised\n      // Skip elements managed by django-tomselect's AJAX widgets — they\n      // use `data-tomselect` and initialise themselves via inline <script>.\n      if (el.hasAttribute(\"data-tomselect\")) return;\n      // Strip any stale TomSelect classes that may remain on the element after\n      // an HTMX swap (e.g. when form.media re-executes tomselect-init.js during\n      // the settle phase). If these are present when the TomSelect constructor\n      // reads el.className, they get copied onto the ts-wrapper, which then\n      // receives ts-hidden-accessible and becomes invisible.\n      // Fixes bug where TomSelect fails to initialise on HTMX swap after form_invalid.\n      el.classList.remove(\"tomselected\", \"ts-hidden-accessible\");\n      var raw = {};\n      try {\n        raw = JSON.parse(el.getAttribute(\"data-tomselect-prefilled\"));\n        // Attribute can receive a config object\n        // E.g '{\"placeholder\": \"Select an option\", \"maxItems\": 3, \"plugins\": [\"clear_button\"]}'\n      } catch (_) {}\n      var config = buildConfig(raw);\n      if (!canFloat) config.dropdownParent = \"body\"; // escape overflow clipping\n      var tomSelect = new TomSelect(el, config);\n      setupMultiOverflowCount(tomSelect, raw);\n      if (canFloat) floatDropdown(tomSelect);\n      else attachToDialog(tomSelect);\n    });\n  }\n\n  // Init on page load\n  if (document.readyState === \"loading\") {\n    document.addEventListener(\"DOMContentLoaded\", function () {\n      initTomSelects();\n    });\n  } else {\n    initTomSelects();\n  }\n\n  // Re-init after HTMX swaps, whole page as an outerHTML target is detached\n  document.addEventListener(\"htmx:afterSettle\", function () {\n    initTomSelects();\n  });\n\n  // Field removed (htmx swap, modal/drawer reset): free its Tom Select.\n  // ??= as form media reruns this file on every swap\n  window.tomSelectCleanup ??= new MutationObserver(function (mutations) {\n    mutations.forEach(function (m) {\n      m.removedNodes.forEach(function (node) {\n        if (!node.querySelectorAll) return;\n        [node, ...node.querySelectorAll(\".tomselected\")].forEach(function (el) {\n          if (el.tomselect && !el.isConnected) el.tomselect.destroy();\n        });\n      });\n    });\n  });\n  window.tomSelectCleanup.observe(document.documentElement, {\n    childList: true,\n    subtree: true,\n  });\n})();\n"
  ],
  "mappings": "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",
  "debugId": "507B0CE54B8FE8AE64756E2164756E21",
  "names": []
}