nodebb-plugin-ezoic-infinite 1.5.49 → 1.5.51

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.49",
3
+ "version": "1.5.51",
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
@@ -100,7 +100,7 @@
100
100
  function markEmptyWrapper(id) {
101
101
  try {
102
102
  const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
103
- if (!ph || !ph.isConnected) return;
103
+ if (!ph || !ph.isConnected) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
104
104
  const wrap = ph.closest ? ph.closest(`.${WRAP_CLASS}`) : null;
105
105
  if (!wrap) return;
106
106
  // If still empty after a delay, collapse it.
@@ -205,6 +205,13 @@
205
205
  ['dns-prefetch', 'https://g.ezoic.net', false],
206
206
  ['preconnect', 'https://go.ezoic.net', true],
207
207
  ['dns-prefetch', 'https://go.ezoic.net', false],
208
+ // Google Ads / Safeframe warm-up (helps cold-start latency)
209
+ ['preconnect', 'https://pagead2.googlesyndication.com', true],
210
+ ['dns-prefetch', 'https://pagead2.googlesyndication.com', false],
211
+ ['preconnect', 'https://securepubads.g.doubleclick.net', true],
212
+ ['dns-prefetch', 'https://securepubads.g.doubleclick.net', false],
213
+ ['preconnect', 'https://tpc.googlesyndication.com', true],
214
+ ['dns-prefetch', 'https://tpc.googlesyndication.com', false],
208
215
  ];
209
216
  for (const [rel, href, cors] of links) {
210
217
  const key = `${rel}|${href}`;
@@ -232,7 +239,7 @@
232
239
  const orig = ez.showAds;
233
240
 
234
241
  ez.showAds = function (...args) {
235
- if (isBlocked()) return;
242
+ if (isBlocked()) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
236
243
 
237
244
  let ids = [];
238
245
  if (args.length === 1 && Array.isArray(args[0])) ids = args[0];
@@ -370,7 +377,7 @@ function withInternalDomChange(fn) {
370
377
  window.setTimeout(() => {
371
378
  try {
372
379
  const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
373
- if (!ph || !ph.isConnected) return;
380
+ if (!ph || !ph.isConnected) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
374
381
  const wrap = ph.closest(`.${WRAP_CLASS}`);
375
382
  if (!wrap) return;
376
383
  const hasContent = ph.childElementCount > 0 || ph.offsetHeight > 0;
@@ -483,7 +490,7 @@ function buildWrap(id, kindClass, afterPos) {
483
490
  }
484
491
 
485
492
  function drainQueue() {
486
- if (isBlocked()) return;
493
+ if (isBlocked()) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
487
494
  const max = getMaxInflight();
488
495
  while (state.inflight < max && state.pending.length) {
489
496
  const id = state.pending.shift();
@@ -508,14 +515,14 @@ function startShow(id) {
508
515
 
509
516
  requestAnimationFrame(() => {
510
517
  try {
511
- if (isBlocked()) return;
518
+ if (isBlocked()) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
512
519
 
513
520
  const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
514
- if (!ph || !ph.isConnected) return;
521
+ if (!ph || !ph.isConnected) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
515
522
 
516
523
  const now2 = Date.now();
517
524
  const last2 = state.lastShowById.get(id) || 0;
518
- if (now2 - last2 < 900) return;
525
+ if (now2 - last2 < 900) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
519
526
  state.lastShowById.set(id, now2);
520
527
 
521
528
  window.ezstandalone = window.ezstandalone || {};
@@ -523,16 +530,35 @@ function startShow(id) {
523
530
 
524
531
  const doShow = () => {
525
532
  try {
533
+ // Re-check at execution time: ajaxify/infinite-scroll may have removed the placeholder.
534
+ const phNow = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
535
+ if (!phNow || !phNow.isConnected) {
536
+ try { clearTimeout(hardTimer); } catch (e) {}
537
+ release();
538
+ return;
539
+ }
540
+ } catch (e) {}
541
+
542
+ try {
543
+ // If we reused an id in this pageview, destroy first (use DOM id string form).
526
544
  if (state.usedOnce && state.usedOnce.has(id) && typeof ez.destroyPlaceholders === 'function') {
527
- try { ez.destroyPlaceholders(id); } catch (e) {}
545
+ try { ez.destroyPlaceholders([`${PLACEHOLDER_PREFIX}${id}`]); } catch (e) {}
528
546
  }
529
547
  } catch (e) {}
530
548
 
531
- try { ez.showAds(id); } catch (e) {}
549
+ try {
550
+ // Call Ezoic. Our showAds patch will also filter if DOM disappeared.
551
+ ez.showAds(id);
552
+ } catch (e) {}
553
+
532
554
  try { state.usedOnce && state.usedOnce.add(id); } catch (e) {}
533
555
  try { markEmptyWrapper(id); } catch (e) {}
534
556
 
535
- setTimeout(() => { clearTimeout(hardTimer); release(); }, 650);
557
+ // Release budget quickly; rendering continues async in ad stack.
558
+ setTimeout(() => {
559
+ try { clearTimeout(hardTimer); } catch (e) {}
560
+ release();
561
+ }, 300);
536
562
  };
537
563
 
538
564
  if (Array.isArray(ez.cmd)) {
@@ -588,7 +614,7 @@ function startShow(id) {
588
614
 
589
615
  function observePlaceholder(id) {
590
616
  const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
591
- if (!ph || !ph.isConnected) return;
617
+ if (!ph || !ph.isConnected) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
592
618
  const io = ensurePreloadObserver();
593
619
  try { io && io.observe(ph); } catch (e) {}
594
620
 
@@ -848,7 +874,7 @@ function startShow(id) {
848
874
 
849
875
  // Infinite scroll / partial updates
850
876
  $(window).on('action:posts.loaded.ezoicInfinite action:topics.loaded.ezoicInfinite action:category.loaded.ezoicInfinite action:topic.loaded.ezoicInfinite', () => {
851
- if (isBlocked()) return;
877
+ if (isBlocked()) { try { clearTimeout(hardTimer); } catch (e) {} release(); return; }
852
878
  scheduleRun();
853
879
  });
854
880
  }
package/public/style.css CHANGED
@@ -38,3 +38,16 @@
38
38
  .ezoic-ad > [id^="ezoic-pub-ad-placeholder-"] {
39
39
  min-height: 0 !important;
40
40
  }
41
+
42
+
43
+ /* Smooth fill: avoid harsh flash when safeframe/iframe arrives */
44
+ .ezoic-ad iframe {
45
+ opacity: 0;
46
+ transition: opacity 140ms ease;
47
+ display: block !important;
48
+ vertical-align: top !important;
49
+ }
50
+ .ezoic-ad iframe[data-load-complete="true"],
51
+ .ezoic-ad iframe[src] {
52
+ opacity: 1;
53
+ }