nodebb-plugin-ezoic-infinite 1.5.51 → 1.5.52
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 +1 -1
- package/public/client.js +104 -78
- package/public/style.css +0 -13
package/package.json
CHANGED
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)
|
|
103
|
+
if (!ph || !ph.isConnected) 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,13 +205,6 @@
|
|
|
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],
|
|
215
208
|
];
|
|
216
209
|
for (const [rel, href, cors] of links) {
|
|
217
210
|
const key = `${rel}|${href}`;
|
|
@@ -227,46 +220,76 @@
|
|
|
227
220
|
}
|
|
228
221
|
|
|
229
222
|
// Patch showAds to avoid warnings when a placeholder disappears (infinite scroll, ajaxify)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
223
|
+
|
|
224
|
+
function patchShowAds() {
|
|
225
|
+
// Robustly filter ez.showAds calls so Ezoic won't spam "placeholder does not exist"
|
|
226
|
+
// during ajaxify navigation or when some placeholders are not present on the current view.
|
|
227
|
+
try {
|
|
228
|
+
window.ezstandalone = window.ezstandalone || {};
|
|
229
|
+
const ez = window.ezstandalone;
|
|
230
|
+
ez.cmd = ez.cmd || [];
|
|
231
|
+
|
|
232
|
+
const wrap = (orig) => {
|
|
233
|
+
if (typeof orig !== 'function') return orig;
|
|
234
|
+
if (orig.__nodebbWrapped) return orig;
|
|
235
|
+
|
|
236
|
+
const wrapped = function (...args) {
|
|
237
|
+
if (isBlocked()) return;
|
|
238
|
+
|
|
239
|
+
let ids = [];
|
|
240
|
+
if (args.length === 1 && Array.isArray(args[0])) ids = args[0];
|
|
241
|
+
else ids = args;
|
|
242
|
+
|
|
243
|
+
const filtered = [];
|
|
244
|
+
const seen = new Set();
|
|
245
|
+
for (const v of ids) {
|
|
246
|
+
const id = parseInt(v, 10);
|
|
247
|
+
if (!Number.isFinite(id) || id <= 0 || seen.has(id)) continue;
|
|
248
|
+
const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
249
|
+
if (!ph || !ph.isConnected) continue;
|
|
250
|
+
seen.add(id);
|
|
251
|
+
filtered.push(id);
|
|
252
|
+
}
|
|
253
|
+
if (!filtered.length) return;
|
|
254
|
+
|
|
255
|
+
// Call original with the same shape most implementations accept
|
|
256
|
+
try { return orig.call(ez, filtered.length === 1 ? filtered[0] : filtered); } catch (e) {}
|
|
257
|
+
};
|
|
258
|
+
wrapped.__nodebbWrapped = true;
|
|
259
|
+
wrapped.__nodebbOrig = orig;
|
|
260
|
+
return wrapped;
|
|
259
261
|
};
|
|
260
262
|
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
window.ezstandalone.cmd = window.ezstandalone.cmd || [];
|
|
266
|
-
window.ezstandalone.cmd.push(applyPatch);
|
|
267
|
-
} catch (e) {}
|
|
263
|
+
// If showAds already exists, wrap it now.
|
|
264
|
+
if (typeof ez.showAds === 'function') {
|
|
265
|
+
ez.showAds = wrap(ez.showAds);
|
|
266
|
+
return;
|
|
268
267
|
}
|
|
269
|
-
|
|
268
|
+
|
|
269
|
+
// Otherwise, define a setter hook so whenever Ezoic defines showAds, we wrap it.
|
|
270
|
+
if (!ez.__nodebbShowAdsHooked) {
|
|
271
|
+
ez.__nodebbShowAdsHooked = true;
|
|
272
|
+
let _showAds = null;
|
|
273
|
+
|
|
274
|
+
Object.defineProperty(ez, 'showAds', {
|
|
275
|
+
configurable: true,
|
|
276
|
+
enumerable: true,
|
|
277
|
+
get() { return _showAds; },
|
|
278
|
+
set(fn) { _showAds = wrap(fn); }
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// In case Ezoic sets showAds from cmd queue
|
|
282
|
+
ez.cmd.push(() => {
|
|
283
|
+
try {
|
|
284
|
+
if (typeof ez.showAds === 'function' && !ez.showAds.__nodebbWrapped) {
|
|
285
|
+
ez.showAds = wrap(ez.showAds);
|
|
286
|
+
}
|
|
287
|
+
} catch (e) {}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
} catch (e) {}
|
|
291
|
+
}
|
|
292
|
+
|
|
270
293
|
|
|
271
294
|
const RECYCLE_COOLDOWN_MS = 1500;
|
|
272
295
|
|
|
@@ -377,7 +400,7 @@ function withInternalDomChange(fn) {
|
|
|
377
400
|
window.setTimeout(() => {
|
|
378
401
|
try {
|
|
379
402
|
const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
380
|
-
if (!ph || !ph.isConnected)
|
|
403
|
+
if (!ph || !ph.isConnected) return;
|
|
381
404
|
const wrap = ph.closest(`.${WRAP_CLASS}`);
|
|
382
405
|
if (!wrap) return;
|
|
383
406
|
const hasContent = ph.childElementCount > 0 || ph.offsetHeight > 0;
|
|
@@ -490,7 +513,7 @@ function buildWrap(id, kindClass, afterPos) {
|
|
|
490
513
|
}
|
|
491
514
|
|
|
492
515
|
function drainQueue() {
|
|
493
|
-
if (isBlocked())
|
|
516
|
+
if (isBlocked()) return;
|
|
494
517
|
const max = getMaxInflight();
|
|
495
518
|
while (state.inflight < max && state.pending.length) {
|
|
496
519
|
const id = state.pending.shift();
|
|
@@ -502,6 +525,7 @@ function drainQueue() {
|
|
|
502
525
|
function startShow(id) {
|
|
503
526
|
if (!id || isBlocked()) return;
|
|
504
527
|
|
|
528
|
+
// Reserve one inflight slot for this request
|
|
505
529
|
state.inflight++;
|
|
506
530
|
let released = false;
|
|
507
531
|
const release = () => {
|
|
@@ -513,16 +537,22 @@ function startShow(id) {
|
|
|
513
537
|
|
|
514
538
|
const hardTimer = setTimeout(release, 6500);
|
|
515
539
|
|
|
540
|
+
const earlyExit = () => {
|
|
541
|
+
try { clearTimeout(hardTimer); } catch (e) {}
|
|
542
|
+
release();
|
|
543
|
+
};
|
|
544
|
+
|
|
516
545
|
requestAnimationFrame(() => {
|
|
517
546
|
try {
|
|
518
|
-
if (isBlocked())
|
|
547
|
+
if (isBlocked()) return earlyExit();
|
|
519
548
|
|
|
520
|
-
const
|
|
521
|
-
|
|
549
|
+
const domId = `${PLACEHOLDER_PREFIX}${id}`;
|
|
550
|
+
const ph = document.getElementById(domId);
|
|
551
|
+
if (!ph || !ph.isConnected) return earlyExit();
|
|
522
552
|
|
|
523
553
|
const now2 = Date.now();
|
|
524
554
|
const last2 = state.lastShowById.get(id) || 0;
|
|
525
|
-
if (now2 - last2 < 900)
|
|
555
|
+
if (now2 - last2 < 900) return earlyExit();
|
|
526
556
|
state.lastShowById.set(id, now2);
|
|
527
557
|
|
|
528
558
|
window.ezstandalone = window.ezstandalone || {};
|
|
@@ -530,35 +560,31 @@ function startShow(id) {
|
|
|
530
560
|
|
|
531
561
|
const doShow = () => {
|
|
532
562
|
try {
|
|
533
|
-
|
|
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) {}
|
|
563
|
+
if (isBlocked()) return earlyExit();
|
|
541
564
|
|
|
542
|
-
|
|
543
|
-
|
|
565
|
+
// Re-check at execution time (cmd queue may delay)
|
|
566
|
+
const ph2 = document.getElementById(domId);
|
|
567
|
+
if (!ph2 || !ph2.isConnected) return earlyExit();
|
|
568
|
+
|
|
569
|
+
// If this id was used before in this pageview, destroy first (Ezoic best practice on recycle)
|
|
544
570
|
if (state.usedOnce && state.usedOnce.has(id) && typeof ez.destroyPlaceholders === 'function') {
|
|
545
|
-
try { ez.destroyPlaceholders([
|
|
571
|
+
try { ez.destroyPlaceholders([domId]); } catch (e) {}
|
|
546
572
|
}
|
|
547
|
-
} catch (e) {}
|
|
548
573
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
ez.showAds(id);
|
|
552
|
-
} catch (e) {}
|
|
574
|
+
// Call showAds (patched to filter missing placeholders)
|
|
575
|
+
try { ez.showAds(id); } catch (e) {}
|
|
553
576
|
|
|
554
|
-
|
|
555
|
-
|
|
577
|
+
try { state.usedOnce && state.usedOnce.add(id); } catch (e) {}
|
|
578
|
+
try { markEmptyWrapper(id); } catch (e) {} // harmless; if removed later, it no-ops
|
|
556
579
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
580
|
+
// Release shortly after triggering, so we can pipeline the next ones
|
|
581
|
+
setTimeout(() => {
|
|
582
|
+
try { clearTimeout(hardTimer); } catch (e) {}
|
|
583
|
+
release();
|
|
584
|
+
}, 650);
|
|
585
|
+
} catch (e) {
|
|
586
|
+
earlyExit();
|
|
587
|
+
}
|
|
562
588
|
};
|
|
563
589
|
|
|
564
590
|
if (Array.isArray(ez.cmd)) {
|
|
@@ -566,8 +592,8 @@ function startShow(id) {
|
|
|
566
592
|
} else {
|
|
567
593
|
doShow();
|
|
568
594
|
}
|
|
569
|
-
}
|
|
570
|
-
|
|
595
|
+
} catch (e) {
|
|
596
|
+
earlyExit();
|
|
571
597
|
}
|
|
572
598
|
});
|
|
573
599
|
}
|
|
@@ -614,7 +640,7 @@ function startShow(id) {
|
|
|
614
640
|
|
|
615
641
|
function observePlaceholder(id) {
|
|
616
642
|
const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
617
|
-
if (!ph || !ph.isConnected)
|
|
643
|
+
if (!ph || !ph.isConnected) return;
|
|
618
644
|
const io = ensurePreloadObserver();
|
|
619
645
|
try { io && io.observe(ph); } catch (e) {}
|
|
620
646
|
|
|
@@ -874,7 +900,7 @@ function startShow(id) {
|
|
|
874
900
|
|
|
875
901
|
// Infinite scroll / partial updates
|
|
876
902
|
$(window).on('action:posts.loaded.ezoicInfinite action:topics.loaded.ezoicInfinite action:category.loaded.ezoicInfinite action:topic.loaded.ezoicInfinite', () => {
|
|
877
|
-
if (isBlocked())
|
|
903
|
+
if (isBlocked()) return;
|
|
878
904
|
scheduleRun();
|
|
879
905
|
});
|
|
880
906
|
}
|
package/public/style.css
CHANGED
|
@@ -38,16 +38,3 @@
|
|
|
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
|
-
}
|