nodebb-plugin-ezoic-infinite 1.5.30 → 1.5.32
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 +120 -62
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -10,8 +10,24 @@
|
|
|
10
10
|
// Insert at most N ads per run to keep the UI smooth on infinite scroll
|
|
11
11
|
const MAX_INSERTS_PER_RUN = 3;
|
|
12
12
|
|
|
13
|
-
// Preload before viewport (
|
|
14
|
-
const
|
|
13
|
+
// Preload before viewport (earlier load for smoother scroll)
|
|
14
|
+
const PRELOAD_MARGIN_DESKTOP = '2600px 0px 2600px 0px';
|
|
15
|
+
const PRELOAD_MARGIN_MOBILE = '1500px 0px 1500px 0px';
|
|
16
|
+
|
|
17
|
+
const MAX_INFLIGHT_DESKTOP = 4;
|
|
18
|
+
const MAX_INFLIGHT_MOBILE = 3;
|
|
19
|
+
|
|
20
|
+
function isMobile() {
|
|
21
|
+
try { return window && window.innerWidth && window.innerWidth < 768; } catch (e) { return false; }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getPreloadRootMargin() {
|
|
25
|
+
return isMobile() ? PRELOAD_MARGIN_MOBILE : PRELOAD_MARGIN_DESKTOP;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getMaxInflight() {
|
|
29
|
+
return isMobile() ? MAX_INFLIGHT_MOBILE : MAX_INFLIGHT_DESKTOP;
|
|
30
|
+
}
|
|
15
31
|
|
|
16
32
|
const SELECTORS = {
|
|
17
33
|
topicItem: 'li[component="category/topic"]',
|
|
@@ -50,22 +66,43 @@
|
|
|
50
66
|
io: null,
|
|
51
67
|
runQueued: false,
|
|
52
68
|
|
|
53
|
-
//
|
|
69
|
+
// preloading budget
|
|
70
|
+
inflight: 0,
|
|
71
|
+
pending: [],
|
|
72
|
+
pendingSet: new Set(),
|
|
73
|
+
|
|
74
|
+
// hero)
|
|
54
75
|
heroDoneForPage: false,
|
|
55
76
|
};
|
|
56
77
|
|
|
57
78
|
const insertingIds = new Set();
|
|
58
79
|
|
|
59
|
-
|
|
60
|
-
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function markEmptyWrapper(id) {
|
|
61
83
|
try {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
84
|
+
const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
85
|
+
if (!ph || !ph.isConnected) return;
|
|
86
|
+
const wrap = ph.closest ? ph.closest(`.${WRAP_CLASS}`) : null;
|
|
87
|
+
if (!wrap) return;
|
|
88
|
+
// If still empty after a delay, collapse it.
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
try {
|
|
91
|
+
const ph2 = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
92
|
+
if (!ph2 || !ph2.isConnected) return;
|
|
93
|
+
const w2 = ph2.closest ? ph2.closest(`.${WRAP_CLASS}`) : null;
|
|
94
|
+
if (!w2) return;
|
|
95
|
+
// consider empty if only whitespace and no iframes/ins/img
|
|
96
|
+
const hasAd = !!(ph2.querySelector && ph2.querySelector('iframe, ins, img, .ez-ad, .ezoic-ad'));
|
|
97
|
+
if (!hasAd) w2.classList.add('is-empty');
|
|
98
|
+
} catch (e) {}
|
|
99
|
+
}, 3500);
|
|
66
100
|
} catch (e) {}
|
|
67
101
|
}
|
|
68
102
|
|
|
103
|
+
// Production build: debug disabled
|
|
104
|
+
function dbg() {}
|
|
105
|
+
|
|
69
106
|
// ---------- small utils ----------
|
|
70
107
|
|
|
71
108
|
function normalizeBool(v) {
|
|
@@ -408,15 +445,51 @@ function buildWrap(id, kindClass, afterPos) {
|
|
|
408
445
|
}
|
|
409
446
|
}
|
|
410
447
|
|
|
411
|
-
function
|
|
412
|
-
|
|
448
|
+
function enqueueShow(id) {
|
|
449
|
+
if (!id || isBlocked()) return;
|
|
413
450
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
451
|
+
// Basic per-id throttle (prevents rapid re-requests when DOM churns)
|
|
452
|
+
const now = Date.now();
|
|
453
|
+
const last = state.lastShowById.get(id) || 0;
|
|
454
|
+
if (now - last < 900) return;
|
|
455
|
+
|
|
456
|
+
const max = getMaxInflight();
|
|
457
|
+
if (state.inflight >= max) {
|
|
458
|
+
if (!state.pendingSet.has(id)) {
|
|
459
|
+
state.pending.push(id);
|
|
460
|
+
state.pendingSet.add(id);
|
|
461
|
+
}
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
startShow(id);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
function drainQueue() {
|
|
468
|
+
if (isBlocked()) return;
|
|
469
|
+
const max = getMaxInflight();
|
|
470
|
+
while (state.inflight < max && state.pending.length) {
|
|
471
|
+
const id = state.pending.shift();
|
|
472
|
+
state.pendingSet.delete(id);
|
|
473
|
+
startShow(id);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function startShow(id) {
|
|
478
|
+
if (!id || isBlocked()) return;
|
|
479
|
+
|
|
480
|
+
state.inflight++;
|
|
481
|
+
let released = false;
|
|
482
|
+
const release = () => {
|
|
483
|
+
if (released) return;
|
|
484
|
+
released = true;
|
|
485
|
+
state.inflight = Math.max(0, state.inflight - 1);
|
|
486
|
+
drainQueue();
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
const hardTimer = setTimeout(release, 6500);
|
|
417
490
|
|
|
418
|
-
|
|
419
|
-
|
|
491
|
+
requestAnimationFrame(() => {
|
|
492
|
+
try {
|
|
420
493
|
if (isBlocked()) return;
|
|
421
494
|
|
|
422
495
|
const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
@@ -424,54 +497,36 @@ function buildWrap(id, kindClass, afterPos) {
|
|
|
424
497
|
|
|
425
498
|
const now2 = Date.now();
|
|
426
499
|
const last2 = state.lastShowById.get(id) || 0;
|
|
427
|
-
if (now2 - last2 <
|
|
500
|
+
if (now2 - last2 < 900) return;
|
|
428
501
|
state.lastShowById.set(id, now2);
|
|
429
502
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const ez = window.ezstandalone;
|
|
503
|
+
window.ezstandalone = window.ezstandalone || {};
|
|
504
|
+
const ez = window.ezstandalone;
|
|
433
505
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
} catch (e) {}
|
|
441
|
-
try { ez.showAds(id); } catch (e) {}
|
|
442
|
-
try { state.usedOnce && state.usedOnce.add(id); } catch (e) {}
|
|
443
|
-
};
|
|
506
|
+
const doShow = () => {
|
|
507
|
+
try {
|
|
508
|
+
if (state.usedOnce && state.usedOnce.has(id) && typeof ez.destroyPlaceholders === 'function') {
|
|
509
|
+
try { ez.destroyPlaceholders(id); } catch (e) {}
|
|
510
|
+
}
|
|
511
|
+
} catch (e) {}
|
|
444
512
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
513
|
+
try { ez.showAds(id); } catch (e) {}
|
|
514
|
+
try { state.usedOnce && state.usedOnce.add(id); } catch (e) {}
|
|
515
|
+
try { markEmptyWrapper(id); } catch (e) {}
|
|
450
516
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
ez2.destroyPlaceholders(id);
|
|
465
|
-
}
|
|
466
|
-
} catch (e) {}
|
|
467
|
-
try { ez2.showAds(id); } catch (e) {}
|
|
468
|
-
try { state.usedOnce && state.usedOnce.add(id); } catch (e) {}
|
|
469
|
-
} catch (e) {}
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
} catch (e) {}
|
|
473
|
-
});
|
|
474
|
-
}
|
|
517
|
+
setTimeout(() => { clearTimeout(hardTimer); release(); }, 650);
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
if (Array.isArray(ez.cmd)) {
|
|
521
|
+
try { ez.cmd.push(doShow); } catch (e) { doShow(); }
|
|
522
|
+
} else {
|
|
523
|
+
doShow();
|
|
524
|
+
}
|
|
525
|
+
} finally {
|
|
526
|
+
// If we returned early, hardTimer will release.
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
}
|
|
475
530
|
|
|
476
531
|
|
|
477
532
|
// ---------- preload / above-the-fold ----------
|
|
@@ -487,9 +542,9 @@ function buildWrap(id, kindClass, afterPos) {
|
|
|
487
542
|
|
|
488
543
|
const idAttr = el && el.getAttribute && el.getAttribute('data-ezoic-id');
|
|
489
544
|
const id = parseInt(idAttr, 10);
|
|
490
|
-
if (Number.isFinite(id) && id > 0)
|
|
545
|
+
if (Number.isFinite(id) && id > 0) enqueueShow(id);
|
|
491
546
|
}
|
|
492
|
-
}, { root: null, rootMargin:
|
|
547
|
+
}, { root: null, rootMargin: getPreloadRootMargin(), threshold: 0 });
|
|
493
548
|
} catch (e) {
|
|
494
549
|
state.io = null;
|
|
495
550
|
}
|
|
@@ -505,7 +560,7 @@ function buildWrap(id, kindClass, afterPos) {
|
|
|
505
560
|
// If already above fold, fire immediately
|
|
506
561
|
try {
|
|
507
562
|
const r = ph.getBoundingClientRect();
|
|
508
|
-
if (r.top < window.innerHeight *
|
|
563
|
+
if (r.top < window.innerHeight * 3.0 && r.bottom > -800) enqueueShow(id);
|
|
509
564
|
} catch (e) {}
|
|
510
565
|
}
|
|
511
566
|
|
|
@@ -708,6 +763,9 @@ function buildWrap(id, kindClass, afterPos) {
|
|
|
708
763
|
state.curPosts = 0;
|
|
709
764
|
state.curCategories = 0;
|
|
710
765
|
state.lastShowById.clear();
|
|
766
|
+
state.inflight = 0;
|
|
767
|
+
state.pending = [];
|
|
768
|
+
try { state.pendingSet && state.pendingSet.clear(); } catch (e) {}
|
|
711
769
|
try { state.usedOnce && state.usedOnce.clear(); } catch (e) {}
|
|
712
770
|
state.heroDoneForPage = false;
|
|
713
771
|
|