1(function () { 2 'use strict'; 3 4 var i18n = window.homepageI18n || {}; 5 var cfg = window.homepageConfig || {}; 6 7 /* âââ Pomocnicza - sprawdza czy img ma realny rozmiar âââââââ */ 8 function imageLooksVisible(img) { 9 var wAttr = parseInt(img.getAttribute('width') || '0', 10); 10 var hAttr = parseInt(img.getAttribute('height') || '0', 10); 11 var w = Math.max(img.clientWidth || 0, img.naturalWidth || 0, isNaN(wAttr) ? 0 : wAttr); 12 var h = Math.max(img.clientHeight || 0, img.naturalHeight || 0, isNaN(hAttr) ? 0 : hAttr); 13 return w > 1 && h > 1; 14 } 15 16 /* âââ Czy kontener reklamowy zawiera widocznÄ kreacjÄ ââââââââ */ 17 function hasRenderableCreative(container) { 18 if (container.querySelector('iframe, object, embed, video')) return true; 19 20 var links = container.querySelectorAll('a[href]'); 21 for (var i = 0; i < links.length; i++) { 22 var a = links[i]; 23 var href = (a.getAttribute('href') || '').trim(); 24 var aText = (a.textContent || '').trim(); 25 var aImg = a.querySelector('img'); 26 if (href !== '' && aImg && imageLooksVisible(aImg)) return true; 27 if (href !== '' && aText.length > 0) return true; 28 } 29 30 var imgs = container.querySelectorAll('img'); 31 for (var j = 0; j < imgs.length; j++) { 32 var img = imgs[j]; 33 var inBeacon = !!img.closest('[id^="beacon_"]'); 34 if (!inBeacon && imageLooksVisible(img)) return true; 35 } 36 37 return false; 38 } 39 40 /* âââ Czy Revive zwróciÅ jawny no-fill âââââââââââââââââââââââ */ 41 function isExplicitNoFill(container) { 42 var html = (container.innerHTML || '').toLowerCase(); 43 return html.indexOf('bannerid=0') !== -1 || html.indexOf('campaignid=0') !== -1; 44 } 45 46 /** 47 * Po zakoÅczeniu async Revive ustawia na <ins> m.in. data-revive-loaded="1". 48 * Przy braku kreacji w kontenerze traktujemy to jako brak emisji (jak na LB w sekcjach). 49 */ 50 function isReviveFinishedWithoutCreative(banner) { 51 var ins = banner.querySelector('ins[data-revive-zoneid]'); 52 if (!ins || ins.getAttribute('data-revive-loaded') !== '1') return false; 53 return !hasRenderableCreative(banner); 54 } 55 56 /* Po tym czasie ukrywamy karty nadal bez kreacji (unikamy âpustychâ 510px). */ 57 var adSlotAuditDeadline = Date.now() + 20000; 58 59 /* âââ Ukrywa puste sloty reklamowe w siatce ââââââââââââââââââ */ 60 function hideEmptyAdSlots() { 61 var slots = document.querySelectorAll('.cards-grid .card-special--ad'); 62 if (!slots.length) return; 63 64 var pastAuditDeadline = Date.now() >= adSlotAuditDeadline; 65 66 // FAZA 1: wyÅÄ cznie odczyty (pomiary layoutu) - bez żadnych zmian DOM/style 67 var decisions = []; 68 slots.forEach(function (slot) { 69 var banner = slot.querySelector('.card-special__ad-banner'); 70 if (!banner) { decisions.push(null); return; } 71 var hasCreative = hasRenderableCreative(banner); 72 var noFill = isExplicitNoFill(banner) 73 || isReviveFinishedWithoutCreative(banner); 74 decisions.push({ 75 slot: slot, 76 hasCreative: hasCreative, 77 noFill: noFill, 78 hideAsEmpty: hasCreative ? false : (noFill || pastAuditDeadline), 79 }); 80 }); 81 82 // FAZA 2: klasa BEM (display w CSS) â bez inline style 83 decisions.forEach(function (d) { 84 if (!d) return; 85 if (d.hideAsEmpty) { 86 d.slot.classList.add('card-special--ad-empty'); 87 } else { 88 d.slot.classList.remove('card-special--ad-empty'); 89 } 90 }); 91 zoneDebugUpdateRuntime(); 92 } 93 94 /* âââ Audyt co ~1 s + obserwator DOM (późne wstrzykniÄcia Revive) â */ 95 function scheduleAdSlotAudit() { 96 var runs = 0; 97 var maxRuns = 20; 98 hideEmptyAdSlots(); 99 var timer = setInterval(function () { 100 hideEmptyAdSlots(); 101 runs++; 102 if (runs >= maxRuns) clearInterval(timer); 103 }, 1000); 104 } 105 106 var cardsGrid = document.querySelector('.cards-grid'); 107 if (cardsGrid && typeof MutationObserver !== 'undefined') { 108 var adGridObserver = new MutationObserver(function () { 109 hideEmptyAdSlots(); 110 }); 111 adGridObserver.observe(cardsGrid, { childList: true, subtree: true }); 112 } 113 114 function zoneDebugUpdateRuntime() { 115 if (!window.homepageZoneDebug) return; 116 var rows = document.querySelectorAll('#zone-debug-placements .zone-debug__row'); 117 rows.forEach(function (row) { 118 var cell = row.querySelector('.zone-debug__runtime'); 119 if (!cell) return; 120 var kind = row.getAttribute('data-zone-debug-row'); 121 var msg = 'â'; 122 if (kind === 'special-ad') { 123 var si = row.getAttribute('data-slot-index'); 124 var el = document.querySelector('.cards-grid .card-special--ad[data-slot-index="' + si + '"]'); 125 if (!el) { 126 msg = 'brak w DOM'; 127 } else if (el.classList.contains('card-special--ad-empty')) { 128 msg = 'ukryta (pusto)'; 129 } else { 130 var ban = el.querySelector('.card-special__ad-banner'); 131 if (ban && hasRenderableCreative(ban)) msg = 'kreacja w DOM'; 132 else { 133 var ins = ban && ban.querySelector('ins[data-revive-zoneid]'); 134 if (ins && ins.getAttribute('data-revive-loaded') === '1') msg = 'Revive: brak fill'; 135 else msg = 'oczek./Åadowanie'; 136 } 137 } 138 } else if (kind === 'leaderboard') { 139 var lbi = row.getAttribute('data-lb-index'); 140 var lb = document.querySelector('.cards-grid .grid-leaderboard[data-lb-index="' + lbi + '"]'); 141 if (!lb) msg = 'brak w DOM'; 142 else if (!lb.classList.contains('grid-leaderboard--visible')) msg = 'ukryta'; 143 else { 144 var sl = lb.querySelector('.grid-leaderboard__slot'); 145 if (sl && hasRenderableCreative(sl) && !isExplicitNoFill(sl)) msg = 'kreacja w DOM'; 146 else msg = 'slot pusty / Åadowanie'; 147 } 148 } else if (kind === 'mobile-b0') { 149 var b0 = document.querySelector('.cards-grid .revive-home-b0'); 150 if (!b0) msg = 'brak w DOM'; 151 else { 152 var vw = window.innerWidth || 0; 153 if (vw > 680) msg = 'ukryta (viewport > 680px)'; 154 else { 155 var b0sl = b0.querySelector('.revive-home-b0__slot'); 156 if (b0sl && hasRenderableCreative(b0sl)) msg = 'kreacja w DOM'; 157 else { 158 var b0ins = b0sl && b0sl.querySelector('ins[data-revive-zoneid]'); 159 if (b0ins && b0ins.getAttribute('data-revive-loaded') === '1') msg = 'Revive: brak fill'; 160 else msg = 'oczek./Åadowanie'; 161 } 162 } 163 } 164 } 165 cell.textContent = msg; 166 }); 167 } 168 169 function zoneDebugInit() { 170 if (!window.homepageZoneDebug) return; 171 var panel = document.getElementById('zone-debug-panel'); 172 var toggle = document.getElementById('zone-debug-toggle'); 173 if (toggle && panel) { 174 toggle.addEventListener('click', function () { 175 var collapsed = panel.classList.toggle('zone-debug--collapsed');
176 toggle.textContent = collapsed ? 'RozwiÅ' : 'ZwiÅ'; 177 toggle.setAttribute('aria-expanded', collapsed ? 'false' : 'true'); 178 }); 179 } 180 zoneDebugUpdateRuntime(); 181 var zr = 0; 182 var zt = setInterval(function () { 183 zoneDebugUpdateRuntime(); 184 zr++; 185 if (zr >= 25) clearInterval(zt); 186 }, 1000); 187 if (cardsGrid && typeof MutationObserver !== 'undefined') { 188 var zmo = new MutationObserver(function () { zoneDebugUpdateRuntime(); }); 189 zmo.observe(cardsGrid, { 190 childList: true, 191 subtree: true, 192 attributes: true, 193 attributeFilter: ['class', 'data-revive-loaded', 'style'], 194 }); 195 } 196 } 197 198 /* âââ Audyt pollujÄ cy leaderboardów (analogiczny do slotów w sekcjach) â 199 * DomyÅlny stan CSS `.grid-leaderboard` to display:none â klasa 200 * `--visible` pokazuje slot. Pokazujemy go DOPIERO po potwierdzeniu 201 * realnej kreacji; dopóki Revive nie skoÅczyÅ, slot zostaje schowany 202 * (brak pustego migotania). Gdy kampania wygasÅa (Revive skoÅczyÅ bez 203 * kreacji) lub minÄ Å deadline â slot pozostaje ukryty. Bez pÄtli stan 204 * z jednej klatki nigdy nie byÅ rewidowany â pusty slot zostawaÅ. */ 205 function auditGridLeaderboards(lbChecks) { 206 if (!lbChecks || !lbChecks.length) { zoneDebugUpdateRuntime(); return; } 207 208 function pass() { 209 var pastDeadline = Date.now() >= adSlotAuditDeadline; 210 var allResolved = true; 211 lbChecks.forEach(function (item) { 212 if (hasRenderableCreative(item.el) && !isExplicitNoFill(item.el)) { 213 item.lb.classList.add('grid-leaderboard--visible'); 214 return; 215 } 216 // brak kreacji â chowamy; jeÅli to jeszcze nie no-fill i nie po 217 // deadline, rewidujemy w kolejnym cyklu (Revive może domknÄ Ä render). 218 item.lb.classList.remove('grid-leaderboard--visible'); 219 var resolvedEmpty = isExplicitNoFill(item.el) 220 || isReviveFinishedWithoutCreative(item.el) 221 || pastDeadline; 222 if (!resolvedEmpty) allResolved = false; 223 }); 224 zoneDebugUpdateRuntime(); 225 return allResolved; 226 } 227 228 if (pass()) return; 229 var runs = 0; 230 var maxRuns = 20; 231 var timer = setInterval(function () { 232 runs++; 233 if (pass() || runs >= maxRuns) clearInterval(timer); 234 }, 1000); 235 } 236 237 /* âââ Leaderboardy (reklamy poziome miÄdzy kartami) ââââââââââ */ 238 function loadLeaderboards(root) { 239 var scope = root || document; 240 var slots = scope.querySelectorAll('.grid-leaderboard .grid-leaderboard__slot[data-lb-zone]'); 241 if (!slots.length) return; 242 243 var server = (cfg.reviveServer || '').replace(/\/$/, ''); 244 if (!server) return; 245 246 var zones = [], lbMap = {}; 247 248 slots.forEach(function (el) { 249 var lb = el.closest('.grid-leaderboard'); 250 if (!lb || lb.getAttribute('data-lb-loaded') === '1') return; 251 252 var z = el.getAttribute('data-lb-zone'); 253 if (!z || z === '0') return; 254 var seq = zones.length; 255 zones.push(z); 256 lbMap[seq] = el; 257 lb.setAttribute('data-lb-loaded', '1'); 258 }); 259 260 if (!zones.length) return; 261 262 var url = server + '/delivery/asyncspc.php' 263 + '?zones=' + zones.join('%7C') 264 + '&prefix=lb-' 265 + '&loc=' + encodeURIComponent(location.href) 266 + '&strona=index' 267 + '&urlreg=' + encodeURIComponent(location.pathname) 268 + '&cb=' + Math.floor(Math.random() * 1e9); 269 270 fetch(url) 271 .then(function (r) { return r.json(); }) 272 .then(function (data) { 273 // FAZA 1: wszystkie zapisy innerHTML (DOM write) 274 var lbChecks = []; 275 Object.keys(lbMap).forEach(function (seq) { 276 var el = lbMap[seq]; 277 var lb = el.closest('.grid-leaderboard'); 278 var key = 'lb-' + seq; 279 var d = data[key]; 280 if (d && d.html && d.html.indexOf('bannerid=0') === -1) { 281 el.innerHTML = d.html; 282 lbChecks.push({ el: el, lb: lb }); 283 } else { 284 lb.classList.remove('grid-leaderboard--visible'); 285 } 286 });
287 // FAZA 2: audyt pollujÄ cy (jak sloty w sekcjach) â pojedyncza klatka 288 // nie wystarcza: Revive po wygaÅniÄciu kampanii zwraca wrapper/beacon 289 // bez `bannerid=0`, a obrazkowa kreacja ma chwilowo naturalWidth=0. 290 auditGridLeaderboards(lbChecks); 291 }) 292 .catch(function () { 293 Object.keys(lbMap).forEach(function (seq) { 294 var lb = lbMap[seq].closest('.grid-leaderboard'); 295 if (lb) lb.classList.remove('grid-leaderboard--visible'); 296 }); 297 }); 298 } 299 300 loadLeaderboards(); 301 302 scheduleAdSlotAudit(); 303 304 zoneDebugInit(); 305 306 /* âââ Load More âââââââââââââââââââââââââââââââââââââââââââââââ */ 307 (function () { 308 var btn = document.getElementById('load-more-btn'); 309 if (!btn) return; 310 var grid = document.querySelector('.cards-grid'); 311 if (!grid) return; 312 313 btn.addEventListener('click', function () { 314 var offset = parseInt(btn.getAttribute('data-offset') || '0', 10); 315 var startPos = parseInt(btn.getAttribute('data-start-pos') || '1', 10); 316 var cardCount = parseInt(btn.getAttribute('data-card-count') || '0', 10); 317 if (isNaN(offset) || offset < 1) return; 318 319 btn.disabled = true; 320 btn.classList.add('loading'); 321 btn.textContent = i18n.loading || ''; 322 323 var xhr = new XMLHttpRequest(); 324 xhr.open('GET', '/?ajax=1&offset=' + offset + '&start_pos=' + startPos + '&card_count_start=' + cardCount); 325 326 xhr.onload = function () { 327 if (xhr.status !== 200) { 328 btn.disabled = false; 329 btn.classList.remove('loading'); 330 btn.textContent = i18n.loadMore || ''; 331 return; 332 } 333 334 var frag = document.createElement('div'); 335 frag.innerHTML = xhr.responseText; 336 var meta = frag.querySelector('#load-more-meta'); 337 var items = frag.querySelectorAll('article, .card-special, .grid-leaderboard'); 338 items.forEach(function (el) { grid.appendChild(el); }); 339 340 if (window.reviveAsync) { 341 Object.keys(window.reviveAsync).forEach(function (id) { 342 var ra = window.reviveAsync[id]; 343 if (ra && typeof ra.dispatchEvent === 'function') ra.dispatchEvent('refresh'); 344 }); 345 } 346 347 loadLeaderboards(grid); 348 scheduleAdSlotAudit(); 349 zoneDebugUpdateRuntime(); 350 351 if (meta) { 352 try { 353 var d = JSON.parse(meta.textContent); 354 btn.setAttribute('data-offset', d.nextOffset); 355 btn.setAttribute('data-start-pos', d.nextStartPos); 356 btn.setAttribute('data-card-count', d.nextCardCount); 357 if (!d.hasMore) { 358 if (d.archiveUrl && btn.parentNode) { 359 var archiveLink = document.createElement('a'); 360 archiveLink.href = d.archiveUrl; 361 archiveLink.className = 'btn-load-more btn-load-more--archive'; 362 archiveLink.textContent = d.archiveLabel || i18n.loadMore || ''; 363 btn.parentNode.replaceChild(archiveLink, btn); 364 } else if (btn.parentNode) { 365 btn.parentNode.removeChild(btn); 366 } 367 return; 368 } 369 } catch (e) {} 370 } 371 372 btn.disabled = false; 373 btn.classList.remove('loading'); 374 btn.textContent = i18n.loadMore || ''; 375 }; 376 377 xhr.onerror = function () { 378 btn.disabled = false; 379 btn.classList.remove('loading'); 380 btn.textContent = i18n.loadMore || ''; 381 }; 382 383 xhr.send(); 384 }); 385 }()); 386 387}());
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.