nodebb-plugin-ezoic-infinite 1.6.91 → 1.6.93

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 +51 -31
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.6.91",
3
+ "version": "1.6.93",
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
@@ -9,8 +9,12 @@
9
9
 
10
10
  let config = null;
11
11
  let isInternalChange = false;
12
+
13
+ // Registre global pour ne JAMAIS redéfinir un ID déjà vu par Ezoic
14
+ window.ezoicDefinedIds = window.ezoicDefinedIds || new Set();
15
+
12
16
  let pendingIds = new Set();
13
- let refreshTimer = null;
17
+ let triggerTimer = null;
14
18
 
15
19
  function getPool() {
16
20
  let p = document.getElementById(POOL_ID);
@@ -27,18 +31,24 @@
27
31
  if (typeof window.ezstandalone === 'undefined' || pendingIds.size === 0) return;
28
32
 
29
33
  window.ezstandalone.cmd.push(function() {
30
- const idsToProcess = Array.from(pendingIds);
34
+ const allPending = Array.from(pendingIds);
31
35
  pendingIds.clear();
32
36
 
33
- // On enregistre les IDs
34
- window.ezstandalone.define(idsToProcess);
37
+ // Filtrer pour ne garder que les IDs JAMAIS définis auparavant
38
+ const newIdsToDefine = allPending.filter(id => !window.ezoicDefinedIds.has(id));
39
+
40
+ if (newIdsToDefine.length > 0) {
41
+ window.ezstandalone.define(newIdsToDefine);
42
+ newIdsToDefine.forEach(id => window.ezoicDefinedIds.add(id));
43
+ }
35
44
 
36
- // On appelle UNIQUEMENT refresh.
37
- // Si Ezoic n'est pas "enabled", il ignorera l'appel sans erreur bloquante.
45
+ // La doc dit : showAds(id1, id2) pour le nouveau contenu
46
+ // On appelle showAds sur tous les IDs qu'on vient d'injecter,
47
+ // qu'ils soient nouveaux ou recyclés.
38
48
  try {
39
- window.ezstandalone.refresh();
49
+ window.ezstandalone.showAds.apply(null, allPending);
40
50
  } catch (e) {
41
- console.debug('[Ezoic] Refresh deferred');
51
+ console.warn('[Ezoic] showAds failed', e);
42
52
  }
43
53
  });
44
54
  }
@@ -47,29 +57,28 @@
47
57
  const pid = parseInt(id, 10);
48
58
  if (isNaN(pid)) return;
49
59
  pendingIds.add(pid);
50
-
51
- clearTimeout(refreshTimer);
52
- refreshTimer = setTimeout(triggerEzoic, 300);
60
+
61
+ clearTimeout(triggerTimer);
62
+ triggerTimer = setTimeout(triggerEzoic, 150);
53
63
  }
54
64
 
55
65
  function redistribute() {
56
66
  if (!config || config.excluded) return;
57
67
 
58
- // 1. Accueil (Catégories)
59
- const categoryItems = document.querySelectorAll('.category-item, [component="categories/category"]');
60
- // 2. Liste Topics
61
- const topicItems = document.querySelectorAll('li[component="category/topic"]');
62
- // 3. Messages
63
- const postItems = document.querySelectorAll('[component="post"]');
68
+ const selectors = {
69
+ 'home': '.category-item, [component="categories/category"]',
70
+ 'topic-list': 'li[component="category/topic"]',
71
+ 'message': '[component="post"]'
72
+ };
64
73
 
65
- if (categoryItems.length > 0 && config.enableCategoryAds) {
66
- process(Array.from(categoryItems), 'home', config.intervalCategories, config.showFirstCategoryAd);
74
+ if (config.enableCategoryAds) {
75
+ process(Array.from(document.querySelectorAll(selectors.home)), 'home', config.intervalCategories, config.showFirstCategoryAd);
67
76
  }
68
- if (topicItems.length > 0 && config.enableBetweenAds) {
69
- process(Array.from(topicItems), 'topic-list', config.intervalPosts, config.showFirstTopicAd);
77
+ if (config.enableBetweenAds) {
78
+ process(Array.from(document.querySelectorAll(selectors['topic-list'])), 'topic-list', config.intervalPosts, config.showFirstTopicAd);
70
79
  }
71
- if (postItems.length > 0 && config.enableMessageAds) {
72
- process(Array.from(postItems), 'message', config.messageIntervalPosts, config.showFirstMessageAd);
80
+ if (config.enableMessageAds) {
81
+ process(Array.from(document.querySelectorAll(selectors.message)), 'message', config.messageIntervalPosts, config.showFirstMessageAd);
73
82
  }
74
83
  }
75
84
 
@@ -79,14 +88,16 @@
79
88
  const pos = index + 1;
80
89
  const shouldHaveAd = (pos === 1 && showFirst) || (pos % int === 0);
81
90
  const next = item.nextElementSibling;
91
+
82
92
  if (shouldHaveAd && !(next && next.classList.contains(WRAP_CLASS))) {
83
93
  const pool = getPool();
84
94
  const available = pool.querySelector(`.${WRAP_CLASS}[data-kind="${kind}"]`);
95
+
85
96
  if (available) {
86
97
  isInternalChange = true;
87
98
  item.parentNode.insertBefore(available, item.nextSibling);
88
99
  callEzoic(available.getAttribute('data-placeholder-id'));
89
- setTimeout(() => { isInternalChange = false; }, 100);
100
+ setTimeout(() => { isInternalChange = false; }, 50);
90
101
  }
91
102
  }
92
103
  });
@@ -101,17 +112,21 @@
101
112
  const setup = (raw, kind) => {
102
113
  if (!raw) return;
103
114
  raw.split(/[\s,]+/).filter(Boolean).forEach(id => {
104
- const d = document.createElement('div');
105
- d.className = WRAP_CLASS;
106
- d.setAttribute('data-kind', kind);
107
- d.setAttribute('data-placeholder-id', id);
108
- d.innerHTML = `<div id="ezoic-pub-ad-placeholder-${id}"></div>`;
109
- pool.appendChild(d);
115
+ // Créer le placeholder dans le pool s'il n'existe pas encore physiquement
116
+ if (!pool.querySelector(`[data-placeholder-id="${id}"]`)) {
117
+ const d = document.createElement('div');
118
+ d.className = WRAP_CLASS;
119
+ d.setAttribute('data-kind', kind);
120
+ d.setAttribute('data-placeholder-id', id);
121
+ d.innerHTML = `<div id="ezoic-pub-ad-placeholder-${id}"></div>`;
122
+ pool.appendChild(d);
123
+ }
110
124
  });
111
125
  };
112
126
  setup(config.categoryPlaceholderIds, 'home');
113
127
  setup(config.placeholderIds, 'topic-list');
114
128
  setup(config.messagePlaceholderIds, 'message');
129
+
115
130
  redistribute();
116
131
 
117
132
  const observer = new MutationObserver(() => {
@@ -121,7 +136,12 @@
121
136
  });
122
137
  }
123
138
 
124
- window.addEventListener('action:ajaxify.end', () => setTimeout(redistribute, 500));
139
+ // Navigation NodeBB (Ajaxify)
140
+ window.addEventListener('action:ajaxify.end', () => {
141
+ // On ne détruit RIEN au changement de page pour éviter les erreurs "already defined"
142
+ // On se contente de ré-injecter les placeholders du pool
143
+ setTimeout(redistribute, 500);
144
+ });
125
145
 
126
146
  if (document.readyState === 'loading') {
127
147
  document.addEventListener('DOMContentLoaded', init);