← back to CelebritySignatures

public/assets/ads.js

54 lines

/* Reserved ad-zone activator for CelebritySignatures.
 * Zones sit in the page as <div class="ad-zone" data-ad-zone="gallery|article|game">.
 * They render NOTHING until their per-zone data-ad-slot id is configured server-side
 * (window.__ADSLOTS, populated from env once the site is AdSense-approved). This keeps
 * the pre-approval site clean (no empty gaps) and, once live, reserves height so the
 * ad load causes zero layout shift (CLS). "Advertisement" label per AdSense policy. */
(function () {
  var pub = window.__ADPUB, slots = window.__ADSLOTS || {};
  if (!pub) return;
  // reserved minimum heights by zone (auto ads grow past this; the floor kills CLS)
  var MINH = { gallery: 100, article: 250, game: 120 };
  // inject scoped styles once
  var css = document.createElement('style');
  css.textContent =
    '.ad-zone{display:none}' +
    '.ad-zone.ad-ready{display:block;margin:26px auto;max-width:970px;padding:0 16px;text-align:center}' +
    '.ad-zone.ad-ready>.ad-label{font:600 10px/1 -apple-system,sans-serif;letter-spacing:.12em;text-transform:uppercase;color:#b3ada3;margin-bottom:6px}' +
    '.ad-zone.ad-ready>ins{display:block}';
  document.head.appendChild(css);

  // preview mode: /?adpreview=1 renders a labeled placeholder box at every zone
  // (dashed, reserved height) so placement is visible WITHOUT slot ids/approval.
  var PREVIEW = /[?&]adpreview=1/.test(location.search);
  var LABELS = { gallery: 'Ad space · below hero / above gallery', article: 'Ad space · in-article (best inventory)', game: 'Ad space · game results' };

  function activate(zone) {
    var key = zone.getAttribute('data-ad-zone');
    if (PREVIEW) {
      zone.style.minHeight = (MINH[key] || 100) + 'px';
      zone.innerHTML = '<div class="ad-label">Advertisement</div>' +
        '<div style="display:flex;align-items:center;justify-content:center;min-height:' + (MINH[key] || 100) + 'px;border:2px dashed #cfc7ba;border-radius:8px;background:repeating-linear-gradient(45deg,#faf8f4,#faf8f4 10px,#f3efe8 10px,#f3efe8 20px);color:#9a9384;font:600 13px/1.5 -apple-system,sans-serif;text-align:center;padding:12px">' + (LABELS[key] || key) + '<br><span style="font-weight:400;font-size:11px">(placeholder — real ad appears here once approved)</span></div>';
      zone.classList.add('ad-ready');
      return;
    }
    var slot = slots[key];
    if (!slot || !/^\d{6,}$/.test(slot)) return; // no real slot id yet → stay hidden
    zone.style.minHeight = (MINH[key] || 100) + 'px';
    var label = document.createElement('div'); label.className = 'ad-label'; label.textContent = 'Advertisement';
    var ins = document.createElement('ins');
    ins.className = 'adsbygoogle';
    ins.style.display = 'block';
    ins.setAttribute('data-ad-client', pub);
    ins.setAttribute('data-ad-slot', slot);
    ins.setAttribute('data-ad-format', 'auto');
    ins.setAttribute('data-full-width-responsive', 'true');
    zone.appendChild(label); zone.appendChild(ins);
    zone.classList.add('ad-ready');
    try { (window.adsbygoogle = window.adsbygoogle || []).push({}); } catch (e) { /* loader not ready yet */ }
  }

  function run() { Array.prototype.forEach.call(document.querySelectorAll('.ad-zone[data-ad-zone]'), activate); }
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run); else run();
})();