nodebb-plugin-ezoic-infinite 1.5.24 → 1.5.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/public/client.js +50 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.5.24",
3
+ "version": "1.5.25",
4
4
  "description": "Production-ready Ezoic infinite ads integration for NodeBB 4.x",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -48,6 +48,16 @@
48
48
 
49
49
  const insertingIds = new Set();
50
50
 
51
+ // Debug logs (enable with localStorage.ezoicInfiniteDebug = "1")
52
+ function dbg(...args) {
53
+ try {
54
+ if (window && window.localStorage && window.localStorage.getItem('ezoicInfiniteDebug') === '1') {
55
+ // eslint-disable-next-line no-console
56
+ console.log('[ezoicInfinite]', ...args);
57
+ }
58
+ } catch (e) {}
59
+ }
60
+
51
61
  // ---------- small utils ----------
52
62
 
53
63
  function normalizeBool(v) {
@@ -274,6 +284,34 @@
274
284
  return null;
275
285
  }
276
286
 
287
+
288
+ function removeOneOldWrap(kindClass) {
289
+ try {
290
+ const wraps = Array.from(document.querySelectorAll(`.${WRAP_CLASS}.${kindClass}`));
291
+ if (!wraps.length) return false;
292
+
293
+ // Prefer a wrap far above the viewport
294
+ let victim = null;
295
+ for (const w of wraps) {
296
+ const r = w.getBoundingClientRect();
297
+ if (r.bottom < -2000) { victim = w; break; }
298
+ }
299
+ // Otherwise remove the earliest one in the document
300
+ if (!victim) victim = wraps[0];
301
+
302
+ // Unobserve placeholder if still observed
303
+ try {
304
+ const ph = victim.querySelector && victim.querySelector(`[id^="${PLACEHOLDER_PREFIX}"]`);
305
+ if (ph && state.io) state.io.unobserve(ph);
306
+ } catch (e) {}
307
+
308
+ victim.remove();
309
+ return true;
310
+ } catch (e) {
311
+ return false;
312
+ }
313
+ }
314
+
277
315
  function showAd(id) {
278
316
  if (!id || EZOIC_BLOCKED) return;
279
317
 
@@ -373,7 +411,13 @@
373
411
  if (isAdjacentAd(el)) continue;
374
412
  if (findWrap(kindClass, afterPos)) continue;
375
413
 
376
- const id = pickIdFromAll(allIds, cursorKey);
414
+ let id = pickIdFromAll(allIds, cursorKey);
415
+ if (!id) {
416
+ // No free ids: recycle an old ad wrapper so we can reuse its placeholder id
417
+ const recycled = removeOneOldWrap(kindClass);
418
+ dbg('recycle-needed', kindClass, { recycled, ids: allIds.length });
419
+ id = pickIdFromAll(allIds, cursorKey);
420
+ }
377
421
  if (!id) break;
378
422
  const wrap = insertAfter(el, id, kindClass, afterPos);
379
423
  if (!wrap) {
@@ -390,7 +434,8 @@
390
434
  async function insertHeroAdEarly() {
391
435
  if (state.heroDoneForPage) return;
392
436
  const cfg = await fetchConfigOnce();
393
- if (!cfg || cfg.excluded) return;
437
+ if (!cfg) { dbg('no-config'); return; }
438
+ if (cfg.excluded) { dbg('excluded'); return; }
394
439
 
395
440
  initPools(cfg);
396
441
 
@@ -446,12 +491,13 @@
446
491
  }
447
492
 
448
493
  async function runCore() {
449
- if (EZOIC_BLOCKED) return;
494
+ if (EZOIC_BLOCKED) { dbg('blocked'); return; }
450
495
 
451
496
  patchShowAds();
452
497
 
453
498
  const cfg = await fetchConfigOnce();
454
- if (!cfg || cfg.excluded) return;
499
+ if (!cfg) { dbg('no-config'); return; }
500
+ if (cfg.excluded) { dbg('excluded'); return; }
455
501
  initPools(cfg);
456
502
 
457
503
  const kind = getKind();