nodebb-plugin-ezoic-infinite 1.8.96 → 1.8.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/.claude/settings.local.json +4 -1
- package/library.js +3 -8
- package/package.json +1 -1
- package/public/client.js +52 -19
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
"WebFetch(domain:registry.npmjs.org)",
|
|
5
5
|
"Bash(curl -sL \"https://registry.npmjs.org/nodebb-plugin-ezoic-infinite/-/nodebb-plugin-ezoic-infinite-1.8.81.tgz\" -o /tmp/ezoic-1.8.81.tgz && tar -tzf /tmp/ezoic-1.8.81.tgz)",
|
|
6
6
|
"Bash(tar -xzf /tmp/ezoic-1.8.81.tgz -C /tmp/ package/library.js package/public/client.js package/package.json)",
|
|
7
|
-
"Bash(cd /tmp && curl -sL \"https://registry.npmjs.org/nodebb-plugin-ezoic-infinite/-/nodebb-plugin-ezoic-infinite-1.8.81.tgz\" -o ezoic-1.8.81.tgz && tar -xzf ezoic-1.8.81.tgz && echo \"Extracted OK\")"
|
|
7
|
+
"Bash(cd /tmp && curl -sL \"https://registry.npmjs.org/nodebb-plugin-ezoic-infinite/-/nodebb-plugin-ezoic-infinite-1.8.81.tgz\" -o ezoic-1.8.81.tgz && tar -xzf ezoic-1.8.81.tgz && echo \"Extracted OK\")",
|
|
8
|
+
"Bash(node -e \"require\\(''./library.js''\\)\")",
|
|
9
|
+
"Bash(node --check \"C:\\\\Users\\\\arnau\\\\OneDrive\\\\Dev\\\\nodebb-plugin-onekite-ezoic\\\\public\\\\client.js\")",
|
|
10
|
+
"Bash(node --check \"C:\\\\Users\\\\arnau\\\\OneDrive\\\\Dev\\\\nodebb-plugin-onekite-ezoic\\\\library.js\")"
|
|
8
11
|
]
|
|
9
12
|
}
|
|
10
13
|
}
|
package/library.js
CHANGED
|
@@ -101,15 +101,10 @@ async function isUserExcluded(uid, excludedGroups) {
|
|
|
101
101
|
|
|
102
102
|
_excludeCache.set(key, { value, at: Date.now() });
|
|
103
103
|
if (_excludeCache.size > 1000) {
|
|
104
|
-
let
|
|
105
|
-
const t = Date.now();
|
|
106
|
-
for (const [k, v] of _excludeCache) {
|
|
107
|
-
if (!toDel) break;
|
|
108
|
-
if (t - v.at >= EXCLUDE_TTL) { _excludeCache.delete(k); toDel--; }
|
|
109
|
-
}
|
|
104
|
+
let n = 100;
|
|
110
105
|
for (const k of _excludeCache.keys()) {
|
|
111
|
-
if (!
|
|
112
|
-
_excludeCache.delete(k);
|
|
106
|
+
if (!n--) break;
|
|
107
|
+
_excludeCache.delete(k);
|
|
113
108
|
}
|
|
114
109
|
}
|
|
115
110
|
|
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
SHOW_TIMEOUT_MS: 4_500,
|
|
35
35
|
SHOW_RELEASE_MS: 700,
|
|
36
36
|
RECYCLE_DELAY_MS: 300,
|
|
37
|
-
UNCOLLAPSE_CHECK_MS: [500,
|
|
37
|
+
UNCOLLAPSE_CHECK_MS: [500, 5_000],
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
const MAX_INSERTS_RUN = 6;
|
|
@@ -105,6 +105,12 @@
|
|
|
105
105
|
|
|
106
106
|
const isBlocked = () => now() < S.blockedUntil;
|
|
107
107
|
|
|
108
|
+
// ── Posts cache (burst-scoped) ─────────────────────────────────────────────
|
|
109
|
+
|
|
110
|
+
let _postsCache = null;
|
|
111
|
+
let _postsCacheTs = 0;
|
|
112
|
+
const POSTS_CACHE_MS = 200;
|
|
113
|
+
|
|
108
114
|
function mutate(fn) {
|
|
109
115
|
S.mutGuard++;
|
|
110
116
|
try { fn(); } finally { S.mutGuard--; }
|
|
@@ -176,6 +182,8 @@
|
|
|
176
182
|
// ── DOM queries ────────────────────────────────────────────────────────────
|
|
177
183
|
|
|
178
184
|
function getPosts() {
|
|
185
|
+
const t = now();
|
|
186
|
+
if (_postsCache && t - _postsCacheTs < POSTS_CACHE_MS) return _postsCache;
|
|
179
187
|
const all = document.querySelectorAll(SEL.post);
|
|
180
188
|
const out = [];
|
|
181
189
|
for (let i = 0; i < all.length; i++) {
|
|
@@ -188,6 +196,8 @@
|
|
|
188
196
|
if (el.getAttribute('component') === 'post/parent') continue;
|
|
189
197
|
out.push(el);
|
|
190
198
|
}
|
|
199
|
+
_postsCache = out;
|
|
200
|
+
_postsCacheTs = t;
|
|
191
201
|
return out;
|
|
192
202
|
}
|
|
193
203
|
|
|
@@ -256,17 +266,14 @@
|
|
|
256
266
|
const cfg = KIND[klass];
|
|
257
267
|
if (!cfg) return false;
|
|
258
268
|
const parent = wrap.parentElement;
|
|
259
|
-
if (parent)
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
269
|
+
if (!parent) return false;
|
|
270
|
+
const sel = `${cfg.baseTag || ''}[${cfg.anchorAttr}="${anchorId}"]`;
|
|
271
|
+
for (const sib of parent.children) {
|
|
272
|
+
if (sib !== wrap) {
|
|
273
|
+
try { if (sib.matches(sel)) return sib.isConnected; } catch (_) {}
|
|
265
274
|
}
|
|
266
275
|
}
|
|
267
|
-
|
|
268
|
-
return document.querySelector(`${cfg.sel}[${cfg.anchorAttr}="${anchorId}"]`)?.isConnected === true;
|
|
269
|
-
} catch (_) { return false; }
|
|
276
|
+
return false;
|
|
270
277
|
}
|
|
271
278
|
|
|
272
279
|
const adjacentWrap = el => wrapIsLive(el.nextElementSibling) || wrapIsLive(el.previousElementSibling);
|
|
@@ -489,9 +496,12 @@
|
|
|
489
496
|
|
|
490
497
|
// ── IntersectionObserver ───────────────────────────────────────────────────
|
|
491
498
|
|
|
499
|
+
let _ioMobile = null;
|
|
500
|
+
|
|
492
501
|
function getIO() {
|
|
493
502
|
if (S.io) return S.io;
|
|
494
503
|
try {
|
|
504
|
+
_ioMobile = isMobile();
|
|
495
505
|
S.io = new IntersectionObserver(entries => {
|
|
496
506
|
for (const e of entries) {
|
|
497
507
|
if (!e.isIntersecting) continue;
|
|
@@ -501,7 +511,7 @@
|
|
|
501
511
|
}
|
|
502
512
|
}, {
|
|
503
513
|
root: null,
|
|
504
|
-
rootMargin:
|
|
514
|
+
rootMargin: _ioMobile ? IO_MARGIN_MOBILE : IO_MARGIN_DESKTOP,
|
|
505
515
|
threshold: 0,
|
|
506
516
|
});
|
|
507
517
|
} catch (_) { S.io = null; }
|
|
@@ -700,7 +710,8 @@
|
|
|
700
710
|
for (const timers of S.wrapTimers.values()) { for (const t of timers) clearTimeout(t); }
|
|
701
711
|
S.wrapTimers.clear();
|
|
702
712
|
S.domObs?.disconnect(); S.domObs = null;
|
|
703
|
-
S.io?.disconnect(); S.io = null;
|
|
713
|
+
S.io?.disconnect(); S.io = null; _ioMobile = null;
|
|
714
|
+
_postsCache = null; _postsCacheTs = 0;
|
|
704
715
|
S.cfg = null;
|
|
705
716
|
S.opts = null;
|
|
706
717
|
S.poolsReady = false;
|
|
@@ -767,9 +778,12 @@
|
|
|
767
778
|
}
|
|
768
779
|
}
|
|
769
780
|
}
|
|
770
|
-
if (needsBurst) requestBurst();
|
|
781
|
+
if (needsBurst) { _postsCacheTs = 0; requestBurst(); }
|
|
771
782
|
});
|
|
772
|
-
try {
|
|
783
|
+
try {
|
|
784
|
+
const target = document.getElementById('content') || document.body;
|
|
785
|
+
S.domObs.observe(target, { childList: true, subtree: true });
|
|
786
|
+
} catch (_) {}
|
|
773
787
|
}
|
|
774
788
|
|
|
775
789
|
// ── TCF / CMP Protection ───────────────────────────────────────────────────
|
|
@@ -830,6 +844,8 @@
|
|
|
830
844
|
S.pageKey = pageKey(); S.kind = null; S.blockedUntil = 0;
|
|
831
845
|
ensureTcfLocator(); protectAriaHidden();
|
|
832
846
|
patchShowAds(); getIO(); ensureDomObserver();
|
|
847
|
+
RETRY.count = 0; RETRY.scriptReloaded = false; RETRY.postReloadShown = false; RETRY.gen++;
|
|
848
|
+
setTimeout(() => retryBoot(RETRY.gen), 250);
|
|
833
849
|
requestBurst();
|
|
834
850
|
});
|
|
835
851
|
// action:ajaxify.contentLoaded et action:category.loaded ne passent pas par hooks → jQuery uniquement
|
|
@@ -841,7 +857,7 @@
|
|
|
841
857
|
try {
|
|
842
858
|
require(['hooks'], hooks => {
|
|
843
859
|
if (typeof hooks?.on !== 'function') return;
|
|
844
|
-
for (const ev of ['action:
|
|
860
|
+
for (const ev of ['action:posts.loaded', 'action:topics.loaded', 'action:categories.loaded', 'action:topic.loaded'])
|
|
845
861
|
try { hooks.on(ev, () => { if (!isBlocked()) requestBurst(); }); } catch (_) {}
|
|
846
862
|
});
|
|
847
863
|
} catch (_) {}
|
|
@@ -855,6 +871,21 @@
|
|
|
855
871
|
}, { passive: true });
|
|
856
872
|
}
|
|
857
873
|
|
|
874
|
+
function bindResize() {
|
|
875
|
+
let timer = null;
|
|
876
|
+
window.addEventListener('resize', () => {
|
|
877
|
+
clearTimeout(timer);
|
|
878
|
+
timer = setTimeout(() => {
|
|
879
|
+
if (!S.io || _ioMobile === null) return;
|
|
880
|
+
const m = isMobile();
|
|
881
|
+
if (m === _ioMobile) return;
|
|
882
|
+
S.io.disconnect(); S.io = null; _ioMobile = null;
|
|
883
|
+
getIO();
|
|
884
|
+
for (const id of S.mountedIds) observePh(id);
|
|
885
|
+
}, 250);
|
|
886
|
+
}, { passive: true });
|
|
887
|
+
}
|
|
888
|
+
|
|
858
889
|
// ── Boot ───────────────────────────────────────────────────────────────────
|
|
859
890
|
|
|
860
891
|
S.pageKey = pageKey();
|
|
@@ -865,6 +896,7 @@
|
|
|
865
896
|
ensureDomObserver();
|
|
866
897
|
bindNodeBB();
|
|
867
898
|
bindScroll();
|
|
899
|
+
bindResize();
|
|
868
900
|
S.blockedUntil = 0;
|
|
869
901
|
if (document.readyState === 'complete') {
|
|
870
902
|
requestBurst();
|
|
@@ -882,8 +914,9 @@
|
|
|
882
914
|
// in ez-standalone.js → onStandaloneLoadEvent crash). After ~6s, remove and reload
|
|
883
915
|
// sa.min.js; Ezoic's partial first-run state may let the second run succeed.
|
|
884
916
|
// Once recovered, re-enqueue all mounted placeholders so showAds() fires.
|
|
885
|
-
const RETRY = { count: 0, scriptReloaded: false, postReloadShown: false };
|
|
886
|
-
function retryBoot() {
|
|
917
|
+
const RETRY = { count: 0, scriptReloaded: false, postReloadShown: false, gen: 0 };
|
|
918
|
+
function retryBoot(gen) {
|
|
919
|
+
if (gen !== RETRY.gen) return;
|
|
887
920
|
if (RETRY.count >= 12) return;
|
|
888
921
|
RETRY.count++;
|
|
889
922
|
// On pages that never show ads, no need to retry (unless mid-reload recovery)
|
|
@@ -938,8 +971,8 @@
|
|
|
938
971
|
S.lastBurstTs = now() - TIMING.BURST_COOLDOWN_MS;
|
|
939
972
|
requestBurst();
|
|
940
973
|
}
|
|
941
|
-
setTimeout(retryBoot, RETRY.count <= 4 ? 300 : 1000);
|
|
974
|
+
setTimeout(() => retryBoot(gen), RETRY.count <= 4 ? 300 : 1000);
|
|
942
975
|
}
|
|
943
|
-
setTimeout(retryBoot, 250);
|
|
976
|
+
setTimeout(() => retryBoot(RETRY.gen), 250);
|
|
944
977
|
|
|
945
978
|
})();
|