nodebb-plugin-ezoic-infinite 1.0.7 → 1.0.10

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 +58 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.0.7",
3
+ "version": "1.0.10",
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
@@ -40,7 +40,27 @@
40
40
  return document.querySelectorAll('li[component="category/topic"]').length > 0 && !isTopicPage();
41
41
  }
42
42
 
43
+
44
+ function normalizeBool(v) {
45
+ return v === true || v === 1 || v === '1' || v === 'on' || v === 'true' || v === 'yes';
46
+ }
47
+
48
+ function normalizeInterval(v, fallback) {
49
+ const n = parseInt(v, 10);
50
+ return Number.isFinite(n) && n > 0 ? n : fallback;
51
+ }
52
+
53
+ function getPoolValue(v) {
54
+ // Accept string, array of numbers/strings
55
+ if (Array.isArray(v)) return v.join('\n');
56
+ return v;
57
+ }
58
+
43
59
  function parsePool(raw) {
60
+ raw = getPoolValue(raw);
61
+
62
+ raw = getPoolValue(raw);
63
+
44
64
  if (!raw) return [];
45
65
  // accept newline, comma, space, semicolon
46
66
  const arr = String(raw).split(/[\n,;\s]+/)
@@ -91,13 +111,20 @@
91
111
  destroyPlaceholder(id);
92
112
  }
93
113
 
114
+ function showAdsOnceForElement(wrapperEl, id) {
115
+ if (!wrapperEl || !id) return;
116
+ if (wrapperEl.getAttribute('data-ezoic-shown') === '1') return;
117
+ wrapperEl.setAttribute('data-ezoic-shown', '1');
118
+ callShowAdsSingle(id);
119
+ }
120
+
94
121
  function callShowAdsSingle(id) {
95
122
  if (!id) return;
96
123
 
97
124
  const now = Date.now();
98
125
  window.__ezoicLastSingle = window.__ezoicLastSingle || {};
99
126
  const last = window.__ezoicLastSingle[id] || 0;
100
- if (now - last < 1200) return;
127
+ if (now - last < 4000) return;
101
128
  window.__ezoicLastSingle[id] = now;
102
129
 
103
130
  window.ezstandalone = window.ezstandalone || {};
@@ -150,11 +177,12 @@
150
177
  wrap.setAttribute('data-ezoic-after', String(afterVal));
151
178
  wrap.innerHTML = '<div class="ezoic-ad-inner"><div id="ezoic-pub-ad-placeholder-' + id + '"></div></div>';
152
179
  targetEl.insertAdjacentElement('afterend', wrap);
180
+ return wrap;
153
181
  }
154
182
 
155
183
  function injectBetweenTopics(cfg) {
156
- if (!cfg.enableBetweenAds) return;
157
- const interval = Math.max(1, parseInt(cfg.intervalPosts, 10) || 6);
184
+ if (!normalizeBool(cfg.enableBetweenAds)) return;
185
+ const interval = normalizeInterval(cfg.intervalPosts ?? cfg.intervalTopics, 6);
158
186
  const pool = parsePool(cfg.placeholderIds);
159
187
  if (!pool.length) return;
160
188
 
@@ -178,14 +206,14 @@
178
206
  usedBetween.add(id);
179
207
  fifoBetween.push({ id, after: pos });
180
208
 
181
- insertAfter(li, id, 'ezoic-ad-between', pos);
182
- callShowAdsSingle(id);
209
+ const wrap = insertAfter(li, id, 'ezoic-ad-between', pos);
210
+ showAdsOnceForElement(wrap, id);
183
211
  });
184
212
  }
185
213
 
186
214
  function injectBetweenMessages(cfg) {
187
- if (!cfg.enableMessageAds) return;
188
- const interval = Math.max(1, parseInt(cfg.messageIntervalPosts, 10) || 3);
215
+ if (!normalizeBool(cfg.enableMessageAds)) return;
216
+ const interval = normalizeInterval(cfg.messageIntervalPosts, 3);
189
217
  const pool = parsePool(cfg.messagePlaceholderIds);
190
218
  if (!pool.length) return;
191
219
 
@@ -209,8 +237,8 @@
209
237
  usedMessage.add(id);
210
238
  fifoMessage.push({ id, after: no });
211
239
 
212
- insertAfter(post, id, 'ezoic-ad-message', no);
213
- callShowAdsSingle(id);
240
+ const wrap = insertAfter(post, id, 'ezoic-ad-message', no);
241
+ showAdsOnceForElement(wrap, id);
214
242
  });
215
243
  }
216
244
 
@@ -223,13 +251,27 @@
223
251
  if (pageKey !== key) {
224
252
  pageKey = key;
225
253
  cleanupForNewPage();
254
+ window.__ezoicCatRetry = 0;
226
255
  }
227
256
 
228
257
  const cfg = await fetchConfig();
229
258
  if (!cfg || cfg.excluded) return;
230
259
 
231
- if (isTopicPage()) injectBetweenMessages(cfg);
232
- else if (isCategoryTopicList()) injectBetweenTopics(cfg);
260
+ if (isTopicPage()) {
261
+ injectBetweenMessages(cfg);
262
+ } else {
263
+ // category/topic list pages may render after ajaxify end; retry a few times
264
+ const hasList = document.querySelectorAll('li[component="category/topic"]').length > 0;
265
+ if (hasList) {
266
+ injectBetweenTopics(cfg);
267
+ } else {
268
+ window.__ezoicCatRetry = window.__ezoicCatRetry || 0;
269
+ if (window.__ezoicCatRetry < 10) {
270
+ window.__ezoicCatRetry++;
271
+ setTimeout(run, 250);
272
+ }
273
+ }
274
+ }
233
275
  } catch (e) {
234
276
  // silent
235
277
  } finally {
@@ -259,6 +301,7 @@ function bindNodeBBEvents() {
259
301
  $w.on('action:ajaxify.start.ezoicInfinite', function () {
260
302
  pageKey = null;
261
303
  cleanupForNewPage();
304
+ window.__ezoicCatRetry = 0;
262
305
  });
263
306
  }
264
307
  }
@@ -267,7 +310,10 @@ function bindNodeBBEvents() {
267
310
 
268
311
  // Run immediately, so it works on first ajaxify navigation too
269
312
  run();
270
- setTimeout(run, 1200);
313
+ setTimeout(function(){
314
+ // only retry if nothing was injected yet
315
+ if (!document.querySelector('.ezoic-ad')) run();
316
+ }, 1400);
271
317
 
272
318
  // Also run on hard-refresh initial load
273
319
  if (document.readyState === 'loading') {