nodebb-plugin-ezoic-infinite 1.7.24 → 1.7.25

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 +52 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.7.24",
3
+ "version": "1.7.25",
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,5 +1,5 @@
1
1
  /**
2
- * NodeBB Ezoic Infinite Ads — client.js v30
2
+ * NodeBB Ezoic Infinite Ads — client.js v31
3
3
  *
4
4
  * Historique des corrections majeures
5
5
  * ────────────────────────────────────
@@ -31,6 +31,13 @@
31
31
  *
32
32
  * v29 Fix ancrage topics : data-index → data-tid.
33
33
  *
34
+ * v31 pruneOrphans réactivé UNIQUEMENT pour ezoic-ad-between (topics de catégorie).
35
+ * NodeBB NE virtualise PAS les topics dans une liste de catégorie — les ancres
36
+ * restent dans le DOM entre les scrolls. pruneOrphans est donc safe ici et
37
+ * c'est lui qui empêche l'empilement des pubs en haut après un scroll long.
38
+ * Pour ezoic-ad-message (posts de topic), pruneOrphans reste désactivé car
39
+ * NodeBB virtualise les posts hors-viewport → faux-orphelins → bug réinjection.
40
+ *
34
41
  * v30 Fix adjacentWrap : ne compte plus les wraps orphelins (ancre hors DOM).
35
42
  * Quand NodeBB virtualise et retire des topics du DOM, les wraps restent
36
43
  * en place (div dans le ul). adjacentWrap(el) retournait true sur ces
@@ -319,15 +326,45 @@
319
326
  } catch (_) {}
320
327
  }
321
328
 
322
- // ── Prune : désactivé ─────────────────────────────────────────────────────
329
+ // ── Prune (topics de catégorie uniquement) ────────────────────────────────
330
+ //
331
+ // pruneOrphans est réactivé UNIQUEMENT pour 'ezoic-ad-between'.
323
332
  //
324
- // pruneOrphans() a été supprimé car il causait le bug "pubs en haut".
325
- // NodeBB virtualise les posts hors viewport les ancres disparaissent du DOM
326
- // temporairement pruneOrphans supprimait les wraps scroll retour → les
327
- // ancres revenaient injectBetween réinjectait tout en haut.
333
+ // Pourquoi safe pour les topics ?
334
+ // NodeBB ne virtualise PAS la liste des topics dans une catégorie.
335
+ // Les <li component="category/topic"> restent dans le DOM pendant toute
336
+ // la session. Leurs ancres (data-tid) sont donc stables un wrap orphelin
337
+ // signifie vraiment que le topic a été retiré (navigation, filtre, etc.).
328
338
  //
329
- // Les wraps ne sont supprimés que par cleanup() à chaque navigation ajaxify.
330
- // decluster() et pruneOrphans() sont désactivés voir v28.
339
+ // Pourquoi désactivé pour les posts ?
340
+ // NodeBB virtualise les posts hors-viewport : il retire les <li> du DOM
341
+ // puis les réinsère au scroll retour. pruneOrphans verait des ancres
342
+ // absentes → supprimerait les wraps → réinjection en haut au scroll retour.
343
+ //
344
+ // MIN_PRUNE_AGE_MS : délai de grâce après création (stabilisation du DOM).
345
+
346
+ const MIN_PRUNE_AGE_MS = 8_000;
347
+
348
+ function pruneOrphansBetween() {
349
+ const klass = 'ezoic-ad-between';
350
+ const cfg = KIND[klass];
351
+
352
+ document.querySelectorAll(`.${WRAP_CLASS}.${klass}`).forEach(w => {
353
+ // Délai de grâce : ne pas pruner un wrap trop récent
354
+ const created = parseInt(w.getAttribute(A_CREATED) || '0', 10);
355
+ if (ts() - created < MIN_PRUNE_AGE_MS) return;
356
+
357
+ const key = w.getAttribute(A_ANCHOR) ?? '';
358
+ const sid = key.slice(klass.length + 1); // partie après "ezoic-ad-between:"
359
+ if (!sid) { mutate(() => dropWrap(w)); return; }
360
+
361
+ // Chercher l'ancre par data-tid
362
+ const anchorEl = document.querySelector(`${cfg.baseTag}[${cfg.anchorAttr}="${sid}"]`);
363
+ if (!anchorEl || !anchorEl.isConnected) {
364
+ mutate(() => dropWrap(w));
365
+ }
366
+ });
367
+ }
331
368
 
332
369
 
333
370
  // ── Injection ──────────────────────────────────────────────────────────────
@@ -520,10 +557,13 @@
520
557
  'ezoic-ad-message', getPosts,
521
558
  cfg.enableMessageAds, cfg.messageIntervalPosts, cfg.showFirstMessageAd, 'posts'
522
559
  );
523
- if (kind === 'categoryTopics') return exec(
524
- 'ezoic-ad-between', getTopics,
525
- cfg.enableBetweenAds, cfg.intervalPosts, cfg.showFirstTopicAd, 'topics'
526
- );
560
+ if (kind === 'categoryTopics') {
561
+ pruneOrphansBetween(); // nettoie les wraps dont le topic a disparu du DOM
562
+ return exec(
563
+ 'ezoic-ad-between', getTopics,
564
+ cfg.enableBetweenAds, cfg.intervalPosts, cfg.showFirstTopicAd, 'topics'
565
+ );
566
+ }
527
567
  return exec(
528
568
  'ezoic-ad-categories', getCategories,
529
569
  cfg.enableCategoryAds, cfg.intervalCategories, cfg.showFirstCategoryAd, 'categories'