/* * Salla Advanced JavaScript (injected in ). * Keeps the first-paint flower visible for at least one second and releases it * only after our homepage landing is interactive. A hard cap prevents lockups. */ (function () { "use strict"; var path = window.location.pathname.replace(/\/+$/, "") || "/"; if (path !== "/") return; var html = document.documentElement; var startedAt = window.performance && performance.now ? performance.now() : Date.now(); var minimumVisibleMs = 1000; var hardReleaseMs = 3400; var finished = false; var preparing = false; var observer = null; var releaseTimer = 0; html.classList.add("loe-critical-loading"); html.classList.remove("loe-critical-ready"); function elapsed() { var now = window.performance && performance.now ? performance.now() : Date.now(); return now - startedAt; } function hideInnerLoader() { var innerLoader = document.getElementById("loeBoot"); if (!innerLoader) return; innerLoader.setAttribute("data-complete", "true"); window.setTimeout(function () { if (innerLoader && innerLoader.parentNode) innerLoader.parentNode.removeChild(innerLoader); }, 260); } function disconnect() { if (observer) observer.disconnect(); window.clearTimeout(releaseTimer); } function releaseReady() { if (finished) return; finished = true; disconnect(); hideInnerLoader(); html.classList.add("loe-critical-ready"); html.classList.remove("loe-critical-failed"); html.classList.remove("loe-critical-loading"); } function failOpen() { if (finished) return; finished = true; disconnect(); hideInnerLoader(); html.classList.add("loe-critical-failed"); html.classList.remove("loe-critical-ready"); html.classList.remove("loe-critical-loading"); } function landingIsReady() { return !!document.querySelector('#main-content .loe[data-ready="true"]'); } function delay(ms) { return new Promise(function (resolve) { window.setTimeout(resolve, ms); }); } function waitForCover(root) { var cover = root.querySelector(".loe__cover img"); if (!cover) return Promise.resolve(); var loaded = cover.complete ? Promise.resolve() : new Promise(function (resolve) { var timer = window.setTimeout(settle, 760); function settle() { window.clearTimeout(timer); cover.removeEventListener("load", settle); cover.removeEventListener("error", settle); resolve(); } cover.addEventListener("load", settle, { once: true }); cover.addEventListener("error", settle, { once: true }); }); return loaded.then(function () { if (typeof cover.decode !== "function") return; return Promise.race([cover.decode().catch(function () {}), delay(220)]); }); } function waitForHeroFonts() { if (!document.fonts || typeof document.fonts.load !== "function") { return Promise.resolve(); } return Promise.race([ Promise.all([ document.fonts.load("400 1em 'IBM Plex Sans Arabic'"), document.fonts.load("700 1em 'IBM Plex Sans Arabic'") ]).catch(function () {}), delay(680) ]); } function prepareLanding() { if (finished || preparing) return; var root = document.querySelector('#main-content .loe[data-ready="true"]'); if (!root) return; preparing = true; var minimumVisible = delay(Math.max(0, minimumVisibleMs - elapsed())); var heroReady = Promise.race([ Promise.all([waitForCover(root), waitForHeroFonts()]), delay(900) ]); Promise.all([minimumVisible, heroReady]) .then(releaseReady) .catch(failOpen); } function watchLanding() { if (landingIsReady()) { prepareLanding(); return; } observer = new MutationObserver(function () { if (landingIsReady()) prepareLanding(); }); observer.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ["data-ready"] }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", watchLanding, { once: true }); } else { watchLanding(); } /* Never trap the customer behind the loader if the component fails. */ window.setTimeout(failOpen, hardReleaseMs); /* A back-forward cache restore already has a painted, ready page. */ window.addEventListener("pageshow", function (event) { if (event.persisted) releaseReady(); }); })();