nodebb-plugin-ezoic-infinite 1.6.92 → 1.6.94
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/package.json +1 -1
- package/public/client.js +49 -78
- package/public/style.css +71 -14
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -5,73 +5,12 @@
|
|
|
5
5
|
window.ezInfiniteInjected = true;
|
|
6
6
|
|
|
7
7
|
const WRAP_CLASS = 'nodebb-ezoic-wrap';
|
|
8
|
-
const POOL_ID = 'nodebb-ezoic-placeholder-pool';
|
|
9
|
-
|
|
10
8
|
let config = null;
|
|
11
9
|
let isInternalChange = false;
|
|
12
|
-
let activeIdsOnPage = new Set();
|
|
13
|
-
let pendingIds = new Set();
|
|
14
10
|
let triggerTimer = null;
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (!p) {
|
|
19
|
-
p = document.createElement('div');
|
|
20
|
-
p.id = POOL_ID;
|
|
21
|
-
p.style.display = 'none';
|
|
22
|
-
document.body.appendChild(p);
|
|
23
|
-
}
|
|
24
|
-
return p;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function triggerEzoic() {
|
|
28
|
-
if (typeof window.ezstandalone === 'undefined' || pendingIds.size === 0) return;
|
|
29
|
-
|
|
30
|
-
window.ezstandalone.cmd.push(function() {
|
|
31
|
-
const idsToProcess = Array.from(pendingIds);
|
|
32
|
-
pendingIds.clear();
|
|
33
|
-
|
|
34
|
-
// 1. Définir les IDs (requis par Ezoic avant l'affichage)
|
|
35
|
-
window.ezstandalone.define(idsToProcess);
|
|
36
|
-
|
|
37
|
-
if (!window.ezstandalone.enabled) {
|
|
38
|
-
// PREMIER CHARGEMENT
|
|
39
|
-
window.ezstandalone.enable();
|
|
40
|
-
window.ezstandalone.showAds(); // Appelle tout ce qui est présent
|
|
41
|
-
} else {
|
|
42
|
-
// NOUVEAU CONTENU (INFINITE SCROLL)
|
|
43
|
-
// La doc dit : ezstandalone.showAds(104, 105);
|
|
44
|
-
window.ezstandalone.showAds.apply(null, idsToProcess);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// On garde trace pour le nettoyage futur
|
|
48
|
-
idsToProcess.forEach(id => activeIdsOnPage.add(id));
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function callEzoic(id) {
|
|
53
|
-
const pid = parseInt(id, 10);
|
|
54
|
-
if (isNaN(pid)) return;
|
|
55
|
-
pendingIds.add(pid);
|
|
56
|
-
|
|
57
|
-
// On attend un peu pour grouper si plusieurs pubs arrivent en même temps
|
|
58
|
-
clearTimeout(triggerTimer);
|
|
59
|
-
triggerTimer = setTimeout(triggerEzoic, 200);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// "Changing Pages" : Nettoyage complet lors de la navigation NodeBB
|
|
63
|
-
function onPageChangeStart() {
|
|
64
|
-
if (typeof window.ezstandalone !== 'undefined') {
|
|
65
|
-
window.ezstandalone.cmd.push(function() {
|
|
66
|
-
// On nettoie tout avant de charger la nouvelle page
|
|
67
|
-
if (typeof window.ezstandalone.destroyAll === 'function') {
|
|
68
|
-
window.ezstandalone.destroyAll();
|
|
69
|
-
}
|
|
70
|
-
activeIdsOnPage.clear();
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
12
|
+
// On récupère les IDs déjà présents dans la page (générés par ton intégration de base)
|
|
13
|
+
// pour éviter de tenter de les redéfinir.
|
|
75
14
|
function redistribute() {
|
|
76
15
|
if (!config || config.excluded) return;
|
|
77
16
|
|
|
@@ -94,44 +33,80 @@
|
|
|
94
33
|
|
|
95
34
|
function process(items, kind, interval, showFirst) {
|
|
96
35
|
const int = parseInt(interval, 10) || 10;
|
|
36
|
+
const pool = document.getElementById('nodebb-ezoic-placeholder-pool');
|
|
37
|
+
if (!pool) return;
|
|
38
|
+
|
|
97
39
|
items.forEach((item, index) => {
|
|
98
40
|
const pos = index + 1;
|
|
99
41
|
const shouldHaveAd = (pos === 1 && showFirst) || (pos % int === 0);
|
|
100
42
|
const next = item.nextElementSibling;
|
|
101
43
|
|
|
44
|
+
// Si on doit mettre une pub et qu'il n'y en a pas déjà une après cet élément
|
|
102
45
|
if (shouldHaveAd && !(next && next.classList.contains(WRAP_CLASS))) {
|
|
103
|
-
const pool = getPool();
|
|
104
46
|
const available = pool.querySelector(`.${WRAP_CLASS}[data-kind="${kind}"]`);
|
|
105
47
|
|
|
106
48
|
if (available) {
|
|
107
49
|
isInternalChange = true;
|
|
108
50
|
item.parentNode.insertBefore(available, item.nextSibling);
|
|
109
|
-
|
|
51
|
+
|
|
52
|
+
const placeholderId = available.getAttribute('data-placeholder-id');
|
|
53
|
+
refreshAd(placeholderId);
|
|
54
|
+
|
|
110
55
|
setTimeout(() => { isInternalChange = false; }, 50);
|
|
111
56
|
}
|
|
112
57
|
}
|
|
113
58
|
});
|
|
114
59
|
}
|
|
115
60
|
|
|
61
|
+
function refreshAd(id) {
|
|
62
|
+
if (typeof window.ezstandalone === 'undefined') return;
|
|
63
|
+
|
|
64
|
+
clearTimeout(triggerTimer);
|
|
65
|
+
triggerTimer = setTimeout(() => {
|
|
66
|
+
window.ezstandalone.cmd.push(function() {
|
|
67
|
+
// Au lieu de define(), on utilise simplement showAds()
|
|
68
|
+
// Ezoic va détecter que le div avec cet ID a bougé et va le remplir.
|
|
69
|
+
try {
|
|
70
|
+
// On force l'affichage de cet ID spécifique
|
|
71
|
+
window.ezstandalone.showAds(parseInt(id, 10));
|
|
72
|
+
console.debug('[Ezoic] Displaying ID:', id);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
console.error('[Ezoic] Error showing ID:', id, e);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}, 100);
|
|
78
|
+
}
|
|
79
|
+
|
|
116
80
|
function init() {
|
|
117
81
|
fetch('/api/plugins/ezoic-infinite/config')
|
|
118
82
|
.then(r => r.json())
|
|
119
83
|
.then(data => {
|
|
120
84
|
config = data;
|
|
121
|
-
|
|
85
|
+
|
|
86
|
+
// On crée un pool CACHÉ qui contient tous les placeholders déclarés dans l'admin
|
|
87
|
+
let pool = document.getElementById('nodebb-ezoic-placeholder-pool');
|
|
88
|
+
if (!pool) {
|
|
89
|
+
pool = document.createElement('div');
|
|
90
|
+
pool.id = 'nodebb-ezoic-placeholder-pool';
|
|
91
|
+
pool.style.display = 'none';
|
|
92
|
+
document.body.appendChild(pool);
|
|
93
|
+
}
|
|
94
|
+
|
|
122
95
|
const setup = (raw, kind) => {
|
|
123
96
|
if (!raw) return;
|
|
124
97
|
raw.split(/[\s,]+/).filter(Boolean).forEach(id => {
|
|
125
|
-
if (!
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
98
|
+
if (!document.getElementById(`ezoic-pub-ad-placeholder-${id}`)) {
|
|
99
|
+
const wrap = document.createElement('div');
|
|
100
|
+
wrap.className = WRAP_CLASS;
|
|
101
|
+
wrap.setAttribute('data-kind', kind);
|
|
102
|
+
wrap.setAttribute('data-placeholder-id', id);
|
|
103
|
+
// Structure exacte attendue par Ezoic
|
|
104
|
+
wrap.innerHTML = `<div id="ezoic-pub-ad-placeholder-${id}"></div>`;
|
|
105
|
+
pool.appendChild(wrap);
|
|
132
106
|
}
|
|
133
107
|
});
|
|
134
108
|
};
|
|
109
|
+
|
|
135
110
|
setup(config.categoryPlaceholderIds, 'home');
|
|
136
111
|
setup(config.placeholderIds, 'topic-list');
|
|
137
112
|
setup(config.messagePlaceholderIds, 'message');
|
|
@@ -145,11 +120,7 @@
|
|
|
145
120
|
});
|
|
146
121
|
}
|
|
147
122
|
|
|
148
|
-
|
|
149
|
-
window.addEventListener('action:ajaxify.start', onPageChangeStart);
|
|
150
|
-
window.addEventListener('action:ajaxify.end', () => {
|
|
151
|
-
setTimeout(redistribute, 500);
|
|
152
|
-
});
|
|
123
|
+
window.addEventListener('action:ajaxify.end', () => setTimeout(redistribute, 500));
|
|
153
124
|
|
|
154
125
|
if (document.readyState === 'loading') {
|
|
155
126
|
document.addEventListener('DOMContentLoaded', init);
|
package/public/style.css
CHANGED
|
@@ -1,34 +1,91 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* ============================================================
|
|
2
|
+
CONTAINER GLOBAL DES PUBS
|
|
3
|
+
============================================================ */
|
|
2
4
|
.nodebb-ezoic-wrap {
|
|
3
5
|
display: block !important;
|
|
4
6
|
width: 100% !important;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
min-height: 250px; /* Réserve l'espace pour éviter le saut de contenu (CLS) */
|
|
8
|
+
margin: 30px 0 !important;
|
|
9
|
+
padding: 0;
|
|
10
|
+
clear: both !important;
|
|
8
11
|
text-align: center;
|
|
12
|
+
position: relative;
|
|
13
|
+
overflow: hidden;
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
/*
|
|
16
|
+
/* On s'assure que le contenu Ezoic à l'intérieur est centré */
|
|
17
|
+
.nodebb-ezoic-wrap > div {
|
|
18
|
+
margin: 0 auto !important;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* ============================================================
|
|
22
|
+
1. PAGE D'ACCUEIL (Liste des catégories)
|
|
23
|
+
============================================================ */
|
|
12
24
|
[component="categories/category"] + .nodebb-ezoic-wrap,
|
|
13
25
|
.category-item + .nodebb-ezoic-wrap {
|
|
14
26
|
margin: 40px 0 !important;
|
|
15
27
|
border-top: 1px solid rgba(0,0,0,0.05);
|
|
28
|
+
padding-top: 25px;
|
|
29
|
+
background: transparent;
|
|
16
30
|
}
|
|
17
31
|
|
|
18
|
-
/*
|
|
32
|
+
/* ============================================================
|
|
33
|
+
2. PAGE CATÉGORIE (Liste des Topics / Sujets)
|
|
34
|
+
============================================================ */
|
|
35
|
+
/* Important : NodeBB Harmony utilise des <li> pour les topics.
|
|
36
|
+
On s'assure que notre wrap ne casse pas la structure de liste
|
|
37
|
+
mais s'affiche comme un bloc complet. */
|
|
19
38
|
li[component="category/topic"] + .nodebb-ezoic-wrap {
|
|
20
39
|
list-style: none !important;
|
|
21
|
-
|
|
40
|
+
margin: 0 !important;
|
|
41
|
+
padding: 20px 0 !important;
|
|
22
42
|
border-bottom: 1px solid rgba(0,0,0,0.05);
|
|
43
|
+
display: block !important;
|
|
44
|
+
float: none !important;
|
|
45
|
+
width: 100%;
|
|
23
46
|
}
|
|
24
47
|
|
|
25
|
-
/*
|
|
48
|
+
/* ============================================================
|
|
49
|
+
3. PAGE DES POSTS (Messages à l'intérieur d'un topic)
|
|
50
|
+
============================================================ */
|
|
26
51
|
[component="post"] + .nodebb-ezoic-wrap {
|
|
27
|
-
margin:
|
|
28
|
-
padding:
|
|
29
|
-
background: rgba(0,0,0,0.
|
|
52
|
+
margin: 45px 0 !important;
|
|
53
|
+
padding: 25px;
|
|
54
|
+
background: rgba(0,0,0,0.02); /* Léger fond pour distinguer le message pub */
|
|
55
|
+
border-radius: 12px;
|
|
56
|
+
border: 1px inset rgba(0,0,0,0.03);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* ============================================================
|
|
60
|
+
CORRECTIFS ANTI "PILE-UP" & AFFICHAGE
|
|
61
|
+
============================================================ */
|
|
62
|
+
|
|
63
|
+
/* Évite que les pubs ne soient invisibles si Ezoic ne charge rien immédiatement */
|
|
64
|
+
.nodebb-ezoic-wrap:empty {
|
|
65
|
+
min-height: 1px;
|
|
66
|
+
height: 1px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Neutralise les marges forcées par Ezoic qui pourraient décaler le layout */
|
|
70
|
+
.ezoic-ad {
|
|
71
|
+
margin: 10px auto !important;
|
|
72
|
+
display: block !important;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* Mobile : Réduction des marges pour ne pas perdre trop de place */
|
|
76
|
+
@media (max-width: 767px) {
|
|
77
|
+
.nodebb-ezoic-wrap {
|
|
78
|
+
margin: 20px 0 !important;
|
|
79
|
+
min-height: 100px;
|
|
80
|
+
}
|
|
81
|
+
[component="post"] + .nodebb-ezoic-wrap {
|
|
82
|
+
padding: 10px;
|
|
83
|
+
margin: 25px 0 !important;
|
|
84
|
+
}
|
|
30
85
|
}
|
|
31
86
|
|
|
32
|
-
/*
|
|
33
|
-
.nodebb-ezoic-wrap
|
|
34
|
-
.ezoic-
|
|
87
|
+
/* Empêche les sauts de ligne bizarres dans les listes Harmony */
|
|
88
|
+
.categories > li.nodebb-ezoic-wrap,
|
|
89
|
+
.category > li.nodebb-ezoic-wrap {
|
|
90
|
+
float: none !important;
|
|
91
|
+
}
|