nodebb-plugin-ezoic-infinite 1.6.80 → 1.6.82
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 +2 -2
- package/package.json +1 -1
- package/public/client.js +200 -209
- package/public/style.css +27 -27
package/library.js
CHANGED
|
@@ -8,12 +8,12 @@ const SETTINGS_KEY = 'ezoic-infinite';
|
|
|
8
8
|
const plugin = {};
|
|
9
9
|
|
|
10
10
|
async function getSettings() {
|
|
11
|
-
|
|
11
|
+
const settings = await meta.settings.get(SETTINGS_KEY);
|
|
12
|
+
return settings || {};
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
async function isUserExcluded(uid, excludedGroups) {
|
|
15
16
|
if (!uid || !excludedGroups) return false;
|
|
16
|
-
// Gérer le format multiple de NodeBB
|
|
17
17
|
const groupsList = Array.isArray(excludedGroups) ? excludedGroups : [excludedGroups];
|
|
18
18
|
if (!groupsList.length) return false;
|
|
19
19
|
return await groups.isMemberOfGroups(uid, groupsList);
|
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1,229 +1,220 @@
|
|
|
1
1
|
(function () {
|
|
2
|
-
|
|
2
|
+
'use strict';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
// Singleton pour éviter les conflits lors de la navigation AJAX de NodeBB
|
|
5
|
+
if (window.ezInfiniteInjected) return;
|
|
6
|
+
window.ezInfiniteInjected = true;
|
|
7
|
+
|
|
8
|
+
const WRAP_CLASS = 'nodebb-ezoic-wrap';
|
|
9
|
+
const POOL_ID = 'nodebb-ezoic-placeholder-pool';
|
|
10
|
+
|
|
11
|
+
let config = null;
|
|
12
|
+
let isInternalChange = false;
|
|
13
|
+
let ezEnabledInternally = false;
|
|
14
|
+
|
|
15
|
+
// Détection du sens du scroll pour le nettoyage (Pillup prevention)
|
|
16
|
+
let lastScrollY = window.scrollY;
|
|
17
|
+
let scrollDir = 1;
|
|
8
18
|
window.addEventListener('scroll', () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (Math.abs(d) > 4) {
|
|
12
|
-
scrollDir = d > 0 ? 1 : -1;
|
|
19
|
+
const y = window.scrollY;
|
|
20
|
+
scrollDir = y > lastScrollY ? 1 : -1;
|
|
13
21
|
lastScrollY = y;
|
|
14
|
-
}
|
|
15
22
|
}, { passive: true });
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const MAX_INSERTS_PER_RUN = 8;
|
|
21
|
-
|
|
22
|
-
let config = null;
|
|
23
|
-
let isInternalChange = false;
|
|
24
|
-
let ezEnabled = false; // Flag pour savoir si ezstandalone.enable() a été appelé
|
|
25
|
-
|
|
26
|
-
function withInternalDomChange(fn) {
|
|
27
|
-
isInternalChange = true;
|
|
28
|
-
try { fn(); } finally { isInternalChange = false; }
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function getPool() {
|
|
32
|
-
let p = document.getElementById(POOL_ID);
|
|
33
|
-
if (!p) {
|
|
34
|
-
p = document.createElement('div');
|
|
35
|
-
p.id = POOL_ID;
|
|
36
|
-
p.style.display = 'none';
|
|
37
|
-
document.body.appendChild(p);
|
|
38
|
-
}
|
|
39
|
-
return p;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function releaseWrapNode(wrap) {
|
|
43
|
-
if (!wrap) return;
|
|
44
|
-
const pool = getPool();
|
|
45
|
-
wrap.classList.remove('ez-orphan-hidden');
|
|
46
|
-
if (wrap.parentNode !== pool) {
|
|
47
|
-
pool.appendChild(wrap);
|
|
23
|
+
|
|
24
|
+
function withInternalDomChange(fn) {
|
|
25
|
+
isInternalChange = true;
|
|
26
|
+
try { fn(); } finally { isInternalChange = false; }
|
|
48
27
|
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function decluster(container) {
|
|
52
|
-
const wraps = Array.from(container.querySelectorAll(`.${WRAP_CLASS}`));
|
|
53
|
-
wraps.forEach(wrap => {
|
|
54
|
-
let next = wrap.nextElementSibling;
|
|
55
|
-
if (next && next.classList.contains(WRAP_CLASS)) {
|
|
56
|
-
withInternalDomChange(() => releaseWrapNode(next));
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function pruneOrphanWraps() {
|
|
62
|
-
const wraps = document.querySelectorAll(`.${WRAP_CLASS}`);
|
|
63
|
-
const items = document.querySelectorAll('[component="category/topic"], [component="post"]');
|
|
64
|
-
const itemSet = new Set(items);
|
|
65
|
-
|
|
66
|
-
wraps.forEach(wrap => {
|
|
67
|
-
if (wrap.parentElement && wrap.parentElement.id === POOL_ID) return;
|
|
68
|
-
let hasNeighbor = false;
|
|
69
|
-
let prev = wrap.previousElementSibling;
|
|
70
|
-
for (let i = 0; i < 3 && prev; i++) {
|
|
71
|
-
if (itemSet.has(prev)) { hasNeighbor = true; break; }
|
|
72
|
-
prev = prev.previousElementSibling;
|
|
73
|
-
}
|
|
74
|
-
if (!hasNeighbor) {
|
|
75
|
-
let next = wrap.nextElementSibling;
|
|
76
|
-
for (let i = 0; i < 3 && next; i++) {
|
|
77
|
-
if (itemSet.has(next)) { hasNeighbor = true; break; }
|
|
78
|
-
next = next.nextElementSibling;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
28
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
29
|
+
function getPool() {
|
|
30
|
+
let p = document.getElementById(POOL_ID);
|
|
31
|
+
if (!p) {
|
|
32
|
+
p = document.createElement('div');
|
|
33
|
+
p.id = POOL_ID;
|
|
34
|
+
p.style.display = 'none';
|
|
35
|
+
document.body.appendChild(p);
|
|
87
36
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
37
|
+
return p;
|
|
38
|
+
}
|
|
93
39
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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);
|
|
40
|
+
function releaseWrapNode(wrap) {
|
|
41
|
+
if (!wrap || !wrap.parentNode) return;
|
|
42
|
+
const pool = getPool();
|
|
43
|
+
wrap.classList.remove('ez-orphan-hidden');
|
|
44
|
+
if (wrap.parentNode !== pool) {
|
|
45
|
+
pool.appendChild(wrap);
|
|
46
|
+
}
|
|
115
47
|
}
|
|
116
|
-
}
|
|
117
48
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
let interval = 10;
|
|
129
|
-
let kind = '';
|
|
130
|
-
let items = [];
|
|
131
|
-
let showFirst = false;
|
|
132
|
-
|
|
133
|
-
if (isTopicList && config.enableBetweenAds) {
|
|
134
|
-
enabled = true;
|
|
135
|
-
interval = parseInt(config.intervalPosts, 10) || 10;
|
|
136
|
-
kind = 'between';
|
|
137
|
-
items = Array.from(container.querySelectorAll('[component="category/topic"]'));
|
|
138
|
-
showFirst = config.showFirstTopicAd;
|
|
139
|
-
} else if (isPostList && config.enableMessageAds) {
|
|
140
|
-
enabled = true;
|
|
141
|
-
interval = parseInt(config.messageIntervalPosts, 10) || 10;
|
|
142
|
-
kind = 'message';
|
|
143
|
-
items = Array.from(container.querySelectorAll('[component="post"]'));
|
|
144
|
-
showFirst = config.showFirstMessageAd;
|
|
49
|
+
// ANTI-PILLUP : Supprime les pubs si elles se touchent
|
|
50
|
+
function decluster(container) {
|
|
51
|
+
const wraps = Array.from(container.querySelectorAll(`.${WRAP_CLASS}`));
|
|
52
|
+
wraps.forEach(wrap => {
|
|
53
|
+
let next = wrap.nextElementSibling;
|
|
54
|
+
// Si l'élément suivant est une autre pub, on la remet au pool
|
|
55
|
+
if (next && next.classList.contains(WRAP_CLASS)) {
|
|
56
|
+
withInternalDomChange(() => releaseWrapNode(next));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
145
59
|
}
|
|
146
60
|
|
|
147
|
-
|
|
61
|
+
// Nettoyage des orphelins (Virtualisation NodeBB)
|
|
62
|
+
function pruneOrphanWraps() {
|
|
63
|
+
const wraps = document.querySelectorAll(`.${WRAP_CLASS}`);
|
|
64
|
+
const items = document.querySelectorAll('[component="category/topic"], [component="post"]');
|
|
65
|
+
const itemSet = new Set(items);
|
|
66
|
+
|
|
67
|
+
wraps.forEach(wrap => {
|
|
68
|
+
if (wrap.parentElement && wrap.parentElement.id === POOL_ID) return;
|
|
69
|
+
|
|
70
|
+
let hasNeighbor = false;
|
|
71
|
+
let p = wrap.previousElementSibling;
|
|
72
|
+
// On vérifie sur 2 voisins pour être sûr
|
|
73
|
+
for (let i = 0; i < 2 && p; i++) {
|
|
74
|
+
if (itemSet.has(p)) { hasNeighbor = true; break; }
|
|
75
|
+
p = p.previousElementSibling;
|
|
76
|
+
}
|
|
77
|
+
if (!hasNeighbor) {
|
|
78
|
+
let n = wrap.nextElementSibling;
|
|
79
|
+
for (let i = 0; i < 2 && n; i++) {
|
|
80
|
+
if (itemSet.has(n)) { hasNeighbor = true; break; }
|
|
81
|
+
n = n.nextElementSibling;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
148
84
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
85
|
+
if (!hasNeighbor) {
|
|
86
|
+
// En remontée (Up), on recycle immédiatement pour éviter l'empilement
|
|
87
|
+
if (scrollDir === -1) {
|
|
88
|
+
withInternalDomChange(() => releaseWrapNode(wrap));
|
|
89
|
+
} else {
|
|
90
|
+
wrap.classList.add('ez-orphan-hidden');
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
wrap.classList.remove('ez-orphan-hidden');
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
155
97
|
|
|
156
|
-
|
|
157
|
-
|
|
98
|
+
// Appel à la bibliothèque Ezoic déjà initialisée
|
|
99
|
+
function callEzoicRefresh(placeholderId) {
|
|
100
|
+
if (typeof window.ezstandalone === 'undefined') return;
|
|
101
|
+
const pid = parseInt(placeholderId, 10);
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
// On définit l'ID
|
|
105
|
+
window.ezstandalone.define(pid);
|
|
106
|
+
|
|
107
|
+
// Si c'est le tout premier, on tente un display
|
|
108
|
+
if (!ezEnabledInternally) {
|
|
109
|
+
window.ezstandalone.enable();
|
|
110
|
+
window.ezstandalone.display();
|
|
111
|
+
ezEnabledInternally = true;
|
|
112
|
+
} else {
|
|
113
|
+
// Sinon on rafraîchit (avec un petit délai pour le rendu DOM)
|
|
114
|
+
setTimeout(() => {
|
|
115
|
+
const el = document.getElementById('ezoic-pub-ad-placeholder-' + pid);
|
|
116
|
+
if (el && el.offsetParent !== null) {
|
|
117
|
+
window.ezstandalone.refresh();
|
|
118
|
+
}
|
|
119
|
+
}, 250);
|
|
120
|
+
}
|
|
121
|
+
} catch (e) {
|
|
122
|
+
console.warn('[Ezoic-Infinite] Refresh skip:', e.message);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
158
125
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
126
|
+
function redistribute(container) {
|
|
127
|
+
if (!container || !config || config.excluded) return;
|
|
128
|
+
|
|
129
|
+
pruneOrphanWraps();
|
|
130
|
+
decluster(container);
|
|
131
|
+
|
|
132
|
+
const isTopicList = container.getAttribute('component') === 'category' || container.classList.contains('topic-list');
|
|
133
|
+
const isPostList = container.getAttribute('component') === 'topic' || container.querySelectorAll('[component="post"]').length > 0;
|
|
134
|
+
|
|
135
|
+
let interval = 10;
|
|
136
|
+
let kind = '';
|
|
137
|
+
let items = [];
|
|
138
|
+
let showFirst = false;
|
|
139
|
+
|
|
140
|
+
if (isTopicList && config.enableBetweenAds) {
|
|
141
|
+
interval = parseInt(config.intervalPosts, 10) || 10;
|
|
142
|
+
kind = 'between';
|
|
143
|
+
items = Array.from(container.querySelectorAll('[component="category/topic"]'));
|
|
144
|
+
showFirst = config.showFirstTopicAd;
|
|
145
|
+
} else if (isPostList && config.enableMessageAds) {
|
|
146
|
+
interval = parseInt(config.messageIntervalPosts, 10) || 10;
|
|
147
|
+
kind = 'message';
|
|
148
|
+
items = Array.from(container.querySelectorAll('[component="post"]'));
|
|
149
|
+
showFirst = config.showFirstMessageAd;
|
|
168
150
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
d.setAttribute('data-placeholder-id', id);
|
|
188
|
-
const inner = document.createElement('div');
|
|
189
|
-
inner.id = 'ezoic-pub-ad-placeholder-' + id;
|
|
190
|
-
inner.className = 'ezoic-ad';
|
|
191
|
-
d.appendChild(inner);
|
|
192
|
-
pool.appendChild(d);
|
|
151
|
+
|
|
152
|
+
if (items.length === 0) return;
|
|
153
|
+
|
|
154
|
+
items.forEach((item, index) => {
|
|
155
|
+
const pos = index + 1;
|
|
156
|
+
let shouldHaveAd = (pos % interval === 0);
|
|
157
|
+
if (pos === 1 && showFirst) shouldHaveAd = true;
|
|
158
|
+
|
|
159
|
+
const next = item.nextElementSibling;
|
|
160
|
+
if (shouldHaveAd && !(next && next.classList.contains(WRAP_CLASS))) {
|
|
161
|
+
const pool = getPool();
|
|
162
|
+
const available = pool.querySelector(`.${WRAP_CLASS}[data-kind="${kind}"]`);
|
|
163
|
+
if (available) {
|
|
164
|
+
withInternalDomChange(() => {
|
|
165
|
+
item.parentNode.insertBefore(available, item.nextSibling);
|
|
166
|
+
callEzoicRefresh(available.getAttribute('data-placeholder-id'));
|
|
167
|
+
});
|
|
168
|
+
}
|
|
193
169
|
}
|
|
194
|
-
});
|
|
195
|
-
};
|
|
196
|
-
setupPool(config.placeholderIds, 'between');
|
|
197
|
-
setupPool(config.messagePlaceholderIds, 'message');
|
|
198
|
-
cb();
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
let timer = null;
|
|
203
|
-
function schedule() {
|
|
204
|
-
if (timer) clearTimeout(timer);
|
|
205
|
-
timer = setTimeout(() => {
|
|
206
|
-
const lists = document.querySelectorAll('[component="category"], .topic-list, [component="topic"], [component="category/topic/list"]');
|
|
207
|
-
lists.forEach(redistribute);
|
|
208
|
-
}, 150); // Un peu plus de délai pour NodeBB 4.x
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function init() {
|
|
212
|
-
fetchConfig(() => {
|
|
213
|
-
schedule();
|
|
214
|
-
if (typeof MutationObserver !== 'undefined') {
|
|
215
|
-
const mo = new MutationObserver((muts) => {
|
|
216
|
-
if (isInternalChange) return;
|
|
217
|
-
schedule();
|
|
218
170
|
});
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let timer = null;
|
|
174
|
+
function schedule() {
|
|
175
|
+
if (timer) clearTimeout(timer);
|
|
176
|
+
timer = setTimeout(() => {
|
|
177
|
+
const targets = document.querySelectorAll('[component="category"], .topic-list, [component="topic"], [component="category/topic/list"]');
|
|
178
|
+
targets.forEach(redistribute);
|
|
179
|
+
}, 300);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function init() {
|
|
183
|
+
fetch('/api/plugins/ezoic-infinite/config')
|
|
184
|
+
.then(r => r.json())
|
|
185
|
+
.then(data => {
|
|
186
|
+
config = data;
|
|
187
|
+
const pool = getPool();
|
|
188
|
+
const setup = (raw, kind) => {
|
|
189
|
+
if (!raw) return;
|
|
190
|
+
raw.split(/[\s,]+/).filter(Boolean).forEach(id => {
|
|
191
|
+
if (!document.querySelector(`[data-placeholder-id="${id}"]`)) {
|
|
192
|
+
const d = document.createElement('div');
|
|
193
|
+
d.className = WRAP_CLASS;
|
|
194
|
+
d.setAttribute('data-kind', kind);
|
|
195
|
+
d.setAttribute('data-placeholder-id', id);
|
|
196
|
+
d.innerHTML = `<div id="ezoic-pub-ad-placeholder-${id}" class="ezoic-ad"></div>`;
|
|
197
|
+
pool.appendChild(d);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
setup(config.placeholderIds, 'between');
|
|
202
|
+
setup(config.messagePlaceholderIds, 'message');
|
|
203
|
+
|
|
204
|
+
schedule();
|
|
205
|
+
|
|
206
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
207
|
+
const mo = new MutationObserver(() => {
|
|
208
|
+
if (!isInternalChange) schedule();
|
|
209
|
+
});
|
|
210
|
+
mo.observe(document.body, { childList: true, subtree: true });
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (document.readyState === 'loading') {
|
|
216
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
217
|
+
} else {
|
|
218
|
+
init();
|
|
219
|
+
}
|
|
229
220
|
})();
|
package/public/style.css
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
+
/* Container de base */
|
|
1
2
|
.nodebb-ezoic-wrap {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
min-height: 50px; /* Aide Ezoic à détecter l'élément */
|
|
3
|
+
display: block;
|
|
4
|
+
width: 100%;
|
|
5
|
+
margin: 30px auto !important;
|
|
6
|
+
padding: 0 !important;
|
|
7
|
+
clear: both;
|
|
8
|
+
min-height: 100px; /* Important pour Ezoic */
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
/*
|
|
12
|
-
.nodebb-ezoic-wrap.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
margin: 0 !important;
|
|
17
|
-
padding: 0 !important;
|
|
11
|
+
/* ANTI-PILLUP RADICAL : Si deux pubs se suivent, on cache la 2ème immédiatement par CSS */
|
|
12
|
+
.nodebb-ezoic-wrap + .nodebb-ezoic-wrap {
|
|
13
|
+
display: none !important;
|
|
14
|
+
height: 0 !important;
|
|
15
|
+
margin: 0 !important;
|
|
18
16
|
}
|
|
19
17
|
|
|
20
|
-
/*
|
|
21
|
-
.nodebb-ezoic-wrap
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
line-height: normal !important;
|
|
18
|
+
/* Cache les blocs orphelins (ceux qui ont perdu leurs posts voisins au scroll up) */
|
|
19
|
+
.nodebb-ezoic-wrap.ez-orphan-hidden {
|
|
20
|
+
display: none !important;
|
|
21
|
+
height: 0 !important;
|
|
22
|
+
margin: 0 !important;
|
|
23
|
+
padding: 0 !important;
|
|
27
24
|
}
|
|
28
25
|
|
|
29
|
-
/*
|
|
30
|
-
.nodebb-ezoic-wrap
|
|
31
|
-
|
|
26
|
+
/* Évite les espaces blancs inutiles à l'intérieur */
|
|
27
|
+
.nodebb-ezoic-wrap .ezoic-ad {
|
|
28
|
+
margin: 0 auto !important;
|
|
29
|
+
min-height: 1px !important;
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
/*
|
|
35
|
-
.ezoic-
|
|
36
|
-
|
|
32
|
+
/* Harmonisation NodeBB 4.x / Harmony */
|
|
33
|
+
[component="category"] .nodebb-ezoic-wrap,
|
|
34
|
+
.topic-list .nodebb-ezoic-wrap {
|
|
35
|
+
border-top: 1px solid rgba(0,0,0,0.05);
|
|
36
|
+
padding-top: 10px !important;
|
|
37
37
|
}
|