PageSourceSearch

https://fourstarpizzaploiesti.ro/js/consent.js

js fourstarpizzaploiesti.ro collected 2026-10-02 01:08:10 UTC 9,970 bytes, 221 lines download raw bytes

1/**
2 * Four Star Pizza – Custom Cookie Consent Banner
3 * Înlocuiește CookieYes. Nu are dependențe externe.
4 *
5 * Cookie stocat: fsp_consent  (valoare JSON, 365 zile)
6 * {analytics: true|false, marketing: true|false}
7 *
8 * Eveniment custom: fsp_consent_update — fired pe document după orice decizie
9 */
10(function () {
11  'use strict';
12
13  var COOKIE_NAME = 'fsp_consent';
14  var COOKIE_DAYS = 365;
15
16  // ── helpers ──────────────────────────────────────────────────────────────
17
18  function setCookie(name, value, days) {
19    var d = new Date();
20    d.setTime(d.getTime() + days * 864e5);
21    document.cookie = name + '=' + encodeURIComponent(JSON.stringify(value)) +
22      '; expires=' + d.toUTCString() + '; path=/; SameSite=Lax';
23  }
24
25  function getCookie(name) {
26    var match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]+)'));
27    if (!match) return null;
28    try { return JSON.parse(decodeURIComponent(match[1])); } catch (e) { return null; }
29  }
30
31  function fireConsentEvent(consent) {
32    try {
33      document.dispatchEvent(new CustomEvent('fsp_consent_update', { detail: consent }));
34    } catch (e) { /* IE fallback */ }
35  }
36
37  // ── public API ───────────────────────────────────────────────────────────
38
39  window.getFspConsent = function () {
40    return getCookie(COOKIE_NAME);
41  };
42
43  window.fspAcceptAll = function () {
44    var c = { analytics: true, marketing: true, necessary: true };
45    setCookie(COOKIE_NAME, c, COOKIE_DAYS);
46    fireConsentEvent(c);
47    hideBanner();
48  };
49
50  window.fspRejectAll = function () {
51    var c = { analytics: false, marketing: false, necessary: true };
52    setCookie(COOKIE_NAME, c, COOKIE_DAYS);
53    fireConsentEvent(c);
54    hideBanner();
55  };
56
57  window.fspSavePreferences = function () {
58    var analyticsBox = document.getElementById('fsp-toggle-analytics');
59    var marketingBox = document.getElementById('fsp-toggle-marketing');
60    var c = {
61      analytics: analyticsBox ? analyticsBox.checked : false,
62      marketing: marketingBox ? marketingBox.checked : false,
63      necessary: true
64    };
65    setCookie(COOKIE_NAME, c, COOKIE_DAYS);
66    fireConsentEvent(c);
67    hideBanner();
68  };
69
70  // ── banner DOM ───────────────────────────────────────────────────────────
71
72  var bannerResizeObserver = null;
73
74  // Bannerul e position:fixed peste conținut — fără padding rezervat pe body,
75  // acoperă orice cade în ultimii ~100-150px din viewport (ex. linia WhatsApp
76  // din contact.html). Rezervăm padding-bottom = înălțimea reală a bannerului,
77  // recalculat automat la orice schimbare de dimensiune (inclusiv când se
78  // deschide panoul "Personalizează", care crește bannerul).
79  function reserveSpaceFor(el) {
80    document.body.style.paddingBottom = el.offsetHeight + 'px';
81    if (typeof ResizeObserver !== 'undefined') {
82      bannerResizeObserver = new ResizeObserver(function () {
83        document.body.style.paddingBottom = el.offsetHeight + 'px';
84      });
85      bannerResizeObserver.observe(el);
86    }
87  }
88
89  function hideBanner() {
90    var el = document.getElementById('fsp-consent-banner');
91    if (el) {
92      if (bannerResizeObserver) {
93        bannerResizeObserver.disconnect();
94        bannerResizeObserver = null;
95      }
96      document.body.style.paddingBottom = '';
97      el.style.transition = 'opacity .25s ease, transform .25s ease';
98      el.style.opacity = '0';
99      el.style.transform = 'translateY(8px)';
100      setTimeout(function () { if (el.parentNode) el.parentNode.removeChild(el); }, 280);
101    }
102  }
103
104  function buildBanner() {
105    var banner = document.createElement('div');
106    banner.id = 'fsp-consent-banner';
107    banner.setAttribute('role', 'dialog');
108    banner.setAttribute('aria-modal', 'false');
109    banner.setAttribute('aria-label', 'Setări cookie');
110    banner.innerHTML = [
111      '<div class="fsp-cb-inner">',
112      '  <div class="fsp-cb-text">',
113      '    <p>🍪 Folosim cookie-uri pentru navigare, analiză și marketing. <a href="/politica-cookies.html">Detalii</a></p>',
114      '  </div>',
115      '  <div class="fsp-cb-actions">',
116      '    <button class="fsp-btn fsp-btn-outline" onclick="fspRejectAll()">Respinge</button>',
117      '    <button class="fsp-btn fsp-btn-primary" onclick="fspAcceptAll()">Acceptă tot</button>',
118      '    <button class="fsp-btn-link" id="fsp-btn-customize" aria-expanded="false" aria-controls="fsp-preferences">
118Personalizează</button>',
119      '  </div>',
120      '  <div id="fsp-preferences" class="fsp-prefs" hidden>',
121      '    <div class="fsp-pref-row">',
122      '      <label><input type="checkbox" id="fsp-toggle-necessary" checked disabled> <span>Necesare</span></label>',
123      '      <small>Esențiale pentru funcționarea site-ului (coș, sesiune). Nu pot fi dezactivate.</small>',
124      '    </div>',
125      '    <div class="fsp-pref-row">',
126      '      <label><input type="checkbox" id="fsp-toggle-analytics"> <span>Analiză (Google Analytics)</span></label>',
127      '      <small>Ne ajută să înțelegem cum folosești site-ul, în mod anonim.</small>',
128      '    </div>',
129      '    <div class="fsp-pref-row">',
130      '      <label><input type="checkbox" id="fsp-toggle-marketing"> <span>Marketing (Facebook Pixel)</span></label>',
131      '      <small>Folosit pentru reclame relevante pe rețele sociale.</small>',
132      '    </div>',
133      '    <div class="fsp-pref-save">',
134      '      <button class="fsp-btn fsp-btn-primary" onclick="fspSavePreferences()">Salvează preferințele</button>',
135      '    </div>',
136      '  </div>',
137      '</div>'
138    ].join('\n');
139
140    // toggle preferences panel
141    var customizeBtn = banner.querySelector('#fsp-btn-customize');
142    customizeBtn.addEventListener('click', function () {
143      var panel = document.getElementById('fsp-preferences');
144      var open = !panel.hidden;
145      panel.hidden = open;
146      customizeBtn.setAttribute('aria-expanded', String(!open));
147    });
148
149    return banner;
150  }
151
152  function injectStyles() {
153    if (document.getElementById('fsp-consent-style')) return;
154    var s = document.createElement('style');
155    s.id = 'fsp-consent-style';
156    s.textContent = [
157      '#fsp-consent-banner{',
158      '  position:fixed;bottom:0;left:0;right:0;z-index:99999;',
159      '  background:var(--bg,#00558b);color:#fff;',
160      '  border-top:2px solid var(--brand,#e11d48);',
161      '  box-shadow:0 -4px 24px rgba(0,0,0,.45);',
162      '  font-family:Inter,system-ui,sans-serif;font-size:14px;line-height:1.5;',
163      '}',
164      '.fsp-cb-inner{',
165      '  max-width:1120px;margin:0 auto;padding:10px 16px;',
166      '  display:flex;flex-wrap:wrap;align-items:center;gap:10px;',
167      '}',
168      '.fsp-cb-text{flex:1 1 240px;}',
169      '.fsp-cb-text p{margin:0;color:#fff;font-size:13px;opacity:.95;line-height:1.4;}',
170      '.fsp-cb-text a{color:#b3daff;text-decoration:underline;font-weight:500;}',
171      '.fsp-cb-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;}',
172      '.fsp-btn{',
173      '  padding:7px 14px;border-radius:8px;font-size:13px;font-weight:600;',
174      '  cursor:pointer;border:0;white-space:nowrap;transition:opacity .15s;',
175      '}',
176      '.fsp-btn:hover{opacity:.8;}',
177      '.fsp-btn-primary{background:var(--brand,#e11d48);color:#fff;}',
178      '.fsp-btn-outline{background:rgba(255,255,255,.1);color:var(--text,#e6e6e6);border:1px solid rgba(255,255,255,.3);}',
179      '.fsp-btn-link{',
180      '  background:none;border:0;padding:4px 2px;color:#b3daff;font-size:12px;',
181      '  text-decoration:underline;cursor:pointer;white-space:nowrap;',
182      '}',
183      '#fsp-preferences{width:100%;border-top:1px solid rgba(255,255,255,.15);margin-top:10px;padding-top:12px;',
184      '  display:flex;flex-wrap:wrap;gap:16px;}',
185      '#fsp-preferences[hidden]{display:none !important;}',
186      '.fsp-pref-row{flex:1 1 200px;background:rgba(0,0,0,.15);border-radius:8px;padding:10px 12px;}',
187      '.fsp-pref-row label{display:flex;align-items:center;gap:8px;font-weight:600;cursor:pointer;color:var(--text,#e6e6e6);}',
188      '.fsp-pref-row small{display:block;color:var(--muted,#cde);font-size:12px;margin-top:4px;opacity:.8;}',
189      '.fsp-pref-save{width:100%;display:flex;justify-content:flex-end;margin-top:8px;}',
190      '@media(max-width:640px){',
191      '  .fsp-cb-inner{flex-direction:column;align-items:stretch;padding:8px 12px;gap:6px;}',
192      '  .fsp-cb-text{flex:none;}',
193      '  .fsp-cb-text p{font-size:12px;}',
194      '  .fsp-cb-actions{justify-content:center;flex-wrap:wrap;}',
195      '  .fsp-btn{flex:1 1 auto;text-align:center;min-width:100px;}',
196      '  .fsp-btn-link{flex:0 0 100%;text-align:center;}',
197      '  .fsp-pref-row{flex:1 1 100%;}',
198      '}'
199    ].join('');
200    document.head.appendChild(s);
201  }
202
203  // ── init ─────────────────────────────────────────────────────────────────
204
205  function init() {
206    // Dacă există deja consimțământul, nu afișăm bara
207    if (getCookie(COOKIE_NAME) !== null) return;
208
209    injectStyles();
210    var banner = buildBanner();
211    // Adaugă în body — dar nu blochează LCP (adăugat după DOMContentLoaded)
212    document.body.appendChild(banner);
213    reserveSpaceFor(banner);
214  }
215
216  if (document.readyState === 'loading') {
217    document.addEventListener('DOMContentLoaded', init);
218  } else {
219    init();
220  }
221})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.