nodebb-plugin-ezoic-infinite 1.4.38 → 1.4.40

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 +25 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.4.38",
3
+ "version": "1.4.40",
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
@@ -365,12 +365,13 @@
365
365
  if (window.location.pathname !== '/') {
366
366
  console.log('[TIMING] ABORT ID', id, '- navigation détectée avant showAds');
367
367
  }
368
+ // Note: les timeouts seront nettoyés par cleanup()
368
369
  return;
369
370
  }
370
371
 
371
372
  // Si doCall() réussit, Ezoic est chargé et showAds a été appelé → sortir
372
373
  if (doCall()) {
373
- state.pendingById.delete(id); // nettoyage au cas où
374
+ state.pendingById.delete(id);
374
375
  return;
375
376
  }
376
377
 
@@ -392,7 +393,10 @@
392
393
  return;
393
394
  }
394
395
 
395
- if (attempts < 100) setTimeout(waitForPh, 50);
396
+ if (attempts < 100) {
397
+ const timeoutId = setTimeout(waitForPh, 50);
398
+ state.activeTimeouts.add(timeoutId);
399
+ }
396
400
  })();
397
401
  }
398
402
 
@@ -556,7 +560,13 @@
556
560
  // quand NodeBB vide le DOM lors de la navigation ajaxify
557
561
  // Les supprimer manuellement cause des problèmes avec l'état interne d'Ezoic
558
562
 
563
+ // CRITIQUE: Annuler TOUS les timeouts en cours pour éviter que les anciens
564
+ // showAds() continuent à s'exécuter après la navigation
565
+ state.activeTimeouts.forEach(id => clearTimeout(id));
566
+ state.activeTimeouts.clear();
567
+
559
568
  if (state.obs) { state.obs.disconnect(); state.obs = null; }
569
+ state.canInsert = false;
560
570
  state.scheduled = false;
561
571
  clearTimeout(state.timer);
562
572
  state.timer = null;
@@ -569,6 +579,11 @@
569
579
  }
570
580
 
571
581
  async function runCore() {
582
+ // Attendre que canInsert soit true (protection race condition navigation)
583
+ if (!state.canInsert) {
584
+ return;
585
+ }
586
+
572
587
  patchShowAds();
573
588
 
574
589
  const cfg = await fetchConfig();
@@ -658,6 +673,14 @@
658
673
  $(window).on('action:ajaxify.end.ezoicInfinite', () => {
659
674
  state.pageKey = getPageKey();
660
675
  ensureObserver();
676
+
677
+ // CRITIQUE: Attendre 300ms avant de permettre l'insertion de nouveaux placeholders
678
+ // pour laisser les anciens showAds() (en cours) se terminer ou échouer proprement
679
+ // Sinon race condition: NodeBB vide le DOM pendant que Ezoic essaie d'accéder aux placeholders
680
+ state.canInsert = false;
681
+ setTimeout(() => {
682
+ state.canInsert = true;
683
+ }, 1000);
661
684
  });
662
685
 
663
686
  $(window).on('action:category.loaded.ezoicInfinite', () => {