nodebb-plugin-ezoic-infinite 1.8.27 → 1.8.29
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 +79 -15
- package/public/style.css +11 -0
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -136,6 +136,7 @@
|
|
|
136
136
|
firstShown: false,
|
|
137
137
|
wrapsByClass: new Map(),
|
|
138
138
|
kind: null,
|
|
139
|
+
phState: new Map(), // id -> new|show-queued|shown|destroyed
|
|
139
140
|
};
|
|
140
141
|
|
|
141
142
|
let blockedUntil = 0;
|
|
@@ -144,13 +145,42 @@
|
|
|
144
145
|
const isBlocked = () => ts() < blockedUntil;
|
|
145
146
|
const isMobile = () => { try { return window.innerWidth < 768; } catch (_) { return false; } };
|
|
146
147
|
const normBool = v => v === true || v === 'true' || v === 1 || v === '1' || v === 'on';
|
|
147
|
-
const
|
|
148
|
+
const FILL_SEL = 'iframe, ins, img, video, [data-google-container-id], div[id$="__container__"]';
|
|
149
|
+
const isFilled = n => !!(n?.querySelector?.(FILL_SEL));
|
|
150
|
+
function placeholderLooksUsed(ph) {
|
|
151
|
+
try {
|
|
152
|
+
if (!ph?.isConnected) return false;
|
|
153
|
+
return !!ph.querySelector('ins.adsbygoogle, iframe, [data-google-container-id], div[id$="__container__"]');
|
|
154
|
+
} catch (_) { return false; }
|
|
155
|
+
}
|
|
156
|
+
|
|
148
157
|
|
|
149
158
|
function mutate(fn) {
|
|
150
159
|
S.mutGuard++;
|
|
151
160
|
try { fn(); } finally { S.mutGuard--; }
|
|
152
161
|
}
|
|
153
162
|
|
|
163
|
+
|
|
164
|
+
function clearEmptyIfFilled(wrap) {
|
|
165
|
+
try {
|
|
166
|
+
if (!wrap?.isConnected) return false;
|
|
167
|
+
const ph = wrap.querySelector(`[id^="${PH_PREFIX}"]`);
|
|
168
|
+
if (!ph) return false;
|
|
169
|
+
if (!isFilled(ph)) return false;
|
|
170
|
+
wrap.classList.remove('is-empty');
|
|
171
|
+
const id = parseInt(wrap.getAttribute(A_WRAPID) || '0', 10);
|
|
172
|
+
if (Number.isFinite(id) && id > 0) S.phState.set(id, 'shown');
|
|
173
|
+
return true;
|
|
174
|
+
} catch (_) { return false; }
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function scheduleUncollapseChecksForWrap(wrap) {
|
|
178
|
+
if (!wrap) return;
|
|
179
|
+
for (const ms of [500, 1500, 3000, 7000, 15000]) {
|
|
180
|
+
setTimeout(() => { try { clearEmptyIfFilled(wrap); } catch (_) {} }, ms);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
154
184
|
// ── Config ─────────────────────────────────────────────────────────────────
|
|
155
185
|
|
|
156
186
|
async function fetchConfig() {
|
|
@@ -370,14 +400,12 @@
|
|
|
370
400
|
best.setAttribute(A_CREATED, String(ts()));
|
|
371
401
|
best.setAttribute(A_SHOWN, '0');
|
|
372
402
|
best.classList.remove('is-empty');
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
oldPh.replaceWith(fresh);
|
|
380
|
-
}
|
|
403
|
+
best.replaceChildren();
|
|
404
|
+
const fresh = document.createElement('div');
|
|
405
|
+
fresh.id = `${PH_PREFIX}${id}`;
|
|
406
|
+
fresh.setAttribute('data-ezoic-id', String(id));
|
|
407
|
+
fresh.style.minHeight = `${MIN_PLACEHOLDER_HEIGHT}px`;
|
|
408
|
+
best.appendChild(fresh);
|
|
381
409
|
targetEl.insertAdjacentElement('afterend', best);
|
|
382
410
|
});
|
|
383
411
|
if (oldKey && S.wrapByKey.get(oldKey) === best) S.wrapByKey.delete(oldKey);
|
|
@@ -386,11 +414,13 @@
|
|
|
386
414
|
// Recyclage Ezoic : détruire l'ancien placeholder avant de réutiliser le même ID.
|
|
387
415
|
// Puis ré-observer + re-show (batché via patchShowAds) sur le placeholder recréé.
|
|
388
416
|
const doDestroy = () => {
|
|
417
|
+
S.phState.set(id, 'destroyed');
|
|
389
418
|
try { ez.destroyPlaceholders(id); } catch (_) {
|
|
390
419
|
try { ez.destroyPlaceholders([id]); } catch (_) {}
|
|
391
420
|
}
|
|
392
421
|
setTimeout(() => {
|
|
393
422
|
try { observePh(id); } catch (_) {}
|
|
423
|
+
S.phState.set(id, 'new');
|
|
394
424
|
try { enqueueShow(id); } catch (_) {}
|
|
395
425
|
}, 450);
|
|
396
426
|
};
|
|
@@ -425,6 +455,7 @@
|
|
|
425
455
|
const w = makeWrap(id, klass, key);
|
|
426
456
|
mutate(() => el.insertAdjacentElement('afterend', w));
|
|
427
457
|
S.mountedIds.add(id);
|
|
458
|
+
S.phState.set(id, 'new');
|
|
428
459
|
S.wrapByKey.set(key, w);
|
|
429
460
|
registerWrap(klass, w);
|
|
430
461
|
return w;
|
|
@@ -435,7 +466,7 @@
|
|
|
435
466
|
const ph = w.querySelector(`[id^="${PH_PREFIX}"]`);
|
|
436
467
|
if (ph instanceof Element) S.io?.unobserve(ph);
|
|
437
468
|
const id = parseInt(w.getAttribute(A_WRAPID), 10);
|
|
438
|
-
if (Number.isFinite(id)) S.mountedIds.delete(id);
|
|
469
|
+
if (Number.isFinite(id)) { S.mountedIds.delete(id); S.phState.delete(id); }
|
|
439
470
|
const key = w.getAttribute(A_ANCHOR);
|
|
440
471
|
if (key && S.wrapByKey.get(key) === w) S.wrapByKey.delete(key);
|
|
441
472
|
const klass = Array.from(w.classList || []).find(c => c !== WRAP_CLASS && c.startsWith('ezoic-ad-'));
|
|
@@ -554,11 +585,14 @@
|
|
|
554
585
|
|
|
555
586
|
function enqueueShow(id) {
|
|
556
587
|
if (!id || isBlocked()) return;
|
|
588
|
+
const st = S.phState.get(id);
|
|
589
|
+
if (st === 'show-queued' || st === 'shown') return;
|
|
557
590
|
if (ts() - (S.lastShow.get(id) ?? 0) < SHOW_THROTTLE_MS) return;
|
|
558
591
|
if (S.inflight >= MAX_INFLIGHT) {
|
|
559
|
-
if (!S.pendingSet.has(id)) { S.pending.push(id); S.pendingSet.add(id); }
|
|
592
|
+
if (!S.pendingSet.has(id)) { S.pending.push(id); S.pendingSet.add(id); S.phState.set(id, 'show-queued'); }
|
|
560
593
|
return;
|
|
561
594
|
}
|
|
595
|
+
S.phState.set(id, 'show-queued');
|
|
562
596
|
startShow(id);
|
|
563
597
|
}
|
|
564
598
|
|
|
@@ -587,18 +621,23 @@
|
|
|
587
621
|
try {
|
|
588
622
|
if (isBlocked()) { clearTimeout(timer); return release(); }
|
|
589
623
|
const ph = document.getElementById(`${PH_PREFIX}${id}`);
|
|
590
|
-
if (!ph?.isConnected
|
|
624
|
+
if (!ph?.isConnected) { S.phState.delete(id); clearTimeout(timer); return release(); }
|
|
625
|
+
if (isFilled(ph) || placeholderLooksUsed(ph)) { S.phState.set(id, 'shown'); clearTimeout(timer); return release(); }
|
|
591
626
|
|
|
592
627
|
const t = ts();
|
|
593
628
|
if (t - (S.lastShow.get(id) ?? 0) < SHOW_THROTTLE_MS) { clearTimeout(timer); return release(); }
|
|
594
629
|
S.lastShow.set(id, t);
|
|
595
630
|
|
|
596
631
|
try { ph.closest?.(`.${WRAP_CLASS}`)?.setAttribute(A_SHOWN, String(t)); } catch (_) {}
|
|
632
|
+
S.phState.set(id, 'shown');
|
|
597
633
|
|
|
598
634
|
window.ezstandalone = window.ezstandalone || {};
|
|
599
635
|
const ez = window.ezstandalone;
|
|
600
636
|
const doShow = () => {
|
|
637
|
+
let wrap = null;
|
|
638
|
+
try { wrap = ph.closest?.(`.${WRAP_CLASS}`) || null; } catch (_) {}
|
|
601
639
|
try { ez.showAds(id); } catch (_) {}
|
|
640
|
+
if (wrap) scheduleUncollapseChecksForWrap(wrap);
|
|
602
641
|
scheduleEmptyCheck(id, t);
|
|
603
642
|
setTimeout(() => { clearTimeout(timer); release(); }, 700);
|
|
604
643
|
};
|
|
@@ -614,7 +653,8 @@
|
|
|
614
653
|
const wrap = ph?.closest?.(`.${WRAP_CLASS}`);
|
|
615
654
|
if (!wrap || !ph?.isConnected) return;
|
|
616
655
|
if (parseInt(wrap.getAttribute(A_SHOWN) || '0', 10) > showTs) return;
|
|
617
|
-
|
|
656
|
+
if (clearEmptyIfFilled(wrap)) return;
|
|
657
|
+
wrap.classList.add('is-empty');
|
|
618
658
|
} catch (_) {}
|
|
619
659
|
}, EMPTY_CHECK_MS);
|
|
620
660
|
}
|
|
@@ -642,7 +682,12 @@
|
|
|
642
682
|
if (isBlocked() || !q.size) return;
|
|
643
683
|
const ids = Array.from(q).sort((a, b) => a - b);
|
|
644
684
|
q.clear();
|
|
645
|
-
const valid = ids.filter(id =>
|
|
685
|
+
const valid = ids.filter(id => {
|
|
686
|
+
const ph = document.getElementById(`${PH_PREFIX}${id}`);
|
|
687
|
+
if (!ph?.isConnected) { S.phState.delete(id); return false; }
|
|
688
|
+
if (placeholderLooksUsed(ph)) { S.phState.set(id, 'shown'); return false; }
|
|
689
|
+
return true;
|
|
690
|
+
});
|
|
646
691
|
for (let i = 0; i < valid.length; i += BATCH_SIZE) {
|
|
647
692
|
const chunk = valid.slice(i, i + BATCH_SIZE);
|
|
648
693
|
try { orig(...chunk); } catch (_) {
|
|
@@ -656,7 +701,10 @@
|
|
|
656
701
|
for (const v of ids) {
|
|
657
702
|
const id = parseInt(v, 10);
|
|
658
703
|
if (!Number.isFinite(id) || id <= 0) continue;
|
|
659
|
-
|
|
704
|
+
const ph = document.getElementById(`${PH_PREFIX}${id}`);
|
|
705
|
+
if (!ph?.isConnected) continue;
|
|
706
|
+
if (placeholderLooksUsed(ph)) { S.phState.set(id, 'shown'); continue; }
|
|
707
|
+
S.phState.set(id, 'show-queued');
|
|
660
708
|
q.add(id);
|
|
661
709
|
}
|
|
662
710
|
if (!q.size) return;
|
|
@@ -762,6 +810,7 @@
|
|
|
762
810
|
S.wrapByKey.clear();
|
|
763
811
|
S.wrapsByClass.clear();
|
|
764
812
|
S.kind = null;
|
|
813
|
+
S.phState.clear();
|
|
765
814
|
S.inflight = 0;
|
|
766
815
|
S.pending = [];
|
|
767
816
|
S.pendingSet.clear();
|
|
@@ -776,6 +825,21 @@
|
|
|
776
825
|
if (S.domObs) return;
|
|
777
826
|
S.domObs = new MutationObserver(muts => {
|
|
778
827
|
if (S.mutGuard > 0 || isBlocked()) return;
|
|
828
|
+
for (const m of muts) {
|
|
829
|
+
if (m.type !== 'childList') continue;
|
|
830
|
+
for (const node of m.addedNodes) {
|
|
831
|
+
if (!(node instanceof Element)) continue;
|
|
832
|
+
let hasAd = false;
|
|
833
|
+
try {
|
|
834
|
+
hasAd = !!(node.matches?.(FILL_SEL) || node.querySelector?.(FILL_SEL));
|
|
835
|
+
} catch (_) {}
|
|
836
|
+
if (!hasAd) continue;
|
|
837
|
+
try {
|
|
838
|
+
const wrap = node.closest?.(`.${WRAP_CLASS}.is-empty`) || m.target?.closest?.(`.${WRAP_CLASS}.is-empty`);
|
|
839
|
+
if (wrap) clearEmptyIfFilled(wrap);
|
|
840
|
+
} catch (_) {}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
779
843
|
const relevant = (() => {
|
|
780
844
|
const k = getKind();
|
|
781
845
|
if (k === 'topic') return [SEL.post];
|
package/public/style.css
CHANGED
|
@@ -78,3 +78,14 @@
|
|
|
78
78
|
margin: 0 !important;
|
|
79
79
|
padding: 0 !important;
|
|
80
80
|
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
/* Anti-faux-empty : si une pub est présente, annule le collapse */
|
|
84
|
+
.nodebb-ezoic-wrap.is-empty:has(iframe),
|
|
85
|
+
.nodebb-ezoic-wrap.is-empty:has([data-google-container-id]),
|
|
86
|
+
.nodebb-ezoic-wrap.is-empty:has(div[id$="__container__"]) {
|
|
87
|
+
height: auto !important;
|
|
88
|
+
min-height: 0 !important;
|
|
89
|
+
max-height: none !important;
|
|
90
|
+
overflow: visible !important;
|
|
91
|
+
}
|