/* global window, document, localStorage */ const $ = selector => Array.from(document.querySelectorAll(selector)); const $$ = selector => Array.from(document.querySelector(selector)); (() => { "use strict"; /** * Initialize the theme toggle button functionality. * Toggles between 'dark' and 'light' themes and persists the state in localStorage. */ function initThemeToggle() { const themeToggleButton = document.getElementById("theme-toggle-btn"); if (!themeToggleButton) return; themeToggleButton.classList.toggle("btn-ghost", !("theme" in localStorage)); themeToggleButton.addEventListener("click", () => { const documentRoot = document.documentElement; const isSystemTheme = themeToggleButton.classList.contains("btn-ghost"); const isDarkTheme = documentRoot.classList.contains("dark"); const newTheme = isSystemTheme ? "dark" : (isDarkTheme ? "light" : "system"); if (newTheme === "system") { documentRoot.classList.toggle("dark", window.matchMedia("(prefers-color-scheme: dark)").matches); documentRoot.setAttribute("data-theme", window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"); localStorage.removeItem("theme"); } else { if (newTheme === "light") { documentRoot.classList.remove("dark"); } else if (newTheme === "dark") { documentRoot.classList.add("dark"); } documentRoot.setAttribute("data-theme", newTheme); localStorage.setItem("theme", newTheme); } themeToggleButton.classList.toggle("btn-ghost", newTheme === "system"); }); } /** * Initialize event listeners for forms containing multiselect fields. * When the form is submitted, process each 'card-multiselect' to create hidden inputs. */ function initCardMultiselectHandling() { const forms = document.querySelectorAll("form"); forms.forEach(form => { if (form.querySelector("select.card-multiselect")) { form.addEventListener("submit", () => { processMultiselectForm(form); }); } }); } /** * Process multiselect fields within a form before submission by: * - Creating hidden inputs for each selected option with value in 'card_id:quantity' format. * - Removing the original name attribute to avoid duplicate submissions. * * @param {HTMLFormElement} form - The form element to process. */ function processMultiselectForm(form) { const multiselectFields = form.querySelectorAll("select.card-multiselect"); multiselectFields.forEach(selectField => { const originalFieldName = selectField.getAttribute("data-original-name") || selectField.getAttribute("name"); if (!originalFieldName) return; selectField.setAttribute("data-original-name", originalFieldName); // Remove any previously generated hidden inputs for this multiselect. form .querySelectorAll(`input[data-generated-for-card-multiselect="${originalFieldName}"]`) .forEach(input => input.remove()); // For each selected option, create a hidden input. selectField.querySelectorAll("option:checked").forEach(option => { const cardId = option.value; const quantity = option.getAttribute("data-quantity") || "1"; const hiddenInput = document.createElement("input"); hiddenInput.type = "hidden"; hiddenInput.name = originalFieldName; hiddenInput.value = `${cardId}:${quantity}`; hiddenInput.setAttribute("data-generated-for-card-multiselect", originalFieldName); form.appendChild(hiddenInput); }); // Prevent the browser from submitting the select field directly. selectField.removeAttribute("name"); }); } /** * Reset stale selections in all card multiselect fields. * This is triggered on the window's 'pageshow' event to clear any lingering selections. */ function resetCardMultiselectState() { const multiselectFields = document.querySelectorAll("select.card-multiselect"); multiselectFields.forEach(selectField => { // Deselect all options. selectField.querySelectorAll("option").forEach(option => { option.selected = false; }); // If the select field has an associated Choices.js instance, clear its selection. if (selectField.choicesInstance) { const activeSelections = selectField.choicesInstance.getValue(true); if (activeSelections.length > 0) { selectField.choicesInstance.removeActiveItemsByValue(activeSelections); } selectField.choicesInstance.setValue([]); } }); } /** * Process all elements with the 'marquee' class. * For each element, if its content is overflowing (using isElementOverflowing), * wrap its innerHTML within a tag and remove the 'marquee' class. */ function processMarqueeElements() { document.querySelectorAll('.marquee-calc').forEach(element => { console.log(element.innerHTML, element.offsetWidth, element.scrollWidth); if (element.offsetWidth >= 148 || element.offsetWidth < element.scrollWidth) { element.innerHTML = '' + element.innerHTML + ''; } element.classList.remove('marquee-calc'); }); } // Expose processMarqueeElements to be available for AJAX-loaded partial updates. window.processMarqueeElements = processMarqueeElements; // On DOMContentLoaded, initialize theme toggling, form processing, and marquee wrapping. document.addEventListener("DOMContentLoaded", () => { initThemeToggle(); initCardMultiselectHandling(); processMarqueeElements(); }); // On pageshow, only reset multiselect state if the page was loaded from bfcache. window.addEventListener("pageshow", function(event) { if (event.persisted) { resetCardMultiselectState(); } }); })();