nodebb-plugin-ezoic-infinite 1.6.79 → 1.6.80
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 +11 -9
- package/package.json +1 -1
- package/public/client.js +29 -21
- package/public/style.css +12 -23
package/library.js
CHANGED
|
@@ -11,24 +11,26 @@ async function getSettings() {
|
|
|
11
11
|
return await meta.settings.get(SETTINGS_KEY);
|
|
12
12
|
}
|
|
13
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 }));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
14
|
async function isUserExcluded(uid, excludedGroups) {
|
|
21
|
-
if (!uid || !excludedGroups
|
|
22
|
-
|
|
15
|
+
if (!uid || !excludedGroups) return false;
|
|
16
|
+
// Gérer le format multiple de NodeBB
|
|
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
|
+
enableBetweenAds_checked: settings.enableBetweenAds === 'on' ? 'checked' : '',
|
|
33
|
+
enableMessageAds_checked: settings.enableMessageAds === 'on' ? 'checked' : ''
|
|
32
34
|
});
|
|
33
35
|
};
|
|
34
36
|
|
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 ezEnabled = false; // Flag pour savoir si ezstandalone.enable() a été appelé
|
|
25
25
|
|
|
26
26
|
function withInternalDomChange(fn) {
|
|
27
27
|
isInternalChange = true;
|
|
@@ -48,19 +48,16 @@
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
// --- ANTI-PILLUP : Supprime les pubs consécutives ---
|
|
52
51
|
function decluster(container) {
|
|
53
52
|
const wraps = Array.from(container.querySelectorAll(`.${WRAP_CLASS}`));
|
|
54
53
|
wraps.forEach(wrap => {
|
|
55
54
|
let next = wrap.nextElementSibling;
|
|
56
|
-
// Si deux blocs de pub se suivent sans contenu entre les deux
|
|
57
55
|
if (next && next.classList.contains(WRAP_CLASS)) {
|
|
58
56
|
withInternalDomChange(() => releaseWrapNode(next));
|
|
59
57
|
}
|
|
60
58
|
});
|
|
61
59
|
}
|
|
62
60
|
|
|
63
|
-
// --- NETTOYAGE DES ORPHELINS (Virtualisation NodeBB) ---
|
|
64
61
|
function pruneOrphanWraps() {
|
|
65
62
|
const wraps = document.querySelectorAll(`.${WRAP_CLASS}`);
|
|
66
63
|
const items = document.querySelectorAll('[component="category/topic"], [component="post"]');
|
|
@@ -68,9 +65,7 @@
|
|
|
68
65
|
|
|
69
66
|
wraps.forEach(wrap => {
|
|
70
67
|
if (wrap.parentElement && wrap.parentElement.id === POOL_ID) return;
|
|
71
|
-
|
|
72
68
|
let hasNeighbor = false;
|
|
73
|
-
// On vérifie la proximité immédiate (3 éléments) pour voir si le contenu est toujours là
|
|
74
69
|
let prev = wrap.previousElementSibling;
|
|
75
70
|
for (let i = 0; i < 3 && prev; i++) {
|
|
76
71
|
if (itemSet.has(prev)) { hasNeighbor = true; break; }
|
|
@@ -85,7 +80,6 @@
|
|
|
85
80
|
}
|
|
86
81
|
|
|
87
82
|
if (!hasNeighbor) {
|
|
88
|
-
// En remontee (scroll UP), on recycle immédiatement pour éviter l'empilement visuel
|
|
89
83
|
if (scrollDir === -1) {
|
|
90
84
|
withInternalDomChange(() => releaseWrapNode(wrap));
|
|
91
85
|
} else {
|
|
@@ -97,10 +91,33 @@
|
|
|
97
91
|
});
|
|
98
92
|
}
|
|
99
93
|
|
|
94
|
+
function callEzoic(placeholderId) {
|
|
95
|
+
if (typeof window.ezstandalone === 'undefined') return;
|
|
96
|
+
|
|
97
|
+
const pid = parseInt(placeholderId, 10);
|
|
98
|
+
try {
|
|
99
|
+
if (!ezEnabled) {
|
|
100
|
+
window.ezstandalone.define(pid);
|
|
101
|
+
window.ezstandalone.enable();
|
|
102
|
+
window.ezstandalone.display();
|
|
103
|
+
ezEnabled = true;
|
|
104
|
+
} else {
|
|
105
|
+
window.ezstandalone.define(pid);
|
|
106
|
+
// Utiliser une petite pause pour être sûr que le DOM est prêt
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
if (document.getElementById('ezoic-pub-ad-placeholder-' + pid)) {
|
|
109
|
+
window.ezstandalone.refresh();
|
|
110
|
+
}
|
|
111
|
+
}, 100);
|
|
112
|
+
}
|
|
113
|
+
} catch (e) {
|
|
114
|
+
console.warn('[Ezoic-Infinite] Error refreshing ad:', e);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
100
118
|
function redistribute(container) {
|
|
101
119
|
if (!container || !config || config.excluded) return;
|
|
102
120
|
|
|
103
|
-
// 1. On nettoie avant d'injecter
|
|
104
121
|
pruneOrphanWraps();
|
|
105
122
|
decluster(container);
|
|
106
123
|
|
|
@@ -132,7 +149,6 @@
|
|
|
132
149
|
let inserts = 0;
|
|
133
150
|
items.forEach((item, index) => {
|
|
134
151
|
if (inserts >= MAX_INSERTS_PER_RUN) return;
|
|
135
|
-
|
|
136
152
|
const pos = index + 1;
|
|
137
153
|
let shouldHaveAd = (pos % interval === 0);
|
|
138
154
|
if (pos === 1 && showFirst) shouldHaveAd = true;
|
|
@@ -146,14 +162,7 @@
|
|
|
146
162
|
if (available) {
|
|
147
163
|
withInternalDomChange(() => {
|
|
148
164
|
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
|
-
}
|
|
165
|
+
callEzoic(available.getAttribute('data-placeholder-id'));
|
|
157
166
|
});
|
|
158
167
|
inserts++;
|
|
159
168
|
}
|
|
@@ -166,7 +175,6 @@
|
|
|
166
175
|
.then(r => r.json())
|
|
167
176
|
.then(data => {
|
|
168
177
|
config = data;
|
|
169
|
-
// Initialisation du pool d'IDs
|
|
170
178
|
const pool = getPool();
|
|
171
179
|
const setupPool = (idsRaw, kind) => {
|
|
172
180
|
if (!idsRaw) return;
|
|
@@ -195,9 +203,9 @@
|
|
|
195
203
|
function schedule() {
|
|
196
204
|
if (timer) clearTimeout(timer);
|
|
197
205
|
timer = setTimeout(() => {
|
|
198
|
-
const lists = document.querySelectorAll('[component="category"], .topic-list, [component="topic"]');
|
|
206
|
+
const lists = document.querySelectorAll('[component="category"], .topic-list, [component="topic"], [component="category/topic/list"]');
|
|
199
207
|
lists.forEach(redistribute);
|
|
200
|
-
},
|
|
208
|
+
}, 150); // Un peu plus de délai pour NodeBB 4.x
|
|
201
209
|
}
|
|
202
210
|
|
|
203
211
|
function init() {
|
package/public/style.css
CHANGED
|
@@ -1,48 +1,37 @@
|
|
|
1
|
-
/* Container de base */
|
|
2
1
|
.nodebb-ezoic-wrap {
|
|
3
2
|
display: block;
|
|
4
3
|
width: 100%;
|
|
5
|
-
margin:
|
|
4
|
+
margin: 20px 0 !important;
|
|
6
5
|
padding: 0 !important;
|
|
7
6
|
clear: both;
|
|
8
|
-
overflow:
|
|
9
|
-
min-height:
|
|
7
|
+
overflow: visible;
|
|
8
|
+
min-height: 50px; /* Aide Ezoic à détecter l'élément */
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
/* Cache les pubs orphelines
|
|
11
|
+
/* Cache les pubs orphelines proprement */
|
|
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
17
|
padding: 0 !important;
|
|
18
|
-
pointer-events: none;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
/*
|
|
20
|
+
/* Neutralisation du style interne Ezoic pour éviter les énormes espaces blancs */
|
|
22
21
|
.nodebb-ezoic-wrap .ezoic-ad {
|
|
23
22
|
margin: 0 auto !important;
|
|
24
23
|
padding: 0 !important;
|
|
25
24
|
min-height: 1px !important;
|
|
26
25
|
height: auto !important;
|
|
26
|
+
line-height: normal !important;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/*
|
|
30
|
-
.nodebb-ezoic-wrap
|
|
31
|
-
|
|
32
|
-
line-height: 0 !important;
|
|
33
|
-
font-size: 0 !important;
|
|
29
|
+
/* Enlève les marges doubles si plusieurs pubs se suivent malgré le script */
|
|
30
|
+
.nodebb-ezoic-wrap + .nodebb-ezoic-wrap {
|
|
31
|
+
margin-top: 0 !important;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
/*
|
|
37
|
-
|
|
38
|
-
.topic-list .nodebb-ezoic-wrap {
|
|
39
|
-
border-bottom: 1px solid rgba(0,0,0,0.05);
|
|
40
|
-
background: transparent;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/* Empêche le saut visuel si Ezoic met du temps à charger */
|
|
44
|
-
.nodebb-ezoic-wrap iframe {
|
|
45
|
-
display: block !important;
|
|
34
|
+
/* Assurer la visibilité pour l'IntersectionObserver d'Ezoic */
|
|
35
|
+
.ezoic-ad iframe {
|
|
46
36
|
max-width: 100%;
|
|
47
|
-
margin: 0 auto;
|
|
48
37
|
}
|