nodebb-plugin-ezoic-infinite 1.5.90 → 1.5.91
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 -27
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1,32 +1,54 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
// =====
|
|
5
|
-
|
|
4
|
+
// ===== V6 anchor-map stability layer =====
|
|
5
|
+
var __ezoicAnchorMap = Object.create(null);
|
|
6
|
+
|
|
7
|
+
function ezoicGetAnchorKey(el, afterPos, kindClass) {
|
|
6
8
|
try {
|
|
7
|
-
if (!el) return 'pos:' + String(
|
|
9
|
+
if (!el) return kindClass + ':pos:' + String(afterPos || 0);
|
|
8
10
|
var pid = el.getAttribute && (el.getAttribute('data-pid') || el.getAttribute('data-id'));
|
|
9
|
-
if (pid) return 'pid:' + String(pid);
|
|
11
|
+
if (pid) return kindClass + ':pid:' + String(pid);
|
|
10
12
|
var tid = el.getAttribute && (el.getAttribute('data-tid') || el.getAttribute('data-topic-id'));
|
|
11
|
-
if (tid) return 'tid:' + String(tid);
|
|
12
|
-
var
|
|
13
|
-
if (
|
|
14
|
-
var
|
|
15
|
-
if (
|
|
13
|
+
if (tid) return kindClass + ':tid:' + String(tid);
|
|
14
|
+
var a = el.querySelector && el.querySelector('[data-pid],[data-id],[data-tid],[data-topic-id]');
|
|
15
|
+
if (a) {
|
|
16
|
+
var p = a.getAttribute('data-pid') || a.getAttribute('data-id');
|
|
17
|
+
if (p) return kindClass + ':pid:' + String(p);
|
|
18
|
+
var t = a.getAttribute('data-tid') || a.getAttribute('data-topic-id');
|
|
19
|
+
if (t) return kindClass + ':tid:' + String(t);
|
|
16
20
|
}
|
|
17
21
|
} catch (e) {}
|
|
18
|
-
return 'pos:' + String(
|
|
22
|
+
return kindClass + ':pos:' + String(afterPos || 0);
|
|
19
23
|
}
|
|
20
24
|
|
|
21
|
-
function
|
|
25
|
+
function ezoicRegisterWrapAnchor(wrap, anchorKey) {
|
|
22
26
|
try {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
if (!wrap || !anchorKey) return;
|
|
28
|
+
wrap.setAttribute('data-ezoic-anchor', anchorKey);
|
|
29
|
+
__ezoicAnchorMap[anchorKey] = wrap;
|
|
30
|
+
} catch (e) {}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function ezoicFindWrapByAnchor(anchorKey) {
|
|
34
|
+
try {
|
|
35
|
+
var w = __ezoicAnchorMap[anchorKey];
|
|
36
|
+
if (w && w.isConnected) return w;
|
|
37
|
+
} catch (e) {}
|
|
38
|
+
try {
|
|
39
|
+
return document.querySelector('.nodebb-ezoic-wrap[data-ezoic-anchor="' + String(anchorKey).replace(/"/g, '') + '"]');
|
|
40
|
+
} catch (e) { return null; }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function ezoicCleanupAnchorMap() {
|
|
44
|
+
try {
|
|
45
|
+
Object.keys(__ezoicAnchorMap).forEach(function(k){
|
|
46
|
+
var w = __ezoicAnchorMap[k];
|
|
47
|
+
if (!w || !w.isConnected) delete __ezoicAnchorMap[k];
|
|
48
|
+
});
|
|
49
|
+
} catch (e) {}
|
|
28
50
|
}
|
|
29
|
-
// ===== /
|
|
51
|
+
// ===== /V6 =====
|
|
30
52
|
|
|
31
53
|
|
|
32
54
|
// Track scroll direction to avoid aggressive recycling when the user scrolls upward.
|
|
@@ -668,7 +690,8 @@ function globalGapFixInit() {
|
|
|
668
690
|
const wrap = document.createElement('div');
|
|
669
691
|
wrap.className = `${WRAP_CLASS} ${kindClass}`;
|
|
670
692
|
wrap.setAttribute('data-ezoic-after', String(afterPos));
|
|
671
|
-
|
|
693
|
+
var __anchorKey = ezoicGetAnchorKey(el, afterPos, kindClass);
|
|
694
|
+
ezoicRegisterWrapAnchor(wrap, __anchorKey);
|
|
672
695
|
wrap.setAttribute('data-ezoic-wrapid', String(id));
|
|
673
696
|
wrap.setAttribute('data-created', String(now()));
|
|
674
697
|
// "Pinned" placements (after the first item) should remain stable.
|
|
@@ -796,8 +819,8 @@ if (isMessage) {
|
|
|
796
819
|
const farBelow = r.top > vh * 4;
|
|
797
820
|
if (!farAbove && !farBelow) return;
|
|
798
821
|
} catch (e) {
|
|
799
|
-
|
|
800
|
-
}
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
801
824
|
}
|
|
802
825
|
|
|
803
826
|
withInternalDomChange(() => releaseWrapNode(wrap));
|
|
@@ -1108,9 +1131,7 @@ function buildOrdinalMap(items) {
|
|
|
1108
1131
|
}
|
|
1109
1132
|
|
|
1110
1133
|
function injectBetween(kindClass, items, interval, showFirst, allIds, cursorKey) {
|
|
1111
|
-
|
|
1112
|
-
// V5.1: stable anchor dedupe (prevents regrouping while preserving multiple ads)
|
|
1113
|
-
|
|
1134
|
+
ezoicCleanupAnchorMap();
|
|
1114
1135
|
if (!items.length) return 0;
|
|
1115
1136
|
|
|
1116
1137
|
const { map: ordinalMap, max: maxOrdinal } = buildOrdinalMap(items);
|
|
@@ -1134,9 +1155,10 @@ function buildOrdinalMap(items) {
|
|
|
1134
1155
|
// This avoids "Placeholder Id X has already been defined" and also ensures ads keep
|
|
1135
1156
|
// appearing on very long infinite scroll sessions.
|
|
1136
1157
|
if (!id) {
|
|
1137
|
-
//
|
|
1138
|
-
//
|
|
1139
|
-
|
|
1158
|
+
// Safe mode: disable recycling for topic message ads to prevent visual "jumping"
|
|
1159
|
+
// (ads seemingly moving back under the first post during virtualized scroll).
|
|
1160
|
+
const allowRecycle = kindClass !== 'ezoic-ad-message';
|
|
1161
|
+
recycledWrap = (allowRecycle && scrollDir > 0) ? pickRecyclableWrap(kindClass) : null;
|
|
1140
1162
|
if (recycledWrap) {
|
|
1141
1163
|
id = recycledWrap.getAttribute('data-ezoic-wrapid') || '';
|
|
1142
1164
|
}
|
|
@@ -1163,7 +1185,7 @@ function buildOrdinalMap(items) {
|
|
|
1163
1185
|
}
|
|
1164
1186
|
|
|
1165
1187
|
function moveWrapAfter(anchorEl, wrap, kindClass, afterPos) {
|
|
1166
|
-
|
|
1188
|
+
return;
|
|
1167
1189
|
}
|
|
1168
1190
|
|
|
1169
1191
|
async function runCore() {
|
|
@@ -1503,3 +1525,28 @@ function buildOrdinalMap(items) {
|
|
|
1503
1525
|
insertHeroAdEarly().catch(() => {});
|
|
1504
1526
|
requestBurst();
|
|
1505
1527
|
})();
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
// V6 guard: prevent unexpected regrouping under first topic
|
|
1531
|
+
try {
|
|
1532
|
+
if (typeof MutationObserver !== 'undefined' && !window.__ezoicWrapGuardInstalled) {
|
|
1533
|
+
window.__ezoicWrapGuardInstalled = true;
|
|
1534
|
+
var guardObserver = new MutationObserver(function() {
|
|
1535
|
+
try {
|
|
1536
|
+
Object.keys(__ezoicAnchorMap).forEach(function(k){
|
|
1537
|
+
var w = __ezoicAnchorMap[k];
|
|
1538
|
+
if (!w || !w.isConnected) return;
|
|
1539
|
+
var anchor = w.getAttribute('data-ezoic-anchor') || '';
|
|
1540
|
+
var m = anchor.match(/:(pid|tid):(.+)$/);
|
|
1541
|
+
if (!m) return;
|
|
1542
|
+
var val = m[2];
|
|
1543
|
+
var anchorEl = document.querySelector('[data-pid="' + val + '"], [data-id="' + val + '"], [data-tid="' + val + '"], [data-topic-id="' + val + '"]');
|
|
1544
|
+
if (anchorEl && w.previousElementSibling !== anchorEl) {
|
|
1545
|
+
if (anchorEl.parentNode) anchorEl.parentNode.insertBefore(w, anchorEl.nextSibling);
|
|
1546
|
+
}
|
|
1547
|
+
});
|
|
1548
|
+
} catch (e) {}
|
|
1549
|
+
});
|
|
1550
|
+
guardObserver.observe(document.body || document.documentElement, { childList: true, subtree: true });
|
|
1551
|
+
}
|
|
1552
|
+
} catch (e) {}
|