nodebb-plugin-ezoic-infinite 1.5.90 → 1.5.92

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/public/client.js +12 -31
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.5.90",
3
+ "version": "1.5.92",
4
4
  "description": "Production-ready Ezoic infinite ads integration for NodeBB 4.x",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -1,32 +1,15 @@
1
1
  (function () {
2
2
  'use strict';
3
3
 
4
- // ===== V5.1 multi-ads stable anchors =====
5
- function getStableAnchorKey(el, fallbackPos) {
4
+ function ezoicTrySetAnchor(wrap, el, kindClass, afterPos) {
6
5
  try {
7
- if (!el) return 'pos:' + String(fallbackPos || 0);
6
+ if (!wrap || !el) return;
8
7
  var pid = el.getAttribute && (el.getAttribute('data-pid') || el.getAttribute('data-id'));
9
- if (pid) return 'pid:' + String(pid);
10
8
  var tid = el.getAttribute && (el.getAttribute('data-tid') || el.getAttribute('data-topic-id'));
11
- if (tid) return 'tid:' + String(tid);
12
- var topic = el.querySelector && el.querySelector('[data-tid],[data-topic-id]');
13
- if (topic) {
14
- var t = topic.getAttribute('data-tid') || topic.getAttribute('data-topic-id');
15
- if (t) return 'tid:' + String(t);
16
- }
9
+ var key = kindClass + ':' + (pid ? ('pid:' + pid) : (tid ? ('tid:' + tid) : ('pos:' + String(afterPos || 0))));
10
+ wrap.setAttribute('data-ezoic-anchor', key);
17
11
  } catch (e) {}
18
- return 'pos:' + String(fallbackPos || 0);
19
- }
20
-
21
- function findWrapByAnchor(kindClass, anchorKey) {
22
- try {
23
- var sel = '.nodebb-ezoic-wrap.' + kindClass + '[data-ezoic-anchor="' + anchorKey.replace(/"/g, '') + '"]';
24
- return document.querySelector(sel);
25
- } catch (e) {
26
- return null;
27
- }
28
12
  }
29
- // ===== /V5.1 =====
30
13
 
31
14
 
32
15
  // Track scroll direction to avoid aggressive recycling when the user scrolls upward.
@@ -668,7 +651,7 @@ function globalGapFixInit() {
668
651
  const wrap = document.createElement('div');
669
652
  wrap.className = `${WRAP_CLASS} ${kindClass}`;
670
653
  wrap.setAttribute('data-ezoic-after', String(afterPos));
671
- try { wrap.setAttribute('data-ezoic-anchor', getStableAnchorKey(el, afterPos)); } catch (e) {}
654
+ ezoicTrySetAnchor(wrap, el, kindClass, afterPos);
672
655
  wrap.setAttribute('data-ezoic-wrapid', String(id));
673
656
  wrap.setAttribute('data-created', String(now()));
674
657
  // "Pinned" placements (after the first item) should remain stable.
@@ -796,8 +779,8 @@ if (isMessage) {
796
779
  const farBelow = r.top > vh * 4;
797
780
  if (!farAbove && !farBelow) return;
798
781
  } catch (e) {
799
- // keep original behavior in base build
800
- }
782
+ return;
783
+ }
801
784
  }
802
785
 
803
786
  withInternalDomChange(() => releaseWrapNode(wrap));
@@ -1108,9 +1091,6 @@ function buildOrdinalMap(items) {
1108
1091
  }
1109
1092
 
1110
1093
  function injectBetween(kindClass, items, interval, showFirst, allIds, cursorKey) {
1111
-
1112
- // V5.1: stable anchor dedupe (prevents regrouping while preserving multiple ads)
1113
-
1114
1094
  if (!items.length) return 0;
1115
1095
 
1116
1096
  const { map: ordinalMap, max: maxOrdinal } = buildOrdinalMap(items);
@@ -1134,9 +1114,10 @@ function buildOrdinalMap(items) {
1134
1114
  // This avoids "Placeholder Id X has already been defined" and also ensures ads keep
1135
1115
  // appearing on very long infinite scroll sessions.
1136
1116
  if (!id) {
1137
- // Only recycle while scrolling down. Recycling while scrolling up tends to
1138
- // cause perceived instability (ads bunching/disappearing).
1139
- recycledWrap = scrollDir > 0 ? pickRecyclableWrap(kindClass) : null;
1117
+ // Safe mode: disable recycling for topic message ads to prevent visual "jumping"
1118
+ // (ads seemingly moving back under the first post during virtualized scroll).
1119
+ const allowRecycle = kindClass !== 'ezoic-ad-message';
1120
+ recycledWrap = (allowRecycle && scrollDir > 0) ? pickRecyclableWrap(kindClass) : null;
1140
1121
  if (recycledWrap) {
1141
1122
  id = recycledWrap.getAttribute('data-ezoic-wrapid') || '';
1142
1123
  }
@@ -1163,7 +1144,7 @@ function buildOrdinalMap(items) {
1163
1144
  }
1164
1145
 
1165
1146
  function moveWrapAfter(anchorEl, wrap, kindClass, afterPos) {
1166
- // keep original behavior in base build
1147
+ return;
1167
1148
  }
1168
1149
 
1169
1150
  async function runCore() {