nodebb-plugin-ezoic-infinite 1.8.2 → 1.8.4
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 +86 -8
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
const MAX_DESTROY_BATCH = 4; // ids max par destroyPlaceholders(...ids)
|
|
90
90
|
const DESTROY_FLUSH_MS = 30; // micro-buffer destroy pour lisser les rafales
|
|
91
91
|
const BURST_COOLDOWN_MS = 120; // délai min entre deux déclenchements de burst
|
|
92
|
+
const PAGE_WARMUP_MS = 700; // laisse NodeBB rendre le contenu avant les premiers showAds
|
|
93
|
+
const CONTENT_SETTLE_WINDOW_MS = 350;
|
|
94
|
+
const CONTENT_SETTLE_MAX_DELAY_MS = 1500;
|
|
95
|
+
const CONTENT_GROWTH_THRESHOLD_PX = 120;
|
|
92
96
|
|
|
93
97
|
// Marges IO larges et fixes — observer créé une seule fois au boot
|
|
94
98
|
const IO_MARGIN_DESKTOP = '2500px 0px 2500px 0px';
|
|
@@ -138,7 +142,8 @@
|
|
|
138
142
|
destroyPendingSet: new Set(),
|
|
139
143
|
sweepQueued: false,
|
|
140
144
|
wrapByKey: new Map(), // anchorKey → wrap DOM node
|
|
141
|
-
ezActiveIds: new Set(), // ids
|
|
145
|
+
ezActiveIds: new Set(), // ids actifs côté plugin (wrap présent / récemment show)
|
|
146
|
+
ezShownSinceDestroy: new Set(), // ids déjà show depuis le dernier destroy Ezoic
|
|
142
147
|
scrollDir: 1, // 1=bas, -1=haut
|
|
143
148
|
scrollSpeed: 0, // px/s approx (EMA)
|
|
144
149
|
lastScrollY: 0,
|
|
@@ -148,6 +153,10 @@
|
|
|
148
153
|
burstDeadline: 0,
|
|
149
154
|
burstCount: 0,
|
|
150
155
|
lastBurstTs: 0,
|
|
156
|
+
pageWarmUntil: 0,
|
|
157
|
+
settleDelaySince: 0,
|
|
158
|
+
contentSampleH: 0,
|
|
159
|
+
contentSampleTs: 0,
|
|
151
160
|
};
|
|
152
161
|
|
|
153
162
|
let blockedUntil = 0;
|
|
@@ -240,6 +249,54 @@ function destroyEzoicId(id) {
|
|
|
240
249
|
scheduleDestroyFlush();
|
|
241
250
|
}
|
|
242
251
|
|
|
252
|
+
function destroyBeforeReuse(ids) {
|
|
253
|
+
const out = [];
|
|
254
|
+
const toDestroy = [];
|
|
255
|
+
const seen = new Set();
|
|
256
|
+
for (const raw of (ids || [])) {
|
|
257
|
+
const id = parseInt(raw, 10);
|
|
258
|
+
if (!Number.isFinite(id) || id <= 0 || seen.has(id)) continue;
|
|
259
|
+
seen.add(id);
|
|
260
|
+
out.push(id);
|
|
261
|
+
if (S.ezShownSinceDestroy.has(id)) toDestroy.push(id);
|
|
262
|
+
}
|
|
263
|
+
if (toDestroy.length) {
|
|
264
|
+
try { window.ezstandalone?.destroyPlaceholders?.(toDestroy); } catch (_) {}
|
|
265
|
+
for (const id of toDestroy) S.ezShownSinceDestroy.delete(id);
|
|
266
|
+
}
|
|
267
|
+
return out;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
function getContentHeight() {
|
|
272
|
+
try {
|
|
273
|
+
const c = document.getElementById('content') || document.querySelector('main#panel') || document.body;
|
|
274
|
+
if (!c) return 0;
|
|
275
|
+
return Math.max(c.scrollHeight || 0, c.offsetHeight || 0);
|
|
276
|
+
} catch (_) { return 0; }
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function getShowSettleDelayMs(now = ts()) {
|
|
280
|
+
try {
|
|
281
|
+
if (S.pageWarmUntil && now < S.pageWarmUntil) return Math.max(0, Math.min(120, S.pageWarmUntil - now));
|
|
282
|
+
const h = getContentHeight();
|
|
283
|
+
const prevH = S.contentSampleH || 0;
|
|
284
|
+
const prevTs = S.contentSampleTs || 0;
|
|
285
|
+
S.contentSampleH = h;
|
|
286
|
+
S.contentSampleTs = now;
|
|
287
|
+
if (!prevTs || h <= 0) { S.settleDelaySince = 0; return 0; }
|
|
288
|
+
const grew = h - prevH;
|
|
289
|
+
const recent = (now - prevTs) <= CONTENT_SETTLE_WINDOW_MS;
|
|
290
|
+
if (recent && grew >= CONTENT_GROWTH_THRESHOLD_PX) {
|
|
291
|
+
if (!S.settleDelaySince) S.settleDelaySince = now;
|
|
292
|
+
if ((now - S.settleDelaySince) < CONTENT_SETTLE_MAX_DELAY_MS) return CONTENT_SETTLE_WINDOW_MS;
|
|
293
|
+
} else {
|
|
294
|
+
S.settleDelaySince = 0;
|
|
295
|
+
}
|
|
296
|
+
} catch (_) {}
|
|
297
|
+
return 0;
|
|
298
|
+
}
|
|
299
|
+
|
|
243
300
|
|
|
244
301
|
// ── Config ─────────────────────────────────────────────────────────────────
|
|
245
302
|
|
|
@@ -484,11 +541,15 @@ function recycleAndMove(klass, targetEl, newKey) {
|
|
|
484
541
|
S.wrapByKey.set(newKey, best);
|
|
485
542
|
|
|
486
543
|
const doDestroy = () => {
|
|
487
|
-
if (S.
|
|
544
|
+
if (S.ezShownSinceDestroy.has(id)) {
|
|
545
|
+
try { ez.destroyPlaceholders([id]); } catch (_) {}
|
|
546
|
+
S.ezShownSinceDestroy.delete(id);
|
|
547
|
+
}
|
|
548
|
+
S.ezActiveIds.delete(id);
|
|
488
549
|
setTimeout(doDefine, 330);
|
|
489
550
|
};
|
|
490
551
|
const doDefine = () => { try { ez.define([id]); } catch (_) {} setTimeout(doDisplay, 300); };
|
|
491
|
-
const doDisplay = () => { try { ez.displayMore([id]); S.ezActiveIds.add(id); } catch (_) {} };
|
|
552
|
+
const doDisplay = () => { try { ez.displayMore([id]); S.ezActiveIds.add(id); S.ezShownSinceDestroy.add(id); } catch (_) {} };
|
|
492
553
|
try { (typeof ez.cmd?.push === 'function') ? ez.cmd.push(doDestroy) : doDestroy(); } catch (_) {}
|
|
493
554
|
|
|
494
555
|
return { id, wrap: best };
|
|
@@ -529,7 +590,7 @@ function recycleAndMove(klass, targetEl, newKey) {
|
|
|
529
590
|
const ph = w.querySelector(`[id^="${PH_PREFIX}"]`);
|
|
530
591
|
if (ph instanceof Element) S.io?.unobserve(ph);
|
|
531
592
|
const id = parseInt(w.getAttribute(A_WRAPID), 10);
|
|
532
|
-
if (Number.isFinite(id)) {
|
|
593
|
+
if (Number.isFinite(id)) { S.ezActiveIds.delete(id); S.mountedIds.delete(id); }
|
|
533
594
|
const key = w.getAttribute(A_ANCHOR);
|
|
534
595
|
if (key && S.wrapByKey.get(key) === w) S.wrapByKey.delete(key);
|
|
535
596
|
w.remove();
|
|
@@ -657,17 +718,19 @@ function enqueueShow(id) {
|
|
|
657
718
|
scheduleDrainQueue();
|
|
658
719
|
}
|
|
659
720
|
|
|
660
|
-
function scheduleDrainQueue() {
|
|
721
|
+
function scheduleDrainQueue(delayMs = BATCH_FLUSH_MS) {
|
|
661
722
|
if (isBlocked()) return;
|
|
662
723
|
if (S.showBatchTimer) return;
|
|
663
724
|
S.showBatchTimer = setTimeout(() => {
|
|
664
725
|
S.showBatchTimer = 0;
|
|
665
726
|
drainQueue();
|
|
666
|
-
},
|
|
727
|
+
}, Math.max(0, delayMs|0));
|
|
667
728
|
}
|
|
668
729
|
|
|
669
730
|
function drainQueue() {
|
|
670
731
|
if (isBlocked()) return;
|
|
732
|
+
const settleDelay = getShowSettleDelayMs();
|
|
733
|
+
if (settleDelay > 0) { scheduleDrainQueue(Math.max(BATCH_FLUSH_MS, settleDelay)); return; }
|
|
671
734
|
const free = Math.max(0, MAX_INFLIGHT - S.inflight);
|
|
672
735
|
if (!free || !S.pending.length) return;
|
|
673
736
|
|
|
@@ -723,9 +786,12 @@ function startShowBatch(ids) {
|
|
|
723
786
|
window.ezstandalone = window.ezstandalone || {};
|
|
724
787
|
const ez = window.ezstandalone;
|
|
725
788
|
const doShow = () => {
|
|
726
|
-
|
|
727
|
-
|
|
789
|
+
const prepared = destroyBeforeReuse(valid);
|
|
790
|
+
if (!prepared.length) { setTimeout(() => { clearTimeout(timer); release(); }, SHOW_RELEASE_MS); return; }
|
|
791
|
+
try { ez.showAds(...prepared); } catch (_) {}
|
|
792
|
+
for (const id of prepared) {
|
|
728
793
|
S.ezActiveIds.add(id);
|
|
794
|
+
S.ezShownSinceDestroy.add(id);
|
|
729
795
|
}
|
|
730
796
|
setTimeout(() => { clearTimeout(timer); release(); }, SHOW_RELEASE_MS);
|
|
731
797
|
};
|
|
@@ -868,6 +934,7 @@ function startShowBatch(ids) {
|
|
|
868
934
|
S.lastShow.clear();
|
|
869
935
|
S.wrapByKey.clear();
|
|
870
936
|
S.ezActiveIds.clear();
|
|
937
|
+
S.ezShownSinceDestroy.clear();
|
|
871
938
|
S.inflight = 0;
|
|
872
939
|
S.pending = [];
|
|
873
940
|
S.pendingSet.clear();
|
|
@@ -881,6 +948,10 @@ function startShowBatch(ids) {
|
|
|
881
948
|
S.scrollSpeed = 0;
|
|
882
949
|
S.lastScrollY = 0;
|
|
883
950
|
S.lastScrollTs = 0;
|
|
951
|
+
S.pageWarmUntil = 0;
|
|
952
|
+
S.settleDelaySince = 0;
|
|
953
|
+
S.contentSampleH = 0;
|
|
954
|
+
S.contentSampleTs = 0;
|
|
884
955
|
}
|
|
885
956
|
|
|
886
957
|
// ── MutationObserver ───────────────────────────────────────────────────────
|
|
@@ -986,6 +1057,10 @@ function startShowBatch(ids) {
|
|
|
986
1057
|
S.pageKey = pageKey();
|
|
987
1058
|
blockedUntil = 0;
|
|
988
1059
|
muteConsole(); ensureTcfLocator(); warmNetwork();
|
|
1060
|
+
S.pageWarmUntil = ts() + PAGE_WARMUP_MS;
|
|
1061
|
+
S.settleDelaySince = 0;
|
|
1062
|
+
S.contentSampleH = getContentHeight();
|
|
1063
|
+
S.contentSampleTs = ts();
|
|
989
1064
|
patchShowAds(); getIO(); ensureDomObserver(); sweepDeadWraps(); requestBurst();
|
|
990
1065
|
});
|
|
991
1066
|
|
|
@@ -1041,6 +1116,9 @@ function startShowBatch(ids) {
|
|
|
1041
1116
|
ensureDomObserver();
|
|
1042
1117
|
bindNodeBB();
|
|
1043
1118
|
bindScroll();
|
|
1119
|
+
S.pageWarmUntil = ts() + PAGE_WARMUP_MS;
|
|
1120
|
+
S.contentSampleH = getContentHeight();
|
|
1121
|
+
S.contentSampleTs = ts();
|
|
1044
1122
|
blockedUntil = 0;
|
|
1045
1123
|
requestBurst();
|
|
1046
1124
|
|