nodebb-plugin-ezoic-infinite 1.7.96 → 1.7.97
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 +74 -72
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -79,15 +79,14 @@
|
|
|
79
79
|
|
|
80
80
|
const EMPTY_CHECK_MS = 20_000; // délai avant collapse d'un wrap vide post-show
|
|
81
81
|
const MIN_PRUNE_AGE_MS = 8_000; // délai de grâce avant pruning (stabilisation DOM)
|
|
82
|
-
const MAX_INSERTS_RUN =
|
|
82
|
+
const MAX_INSERTS_RUN = 6; // max insertions par appel runCore
|
|
83
83
|
const MAX_INFLIGHT = 4; // max showAds() simultanés
|
|
84
|
-
const SHOW_THROTTLE_MS =
|
|
85
|
-
const BURST_COOLDOWN_MS =
|
|
84
|
+
const SHOW_THROTTLE_MS = 900; // anti-spam showAds() par id
|
|
85
|
+
const BURST_COOLDOWN_MS = 200; // délai min entre deux déclenchements de burst
|
|
86
86
|
|
|
87
87
|
// Marges IO larges et fixes — observer créé une seule fois au boot
|
|
88
88
|
const IO_MARGIN_DESKTOP = '2500px 0px 2500px 0px';
|
|
89
89
|
const IO_MARGIN_MOBILE = '3500px 0px 3500px 0px';
|
|
90
|
-
const FAST_SHOW_MARGIN_PX = 900; // show immédiat si slot déjà proche viewport
|
|
91
90
|
|
|
92
91
|
const SEL = {
|
|
93
92
|
post: '[component="post"][data-pid]',
|
|
@@ -133,8 +132,6 @@
|
|
|
133
132
|
burstDeadline: 0,
|
|
134
133
|
burstCount: 0,
|
|
135
134
|
lastBurstTs: 0,
|
|
136
|
-
scrollDir: 1,
|
|
137
|
-
lastScrollY: 0,
|
|
138
135
|
};
|
|
139
136
|
|
|
140
137
|
let blockedUntil = 0;
|
|
@@ -145,6 +142,34 @@
|
|
|
145
142
|
const normBool = v => v === true || v === 'true' || v === 1 || v === '1' || v === 'on';
|
|
146
143
|
const isFilled = n => !!(n?.querySelector?.('iframe, ins, img, video, [data-google-container-id]'));
|
|
147
144
|
|
|
145
|
+
function ezCmd(fn) {
|
|
146
|
+
try {
|
|
147
|
+
window.ezstandalone = window.ezstandalone || {};
|
|
148
|
+
const ez = window.ezstandalone;
|
|
149
|
+
if (Array.isArray(ez.cmd)) ez.cmd.push(fn);
|
|
150
|
+
else fn();
|
|
151
|
+
} catch (_) {}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function destroyPlaceholderIds(ids) {
|
|
155
|
+
try {
|
|
156
|
+
const uniq = Array.from(new Set((ids || [])
|
|
157
|
+
.map(v => parseInt(v, 10))
|
|
158
|
+
.filter(v => Number.isFinite(v) && v > 0)));
|
|
159
|
+
if (!uniq.length) return;
|
|
160
|
+
ezCmd(() => {
|
|
161
|
+
try {
|
|
162
|
+
const ez = window.ezstandalone;
|
|
163
|
+
if (typeof ez?.destroyPlaceholders === 'function') ez.destroyPlaceholders(uniq);
|
|
164
|
+
} catch (_) {}
|
|
165
|
+
});
|
|
166
|
+
} catch (_) {}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function placeholderCount(id) {
|
|
170
|
+
try { return document.querySelectorAll(`#${PH_PREFIX}${id}`).length; } catch (_) { return 0; }
|
|
171
|
+
}
|
|
172
|
+
|
|
148
173
|
function mutate(fn) {
|
|
149
174
|
S.mutGuard++;
|
|
150
175
|
try { fn(); } finally { S.mutGuard--; }
|
|
@@ -316,58 +341,33 @@
|
|
|
316
341
|
typeof ez?.define !== 'function' ||
|
|
317
342
|
typeof ez?.displayMore !== 'function') return null;
|
|
318
343
|
|
|
319
|
-
const vh
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
let
|
|
325
|
-
let prefFilled = null, prefFilledScore = -Infinity;
|
|
326
|
-
let altEmpty = null, altEmptyScore = -Infinity;
|
|
327
|
-
let altFilled = null, altFilledScore = -Infinity;
|
|
344
|
+
const vh = window.innerHeight || 800;
|
|
345
|
+
// Seuil : -1vh (hors viewport visible). On appelle unobserve(ph) juste
|
|
346
|
+
// après pour neutraliser l'IO — plus de showAds parasite possible.
|
|
347
|
+
const threshold = -vh;
|
|
348
|
+
let bestEmpty = null, bestEmptyBottom = Infinity;
|
|
349
|
+
let bestFilled = null, bestFilledBottom = Infinity;
|
|
328
350
|
|
|
329
|
-
|
|
330
|
-
if (!wrap?.isConnected) continue;
|
|
331
|
-
if (!wrap.classList?.contains(WRAP_CLASS) || !wrap.classList.contains(klass)) continue;
|
|
351
|
+
document.querySelectorAll(`.${WRAP_CLASS}.${klass}`).forEach(wrap => {
|
|
332
352
|
try {
|
|
333
353
|
const rect = wrap.getBoundingClientRect();
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
let score = -Infinity;
|
|
338
|
-
|
|
339
|
-
if (dir >= 0) {
|
|
340
|
-
if (farAbove) { preferred = true; score = Math.abs(rect.bottom); }
|
|
341
|
-
else if (farBelow) { score = Math.abs(rect.top); }
|
|
354
|
+
if (rect.bottom > threshold) return;
|
|
355
|
+
if (!isFilled(wrap)) {
|
|
356
|
+
if (rect.bottom < bestEmptyBottom) { bestEmptyBottom = rect.bottom; bestEmpty = wrap; }
|
|
342
357
|
} else {
|
|
343
|
-
if (
|
|
344
|
-
else if (farAbove) { score = Math.abs(rect.bottom); }
|
|
345
|
-
}
|
|
346
|
-
if (score === -Infinity) continue;
|
|
347
|
-
|
|
348
|
-
const filled = isFilled(wrap);
|
|
349
|
-
if (preferred) {
|
|
350
|
-
if (!filled) {
|
|
351
|
-
if (score > prefEmptyScore) { prefEmptyScore = score; prefEmpty = wrap; }
|
|
352
|
-
} else {
|
|
353
|
-
if (score > prefFilledScore) { prefFilledScore = score; prefFilled = wrap; }
|
|
354
|
-
}
|
|
355
|
-
} else {
|
|
356
|
-
if (!filled) {
|
|
357
|
-
if (score > altEmptyScore) { altEmptyScore = score; altEmpty = wrap; }
|
|
358
|
-
} else {
|
|
359
|
-
if (score > altFilledScore) { altFilledScore = score; altFilled = wrap; }
|
|
360
|
-
}
|
|
358
|
+
if (rect.bottom < bestFilledBottom) { bestFilledBottom = rect.bottom; bestFilled = wrap; }
|
|
361
359
|
}
|
|
362
360
|
} catch (_) {}
|
|
363
|
-
}
|
|
361
|
+
});
|
|
364
362
|
|
|
365
|
-
const best =
|
|
363
|
+
const best = bestEmpty ?? bestFilled;
|
|
366
364
|
if (!best) return null;
|
|
367
365
|
const id = parseInt(best.getAttribute(A_WRAPID), 10);
|
|
368
366
|
if (!Number.isFinite(id)) return null;
|
|
369
367
|
|
|
370
368
|
const oldKey = best.getAttribute(A_ANCHOR);
|
|
369
|
+
// Neutraliser l'IO sur ce wrap avant déplacement — évite un showAds
|
|
370
|
+
// parasite si le nœud était encore dans la zone IO_MARGIN.
|
|
371
371
|
try { const ph = best.querySelector(`#${PH_PREFIX}${id}`); if (ph) S.io?.unobserve(ph); } catch (_) {}
|
|
372
372
|
mutate(() => {
|
|
373
373
|
best.setAttribute(A_ANCHOR, newKey);
|
|
@@ -381,8 +381,9 @@
|
|
|
381
381
|
if (oldKey && S.wrapByKey.get(oldKey) === best) S.wrapByKey.delete(oldKey);
|
|
382
382
|
S.wrapByKey.set(newKey, best);
|
|
383
383
|
|
|
384
|
-
|
|
385
|
-
const
|
|
384
|
+
// Délais requis : destroyPlaceholders est asynchrone en interne
|
|
385
|
+
const doDestroy = () => { try { ez.destroyPlaceholders([id]); } catch (_) {} setTimeout(doDefine, 300); };
|
|
386
|
+
const doDefine = () => { try { ez.define([id]); } catch (_) {} setTimeout(doDisplay, 300); };
|
|
386
387
|
const doDisplay = () => { try { ez.displayMore([id]); } catch (_) {} };
|
|
387
388
|
try { (typeof ez.cmd?.push === 'function') ? ez.cmd.push(doDestroy) : doDestroy(); } catch (_) {}
|
|
388
389
|
|
|
@@ -423,7 +424,10 @@
|
|
|
423
424
|
const ph = w.querySelector(`[id^="${PH_PREFIX}"]`);
|
|
424
425
|
if (ph instanceof Element) S.io?.unobserve(ph);
|
|
425
426
|
const id = parseInt(w.getAttribute(A_WRAPID), 10);
|
|
426
|
-
if (Number.isFinite(id))
|
|
427
|
+
if (Number.isFinite(id)) {
|
|
428
|
+
destroyPlaceholderIds([id]);
|
|
429
|
+
S.mountedIds.delete(id);
|
|
430
|
+
}
|
|
427
431
|
const key = w.getAttribute(A_ANCHOR);
|
|
428
432
|
if (key && S.wrapByKey.get(key) === w) S.wrapByKey.delete(key);
|
|
429
433
|
w.remove();
|
|
@@ -530,16 +534,7 @@
|
|
|
530
534
|
|
|
531
535
|
function observePh(id) {
|
|
532
536
|
const ph = document.getElementById(`${PH_PREFIX}${id}`);
|
|
533
|
-
if (
|
|
534
|
-
try { getIO()?.observe(ph); } catch (_) {}
|
|
535
|
-
try {
|
|
536
|
-
const r = ph.getBoundingClientRect();
|
|
537
|
-
const vh = window.innerHeight || 800;
|
|
538
|
-
if (r.bottom >= -FAST_SHOW_MARGIN_PX && r.top <= vh + FAST_SHOW_MARGIN_PX) {
|
|
539
|
-
const pid = parseInt(ph.getAttribute('data-ezoic-id'), 10);
|
|
540
|
-
if (Number.isFinite(pid) && pid > 0) enqueueShow(pid);
|
|
541
|
-
}
|
|
542
|
-
} catch (_) {}
|
|
537
|
+
if (ph?.isConnected) try { getIO()?.observe(ph); } catch (_) {}
|
|
543
538
|
}
|
|
544
539
|
|
|
545
540
|
function enqueueShow(id) {
|
|
@@ -578,6 +573,7 @@
|
|
|
578
573
|
if (isBlocked()) { clearTimeout(timer); return release(); }
|
|
579
574
|
const ph = document.getElementById(`${PH_PREFIX}${id}`);
|
|
580
575
|
if (!ph?.isConnected || isFilled(ph)) { clearTimeout(timer); return release(); }
|
|
576
|
+
if (placeholderCount(id) !== 1) { clearTimeout(timer); return release(); }
|
|
581
577
|
|
|
582
578
|
const t = ts();
|
|
583
579
|
if (t - (S.lastShow.get(id) ?? 0) < SHOW_THROTTLE_MS) { clearTimeout(timer); return release(); }
|
|
@@ -590,7 +586,7 @@
|
|
|
590
586
|
const doShow = () => {
|
|
591
587
|
try { ez.showAds(id); } catch (_) {}
|
|
592
588
|
scheduleEmptyCheck(id, t);
|
|
593
|
-
setTimeout(() => { clearTimeout(timer); release(); },
|
|
589
|
+
setTimeout(() => { clearTimeout(timer); release(); }, 700);
|
|
594
590
|
};
|
|
595
591
|
Array.isArray(ez.cmd) ? ez.cmd.push(doShow) : doShow();
|
|
596
592
|
} catch (_) { clearTimeout(timer); release(); }
|
|
@@ -631,6 +627,7 @@
|
|
|
631
627
|
const id = parseInt(v, 10);
|
|
632
628
|
if (!Number.isFinite(id) || id <= 0 || seen.has(id)) continue;
|
|
633
629
|
if (!document.getElementById(`${PH_PREFIX}${id}`)?.isConnected) continue;
|
|
630
|
+
if (placeholderCount(id) !== 1) continue;
|
|
634
631
|
seen.add(id);
|
|
635
632
|
try { orig(id); } catch (_) {}
|
|
636
633
|
}
|
|
@@ -715,7 +712,7 @@
|
|
|
715
712
|
S.burstCount++;
|
|
716
713
|
scheduleRun(n => {
|
|
717
714
|
if (!n && !S.pending.length) { S.burstActive = false; return; }
|
|
718
|
-
setTimeout(step, n > 0 ?
|
|
715
|
+
setTimeout(step, n > 0 ? 150 : 300);
|
|
719
716
|
});
|
|
720
717
|
};
|
|
721
718
|
step();
|
|
@@ -725,6 +722,18 @@
|
|
|
725
722
|
|
|
726
723
|
function cleanup() {
|
|
727
724
|
blockedUntil = ts() + 1500;
|
|
725
|
+
try {
|
|
726
|
+
const ids = Array.from(document.querySelectorAll(`.${WRAP_CLASS}[${A_WRAPID}]`))
|
|
727
|
+
.map(w => parseInt(w.getAttribute(A_WRAPID), 10))
|
|
728
|
+
.filter(v => Number.isFinite(v) && v > 0);
|
|
729
|
+
destroyPlaceholderIds(ids);
|
|
730
|
+
ezCmd(() => {
|
|
731
|
+
try {
|
|
732
|
+
const ez = window.ezstandalone;
|
|
733
|
+
if (typeof ez?.destroyAll === 'function') ez.destroyAll();
|
|
734
|
+
} catch (_) {}
|
|
735
|
+
});
|
|
736
|
+
} catch (_) {}
|
|
728
737
|
mutate(() => document.querySelectorAll(`.${WRAP_CLASS}`).forEach(dropWrap));
|
|
729
738
|
S.cfg = null;
|
|
730
739
|
S.poolsReady = false;
|
|
@@ -835,7 +844,9 @@
|
|
|
835
844
|
S.pageKey = pageKey();
|
|
836
845
|
blockedUntil = 0;
|
|
837
846
|
muteConsole(); ensureTcfLocator(); warmNetwork();
|
|
838
|
-
patchShowAds(); getIO(); ensureDomObserver();
|
|
847
|
+
patchShowAds(); getIO(); ensureDomObserver();
|
|
848
|
+
ezCmd(() => { try { window.ezstandalone?.showAds?.(); } catch (_) {} });
|
|
849
|
+
requestBurst();
|
|
839
850
|
});
|
|
840
851
|
|
|
841
852
|
const burstEvts = [
|
|
@@ -860,22 +871,13 @@
|
|
|
860
871
|
window.addEventListener('scroll', () => {
|
|
861
872
|
if (ticking) return;
|
|
862
873
|
ticking = true;
|
|
863
|
-
requestAnimationFrame(() => {
|
|
864
|
-
ticking = false;
|
|
865
|
-
try {
|
|
866
|
-
const y = window.scrollY || window.pageYOffset || 0;
|
|
867
|
-
S.scrollDir = (y < (S.lastScrollY || 0)) ? -1 : 1;
|
|
868
|
-
S.lastScrollY = y;
|
|
869
|
-
} catch (_) {}
|
|
870
|
-
requestBurst();
|
|
871
|
-
});
|
|
874
|
+
requestAnimationFrame(() => { ticking = false; requestBurst(); });
|
|
872
875
|
}, { passive: true });
|
|
873
876
|
}
|
|
874
877
|
|
|
875
878
|
// ── Boot ───────────────────────────────────────────────────────────────────
|
|
876
879
|
|
|
877
880
|
S.pageKey = pageKey();
|
|
878
|
-
try { S.lastScrollY = window.scrollY || window.pageYOffset || 0; } catch (_) {}
|
|
879
881
|
muteConsole();
|
|
880
882
|
ensureTcfLocator();
|
|
881
883
|
warmNetwork();
|