nodebb-plugin-ezoic-infinite 0.8.3 → 0.8.6

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 +49 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "0.8.3",
3
+ "version": "0.8.6",
4
4
  "description": "Ezoic ads with infinite scroll using a pool of placeholder IDs",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -25,7 +25,8 @@ let fifoCat = []; // [{afterPos, id}]
25
25
  function resetState() {
26
26
  seenAfterPostNo = new Set();
27
27
  seenAfterTopicPos = new Set();
28
- usedIds = new Set();
28
+ usedIdsMsg = new Set();
29
+ usedIdsBetween = new Set();
29
30
  fifo = [];
30
31
  fifoCat = [];
31
32
  }
@@ -108,14 +109,23 @@ function cleanupOnNav() {
108
109
  $('.ezoic-ad-post, .ezoic-ad-topic').remove();
109
110
  }
110
111
 
111
- function pickNextId(pool) {
112
+ function pickNextId(pool, usedSet) {
112
113
  for (const id of pool) {
113
- if (!usedIds.has(id)) return id;
114
+ if (!usedSet.has(id)) return id;
114
115
  }
115
116
  return null;
117
+ } finally {
118
+ window.__ezoicRecycling = false;
119
+ }
116
120
  }
117
121
 
118
122
  function destroyEzoicId(id) {
123
+ window.__ezoicLastDestroy = window.__ezoicLastDestroy || {};
124
+ const now = Date.now();
125
+ if (window.__ezoicLastDestroy[id] && now - window.__ezoicLastDestroy[id] < 2000) {
126
+ return;
127
+ }
128
+ window.__ezoicLastDestroy[id] = now;
119
129
  try {
120
130
  window.ezstandalone = window.ezstandalone || {};
121
131
  window.ezstandalone.cmd = window.ezstandalone.cmd || [];
@@ -132,6 +142,9 @@ function destroyEzoicId(id) {
132
142
  }
133
143
 
134
144
  function recycleOldestTopicId($posts) {
145
+ if (window.__ezoicRecycling) return null;
146
+ window.__ezoicRecycling = true;
147
+ try {
135
148
  if (!fifo.length) return null;
136
149
  fifo.sort((a, b) => a.afterPostNo - b.afterPostNo);
137
150
 
@@ -151,14 +164,20 @@ function recycleOldestTopicId($posts) {
151
164
  } catch (e) {}
152
165
 
153
166
  $el.remove();
154
- usedIds.delete(old.id);
167
+ usedIdsMsg.delete(old.id);
155
168
  destroyEzoicId(old.id);
156
169
  return old.id;
157
170
  }
158
171
  return null;
172
+ } finally {
173
+ window.__ezoicRecycling = false;
174
+ }
159
175
  }
160
176
 
161
177
  function recycleOldestCategoryId($items) {
178
+ if (window.__ezoicRecycling) return null;
179
+ window.__ezoicRecycling = true;
180
+ try {
162
181
  if (!fifoCat.length) return null;
163
182
  fifoCat.sort((a, b) => a.afterPos - b.afterPos);
164
183
 
@@ -177,7 +196,7 @@ function recycleOldestCategoryId($items) {
177
196
  } catch (e) {}
178
197
 
179
198
  $el.remove();
180
- usedIds.delete(old.id);
199
+ usedIdsBetween.delete(old.id);
181
200
  destroyEzoicId(old.id);
182
201
  return old.id;
183
202
  }
@@ -336,7 +355,7 @@ function injectTopicMessageAds($posts, pool, interval) {
336
355
  if (postNo % interval !== 0) return;
337
356
  if (seenAfterPostNo.has(postNo)) return;
338
357
 
339
- let id = pickNextId(pool);
358
+ let id = pickNextId(pool, usedIdsMsg);
340
359
  if (!id) {
341
360
  id = recycleOldestTopicId($posts);
342
361
  if (!id) return;
@@ -353,7 +372,7 @@ function injectTopicMessageAds($posts, pool, interval) {
353
372
  $p.after(html);
354
373
 
355
374
  seenAfterPostNo.add(postNo);
356
- usedIds.add(id);
375
+ usedIdsMsg.add(id);
357
376
  fifo.push({ afterPostNo: postNo, id: id });
358
377
  newIds.push(id);
359
378
  });
@@ -375,7 +394,7 @@ function injectCategoryBetweenAds($items, pool, interval) {
375
394
  if (pos % interval !== 0) return;
376
395
  if (seenAfterTopicPos.has(pos)) return;
377
396
 
378
- let id = pickNextId(pool);
397
+ let id = pickNextId(pool, usedIdsBetween);
379
398
  if (!id) {
380
399
  id = recycleOldestCategoryId($items);
381
400
  if (!id) return;
@@ -392,7 +411,7 @@ function injectCategoryBetweenAds($items, pool, interval) {
392
411
  $it.after(html);
393
412
 
394
413
  seenAfterTopicPos.add(pos);
395
- usedIds.add(id);
414
+ usedIdsBetween.add(id);
396
415
  fifoCat.push({ afterPos: pos, id: id });
397
416
  newIds.push(id);
398
417
  });
@@ -401,6 +420,9 @@ function injectCategoryBetweenAds($items, pool, interval) {
401
420
  }
402
421
 
403
422
  async function refreshAds() {
423
+ const now = Date.now();
424
+ if (window.__ezoicRefreshThrottle && now - window.__ezoicRefreshThrottle < 250) return;
425
+ window.__ezoicRefreshThrottle = now;
404
426
  const key = getPageKey();
405
427
  if (pageKey !== key) {
406
428
  pageKey = key;
@@ -462,6 +484,24 @@ function debounceRefresh() {
462
484
 
463
485
  $(document).ready(function () { setupAdAutoHeight(); debounceRefresh(); });
464
486
 
487
+ $(window).on('action:ajaxify.start', function (ev, data) {
488
+ // IMPORTANT: do not cleanup on infinite scroll loads; only when navigating to a different page.
489
+ try {
490
+ const targetUrl = (data && (data.url || data.href)) ? String(data.url || data.href) : '';
491
+ if (targetUrl) {
492
+ const a = document.createElement('a');
493
+ a.href = targetUrl;
494
+ const targetPath = a.pathname || targetUrl;
495
+ // If we're staying on the same logical page (same path), don't wipe ads/state
496
+ if (targetPath === window.location.pathname) {
497
+ return;
498
+ }
499
+ }
500
+ } catch (e) {}
501
+ pageKey = null;
502
+ resetState();
503
+ cleanupOnNav();
504
+ });
465
505
  $(window).on('action:ajaxify.end action:posts.loaded action:topic.loaded action:topics.loaded action:category.loaded', debounceRefresh);
466
506
 
467
507
  setTimeout(function () { setupAdAutoHeight(); debounceRefresh(); }, 2200);