nodebb-plugin-ezoic-infinite 1.5.70 → 1.5.71

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.5.70",
3
+ "version": "1.5.71",
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
@@ -391,43 +391,53 @@
391
391
  const wraps = document.querySelectorAll(`.${WRAP_CLASS}.${kindClass}`);
392
392
  let removed = 0;
393
393
 
394
- wraps.forEach((wrap) => {
395
- let ok = false;
396
- // NodeBB/skins can insert helper nodes between posts (clearfix, separators, etc.).
397
- // Be tolerant so we don't remove a valid ad too early ("disappears too fast").
394
+ const isFilled = (wrap) => {
395
+ return !!(wrap.querySelector('iframe, ins, img, video, [data-google-container-id]'));
396
+ };
397
+
398
+ const hasNearbyItem = (wrap) => {
399
+ // NodeBB/skins can inject separators/spacers; be tolerant.
398
400
  let prev = wrap.previousElementSibling;
399
401
  for (let i = 0; i < 8 && prev; i++) {
400
- if (itemSet.has(prev)) { ok = true; break; }
402
+ if (itemSet.has(prev)) return true;
401
403
  prev = prev.previousElementSibling;
402
404
  }
403
-
404
- if (!ok) {
405
- let next = wrap.nextElementSibling;
406
- for (let i = 0; i < 3 && next; i++) {
407
- if (itemSet.has(next)) { ok = true; break; }
408
- next = next.nextElementSibling;
409
- }
405
+ let next = wrap.nextElementSibling;
406
+ for (let i = 0; i < 8 && next; i++) {
407
+ if (itemSet.has(next)) return true;
408
+ next = next.nextElementSibling;
410
409
  }
410
+ return false;
411
+ };
411
412
 
412
- if (!ok) {
413
- withInternalDomChange(() => releaseWrapNode(wrap));
414
- removed++;
415
- }
413
+ wraps.forEach((wrap) => {
414
+ if (isFilled(wrap)) return; // never prune filled ads
415
+ if (hasNearbyItem(wrap)) return;
416
+
417
+ withInternalDomChange(() => releaseWrapNode(wrap));
418
+ removed++;
416
419
  });
417
420
 
418
421
  return removed;
419
422
  }
420
423
 
421
424
  function decluster(kindClass) {
422
- // Remove consecutive wraps (keep the first)
425
+ // Remove "near-consecutive" wraps (keep the first). Be tolerant of spacer nodes.
423
426
  const wraps = Array.from(document.querySelectorAll(`.${WRAP_CLASS}.${kindClass}`));
424
427
  if (wraps.length < 2) return 0;
428
+
429
+ const isWrap = (el) => !!(el && el.classList && el.classList.contains(WRAP_CLASS));
430
+
425
431
  let removed = 0;
426
432
  for (const w of wraps) {
427
- const prev = w.previousElementSibling;
428
- if (prev && prev.classList && prev.classList.contains(WRAP_CLASS)) {
429
- withInternalDomChange(() => releaseWrapNode(w));
430
- removed++;
433
+ let prev = w.previousElementSibling;
434
+ for (let i = 0; i < 3 && prev; i++) {
435
+ if (isWrap(prev)) {
436
+ withInternalDomChange(() => releaseWrapNode(w));
437
+ removed++;
438
+ break;
439
+ }
440
+ prev = prev.previousElementSibling;
431
441
  }
432
442
  }
433
443
  return removed;
@@ -479,9 +489,6 @@
479
489
  if (!ph || !ph.isConnected) return;
480
490
  ph.setAttribute('data-ezoic-id', String(id));
481
491
 
482
- // When the ad actually fills, tighten height to the real iframe height and remove empty-collapsing.
483
- armFillObserver(ph);
484
-
485
492
  const io = ensurePreloadObserver();
486
493
  try { io && io.observe(ph); } catch (e) {}
487
494
 
@@ -494,56 +501,6 @@
494
501
  } catch (e) {}
495
502
  }
496
503
 
497
- // ---------------- fill tightening ----------------
498
-
499
- const _fillObserved = new WeakSet();
500
- function tightenFilled(ph) {
501
- if (!ph || !ph.isConnected) return;
502
- const wrap = ph.closest ? ph.closest(`.${WRAP_CLASS}`) : null;
503
- if (!wrap) return;
504
-
505
- // If we have any real ad content, we should not be in "empty" mode.
506
- const frame = ph.querySelector ? ph.querySelector('iframe') : null;
507
- const hasAd = !!(frame || (ph.querySelector && ph.querySelector('ins, img, .ez-ad, .ezoic-ad')));
508
- if (!hasAd) return;
509
-
510
- try { wrap.classList.remove('is-empty'); } catch (e) {}
511
-
512
- // Remove the common "extra reserved space" created by Ezoic's min-height styles.
513
- // Set minHeight to the actual iframe height when available.
514
- try {
515
- if (frame && frame.offsetHeight) {
516
- const h = frame.offsetHeight;
517
- const ezoicSpan = ph.closest ? ph.closest('span.ezoic-ad, .ezoic-ad') : null;
518
- if (ezoicSpan && ezoicSpan.style) {
519
- ezoicSpan.style.minHeight = `${h}px`;
520
- }
521
- // Also tighten the wrapper itself to avoid "space under" when the parent is taller.
522
- wrap.style.minHeight = `${h}px`;
523
- }
524
- } catch (e) {}
525
- }
526
-
527
- function armFillObserver(ph) {
528
- if (!ph || _fillObserved.has(ph)) return;
529
- _fillObserved.add(ph);
530
-
531
- // Fast path: already filled
532
- try { tightenFilled(ph); } catch (e) {}
533
-
534
- // Observe until it fills, then disconnect.
535
- try {
536
- const mo = new MutationObserver(() => {
537
- try {
538
- tightenFilled(ph);
539
- const hasFrame = !!(ph.querySelector && ph.querySelector('iframe'));
540
- if (hasFrame) mo.disconnect();
541
- } catch (e) {}
542
- });
543
- mo.observe(ph, { childList: true, subtree: true });
544
- } catch (e) {}
545
- }
546
-
547
504
  function enqueueShow(id) {
548
505
  if (!id || isBlocked()) return;
549
506
 
package/public/style.css CHANGED
@@ -22,10 +22,6 @@
22
22
  .nodebb-ezoic-wrap .ezoic-ad {
23
23
  margin: 0 !important;
24
24
  padding: 0 !important;
25
- /* Ezoic sometimes reserves extra height (e.g. min-height: 400px) even when the filled iframe is smaller.
26
- We prefer zero unused space; JS will also tighten after fill to the real iframe height. */
27
- min-height: 0 !important;
28
- height: auto !important;
29
25
  }
30
26
 
31
27
  /* Remove the classic "gap under iframe" (baseline/inline-block) */
@@ -66,3 +62,9 @@
66
62
  margin: 0 !important;
67
63
  padding: 0 !important;
68
64
  }
65
+ /* Remove Ezoic's large reserved min-height inside our wrappers (topics/messages) */
66
+ .nodebb-ezoic-wrap .ezoic-ad,
67
+ .nodebb-ezoic-wrap span.ezoic-ad {
68
+ min-height: 1px !important; /* kill 400px gaps */
69
+ height: auto !important;
70
+ }