← back to Interiordesignershowroom

public/js/imgfallback.js

25 lines

// Delegated <img> load-failure handler — replaces the inline `onerror=` on product
// card images so a strict `script-src 'self'` CSP (no 'unsafe-inline') can ship on the
// public storefront. Loaded SYNCHRONOUSLY in <head>, capture phase, on purpose:
// `error` events do NOT bubble and fire while the page is still loading, so the listener
// must be registered before any <body> image starts fetching or the early failures are
// missed. Scope + effect exactly mirror the old inline handler (img directly inside
// `.card-img` → hide it and mark the parent for the CSS fallback).
document.addEventListener('error', function (e) {
  var el = e.target;
  if (!el || el.tagName !== 'IMG') return;
  // server-rendered product card: hide + mark parent for the CSS fallback
  if (el.parentElement && el.parentElement.classList.contains('card-img')) {
    el.style.display = 'none';
    el.parentElement.classList.add('noimg-fallback');
    return;
  }
  // JS-rendered thumbs (build/moodboard) + server-rendered guide heroes / room scenes
  // opt in with data-hide-on-error. A missing room-scene hides its whole <figure> so the
  // hotspot layer doesn't float over an empty box (the roomThumbs rail beside it stays).
  if (el.hasAttribute('data-hide-on-error')) {
    var scope = (el.classList.contains('room-scene') && el.closest) ? el.closest('figure.room-scene-wrap') : null;
    (scope || el).style.display = 'none';
  }
}, true);