nodebb-plugin-ezoic-infinite 1.4.10 → 1.4.12

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 +54 -30
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.4.10",
3
+ "version": "1.4.12",
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
@@ -14,6 +14,11 @@
14
14
 
15
15
  const MAX_INSERTS_PER_RUN = 2;
16
16
 
17
+ // IDs ayant été définis par Ezoic au moins une fois dans cette session navigateur.
18
+ // Survit aux navigations ajaxify (contrairement à state.definedIds remis à zéro dans cleanup).
19
+ // Nécessaire pour savoir si on doit appeler destroyPlaceholders avant recyclage.
20
+ const sessionDefinedIds = new Set();
21
+
17
22
  const state = {
18
23
  pageKey: null,
19
24
  cfg: null,
@@ -126,7 +131,8 @@
126
131
  if (!ids || !ids.length) return;
127
132
  // Only destroy ids that were actually "defined" (filled at least once) to avoid Ezoic warnings.
128
133
  const filtered = ids.filter((id) => {
129
- try { return state.definedIds && state.definedIds.has(id); } catch (e) { return true; }
134
+ // Utiliser sessionDefinedIds (survit aux navigations) plutôt que state.definedIds
135
+ try { return sessionDefinedIds.has(id); } catch (e) { return true; }
130
136
  });
131
137
  if (!filtered.length) return;
132
138
 
@@ -233,29 +239,42 @@
233
239
 
234
240
  function patchShowAds() {
235
241
  // Minimal safety net: batch showAds can be triggered by other scripts; split into individual calls.
236
- try {
237
- window.ezstandalone = window.ezstandalone || {};
238
- const ez = window.ezstandalone;
239
- if (window.__nodebbEzoicPatched) return;
240
- if (typeof ez.showAds !== 'function') return;
241
-
242
- window.__nodebbEzoicPatched = true;
243
- const orig = ez.showAds;
244
-
245
- ez.showAds = function (arg) {
246
- if (Array.isArray(arg)) {
247
- const seen = new Set();
248
- for (const v of arg) {
249
- const id = parseInt(v, 10);
250
- if (!Number.isFinite(id) || id <= 0 || seen.has(id)) continue;
251
- seen.add(id);
252
- try { orig.call(ez, id); } catch (e) {}
242
+ // Also ensures the patch is applied even if Ezoic loads after our script.
243
+ const applyPatch = () => {
244
+ try {
245
+ window.ezstandalone = window.ezstandalone || {};
246
+ const ez = window.ezstandalone;
247
+ if (window.__nodebbEzoicPatched) return;
248
+ if (typeof ez.showAds !== 'function') return;
249
+
250
+ window.__nodebbEzoicPatched = true;
251
+ const orig = ez.showAds;
252
+
253
+ ez.showAds = function (arg) {
254
+ if (Array.isArray(arg)) {
255
+ const seen = new Set();
256
+ for (const v of arg) {
257
+ const id = parseInt(v, 10);
258
+ if (!Number.isFinite(id) || id <= 0 || seen.has(id)) continue;
259
+ seen.add(id);
260
+ try { orig.call(ez, id); } catch (e) {}
261
+ }
262
+ return;
253
263
  }
254
- return;
255
- }
256
- return orig.apply(ez, arguments);
257
- };
258
- } catch (e) {}
264
+ return orig.apply(ez, arguments);
265
+ };
266
+ } catch (e) {}
267
+ };
268
+
269
+ applyPatch();
270
+ // Si Ezoic n'est pas encore chargé, appliquer le patch via sa cmd queue
271
+ if (!window.__nodebbEzoicPatched) {
272
+ try {
273
+ window.ezstandalone = window.ezstandalone || {};
274
+ window.ezstandalone.cmd = window.ezstandalone.cmd || [];
275
+ window.ezstandalone.cmd.push(applyPatch);
276
+ } catch (e) {}
277
+ }
259
278
  }
260
279
 
261
280
 
@@ -280,13 +299,13 @@
280
299
  // Already filled?
281
300
  if (ph.childNodes && ph.childNodes.length > 0) {
282
301
  markFilled(wrap);
283
- state.definedIds && state.definedIds.add(id);
302
+ state.definedIds && state.definedIds.add(id); sessionDefinedIds.add(id);
284
303
  return;
285
304
  }
286
305
  const obs = new MutationObserver(() => {
287
306
  if (ph.childNodes && ph.childNodes.length > 0) {
288
307
  markFilled(wrap);
289
- try { state.definedIds && state.definedIds.add(id); } catch (e) {}
308
+ try { state.definedIds && state.definedIds.add(id); sessionDefinedIds.add(id); } catch (e) {}
290
309
  try { obs.disconnect(); } catch (e) {}
291
310
  }
292
311
  });
@@ -305,7 +324,7 @@
305
324
 
306
325
  const filled = !!(ph.childNodes && ph.childNodes.length > 0);
307
326
  if (filled) {
308
- try { state.definedIds && state.definedIds.add(id); } catch (e) {}
327
+ try { state.definedIds && state.definedIds.add(id); sessionDefinedIds.add(id); } catch (e) {}
309
328
  try { markFilled(wrap); } catch (e) {}
310
329
  }
311
330
  return filled;
@@ -347,7 +366,10 @@
347
366
  resetPlaceholderInWrap(wrapNow, id);
348
367
  attachFillObserver(wrapNow, id);
349
368
  }
350
- callShowAdsWhenReady(id);
369
+ // Ne pas appeler showAds si un autre appel est déjà en cours pour cet ID
370
+ if (!state.pendingById.has(id)) {
371
+ callShowAdsWhenReady(id);
372
+ }
351
373
  setTimeout(step, 1100);
352
374
  };
353
375
 
@@ -415,12 +437,13 @@
415
437
  (function waitForPh() {
416
438
  // Abort if the user navigated away since this showAds was scheduled
417
439
  if (state.pageKey !== startPageKey) return;
440
+ // Abort if another concurrent call is already handling this id
441
+ if (state.pendingById.has(id)) return;
418
442
  attempts += 1;
419
443
  const el = document.getElementById(phId);
420
444
  if (el && el.isConnected) {
421
445
  if (doCall()) return;
422
446
 
423
- if (state.pendingById.has(id)) return;
424
447
  state.pendingById.add(id);
425
448
 
426
449
  window.ezstandalone = window.ezstandalone || {};
@@ -525,7 +548,7 @@
525
548
  let wrap = null;
526
549
  if (pick.recycled && pick.recycled.wrap) {
527
550
  // Only destroy if Ezoic has actually defined this placeholder before
528
- if (state.definedIds && state.definedIds.has(id)) {
551
+ if (sessionDefinedIds.has(id)) {
529
552
  destroyPlaceholderIds([id]);
530
553
  }
531
554
  // Remove the old wrapper entirely, then create a fresh wrapper at the new position (same id)
@@ -534,7 +557,8 @@
534
557
  try { oldWrap && oldWrap.remove(); } catch (e) {}
535
558
  wrap = insertAfter(el, id, kindClass, afterPos);
536
559
  if (!wrap) continue;
537
- setTimeout(() => { enqueueRetry(id); }, 450);
560
+ // Attendre 1500ms après destroy pour laisser Ezoic finir son cleanup interne
561
+ setTimeout(() => { enqueueRetry(id); }, 1500);
538
562
  } else {
539
563
  usedSet.add(id);
540
564
  wrap = insertAfter(el, id, kindClass, afterPos);