nodebb-plugin-ezoic-infinite 1.6.79 → 1.6.81
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.
- package/library.js +13 -10
- package/package.json +1 -1
- package/public/client.js +41 -25
- package/public/style.css +12 -25
package/library.js
CHANGED
|
@@ -8,27 +8,30 @@ const SETTINGS_KEY = 'ezoic-infinite';
|
|
|
8
8
|
const plugin = {};
|
|
9
9
|
|
|
10
10
|
async function getSettings() {
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async function getAllGroups() {
|
|
15
|
-
const names = await db.getSortedSetRange('groups:createtime', 0, -1);
|
|
16
|
-
const data = await groups.getGroupsData(names);
|
|
17
|
-
return data.filter(g => g && g.name).map(g => ({ name: g.name }));
|
|
11
|
+
const settings = await meta.settings.get(SETTINGS_KEY);
|
|
12
|
+
return settings || {};
|
|
18
13
|
}
|
|
19
14
|
|
|
20
15
|
async function isUserExcluded(uid, excludedGroups) {
|
|
21
|
-
if (!uid || !excludedGroups
|
|
22
|
-
|
|
16
|
+
if (!uid || !excludedGroups) return false;
|
|
17
|
+
const groupsList = Array.isArray(excludedGroups) ? excludedGroups : [excludedGroups];
|
|
18
|
+
if (!groupsList.length) return false;
|
|
19
|
+
return await groups.isMemberOfGroups(uid, groupsList);
|
|
23
20
|
}
|
|
24
21
|
|
|
25
22
|
plugin.init = async ({ router, middleware }) => {
|
|
26
23
|
const renderAdmin = async (req, res) => {
|
|
27
24
|
const settings = await getSettings();
|
|
28
|
-
const
|
|
25
|
+
const names = await db.getSortedSetRange('groups:createtime', 0, -1);
|
|
26
|
+
const groupsData = await groups.getGroupsData(names);
|
|
27
|
+
const allGroups = groupsData.filter(g => g && g.name).map(g => ({ name: g.name }));
|
|
28
|
+
|
|
29
29
|
res.render('admin/plugins/ezoic-infinite', {
|
|
30
30
|
...settings,
|
|
31
31
|
allGroups,
|
|
32
|
+
// Helper pour le tpl
|
|
33
|
+
enableBetweenAds_checked: settings.enableBetweenAds === 'on' ? 'checked' : '',
|
|
34
|
+
enableMessageAds_checked: settings.enableMessageAds === 'on' ? 'checked' : ''
|
|
32
35
|
});
|
|
33
36
|
};
|
|
34
37
|
|
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
// --- Gestion de la direction du scroll ---
|
|
5
4
|
let lastScrollY = 0;
|
|
6
|
-
let scrollDir = 1;
|
|
5
|
+
let scrollDir = 1;
|
|
7
6
|
try {
|
|
8
7
|
lastScrollY = window.scrollY || 0;
|
|
9
8
|
window.addEventListener('scroll', () => {
|
|
@@ -22,6 +21,7 @@
|
|
|
22
21
|
|
|
23
22
|
let config = null;
|
|
24
23
|
let isInternalChange = false;
|
|
24
|
+
let ezInitialized = false; // Flag crucial pour éviter l'erreur de "refresh"
|
|
25
25
|
|
|
26
26
|
function withInternalDomChange(fn) {
|
|
27
27
|
isInternalChange = true;
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function releaseWrapNode(wrap) {
|
|
43
|
-
if (!wrap) return;
|
|
43
|
+
if (!wrap || !wrap.parentNode) return;
|
|
44
44
|
const pool = getPool();
|
|
45
45
|
wrap.classList.remove('ez-orphan-hidden');
|
|
46
46
|
if (wrap.parentNode !== pool) {
|
|
@@ -48,19 +48,18 @@
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
//
|
|
51
|
+
// Anti-pillup : évite que deux pubs se suivent
|
|
52
52
|
function decluster(container) {
|
|
53
53
|
const wraps = Array.from(container.querySelectorAll(`.${WRAP_CLASS}`));
|
|
54
54
|
wraps.forEach(wrap => {
|
|
55
55
|
let next = wrap.nextElementSibling;
|
|
56
|
-
// Si deux blocs de pub se suivent sans contenu entre les deux
|
|
57
56
|
if (next && next.classList.contains(WRAP_CLASS)) {
|
|
58
57
|
withInternalDomChange(() => releaseWrapNode(next));
|
|
59
58
|
}
|
|
60
59
|
});
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
//
|
|
62
|
+
// Nettoyage des pubs orphelines lors de la virtualisation
|
|
64
63
|
function pruneOrphanWraps() {
|
|
65
64
|
const wraps = document.querySelectorAll(`.${WRAP_CLASS}`);
|
|
66
65
|
const items = document.querySelectorAll('[component="category/topic"], [component="post"]');
|
|
@@ -68,9 +67,7 @@
|
|
|
68
67
|
|
|
69
68
|
wraps.forEach(wrap => {
|
|
70
69
|
if (wrap.parentElement && wrap.parentElement.id === POOL_ID) return;
|
|
71
|
-
|
|
72
70
|
let hasNeighbor = false;
|
|
73
|
-
// On vérifie la proximité immédiate (3 éléments) pour voir si le contenu est toujours là
|
|
74
71
|
let prev = wrap.previousElementSibling;
|
|
75
72
|
for (let i = 0; i < 3 && prev; i++) {
|
|
76
73
|
if (itemSet.has(prev)) { hasNeighbor = true; break; }
|
|
@@ -85,7 +82,6 @@
|
|
|
85
82
|
}
|
|
86
83
|
|
|
87
84
|
if (!hasNeighbor) {
|
|
88
|
-
// En remontee (scroll UP), on recycle immédiatement pour éviter l'empilement visuel
|
|
89
85
|
if (scrollDir === -1) {
|
|
90
86
|
withInternalDomChange(() => releaseWrapNode(wrap));
|
|
91
87
|
} else {
|
|
@@ -97,10 +93,36 @@
|
|
|
97
93
|
});
|
|
98
94
|
}
|
|
99
95
|
|
|
96
|
+
function callEzoic(placeholderId) {
|
|
97
|
+
if (typeof window.ezstandalone === 'undefined') return;
|
|
98
|
+
const pid = parseInt(placeholderId, 10);
|
|
99
|
+
if (isNaN(pid)) return;
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
if (!ezInitialized) {
|
|
103
|
+
// PREMIER APPEL : define + enable + display
|
|
104
|
+
window.ezstandalone.define(pid);
|
|
105
|
+
window.ezstandalone.enable();
|
|
106
|
+
window.ezstandalone.display();
|
|
107
|
+
ezInitialized = true;
|
|
108
|
+
} else {
|
|
109
|
+
// APPELS SUIVANTS (Scroll) : define + refresh
|
|
110
|
+
window.ezstandalone.define(pid);
|
|
111
|
+
// On attend que le DOM soit stable pour le refresh
|
|
112
|
+
setTimeout(() => {
|
|
113
|
+
if (document.getElementById('ezoic-pub-ad-placeholder-' + pid)) {
|
|
114
|
+
window.ezstandalone.refresh();
|
|
115
|
+
}
|
|
116
|
+
}, 150);
|
|
117
|
+
}
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.warn('[Ezoic-Infinite] Ez Error:', e.message);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
100
123
|
function redistribute(container) {
|
|
101
124
|
if (!container || !config || config.excluded) return;
|
|
102
125
|
|
|
103
|
-
// 1. On nettoie avant d'injecter
|
|
104
126
|
pruneOrphanWraps();
|
|
105
127
|
decluster(container);
|
|
106
128
|
|
|
@@ -132,7 +154,6 @@
|
|
|
132
154
|
let inserts = 0;
|
|
133
155
|
items.forEach((item, index) => {
|
|
134
156
|
if (inserts >= MAX_INSERTS_PER_RUN) return;
|
|
135
|
-
|
|
136
157
|
const pos = index + 1;
|
|
137
158
|
let shouldHaveAd = (pos % interval === 0);
|
|
138
159
|
if (pos === 1 && showFirst) shouldHaveAd = true;
|
|
@@ -146,14 +167,7 @@
|
|
|
146
167
|
if (available) {
|
|
147
168
|
withInternalDomChange(() => {
|
|
148
169
|
item.parentNode.insertBefore(available, item.nextSibling);
|
|
149
|
-
|
|
150
|
-
if (typeof window.ezstandalone !== 'undefined') {
|
|
151
|
-
const pid = available.getAttribute('data-placeholder-id');
|
|
152
|
-
try {
|
|
153
|
-
window.ezstandalone.define(parseInt(pid, 10));
|
|
154
|
-
window.ezstandalone.refresh();
|
|
155
|
-
} catch (e) {}
|
|
156
|
-
}
|
|
170
|
+
callEzoic(available.getAttribute('data-placeholder-id'));
|
|
157
171
|
});
|
|
158
172
|
inserts++;
|
|
159
173
|
}
|
|
@@ -166,11 +180,10 @@
|
|
|
166
180
|
.then(r => r.json())
|
|
167
181
|
.then(data => {
|
|
168
182
|
config = data;
|
|
169
|
-
// Initialisation du pool d'IDs
|
|
170
183
|
const pool = getPool();
|
|
171
184
|
const setupPool = (idsRaw, kind) => {
|
|
172
185
|
if (!idsRaw) return;
|
|
173
|
-
const ids = idsRaw.split(/[\s,]+/).filter(Boolean);
|
|
186
|
+
const ids = idsRaw.split(/[\s,]+/).map(s => s.trim()).filter(Boolean);
|
|
174
187
|
ids.forEach(id => {
|
|
175
188
|
if (!document.querySelector(`[data-placeholder-id="${id}"]`)) {
|
|
176
189
|
const d = document.createElement('div');
|
|
@@ -188,16 +201,17 @@
|
|
|
188
201
|
setupPool(config.placeholderIds, 'between');
|
|
189
202
|
setupPool(config.messagePlaceholderIds, 'message');
|
|
190
203
|
cb();
|
|
191
|
-
});
|
|
204
|
+
}).catch(e => console.error('[Ezoic] Config load error', e));
|
|
192
205
|
}
|
|
193
206
|
|
|
194
207
|
let timer = null;
|
|
195
208
|
function schedule() {
|
|
196
209
|
if (timer) clearTimeout(timer);
|
|
197
210
|
timer = setTimeout(() => {
|
|
198
|
-
|
|
211
|
+
// Sélecteurs pour NodeBB 4.x / Harmony
|
|
212
|
+
const lists = document.querySelectorAll('[component="category"], .topic-list, [component="topic"], [component="category/topic/list"]');
|
|
199
213
|
lists.forEach(redistribute);
|
|
200
|
-
},
|
|
214
|
+
}, 200);
|
|
201
215
|
}
|
|
202
216
|
|
|
203
217
|
function init() {
|
|
@@ -206,7 +220,9 @@
|
|
|
206
220
|
if (typeof MutationObserver !== 'undefined') {
|
|
207
221
|
const mo = new MutationObserver((muts) => {
|
|
208
222
|
if (isInternalChange) return;
|
|
209
|
-
|
|
223
|
+
// On vérifie si un élément structurel a été ajouté
|
|
224
|
+
const shouldRun = muts.some(m => m.addedNodes.length > 0);
|
|
225
|
+
if (shouldRun) schedule();
|
|
210
226
|
});
|
|
211
227
|
mo.observe(document.body, { childList: true, subtree: true });
|
|
212
228
|
}
|
package/public/style.css
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
/* Container
|
|
1
|
+
/* Container principal */
|
|
2
2
|
.nodebb-ezoic-wrap {
|
|
3
3
|
display: block;
|
|
4
4
|
width: 100%;
|
|
5
|
-
margin:
|
|
5
|
+
margin: 20px 0 !important;
|
|
6
6
|
padding: 0 !important;
|
|
7
7
|
clear: both;
|
|
8
|
-
|
|
9
|
-
min-height: 1px;
|
|
8
|
+
min-height: 50px; /* Important pour que l'ad-tester détecte le bloc */
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
/* Cache les pubs orphelines sans
|
|
11
|
+
/* Cache les pubs orphelines sans les supprimer du DOM */
|
|
13
12
|
.nodebb-ezoic-wrap.ez-orphan-hidden {
|
|
14
13
|
display: none !important;
|
|
15
14
|
height: 0 !important;
|
|
15
|
+
min-height: 0 !important;
|
|
16
16
|
margin: 0 !important;
|
|
17
|
-
padding: 0 !important;
|
|
18
|
-
pointer-events: none;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
/*
|
|
19
|
+
/* Nettoyage des styles internes Ezoic */
|
|
22
20
|
.nodebb-ezoic-wrap .ezoic-ad {
|
|
23
21
|
margin: 0 auto !important;
|
|
24
22
|
padding: 0 !important;
|
|
@@ -26,23 +24,12 @@
|
|
|
26
24
|
height: auto !important;
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
/*
|
|
30
|
-
.nodebb-ezoic-wrap
|
|
31
|
-
|
|
32
|
-
line-height: 0 !important;
|
|
33
|
-
font-size: 0 !important;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/* Harmonisation pour Harmony/NodeBB 4 */
|
|
37
|
-
[component="category"] .nodebb-ezoic-wrap,
|
|
38
|
-
.topic-list .nodebb-ezoic-wrap {
|
|
39
|
-
border-bottom: 1px solid rgba(0,0,0,0.05);
|
|
40
|
-
background: transparent;
|
|
27
|
+
/* Neutralise les marges doubles */
|
|
28
|
+
.nodebb-ezoic-wrap + .nodebb-ezoic-wrap {
|
|
29
|
+
margin-top: 0 !important;
|
|
41
30
|
}
|
|
42
31
|
|
|
43
|
-
/*
|
|
44
|
-
.
|
|
45
|
-
|
|
46
|
-
max-width: 100%;
|
|
47
|
-
margin: 0 auto;
|
|
32
|
+
/* Évite les débordements sur mobile */
|
|
33
|
+
.ezoic-ad iframe {
|
|
34
|
+
max-width: 100% !important;
|
|
48
35
|
}
|