nodebb-plugin-ezoic-infinite 1.6.56 → 1.6.58
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 +82 -93
- package/public/style.css +18 -57
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
// --- 1. VARIABLES ET CONFIG ---
|
|
5
4
|
const WRAP_CLASS = 'nodebb-ezoic-wrap';
|
|
6
5
|
const PINNED_ATTR = 'data-ezoic-pinned';
|
|
7
6
|
const PLACEHOLDER_PREFIX = 'ezoic-pub-ad-placeholder-';
|
|
@@ -9,17 +8,43 @@
|
|
|
9
8
|
let config = null;
|
|
10
9
|
let usedIds = new Set();
|
|
11
10
|
let scheduleTimer = null;
|
|
11
|
+
let isEzoicEnabled = false;
|
|
12
12
|
|
|
13
|
-
// ---
|
|
13
|
+
// --- SÉLECTEURS COMPATIBLES HARMONY ---
|
|
14
14
|
function getTopicList() {
|
|
15
|
-
return document.querySelector('
|
|
15
|
+
return document.querySelector('[component="topic/list"], [component="category"], [component="categories"]');
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function getPostList() {
|
|
19
19
|
return document.querySelector('[component="topic"], [component="post/list"]');
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
// ---
|
|
22
|
+
// --- GESTION DU SDK EZOIC (SÉCURISÉE) ---
|
|
23
|
+
function callEzoic(idsToDefine) {
|
|
24
|
+
if (!window.ezstandalone || !idsToDefine.length) return;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
// 1. On définit les nouveaux placeholders
|
|
28
|
+
window.ezstandalone.define(idsToDefine);
|
|
29
|
+
|
|
30
|
+
// 2. On gère le cycle de vie (Correction de tes erreurs de log)
|
|
31
|
+
if (!isEzoicEnabled && !window.ezstandalone.enabled) {
|
|
32
|
+
window.ezstandalone.enable();
|
|
33
|
+
window.ezstandalone.display();
|
|
34
|
+
isEzoicEnabled = true;
|
|
35
|
+
} else {
|
|
36
|
+
// Si déjà activé, on attend un cycle CPU pour refresh proprement
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
if (window.ezstandalone.enabled) {
|
|
39
|
+
window.ezstandalone.refresh();
|
|
40
|
+
}
|
|
41
|
+
}, 200);
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
console.warn('[Ezoic] SDK Error:', e);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
23
48
|
function getNextId(poolStr) {
|
|
24
49
|
if (!poolStr) return null;
|
|
25
50
|
const ids = poolStr.split(/[\s,]+/).filter(Boolean);
|
|
@@ -33,131 +58,95 @@
|
|
|
33
58
|
return null;
|
|
34
59
|
}
|
|
35
60
|
|
|
36
|
-
// ---
|
|
37
|
-
function callEzoic(id) {
|
|
38
|
-
if (window.ezstandalone) {
|
|
39
|
-
try {
|
|
40
|
-
const nid = parseInt(id, 10);
|
|
41
|
-
window.ezstandalone.define(nid);
|
|
42
|
-
if (!window.ezstandalone.enabled) {
|
|
43
|
-
window.ezstandalone.enable();
|
|
44
|
-
window.ezstandalone.display();
|
|
45
|
-
} else {
|
|
46
|
-
window.ezstandalone.refresh();
|
|
47
|
-
}
|
|
48
|
-
} catch (e) { console.warn('[ezoic] refresh error', id, e); }
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// --- 5. INJECTION SÉCURISÉE (ANTI-PILEUP) ---
|
|
61
|
+
// --- LOGIQUE D'INJECTION ---
|
|
53
62
|
function inject() {
|
|
54
63
|
if (!config || config.excluded) return;
|
|
55
|
-
|
|
56
|
-
// A. LISTE DES SUJETS (Topics)
|
|
64
|
+
const newIds = [];
|
|
57
65
|
const ul = getTopicList();
|
|
66
|
+
|
|
67
|
+
// A. LISTE DES SUJETS
|
|
58
68
|
if (ul && config.enableBetweenAds) {
|
|
59
|
-
// Nettoyage des
|
|
60
|
-
|
|
61
|
-
wraps.forEach(w => {
|
|
69
|
+
// Nettoyage des blocs vides qui pourraient traîner
|
|
70
|
+
ul.querySelectorAll('.' + WRAP_CLASS).forEach(w => {
|
|
62
71
|
if (!w.previousElementSibling || w.previousElementSibling.tagName !== 'LI') w.remove();
|
|
63
72
|
});
|
|
64
73
|
|
|
65
74
|
const items = Array.from(ul.children).filter(c => c.tagName === 'LI' && !c.classList.contains(WRAP_CLASS));
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
|
|
76
|
+
// Pub n°1 (Après le premier sujet)
|
|
77
|
+
if (config.showFirstTopicAd && !ul.querySelector(`[${PINNED_ATTR}="true"]`)) {
|
|
78
|
+
const id = getNextId(config.placeholderIds);
|
|
79
|
+
if (id) {
|
|
80
|
+
insertAd(items[0], id, true);
|
|
81
|
+
newIds.push(parseInt(id, 10));
|
|
70
82
|
}
|
|
83
|
+
}
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
// Intervalles
|
|
86
|
+
const interval = parseInt(config.intervalPosts, 10) || 5;
|
|
87
|
+
items.forEach((li, idx) => {
|
|
88
|
+
if ((idx + 1) % interval === 0 && idx > 0) {
|
|
89
|
+
if (!li.nextElementSibling || !li.nextElementSibling.classList.contains(WRAP_CLASS)) {
|
|
90
|
+
const id = getNextId(config.placeholderIds);
|
|
91
|
+
if (id) {
|
|
92
|
+
insertAd(li, id, false);
|
|
93
|
+
newIds.push(parseInt(id, 10));
|
|
81
94
|
}
|
|
82
95
|
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
85
98
|
}
|
|
86
99
|
|
|
87
|
-
// B. LISTE DES MESSAGES (
|
|
100
|
+
// B. LISTE DES MESSAGES (Sujets ouverts)
|
|
88
101
|
const postList = getPostList();
|
|
89
102
|
if (postList && config.enableMessageAds) {
|
|
90
103
|
const posts = Array.from(postList.querySelectorAll('[component="post"]'));
|
|
91
104
|
if (config.showFirstMessageAd && posts.length > 0 && !postList.querySelector('.ezoic-msg-first')) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
posts.forEach((post, idx) => {
|
|
98
|
-
const pPos = idx + 1;
|
|
99
|
-
if (pPos > 1 && pPos % msgInterval === 0) {
|
|
100
|
-
if (!post.nextElementSibling || !post.nextElementSibling.classList.contains(WRAP_CLASS)) {
|
|
101
|
-
insertAd(post, getNextId(config.messagePlaceholderIds), false);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
+
const id = getNextId(config.messagePlaceholderIds);
|
|
106
|
+
if (id) {
|
|
107
|
+
insertAd(posts[0], id, false, 'ezoic-msg-first');
|
|
108
|
+
newIds.push(parseInt(id, 10));
|
|
109
|
+
}
|
|
105
110
|
}
|
|
106
111
|
}
|
|
112
|
+
|
|
113
|
+
if (newIds.length > 0) {
|
|
114
|
+
callEzoic(newIds);
|
|
115
|
+
}
|
|
107
116
|
}
|
|
108
117
|
|
|
109
118
|
function insertAd(target, id, isPinned, extraClass = '') {
|
|
110
|
-
if (!target
|
|
119
|
+
if (!target) return;
|
|
111
120
|
const wrap = document.createElement('div');
|
|
112
121
|
wrap.className = `${WRAP_CLASS} ezoic-ad-between ${extraClass}`;
|
|
113
122
|
if (isPinned) wrap.setAttribute(PINNED_ATTR, 'true');
|
|
114
|
-
|
|
115
|
-
const placeholder = document.createElement('div');
|
|
116
|
-
placeholder.id = PLACEHOLDER_PREFIX + id;
|
|
117
|
-
wrap.appendChild(placeholder);
|
|
118
|
-
|
|
123
|
+
wrap.innerHTML = `<div id="${PLACEHOLDER_PREFIX}${id}"></div>`;
|
|
119
124
|
target.after(wrap);
|
|
120
|
-
|
|
121
|
-
// On laisse le DOM respirer 50ms avant d'appeler Ezoic
|
|
122
|
-
setTimeout(() => callEzoic(id), 50);
|
|
123
125
|
}
|
|
124
126
|
|
|
125
|
-
// ---
|
|
126
|
-
async function
|
|
127
|
+
// --- INITIALISATION ---
|
|
128
|
+
async function init() {
|
|
127
129
|
try {
|
|
128
130
|
const res = await fetch('/api/plugins/ezoic-infinite/config');
|
|
129
131
|
config = await res.json();
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
function schedule() {
|
|
134
|
-
if (scheduleTimer) clearTimeout(scheduleTimer);
|
|
135
|
-
scheduleTimer = setTimeout(inject, 250);
|
|
136
|
-
}
|
|
132
|
+
|
|
133
|
+
inject();
|
|
137
134
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const body = document.body;
|
|
144
|
-
const mo = new MutationObserver((mutations) => {
|
|
145
|
-
for (let m of mutations) {
|
|
146
|
-
if (m.addedNodes.length > 0) {
|
|
147
|
-
schedule();
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
135
|
+
// MutationObserver pour détecter le scroll infini
|
|
136
|
+
const observer = new MutationObserver((mutations) => {
|
|
137
|
+
if (mutations.some(m => m.addedNodes.length > 0)) {
|
|
138
|
+
if (scheduleTimer) clearTimeout(scheduleTimer);
|
|
139
|
+
scheduleTimer = setTimeout(inject, 300);
|
|
150
140
|
}
|
|
151
141
|
});
|
|
152
|
-
|
|
153
|
-
});
|
|
142
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
154
143
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
}
|
|
144
|
+
if (window.jQuery) {
|
|
145
|
+
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', () => {
|
|
146
|
+
setTimeout(inject, 500);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
} catch (e) {}
|
|
161
150
|
}
|
|
162
151
|
|
|
163
152
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
package/public/style.css
CHANGED
|
@@ -1,67 +1,28 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* Conteneur de pub */
|
|
2
2
|
.nodebb-ezoic-wrap {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
overflow: hidden;
|
|
10
|
-
/* Améliore les performances de rendu sur NodeBB 4.x */
|
|
11
|
-
contain: layout style;
|
|
3
|
+
display: block !important;
|
|
4
|
+
width: 100% !important;
|
|
5
|
+
clear: both !important;
|
|
6
|
+
margin: 25px 0 !important;
|
|
7
|
+
min-height: 100px; /* Crucial pour que Ezoic détecte l'emplacement */
|
|
8
|
+
text-align: center;
|
|
12
9
|
}
|
|
13
10
|
|
|
14
|
-
/*
|
|
11
|
+
/* Fix spécifique pour le premier sujet */
|
|
15
12
|
.nodebb-ezoic-wrap[data-ezoic-pinned="true"] {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
border-bottom: 1px solid rgba(0,0,0,0.05);
|
|
20
|
-
margin-top: 0 !important;
|
|
13
|
+
min-height: 150px;
|
|
14
|
+
border-bottom: 1px solid rgba(0,0,0,0.05);
|
|
15
|
+
margin-top: 0 !important;
|
|
21
16
|
}
|
|
22
17
|
|
|
23
|
-
/*
|
|
24
|
-
[id^="ezoic-pub-ad-placeholder-"] {
|
|
25
|
-
margin: 0 auto !important;
|
|
26
|
-
padding: 0 !important;
|
|
27
|
-
text-align: center;
|
|
28
|
-
min-height: 1px;
|
|
29
|
-
line-height: 0;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/* --- Nettoyage des éléments Ezoic internes --- */
|
|
33
|
-
.nodebb-ezoic-wrap span.ezoic-ad,
|
|
34
|
-
.nodebb-ezoic-wrap .ezoic-ad {
|
|
35
|
-
display: block !important;
|
|
36
|
-
margin: 0 auto !important;
|
|
37
|
-
/* Force Ezoic à respecter la largeur du flux forum */
|
|
38
|
-
max-width: 100% !important;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/* --- Gestion des blocs vides (Anti-Holes) --- */
|
|
42
|
-
/* Si Ezoic ne renvoie rien ou si le bloc est vide,
|
|
43
|
-
on réduit l'espace pour ne pas avoir de gros trous blancs */
|
|
18
|
+
/* Cache les blocs vides pour éviter les trous blancs */
|
|
44
19
|
.nodebb-ezoic-wrap:empty {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/* --- Adaptation spécifique pour les Messages (Sujets ouverts) --- */
|
|
51
|
-
.ezoic-msg-first {
|
|
52
|
-
margin-bottom: 30px !important;
|
|
53
|
-
border-bottom: 1px solid var(--border-color, #eee);
|
|
54
|
-
padding-bottom: 10px !important;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/* --- Support du mode sombre (NodeBB 4 Harmony) --- */
|
|
58
|
-
[data-theme="dark"] .nodebb-ezoic-wrap[data-ezoic-pinned="true"] {
|
|
59
|
-
border-bottom-color: rgba(255,255,255,0.1);
|
|
20
|
+
height: 0 !important;
|
|
21
|
+
min-height: 0 !important;
|
|
22
|
+
margin: 0 !important;
|
|
60
23
|
}
|
|
61
24
|
|
|
62
|
-
/*
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
margin: 10px 0 !important;
|
|
66
|
-
}
|
|
25
|
+
/* Évite que les pubs "volent" au scroll */
|
|
26
|
+
.nodebb-ezoic-wrap .ezads-sticky-intradiv {
|
|
27
|
+
position: static !important;
|
|
67
28
|
}
|