/** * Velvet Vibes — Flower Zone Theme Engine v5 * CSS + JS only. No HTML/Twig edits. * Fixes: search, nav hover submenu, centered sections, FAQ height, * testimonials pagination, footer Important + Legal links. */ (function () { "use strict"; if (window.__VV_STABLE_V4__) return; window.__VV_STABLE_V4__ = true; window.__VV_STABLE_V5__ = true; window.__VV_STABLE_V3__ = true; /* prevent older pasted scripts from double-running */ /* -------------------------------------------------------------------------- Boot — stop the page restyling itself in front of the customer. Every rule in style.css is scoped to body.vv-fz-theme, and that class used to be added inside init(), which only runs on DOMContentLoaded. So the browser painted the stock Salla theme first and swapped to ours a moment later — that is the jump people see while the store opens. Two things fix it. The theme classes go on as soon as exists, long before init(), so the stylesheet applies to the very first paint. And the page stays cloaked (see the boot cloak in style.css) until the first pass of init() has finished rearranging the header, footer and sliders, so the DOM surgery happens off-screen rather than in view. -------------------------------------------------------------------------- */ var THEME_BODY_CLASSES = [ "vv-body", "vv-clean-theme", "vv-override-theme", "vv-fz-theme", ]; function applyThemeClasses() { if (!document.body) return false; try { THEME_BODY_CLASSES.forEach(function (name) { document.body.classList.add(name); }); } catch (e) {} return true; } /* The script may be injected into , before is parsed. Watch for it rather than waiting for DOMContentLoaded, which is far too late. */ if (!applyThemeClasses() && window.MutationObserver) { var bodyWatcher = new MutationObserver(function () { if (applyThemeClasses()) bodyWatcher.disconnect(); }); try { bodyWatcher.observe(document.documentElement, { childList: true }); } catch (e) {} } /* Lifting the cloak. The stylesheet also reveals on its own after a short delay, so a failure in here can never leave the store blank. */ function revealStore() { if (!document.body) return; try { document.body.classList.add("vv-fz-ready"); } catch (e) {} } window.addEventListener("load", revealStore); setTimeout(revealStore, 1500); var ANNOUNCEMENTS = []; var STORE_MAPS_URL = "https://maps.app.goo.gl/G14sF9B33K39R4sF6"; var BOOK_PARTY_URL = "/احجز-حفلتك/c276742401"; var announceIndex = 0; var announceTimer = null; var contentObserver = null; var resizeTimer = null; var searchApi = null; var wishlistBound = false; function q(selector, root) { try { return (root || document).querySelector(selector); } catch (e) { return null; } } function qa(selector, root) { try { return Array.from((root || document).querySelectorAll(selector)); } catch (e) { return []; } } function safe(fn) { try { fn(); } catch (e) { if (window.console && console.warn) console.warn("[Velvet Vibes]", e); } } function setImportant(el, prop, value) { if (!el) return; try { el.style.setProperty(prop, value, "important"); } catch (e) {} } function decodePath(path) { try { return decodeURIComponent(path || ""); } catch (e) { return path || ""; } } /* -------------------------------------------------------------------------- Header stability — pin logo bar + category links together -------------------------------------------------------------------------- */ function ensureStickyShell(header, main) { if (!header || !main) return null; var shell = q(".vv-header-stick", header); if (shell && shell.contains(main)) return shell; shell = document.createElement("div"); shell.className = "vv-header-stick"; shell.setAttribute("data-vv-sticky", "1"); if (main.parentNode) { main.parentNode.insertBefore(shell, main); } else { header.appendChild(shell); } shell.appendChild(main); var existingNav = q(".vv-desktop-nav", header) || q(".vv-desktop-nav"); if (existingNav && existingNav.parentNode !== shell) { shell.appendChild(existingNav); } return shell; } function ensureHeaderSpacer(shell) { if (!shell || !shell.parentNode) return null; var spacer = q(".vv-header-stick-spacer"); if (!spacer) { spacer = document.createElement("div"); spacer.className = "vv-header-stick-spacer"; spacer.setAttribute("aria-hidden", "true"); shell.parentNode.insertBefore(spacer, shell); } return spacer; } function forceMainnavInFlow(main) { if (!main) return; ["fixed-header", "fixed-pinned", "sticky", "fixed"].forEach(function (c) { /* keep class names for theme, but override geometry */ }); setImportant(main, "position", "relative"); setImportant(main, "top", "auto"); setImportant(main, "right", "auto"); setImportant(main, "bottom", "auto"); setImportant(main, "left", "auto"); setImportant(main, "transform", "none"); setImportant(main, "inset", "auto"); } function syncPinnedHeader() { var header = q("header.store-header"); var main = q("#mainnav.main-nav-container"); if (!header || !main) return; var shell = ensureStickyShell(header, main); if (!shell) return; var nav = q(".vv-desktop-nav", shell) || q(".vv-desktop-nav", header) || q(".vv-desktop-nav"); if (nav && nav.parentNode !== shell) shell.appendChild(nav); var mobile = window.matchMedia("(max-width: 1023px)").matches; var barH = mobile ? "64px" : "88px"; var topBar = q(".top-navbar", header); var threshold = topBar ? topBar.offsetHeight : 0; var shouldPin = (window.scrollY || window.pageYOffset || 0) >= Math.max(4, threshold - 2); setImportant(header, "position", "relative"); setImportant(header, "top", "auto"); setImportant(header, "transform", "none"); setImportant(header, "height", "auto"); setImportant(header, "max-height", "none"); forceMainnavInFlow(main); setImportant(main, "width", "100%"); setImportant(main, "height", barH); setImportant(main, "min-height", barH); setImportant(main, "max-height", barH); [q(".inner", main), q(".inner > .container", main), q(".inner > .container > .relative", main)].forEach( function (el) { if (!el) return; setImportant(el, "height", barH); setImportant(el, "max-height", barH); setImportant(el, "min-height", "0px"); }, ); if (nav) { if (mobile) { setImportant(nav, "display", "none"); } else { setImportant(nav, "display", "flex"); setImportant(nav, "visibility", "visible"); setImportant(nav, "opacity", "1"); setImportant(nav, "position", "relative"); setImportant(nav, "height", "54px"); setImportant(nav, "min-height", "54px"); setImportant(nav, "max-height", "54px"); setImportant(nav, "pointer-events", "auto"); setImportant(nav, "z-index", "120"); } } var spacer = ensureHeaderSpacer(shell); if (shouldPin) { shell.classList.add("is-pinned"); document.body.classList.add("vv-header-pinned"); setImportant(shell, "position", "fixed"); setImportant(shell, "top", "0px"); setImportant(shell, "left", "0px"); setImportant(shell, "right", "0px"); setImportant(shell, "width", "100%"); setImportant(shell, "z-index", "1000"); setImportant(shell, "background", mobile ? "#5c1a1a" : "#ffffff"); var total = shell.offsetHeight || (mobile ? 64 : 88 + 54); if (spacer) { setImportant(spacer, "display", "block"); setImportant(spacer, "height", total + "px"); } } else { shell.classList.remove("is-pinned"); document.body.classList.remove("vv-header-pinned"); setImportant(shell, "position", "relative"); setImportant(shell, "top", "auto"); setImportant(shell, "left", "auto"); setImportant(shell, "right", "auto"); setImportant(shell, "z-index", "110"); if (spacer) { setImportant(spacer, "height", "0px"); } } } function normalizeHeaderDimensions() { syncPinnedHeader(); } function watchThemeHeaderFight() { var main = q("#mainnav.main-nav-container"); if (!main || main.getAttribute("data-vv-pin-watch") === "1") return; main.setAttribute("data-vv-pin-watch", "1"); if (!window.MutationObserver) return; var timer = null; new MutationObserver(function () { clearTimeout(timer); timer = setTimeout(function () { safe(syncPinnedHeader); safe(clearInlineHeaderFight); }, 16); }).observe(main, { attributes: true, attributeFilter: ["style", "class"] }); } function applyAnnouncementMode(track) { if (!track) return; initAnnouncement(); } function initAnnouncement() { if (announceTimer) { clearInterval(announceTimer); announceTimer = null; } qa(".vv-clean-announcement, .vv-ann-row, .vv-ticker-wrap, .vv-ann-track").forEach(function (el) { el.remove(); }); qa(".store-header .top-navbar, .top-navbar").forEach(function (bar) { bar.style.setProperty("display", "none", "important"); bar.style.setProperty("height", "0px", "important"); bar.style.setProperty("min-height", "0px", "important"); bar.style.setProperty("max-height", "0px", "important"); bar.style.setProperty("margin", "0px", "important"); bar.style.setProperty("padding", "0px", "important"); bar.style.setProperty("border", "none", "important"); bar.style.setProperty("overflow", "hidden", "important"); }); } /* -------------------------------------------------------------------------- Professional Velvet Vibes search popup Custom branded modal + live Salla search when available. -------------------------------------------------------------------------- */ var searchState = { api: null, reducedMotion: false }; var pageScrollLock = { active: false, y: 0 }; try { searchState.reducedMotion = window.matchMedia( "(prefers-reduced-motion: reduce)", ).matches; } catch (e) {} function lockPageScroll() { if (pageScrollLock.active) return; pageScrollLock.active = true; pageScrollLock.y = window.scrollY || window.pageYOffset || document.documentElement.scrollTop || 0; document.documentElement.classList.add("vv-searchbox-open"); document.body.classList.add("vv-searchbox-open"); } function unlockPageScroll() { pageScrollLock.active = false; document.documentElement.classList.remove("vv-searchbox-open"); document.body.classList.remove("vv-searchbox-open"); [document.documentElement, document.body].forEach(function (el) { if (!el) return; [ "vv-searchbox-open", "modal-open", "overflow-hidden", "no-scroll", "s-modal-opened", "swal2-shown", "swal2-height-auto", ].forEach(function (c) { el.classList.remove(c); }); var style = el.style; if (!style) return; var lockedPos = style.position === "fixed"; if (lockedPos) { var top = Math.abs(parseInt(style.top, 10) || 0); if (top) pageScrollLock.y = top; style.removeProperty("position"); style.removeProperty("top"); style.removeProperty("left"); style.removeProperty("right"); style.removeProperty("width"); style.removeProperty("height"); } style.removeProperty("overflow"); style.removeProperty("overflow-x"); style.removeProperty("overflow-y"); style.removeProperty("touch-action"); style.removeProperty("overscroll-behavior"); style.removeProperty("padding-right"); style.removeProperty("padding-left"); }); /* Force-clear any leftover Salla modal scroll lock, then let theme CSS win */ try { document.documentElement.style.setProperty("overflow", "visible", "important"); document.body.style.setProperty("overflow-y", "auto", "important"); document.body.style.setProperty("overflow-x", "hidden", "important"); document.body.style.setProperty("touch-action", "auto", "important"); document.body.style.setProperty("pointer-events", "auto", "important"); } catch (e) {} requestAnimationFrame(function () { try { document.documentElement.style.removeProperty("overflow"); document.body.style.removeProperty("overflow-y"); document.body.style.removeProperty("overflow-x"); document.body.style.removeProperty("touch-action"); document.body.style.removeProperty("pointer-events"); /* If computed style still locks Y (stuck Salla rule), keep an unlock override */ var bodyOv = window.getComputedStyle(document.body).overflowY; var htmlOv = window.getComputedStyle(document.documentElement).overflowY; if (bodyOv === "hidden") { document.body.style.setProperty("overflow-y", "auto", "important"); } if (htmlOv === "hidden") { document.documentElement.style.setProperty("overflow-y", "auto", "important"); } } catch (e2) {} try { window.scrollTo(0, pageScrollLock.y || 0); } catch (e3) {} }); /* Hide stray native search backdrops that can freeze clicks/scroll */ qa( "salla-search[data-testid='store-search-modal'], salla-modal.s-search-modal", ).forEach(function (el) { if (el.closest && el.closest(".vv-searchbox")) return; try { if (typeof el.close === "function") el.close(); } catch (e) {} el.classList.add("s-hidden", "vv-native-search-suppressed"); el.setAttribute("aria-hidden", "true"); el.style.setProperty("display", "none", "important"); el.style.setProperty("pointer-events", "none", "important"); }); qa(".s-modal-wrapper").forEach(function (el) { if (el.closest && el.closest(".vv-searchbox")) return; if (!el.querySelector(".s-search-input, salla-search, .s-search-modal")) return; el.classList.add("s-hidden"); el.style.setProperty("display", "none", "important"); el.style.setProperty("pointer-events", "none", "important"); }); try { if (window.salla && salla.event) { if (typeof salla.event.dispatch === "function") { salla.event.dispatch("search::close"); } else if (typeof salla.event.emit === "function") { salla.event.emit("search::close"); } } } catch (e) {} } function getStoreBase() { try { if (window.salla && salla.config && salla.config.get) { var url = salla.config.get("store.url") || salla.config.get("url"); if (url) return String(url).replace(/\/$/, ""); } } catch (e) {} return (location.origin || "").replace(/\/$/, ""); } function buildSearchShell() { var existing = q(".vv-searchbox"); if (existing) existing.remove(); var overlay = document.createElement("div"); overlay.className = "vv-searchbox"; overlay.setAttribute("hidden", ""); var backdrop = document.createElement("div"); backdrop.className = "vv-searchbox__backdrop"; var dialog = document.createElement("div"); dialog.className = "vv-searchbox__dialog"; dialog.setAttribute("role", "dialog"); dialog.setAttribute("aria-modal", "true"); dialog.setAttribute("aria-label", "\u0627\u0644\u0628\u062d\u062b \u0641\u064a \u0627\u0644\u0645\u062a\u062c\u0631"); var close = document.createElement("button"); close.type = "button"; close.className = "vv-searchbox__close"; close.setAttribute("aria-label", "\u0625\u063a\u0644\u0627\u0642 \u0627\u0644\u0628\u062d\u062b"); close.innerHTML = ''; var head = document.createElement("div"); head.className = "vv-searchbox__head"; head.innerHTML = '
' + 'Velvet Vibes' + '

' + "\u0627\u0628\u062d\u062b \u0639\u0646 \u0628\u0627\u0642\u062a\u0643 \u0627\u0644\u0645\u062b\u0627\u0644\u064a\u0629" + '

' + '

' + "\u0648\u0631\u0648\u062f\u060c \u0647\u062f\u0627\u064a\u0627\u060c \u062a\u0646\u0633\u064a\u0642 \u0645\u0646\u0627\u0633\u0628\u0627\u062a \u0648\u0623\u0643\u062b\u0631" + '

' + "
"; var slot = document.createElement("div"); slot.className = "vv-searchbox__slot"; dialog.appendChild(close); dialog.appendChild(head); dialog.appendChild(slot); overlay.appendChild(backdrop); overlay.appendChild(dialog); document.body.appendChild(overlay); return { overlay: overlay, backdrop: backdrop, dialog: dialog, close: close, slot: slot, }; } function buildFallbackForm() { var form = document.createElement("form"); form.className = "vv-searchbox__form"; form.setAttribute("role", "search"); form.action = getStoreBase() + "/search"; form.method = "get"; form.innerHTML = '' + '' + ''; return form; } function buildLiveSearch() { var search = document.createElement("salla-search"); search.setAttribute("inline", ""); search.setAttribute("oval", ""); search.setAttribute("height", "54"); search.setAttribute("data-testid", "velvet-live-search"); search.setAttribute("aria-label", "\u0627\u0644\u0628\u062d\u062b \u0639\u0646 \u0627\u0644\u0645\u0646\u062a\u062c\u0627\u062a"); return search; } function buildQuickLinks() { /* The chips mirror the store menu. If Salla has no menu yet there are simply no chips — never a hardcoded list the merchant cannot edit. */ var live = []; qa( "#mobile-menu .main-menu > li > a, .vv-desktop-nav__list > li > a, custom-main-menu a", ).forEach(function (a) { var label = (a.textContent || "").replace(/\s+/g, " ").trim(); var href = a.getAttribute("href") || a.href || ""; if (!label || !href || /الرئيسية|^home$/i.test(label)) return; if (/بحث|حساب|سلة|wishlist|login|cart/i.test(label)) return; if (live.some(function (c) { return c.label === label; })) return; live.push({ label: label, href: href }); }); var cats = live.slice(0, 5); var wrap = document.createElement("div"); wrap.className = "vv-searchbox__quick"; if (!cats.length) return wrap; var labelEl = document.createElement("span"); labelEl.className = "vv-searchbox__quick-label"; labelEl.textContent = "\u0627\u0644\u0623\u0643\u062b\u0631 \u0628\u062d\u062b\u064b\u0627"; wrap.appendChild(labelEl); cats.forEach(function (cat) { var chip = document.createElement("a"); chip.className = "vv-searchbox__chip"; chip.href = cat.href; chip.textContent = cat.label; wrap.appendChild(chip); }); return wrap; } function refreshSearchQuickLinks(overlay) { if (!overlay) return; var dialog = q(".vv-searchbox__dialog", overlay); if (!dialog) return; var old = q(".vv-searchbox__quick", dialog); var next = buildQuickLinks(); if (old) old.replaceWith(next); else dialog.appendChild(next); } function suppressNativeSearchModal() { qa( 'salla-search[data-testid="store-search-modal"], salla-modal.s-search-modal, .s-search-modal', ).forEach(function (el) { if (el.closest && el.closest(".vv-searchbox")) return; el.classList.add("vv-native-search-suppressed"); try { el.setAttribute("aria-hidden", "true"); el.style.setProperty("display", "none", "important"); if (typeof el.close === "function") el.close(); } catch (e) {} }); /* Close any open native search wrappers */ qa( ".s-modal-wrapper:not(.s-hidden) .s-search-input, salla-modal:not(.s-hidden) .s-search-input", ).forEach(function (input) { var modal = input.closest("salla-modal, .s-modal-container, salla-search"); if (!modal || (modal.closest && modal.closest(".vv-searchbox"))) return; try { if (typeof modal.close === "function") modal.close(); modal.classList.add("s-hidden"); modal.style.setProperty("display", "none", "important"); } catch (e) {} }); } function bindNativeSearchIntercept() { if (window.__VV_SEARCH_INTERCEPT__) return; window.__VV_SEARCH_INTERCEPT__ = true; try { if (window.salla && salla.event && typeof salla.event.on === "function") { salla.event.on("search::open", function () { suppressNativeSearchModal(); openSearch(); }); } } catch (e) {} document.addEventListener( "search::open", function (e) { try { e.stopImmediatePropagation(); e.preventDefault(); } catch (err) {} suppressNativeSearchModal(); openSearch(); }, true, ); } function initSearchPopup() { if (searchState.api) return searchState.api; /* Only one branded popup */ qa(".vv-searchbox").forEach(function (el, i) { if (i > 0) el.remove(); }); var parts = buildSearchShell(); var lastFocus = null; function syncResults() { var box = q(".s-search-results", parts.slot); if (!box) return; var filled = Array.prototype.some.call(box.children, function (child) { if (child.hasAttribute("hidden")) return false; return (child.style.display || "") !== "none"; }); box.classList.toggle("is-filled", filled); } function watchResults() { var box = q(".s-search-results", parts.slot); if (!box || box.getAttribute("data-vv-watch") === "1") return; box.setAttribute("data-vv-watch", "1"); syncResults(); if (!window.MutationObserver) return; new MutationObserver(function () { safe(syncResults); }).observe(box, { childList: true, subtree: true, attributes: true, attributeFilter: ["style", "hidden", "class"], }); } function ensureSearchControl() { if (q("salla-search, .vv-searchbox__form", parts.slot)) return; parts.slot.innerHTML = ""; parts.slot.classList.add("vv-searchbox__slot--salla"); /* Salla's inline component performs live search and renders products. */ if (window.customElements && typeof window.customElements.whenDefined === "function") { parts.slot.appendChild(buildLiveSearch()); } else { parts.slot.classList.remove("vv-searchbox__slot--salla"); parts.slot.appendChild(buildFallbackForm()); } } ensureSearchControl(); /* Results are injected after the Web Component hydrates. */ if (window.MutationObserver) { new MutationObserver(function () { safe(watchResults); safe(syncResults); }).observe(parts.slot, { childList: true, subtree: true }); } safe(watchResults); parts.slot.addEventListener("input", function () { safe(syncResults); }); /* Clicking the white field area must always focus the input */ parts.slot.addEventListener("pointerdown", function (e) { var input = q(".vv-searchbox__input, .s-search-input", parts.slot); if (!input) return; if (e.target === input) return; if (e.target && e.target.closest && e.target.closest("button, a")) return; e.preventDefault(); try { input.focus({ preventScroll: true }); } catch (err) { input.focus(); } }); parts.dialog.appendChild(buildQuickLinks()); function focusInput() { ensureSearchControl(); var input = q(".vv-searchbox__input, .s-search-input", parts.overlay); if (!input) return; input.removeAttribute("readonly"); input.removeAttribute("disabled"); input.style.setProperty("pointer-events", "auto", "important"); try { input.focus({ preventScroll: true }); } catch (e) { try { input.focus(); } catch (e2) {} } if (typeof input.select === "function") input.select(); } function open() { suppressNativeSearchModal(); if (parts.overlay.classList.contains("is-open")) { focusInput(); return; } lastFocus = document.activeElement; ensureSearchControl(); safe(function () { refreshSearchQuickLinks(parts.overlay); }); parts.overlay.removeAttribute("hidden"); parts.overlay.style.setProperty("pointer-events", "auto", "important"); parts.dialog.style.setProperty("pointer-events", "auto", "important"); lockPageScroll(); requestAnimationFrame(function () { requestAnimationFrame(function () { parts.overlay.classList.add("is-open"); suppressNativeSearchModal(); focusInput(); }); }); setTimeout(function () { focusInput(); suppressNativeSearchModal(); }, searchState.reducedMotion ? 0 : 180); } function close() { parts.overlay.classList.remove("is-open"); unlockPageScroll(); suppressNativeSearchModal(); /* Close adopted Salla search widget so it does not keep body locked */ qa("salla-search", parts.slot).forEach(function (el) { try { if (typeof el.close === "function") el.close(); } catch (e) {} }); var delay = searchState.reducedMotion ? 0 : 280; setTimeout(function () { if (!parts.overlay.classList.contains("is-open")) { parts.overlay.setAttribute("hidden", ""); unlockPageScroll(); } }, delay); if (lastFocus && typeof lastFocus.focus === "function") { try { lastFocus.focus({ preventScroll: true }); } catch (e) {} } } parts.backdrop.addEventListener("click", close); parts.close.addEventListener("click", close); parts.dialog.addEventListener("click", function (e) { e.stopPropagation(); }); document.addEventListener("keydown", function (e) { if ((e.key === "Escape" || e.keyCode === 27) && parts.overlay.classList.contains("is-open")) { close(); } }); searchState.api = { open: open, close: close, overlay: parts.overlay }; searchApi = searchState.api; return searchState.api; } function openSearch() { suppressNativeSearchModal(); var api = initSearchPopup(); if (api) api.open(); } function closeSearch() { if (searchState.api) searchState.api.close(); else unlockPageScroll(); suppressNativeSearchModal(); } function initSearch() { bindNativeSearchIntercept(); initSearchPopup(); suppressNativeSearchModal(); var headerSearch = q(".header-search"); if (headerSearch) { headerSearch.classList.add("vv-announcement-search-keep"); } qa( ".vv-clean-search, .vv-search-trigger, button[aria-label='بحث'], a[aria-label='بحث']", ).forEach(function (btn) { if (btn.getAttribute("data-vv-search-bound") === "1") return; if (btn.closest && (btn.closest("salla-search") || btn.closest(".vv-searchbox"))) return; if (btn.closest && btn.closest('[data-testid="store-search-modal"]')) return; btn.setAttribute("data-vv-search-bound", "1"); if (btn.tagName === "BUTTON") btn.type = "button"; btn.addEventListener( "click", function (e) { e.preventDefault(); e.stopPropagation(); if (e.stopImmediatePropagation) e.stopImmediatePropagation(); openSearch(); }, true, ); }); } function hideViewAllLinks() { qa( ".s-slider-block__display-all, a.s-slider-block__display-all", ).forEach(function (a) { var t = ((a.getAttribute("aria-label") || "") + " " + (a.textContent || "")) .replace(/\s+/g, " ") .trim(); if (/عرض\s*الكل|view\s*all|see\s*all/i.test(t)) { if (a.classList.contains("vv-products-all")) return; if (a.closest && a.closest('[data-testid="store-home-products-slider"]')) return; a.style.setProperty("display", "none", "important"); a.setAttribute("hidden", ""); a.setAttribute("aria-hidden", "true"); } }); } function closeNativeMobileMenu() { var closer = q(".close-mobile-menu, .btn--close.close-mobile-menu, .btn--close-sm.close-mobile-menu"); if (closer) { try { closer.click(); } catch (e) {} } try { if (location.hash && /mobile-menu/i.test(location.hash)) { if (history.replaceState) { history.replaceState(null, "", location.pathname + location.search); } else { location.hash = ""; } } } catch (e) {} document.documentElement.classList.remove("mm-wrapper--opened"); document.body.classList.remove("mm-wrapper--opened"); qa(".mm-ocd--open, .mm-ocd--opened").forEach(function (el) { el.classList.remove("mm-ocd--open", "mm-ocd--opened"); }); } function isMobileMenuOpen() { return ( document.documentElement.classList.contains("mm-wrapper--opened") || document.body.classList.contains("mm-wrapper--opened") || !!q(".mm-ocd--open, .mm-ocd--opened") || /mobile-menu/i.test(location.hash || "") ); } function syncMobileMenuCloseBtn() { var btn = q("body > .vv-mobile-menu-close"); if (!btn) return; var open = isMobileMenuOpen(); btn.classList.toggle("is-visible", open); btn.setAttribute("aria-hidden", open ? "false" : "true"); } function injectMobileMenuClose() { var btn = q("body > .vv-mobile-menu-close"); if (!btn) { btn = document.createElement("button"); btn.type = "button"; btn.className = "vv-mobile-menu-close"; btn.setAttribute("aria-label", "إغلاق القائمة"); btn.innerHTML = '"; btn.addEventListener("click", function (e) { e.preventDefault(); e.stopPropagation(); closeNativeMobileMenu(); setTimeout(syncMobileMenuCloseBtn, 30); }); document.body.appendChild(btn); } qa( "#mobile-menu .vv-mobile-menu-close, nav.mobile-menu .vv-mobile-menu-close, .mm-spn--navbar > .vv-mobile-menu-close, #mainnav .vv-mobile-menu-close", ).forEach(function (el) { if (el !== btn) el.remove(); }); syncMobileMenuCloseBtn(); } function menuItemLabel(li) { if (!li) return ""; var a = q(":scope > a", li); if (a) { var span = q("span", a); return ((span && span.textContent) || a.getAttribute("aria-label") || a.textContent || "") .replace(/\s+/g, " ") .trim(); } var head = q(":scope > span", li); return (head ? head.textContent : "").replace(/\s+/g, " ").trim(); } function nestedMenuList(li) { if (!li) return null; return ( q(":scope > ul, :scope > .sub-menu", li) || q(":scope > div > ul", li) || q(":scope > .mm-spn > ul", li) ); } function readNestedChildren(from) { var kids = []; var seen = {}; if (!from) return kids; qa("a", from).forEach(function (a) { var labelSpan = q("span", a); var label = (labelSpan ? labelSpan.textContent : (a.textContent || a.getAttribute("aria-label") || "")) .replace(/\s+/g, " ") .trim(); var href = a.getAttribute("href") || ""; if (!label || !href || seen[label]) return; if (/عرض\s*الكل|view\s*all|see\s*all/i.test(label)) return; if (a.getAttribute("hidden") != null || a.getAttribute("aria-hidden") === "true") return; seen[label] = true; kids.push({ label: label, href: href }); }); return kids; } function getStoreWhatsAppPhone() { // 1. Search page for any existing WhatsApp links (floating button, footer, header, etc.) var waLinks = qa('a[href*="wa.me"], a[href*="whatsapp.com"], a[href*="api.whatsapp"]'); for (var i = 0; i < waLinks.length; i++) { var el = waLinks[i]; if (el.closest && el.closest(".vv-drawer-party-card, .vv-drawer-footer")) continue; var href = el.getAttribute("href") || ""; var match = href.match(/(?:wa\.me\/|phone=|send\?phone=)(\+?\d+)/i); if (match && match[1]) { var clean = match[1].replace(/\D/g, ""); if (clean.length >= 9) return clean; } } // 2. Check salla-contacts or contact telephone links on the page var contactEl = q('salla-contacts a[href^="tel:"], .s-contacts a[href^="tel:"], [data-testid="store-footer-contacts"] a[href^="tel:"], a.vv-footer-phone[href^="tel:"]'); if (contactEl) { var telHref = contactEl.getAttribute("href") || ""; var telDigits = telHref.replace(/\D/g, ""); if (telDigits.length >= 9) return telDigits; } // 3. Fallback default requested by the user: +966 55 889 0343 return "966558890343"; } function normAr(str) { return (sanitizeNavLabel(str) || "") .replace(/[أإآ]/g, "ا") .replace(/ة/g, "ه") .replace(/ى/g, "ي") .replace(/[\u064B-\u065F]/g, "") .toLowerCase(); } function getDesktopSubcategories(normTitle) { if (!normTitle) return []; var candidates = qa("#mainnav li, .vv-desktop-nav li, custom-main-menu li.root-level, [data-menu-item]"); for (var i = 0; i < candidates.length; i++) { var cLi = candidates[i]; var cLabel = menuItemLabel(cLi); if (normAr(cLabel) === normTitle) { var sub = nestedMenuList(cLi); if (sub) { var kids = readNestedChildren(sub); if (kids && kids.length) return kids; } } } return []; } function ensureMobileDrawerSubcategories() { var nav = q("#mobile-menu, nav.mobile-menu"); if (!nav) return; // 1. Ensure prominent glass Back Button exists in nav header for sub-panels var backBtn = q(".vv-drawer-back-btn", nav); if (!backBtn) { backBtn = document.createElement("button"); backBtn.type = "button"; backBtn.className = "vv-drawer-back-btn"; backBtn.setAttribute("aria-label", "الرجوع للقائمة الرئيسية"); backBtn.innerHTML = ''; nav.appendChild(backBtn); } function syncBackBtnVisibility() { if (!backBtn) return; var openUls = qa("ul.mm-spn--open", nav); var inSubPanel = openUls.some(function (u) { return !u.classList.contains("main-menu"); }); if (inSubPanel && !nav.classList.contains("mm-spn--main")) { backBtn.style.setProperty("display", "flex", "important"); } else { backBtn.style.setProperty("display", "none", "important"); } } if (!backBtn._vv_bound) { backBtn._vv_bound = true; backBtn.addEventListener("click", function (e) { e.preventDefault(); e.stopPropagation(); goBackToMainMenu(); }); } function goBackToMainMenu() { var openUls = qa("ul.mm-spn--open", nav); var activeUl = openUls[openUls.length - 1]; if (!activeUl || activeUl.classList.contains("main-menu")) { nav.classList.add("mm-spn--main"); nav.setAttribute("data-mm-spn-title", "القائمة الرئيسية"); syncBackBtnVisibility(); return; } var parentUl = activeUl.parentElement ? activeUl.parentElement.closest("ul") : null; if (!parentUl || parentUl === activeUl) parentUl = q("ul.main-menu", nav); if (parentUl) { activeUl.classList.remove("mm-spn--open"); parentUl.classList.remove("mm-spn--parent"); parentUl.classList.add("mm-spn--open"); if (parentUl.classList.contains("main-menu")) { nav.classList.add("mm-spn--main"); nav.setAttribute("data-mm-spn-title", "القائمة الرئيسية"); } else { var pLi = parentUl.closest("li"); var pTitle = pLi ? menuItemLabel(pLi) : "القائمة الرئيسية"; nav.setAttribute("data-mm-spn-title", pTitle); } } syncBackBtnVisibility(); } // 2. Query all category list items in the drawer var lis = qa("ul.main-menu > li, nav.mobile-menu > ul > li", nav); if (!lis.length) lis = qa("li.lg\\:hidden", nav); lis.forEach(function (li) { if (li.classList.contains("root-level") || li.classList.contains("vv-acc-hide")) return; var label = menuItemLabel(li); var cleanLabel = (label || "").trim(); var norm = normAr(cleanLabel); // Check if child