nodebb-plugin-ezoic-infinite 1.6.65 → 1.6.67
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 +25 -30
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -79,17 +79,12 @@
|
|
|
79
79
|
} catch (e) {}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
f.style.display = 'none';
|
|
89
|
-
f.id = f.name = '__tcfapiLocator';
|
|
90
|
-
(document.body || document.documentElement).appendChild(f);
|
|
91
|
-
} catch (e) {}
|
|
92
|
-
}
|
|
82
|
+
// ensureTcfApiLocator intentionally removed:
|
|
83
|
+
// Creating our own __tcfapiLocator iframe conflicts with the CMP's own locator
|
|
84
|
+
// management and causes "Cannot read properties of null (reading 'postMessage')"
|
|
85
|
+
// errors when the CMP tries to postMessage to an iframe we created then navigated away.
|
|
86
|
+
// The CMP (Ezoic/IAB TCF) handles its own locator iframe lifecycle.
|
|
87
|
+
function ensureTcfApiLocator() { /* no-op */ }
|
|
93
88
|
|
|
94
89
|
// ─── Ezoic min-height tightener ─────────────────────────────────────────────
|
|
95
90
|
// Ezoic injects `min-height:400px !important` on nested wrappers via inline
|
|
@@ -468,10 +463,8 @@
|
|
|
468
463
|
// ─── Orphan / cluster management ────────────────────────────────────────────
|
|
469
464
|
function pruneOrphanWraps(kindClass, items) {
|
|
470
465
|
if (!items || !items.length) return 0;
|
|
471
|
-
const itemSet
|
|
472
|
-
const isMessage
|
|
473
|
-
// Between/category ads are NEVER fully released — only hidden/shown.
|
|
474
|
-
// Releasing frees IDs into the pool → re-injection at wrong positions.
|
|
466
|
+
const itemSet = new Set(items);
|
|
467
|
+
const isMessage = kindClass === 'ezoic-ad-message';
|
|
475
468
|
const allowRelease = isMessage;
|
|
476
469
|
let removed = 0;
|
|
477
470
|
|
|
@@ -495,19 +488,26 @@
|
|
|
495
488
|
|
|
496
489
|
document.querySelectorAll('.' + WRAP_CLASS + '.' + kindClass).forEach((wrap) => {
|
|
497
490
|
if (wrap.getAttribute('data-ezoic-pin') === '1') return;
|
|
498
|
-
const created = parseInt(wrap.getAttribute('data-created') || '0', 10);
|
|
499
|
-
if (created && (now() - created) < keepEmptyWrapMs()) return;
|
|
500
491
|
|
|
501
492
|
if (hasNearbyItem(wrap)) {
|
|
493
|
+
// Anchor is in the DOM → always restore visibility, regardless of age.
|
|
502
494
|
try { wrap.classList.remove('ez-orphan-hidden'); wrap.style.display = ''; } catch (e) {}
|
|
503
495
|
return;
|
|
504
496
|
}
|
|
505
497
|
|
|
506
|
-
// Anchor
|
|
498
|
+
// Anchor is NOT in the DOM → always hide immediately, regardless of age.
|
|
499
|
+
// KEY FIX: the previous code skipped this for fresh wraps (< keepEmptyWrapMs).
|
|
500
|
+
// That meant a wrap whose anchor topic was virtualized away within the first
|
|
501
|
+
// 60-120s would stay visible and float to the top of the list.
|
|
507
502
|
try { wrap.classList.add('ez-orphan-hidden'); wrap.style.display = 'none'; } catch (e) {}
|
|
503
|
+
|
|
504
|
+
// Release (message-ads only): only after the freshness window, and only
|
|
505
|
+
// when far off-screen — we still want late-filling ads to have a chance.
|
|
508
506
|
if (!allowRelease) return;
|
|
509
507
|
|
|
510
|
-
|
|
508
|
+
const created = parseInt(wrap.getAttribute('data-created') || '0', 10);
|
|
509
|
+
if (created && (now() - created) < keepEmptyWrapMs()) return;
|
|
510
|
+
|
|
511
511
|
try {
|
|
512
512
|
const r = wrap.getBoundingClientRect();
|
|
513
513
|
const vh = Math.max(1, window.innerHeight || 1);
|
|
@@ -909,23 +909,18 @@
|
|
|
909
909
|
const maxInserts = MAX_INSERTS_PER_RUN + (isBoosted() ? 1 : 0);
|
|
910
910
|
let inserted = 0;
|
|
911
911
|
|
|
912
|
-
// Viewport top — we never inject after an element that is fully above this.
|
|
913
|
-
// This is the definitive guard against NodeBB loading content above the fold
|
|
914
|
-
// and our scanner immediately injecting ads on those newly-loaded top items.
|
|
915
|
-
// We use a generous negative margin so items just barely scrolled above still
|
|
916
|
-
// get ads injected (they'll be visible when the user scrolls back a little).
|
|
917
|
-
const viewportSafeTop = -(window.innerHeight || 800) * 0.5;
|
|
918
|
-
|
|
919
912
|
for (const afterPos of targets) {
|
|
920
913
|
if (inserted >= maxInserts) break;
|
|
921
914
|
const el = ordinalMap.get(afterPos);
|
|
922
915
|
if (!el || !el.isConnected) continue;
|
|
923
916
|
|
|
924
|
-
//
|
|
925
|
-
//
|
|
917
|
+
// Never inject after an element that is fully above the viewport top.
|
|
918
|
+
// This is the definitive guard: NodeBB loads items above the fold when the
|
|
919
|
+
// user scrolls up. Those items have rect.bottom < 0 at the moment of load.
|
|
920
|
+
// Any negative margin ("a little above is ok") still causes the pile-up
|
|
921
|
+
// because NodeBB loads a whole batch just above — we must use exactly 0.
|
|
926
922
|
try {
|
|
927
|
-
|
|
928
|
-
if (rect.bottom < viewportSafeTop) continue;
|
|
923
|
+
if (el.getBoundingClientRect().bottom < 0) continue;
|
|
929
924
|
} catch (e) {}
|
|
930
925
|
|
|
931
926
|
if (isAdjacentAd(el)) continue;
|