nodebb-plugin-ezoic-infinite 1.6.69 → 1.6.70

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 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.6.69",
3
+ "version": "1.6.70",
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
@@ -232,7 +232,22 @@
232
232
  try {
233
233
  if (!wrap) return;
234
234
  const iframes = wrap.querySelectorAll('iframe');
235
- if (!iframes.length) return;
235
+
236
+ // If no iframe yet (or no-fill), Ezoic can still reserve a large gap via
237
+ // inline `min-height:400px !important` on `.ezoic-ad` elements.
238
+ // Inline !important beats our CSS, so we proactively shrink it.
239
+ if (!iframes.length) {
240
+ const bad = wrap.querySelectorAll('.ezoic-ad[style*="min-height"], .ezoic-ad-adaptive[style*="min-height"], span.ezoic-ad[style*="min-height"]');
241
+ bad.forEach(n => {
242
+ const s = (n.getAttribute('style') || '').toLowerCase();
243
+ if (s.includes('min-height:400') || s.includes('min-height: 400')) {
244
+ try { n.style.setProperty('min-height', '1px', 'important'); } catch (e) { n.style.minHeight = '1px'; }
245
+ try { n.style.setProperty('height', 'auto', 'important'); } catch (e) {}
246
+ try { n.style.setProperty('line-height', '0', 'important'); } catch (e) {}
247
+ }
248
+ });
249
+ return;
250
+ }
236
251
 
237
252
  // Find the nearest ezoic-ad ancestor with the 400px inline min-height.
238
253
  let ref = null;
@@ -529,11 +544,44 @@
529
544
  const w = ph.closest('.' + WRAP_CLASS);
530
545
  if (!w) return;
531
546
  if (isFilled(ph)) { w.classList.remove('is-empty'); tightenMinHeight(w); }
532
- else { w.classList.add('is-empty'); watchFill(w); }
547
+ else {
548
+ w.classList.add('is-empty');
549
+ // Kill any large reserved gap even when there is no iframe.
550
+ tightenMinHeight(w);
551
+ watchFill(w);
552
+ scheduleHardPruneEmpty(id);
553
+ }
533
554
  } catch (e) {}
534
555
  }, 15_000);
535
556
  }
536
557
 
558
+ // If a placement stays empty for a long time, remove it entirely so the user
559
+ // doesn't get persistent blank blocks. This also frees the placeholder ID so
560
+ // a future injection can try a different one.
561
+ function scheduleHardPruneEmpty(id) {
562
+ setTimeout(() => {
563
+ try {
564
+ const ph = document.getElementById(PLACEHOLDER_PREFIX + id);
565
+ if (!ph || !ph.isConnected) return;
566
+ const w = ph.closest('.' + WRAP_CLASS);
567
+ if (!w) return;
568
+ // If still not filled after 45s, drop it.
569
+ if (!isFilled(w)) {
570
+ // Also ensure it isn't cached as detached.
571
+ try {
572
+ const kind = Array.from(w.classList).find(c => c.startsWith('ezoic-ad-'));
573
+ if (kind) {
574
+ const afterPos = parseInt(w.getAttribute('data-ezoic-after') || '0', 10);
575
+ const m = st.detached.get(kind);
576
+ if (m && afterPos && m.get(afterPos) === w) m.delete(afterPos);
577
+ }
578
+ } catch (e) {}
579
+ withInternal(() => dropWrap(w));
580
+ }
581
+ } catch (e) {}
582
+ }, 45_000);
583
+ }
584
+
537
585
  function startShow(id) {
538
586
  if (!id || isBlocked()) return;
539
587
  st.inflight++;