import { isTinyPlaceholderSrc } from "../shared/image-src.js"; const HOST_SELECTOR = ".case-media, .case-media-gallery__item, .case-link-card__media, .case-media-tall__clip, .mp-card__media, .portfolio-card__cover, figure"; const EXCLUDE_ANCESTOR = ".contact-card__icon, .cookie-notice, .case-image-viewer, .case-media-slider, [data-no-img-placeholder]"; function shouldWatch(img) { if (!(img instanceof HTMLImageElement)) return false; if (img.closest(EXCLUDE_ANCESTOR) || img.hasAttribute("data-no-img-placeholder")) return false; const src = (img.getAttribute("src") || "").toLowerCase(); if (src.endsWith(".svg")) return false; const w = Number(img.getAttribute("width")); const h = Number(img.getAttribute("height")); if (w > 0 && h > 0 && Math.max(w, h) <= 40) return false; return true; } function isPending(img) { if (img.hasAttribute("data-src") || img.hasAttribute("data-defer-src")) return true; const src = img.currentSrc || img.getAttribute("src") || ""; if (isTinyPlaceholderSrc(src)) return true; return !img.complete || img.naturalWidth === 0; } function getHost(img) { const host = img.closest(HOST_SELECTOR); if (host) return host; const parent = img.parentElement; if (parent && parent !== document.body && parent !== document.documentElement) return parent; return null; } function setLoading(img, loading) { const host = getHost(img); if (!host) return; if (loading) { img.classList.add("is-img-loading"); host.classList.add("has-img-loading"); } else { img.classList.remove("is-img-loading"); if (!host.querySelector("img.is-img-loading")) host.classList.remove("has-img-loading"); } } function syncImage(img) { if (!shouldWatch(img)) { setLoading(img, false); return; } setLoading(img, isPending(img)); } function bindImage(img) { if (!shouldWatch(img)) return; if (img.dataset.imgLoadPhBound === "1") { syncImage(img); return; } img.dataset.imgLoadPhBound = "1"; const onChange = () => syncImage(img); img.addEventListener("load", onChange); img.addEventListener("error", onChange); const mo = new MutationObserver(onChange); mo.observe(img, { attributes: true, attributeFilter: ["src", "data-src", "data-defer-src"] }); syncImage(img); } export function initImageLoadPlaceholder() { document.querySelectorAll("img").forEach(bindImage); }