nodebb-plugin-ezoic-infinite 1.4.73 → 1.4.74
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/README.md +15 -0
- package/library.js +130 -0
- package/package.json +1 -1
- package/plugin.json +33 -0
- package/{client.js → public/client.js} +32 -35
- package/public/style.css +40 -0
- package/style.css +0 -43
- /package/{admin.js → public/admin.js} +0 -0
- /package/{templates → public/templates}/admin/plugins/ezoic-infinite.tpl +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# NodeBB Plugin – Ezoic Infinite (Production)
|
|
2
|
+
|
|
3
|
+
This plugin injects Ezoic placeholders between topics and posts on NodeBB 4.x,
|
|
4
|
+
with full support for infinite scroll.
|
|
5
|
+
|
|
6
|
+
## Key guarantees
|
|
7
|
+
- No duplicate ads back-to-back
|
|
8
|
+
- One showAds call per placeholder
|
|
9
|
+
- Fast reveal (MutationObserver on first child)
|
|
10
|
+
- Safe with ajaxify navigation
|
|
11
|
+
- Works with NodeBB 4.x + Harmony
|
|
12
|
+
|
|
13
|
+
## Notes
|
|
14
|
+
- Placeholders must exist and be selected in Ezoic
|
|
15
|
+
- Use separate ID pools for topics vs messages
|
package/library.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const meta = require.main.require('./src/meta');
|
|
4
|
+
const groups = require.main.require('./src/groups');
|
|
5
|
+
const db = require.main.require('./src/database');
|
|
6
|
+
|
|
7
|
+
const SETTINGS_KEY = 'ezoic-infinite';
|
|
8
|
+
const plugin = {};
|
|
9
|
+
|
|
10
|
+
function normalizeExcludedGroups(value) {
|
|
11
|
+
if (!value) return [];
|
|
12
|
+
if (Array.isArray(value)) return value;
|
|
13
|
+
return String(value).split(',').map(s => s.trim()).filter(Boolean);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parseBool(v, def = false) {
|
|
17
|
+
if (v === undefined || v === null || v === '') return def;
|
|
18
|
+
if (typeof v === 'boolean') return v;
|
|
19
|
+
const s = String(v).toLowerCase();
|
|
20
|
+
return s === '1' || s === 'true' || s === 'on' || s === 'yes';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function getAllGroups() {
|
|
24
|
+
let names = await db.getSortedSetRange('groups:createtime', 0, -1);
|
|
25
|
+
if (!names || !names.length) {
|
|
26
|
+
names = await db.getSortedSetRange('groups:visible:createtime', 0, -1);
|
|
27
|
+
}
|
|
28
|
+
const filtered = names.filter(name => !groups.isPrivilegeGroup(name));
|
|
29
|
+
const data = await groups.getGroupsData(filtered);
|
|
30
|
+
// Filter out nulls (groups deleted between the sorted-set read and getGroupsData)
|
|
31
|
+
const valid = data.filter(g => g && g.name);
|
|
32
|
+
valid.sort((a, b) => String(a.name).localeCompare(String(b.name), undefined, { sensitivity: 'base' }));
|
|
33
|
+
return valid;
|
|
34
|
+
}
|
|
35
|
+
let _settingsCache = null;
|
|
36
|
+
let _settingsCacheAt = 0;
|
|
37
|
+
const SETTINGS_TTL = 30000; // 30s
|
|
38
|
+
|
|
39
|
+
async function getSettings() {
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
if (_settingsCache && (now - _settingsCacheAt) < SETTINGS_TTL) return _settingsCache;
|
|
42
|
+
const s = await meta.settings.get(SETTINGS_KEY);
|
|
43
|
+
_settingsCacheAt = Date.now();
|
|
44
|
+
_settingsCache = {
|
|
45
|
+
// Between-post ads (simple blocks) in category topic list
|
|
46
|
+
enableBetweenAds: parseBool(s.enableBetweenAds, true),
|
|
47
|
+
showFirstTopicAd: parseBool(s.showFirstTopicAd, false),
|
|
48
|
+
placeholderIds: (s.placeholderIds || '').trim(),
|
|
49
|
+
intervalPosts: Math.max(1, parseInt(s.intervalPosts, 10) || 6),
|
|
50
|
+
|
|
51
|
+
// Home/categories list ads (between categories on / or /categories)
|
|
52
|
+
enableCategoryAds: parseBool(s.enableCategoryAds, false),
|
|
53
|
+
showFirstCategoryAd: parseBool(s.showFirstCategoryAd, false),
|
|
54
|
+
categoryPlaceholderIds: (s.categoryPlaceholderIds || '').trim(),
|
|
55
|
+
intervalCategories: Math.max(1, parseInt(s.intervalCategories, 10) || 4),
|
|
56
|
+
|
|
57
|
+
// "Ad message" between replies (looks like a post)
|
|
58
|
+
enableMessageAds: parseBool(s.enableMessageAds, false),
|
|
59
|
+
showFirstMessageAd: parseBool(s.showFirstMessageAd, false),
|
|
60
|
+
messagePlaceholderIds: (s.messagePlaceholderIds || '').trim(),
|
|
61
|
+
messageIntervalPosts: Math.max(1, parseInt(s.messageIntervalPosts, 10) || 3),
|
|
62
|
+
|
|
63
|
+
excludedGroups: normalizeExcludedGroups(s.excludedGroups),
|
|
64
|
+
};
|
|
65
|
+
return _settingsCache;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function isUserExcluded(uid, excludedGroups) {
|
|
69
|
+
if (!uid || !excludedGroups.length) return false;
|
|
70
|
+
const userGroups = await groups.getUserGroups([uid]);
|
|
71
|
+
return (userGroups[0] || []).some(g => excludedGroups.includes(g.name));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
plugin.onSettingsSet = function (data) {
|
|
75
|
+
// Invalider le cache dès que les settings de ce plugin sont sauvegardés via l'ACP
|
|
76
|
+
if (data && data.hash === SETTINGS_KEY) {
|
|
77
|
+
_settingsCache = null;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
plugin.addAdminNavigation = async (header) => {
|
|
82
|
+
header.plugins = header.plugins || [];
|
|
83
|
+
header.plugins.push({
|
|
84
|
+
route: '/plugins/ezoic-infinite',
|
|
85
|
+
icon: 'fa-ad',
|
|
86
|
+
name: 'Ezoic Infinite Ads'
|
|
87
|
+
});
|
|
88
|
+
return header;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
plugin.init = async ({ router, middleware }) => {
|
|
92
|
+
async function render(req, res) {
|
|
93
|
+
const settings = await getSettings();
|
|
94
|
+
const allGroups = await getAllGroups();
|
|
95
|
+
|
|
96
|
+
res.render('admin/plugins/ezoic-infinite', {
|
|
97
|
+
title: 'Ezoic Infinite Ads',
|
|
98
|
+
...settings,
|
|
99
|
+
enableBetweenAds_checked: settings.enableBetweenAds ? 'checked' : '',
|
|
100
|
+
enableMessageAds_checked: settings.enableMessageAds ? 'checked' : '',
|
|
101
|
+
allGroups,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
router.get('/admin/plugins/ezoic-infinite', middleware.admin.buildHeader, render);
|
|
106
|
+
router.get('/api/admin/plugins/ezoic-infinite', render);
|
|
107
|
+
|
|
108
|
+
router.get('/api/plugins/ezoic-infinite/config', async (req, res) => {
|
|
109
|
+
const settings = await getSettings();
|
|
110
|
+
const excluded = await isUserExcluded(req.uid, settings.excludedGroups);
|
|
111
|
+
|
|
112
|
+
res.json({
|
|
113
|
+
excluded,
|
|
114
|
+
enableBetweenAds: settings.enableBetweenAds,
|
|
115
|
+
showFirstTopicAd: settings.showFirstTopicAd,
|
|
116
|
+
placeholderIds: settings.placeholderIds,
|
|
117
|
+
intervalPosts: settings.intervalPosts,
|
|
118
|
+
enableCategoryAds: settings.enableCategoryAds,
|
|
119
|
+
showFirstCategoryAd: settings.showFirstCategoryAd,
|
|
120
|
+
categoryPlaceholderIds: settings.categoryPlaceholderIds,
|
|
121
|
+
intervalCategories: settings.intervalCategories,
|
|
122
|
+
enableMessageAds: settings.enableMessageAds,
|
|
123
|
+
showFirstMessageAd: settings.showFirstMessageAd,
|
|
124
|
+
messagePlaceholderIds: settings.messagePlaceholderIds,
|
|
125
|
+
messageIntervalPosts: settings.messageIntervalPosts,
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
module.exports = plugin;
|
package/package.json
CHANGED
package/plugin.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "nodebb-plugin-ezoic-infinite",
|
|
3
|
+
"name": "NodeBB Ezoic Infinite Ads",
|
|
4
|
+
"description": "Ezoic ads with infinite scroll using a pool of placeholder IDs",
|
|
5
|
+
"library": "./library.js",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"hook": "static:app.load",
|
|
9
|
+
"method": "init"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"hook": "filter:admin.header.build",
|
|
13
|
+
"method": "addAdminNavigation"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"hook": "action:settings.set",
|
|
17
|
+
"method": "onSettingsSet"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"staticDirs": {
|
|
21
|
+
"public": "public"
|
|
22
|
+
},
|
|
23
|
+
"acpScripts": [
|
|
24
|
+
"public/admin.js"
|
|
25
|
+
],
|
|
26
|
+
"scripts": [
|
|
27
|
+
"public/client.js"
|
|
28
|
+
],
|
|
29
|
+
"templates": "public/templates",
|
|
30
|
+
"css": [
|
|
31
|
+
"public/style.css"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
usedPosts: new Set(),
|
|
24
24
|
usedCategories: new Set(),
|
|
25
25
|
|
|
26
|
+
liveTopics: [],
|
|
27
|
+
livePosts: [],
|
|
28
|
+
liveCategories: [],
|
|
29
|
+
|
|
26
30
|
lastShowById: new Map(),
|
|
27
31
|
pendingById: new Set(),
|
|
28
32
|
definedIds: new Set(),
|
|
@@ -243,6 +247,7 @@
|
|
|
243
247
|
wrap.className = `${WRAP_CLASS} ${kindClass}`;
|
|
244
248
|
wrap.setAttribute('data-ezoic-after', String(afterPos));
|
|
245
249
|
wrap.style.width = '100%';
|
|
250
|
+
wrap.style.display = 'none';
|
|
246
251
|
|
|
247
252
|
const ph = document.createElement('div');
|
|
248
253
|
ph.id = `${PLACEHOLDER_PREFIX}${id}`;
|
|
@@ -318,26 +323,14 @@
|
|
|
318
323
|
}
|
|
319
324
|
}
|
|
320
325
|
|
|
321
|
-
|
|
322
|
-
try {
|
|
323
|
-
if (!wrap) return;
|
|
324
|
-
if (wrap.__ezoicFillObs) { wrap.__ezoicFillObs.disconnect(); wrap.__ezoicFillObs = null; }
|
|
325
|
-
wrap.setAttribute('data-ezoic-filled', '1');
|
|
326
|
-
} catch (e) {}
|
|
327
|
-
}
|
|
328
|
-
|
|
326
|
+
|
|
329
327
|
function forcePlaceholderAutoHeight(wrap, id) {
|
|
330
328
|
try {
|
|
331
|
-
if (!wrap
|
|
332
|
-
const ph = wrap.querySelector && wrap.querySelector(`#${PLACEHOLDER_PREFIX}${id}`);
|
|
329
|
+
if (!wrap) return;
|
|
330
|
+
const ph = id ? wrap.querySelector && wrap.querySelector(`#${PLACEHOLDER_PREFIX}${id}`) : (wrap.querySelector && wrap.querySelector(`[id^="${PLACEHOLDER_PREFIX}"]`));
|
|
333
331
|
if (!ph) return;
|
|
334
|
-
// Override any reserved height/min-height injected by ad scripts
|
|
335
|
-
try {
|
|
336
332
|
ph.style.setProperty('height', 'auto', 'important');
|
|
337
333
|
ph.style.setProperty('min-height', '0px', 'important');
|
|
338
|
-
} catch (e) {}
|
|
339
|
-
// Some creatives adjust after a frame
|
|
340
|
-
try {
|
|
341
334
|
requestAnimationFrame(() => {
|
|
342
335
|
try {
|
|
343
336
|
ph.style.setProperty('height', 'auto', 'important');
|
|
@@ -345,6 +338,16 @@
|
|
|
345
338
|
} catch (e) {}
|
|
346
339
|
});
|
|
347
340
|
} catch (e) {}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function markFilled(wrap, id) {
|
|
344
|
+
try {
|
|
345
|
+
if (!wrap) return;
|
|
346
|
+
if (wrap.__ezoicFillObs) { wrap.__ezoicFillObs.disconnect(); wrap.__ezoicFillObs = null; }
|
|
347
|
+
wrap.setAttribute('data-ezoic-filled', '1');
|
|
348
|
+
// show wrapper only when filled (avoid blank gaps if consent/CMP blocks)
|
|
349
|
+
wrap.style.display = 'block';
|
|
350
|
+
forcePlaceholderAutoHeight(wrap, id);
|
|
348
351
|
} catch (e) {}
|
|
349
352
|
}
|
|
350
353
|
|
|
@@ -358,15 +361,13 @@
|
|
|
358
361
|
if (!ph) return;
|
|
359
362
|
// Already filled?
|
|
360
363
|
if (ph.childNodes && ph.childNodes.length > 0) {
|
|
361
|
-
markFilled(wrap); // Afficher wrapper
|
|
362
|
-
forcePlaceholderAutoHeight(wrap, id);
|
|
364
|
+
markFilled(wrap, id); // Afficher wrapper
|
|
363
365
|
sessionDefinedIds.add(id);
|
|
364
366
|
return;
|
|
365
367
|
}
|
|
366
368
|
const obs = new MutationObserver(() => {
|
|
367
369
|
if (ph.childNodes && ph.childNodes.length > 0) {
|
|
368
|
-
markFilled(wrap); // CRITIQUE: Afficher wrapper maintenant
|
|
369
|
-
forcePlaceholderAutoHeight(wrap, id);
|
|
370
|
+
markFilled(wrap, id); // CRITIQUE: Afficher wrapper maintenant
|
|
370
371
|
try { sessionDefinedIds.add(id); } catch (e) {}
|
|
371
372
|
try { obs.disconnect(); } catch (e) {}
|
|
372
373
|
}
|
|
@@ -386,7 +387,7 @@
|
|
|
386
387
|
const filled = !!(ph.childNodes && ph.childNodes.length > 0);
|
|
387
388
|
if (filled) {
|
|
388
389
|
try { state.definedIds && state.definedIds.add(id); sessionDefinedIds.add(id); } catch (e) {}
|
|
389
|
-
try { markFilled(wrap); } catch (e) {}
|
|
390
|
+
try { markFilled(wrap, id); } catch (e) {}
|
|
390
391
|
}
|
|
391
392
|
return filled;
|
|
392
393
|
}
|
|
@@ -415,23 +416,17 @@
|
|
|
415
416
|
batchShowAdsTimer = setTimeout(() => {
|
|
416
417
|
if (pendingShowAdsIds.size === 0) return;
|
|
417
418
|
|
|
418
|
-
|
|
419
|
-
const idsArray = Array.from(pendingShowAdsIds).filter((id) => {
|
|
420
|
-
const el = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
421
|
-
return !!(el && el.isConnected);
|
|
422
|
-
});
|
|
419
|
+
const idsArray = Array.from(pendingShowAdsIds);
|
|
423
420
|
pendingShowAdsIds.clear();
|
|
424
421
|
|
|
425
|
-
if (!idsArray.length) return;
|
|
426
|
-
|
|
427
422
|
// Appeler showAds avec TOUS les IDs en une fois
|
|
428
423
|
try {
|
|
429
424
|
window.ezstandalone = window.ezstandalone || {};
|
|
430
425
|
window.ezstandalone.cmd = window.ezstandalone.cmd || [];
|
|
431
426
|
window.ezstandalone.cmd.push(function() {
|
|
432
427
|
if (typeof window.ezstandalone.showAds === 'function') {
|
|
433
|
-
//
|
|
434
|
-
window.ezstandalone.showAds(idsArray);
|
|
428
|
+
// Appel batch: showAds(id1, id2, id3...)
|
|
429
|
+
window.ezstandalone.showAds(...idsArray);
|
|
435
430
|
// Tracker tous les IDs
|
|
436
431
|
idsArray.forEach(id => {
|
|
437
432
|
state.lastShowById.set(id, Date.now());
|
|
@@ -459,6 +454,8 @@
|
|
|
459
454
|
window.ezstandalone = window.ezstandalone || {};
|
|
460
455
|
if (typeof window.ezstandalone.showAds === 'function') {
|
|
461
456
|
|
|
457
|
+
const elNow = document.getElementById(phId);
|
|
458
|
+
if (!elNow || !elNow.isConnected) return false;
|
|
462
459
|
state.lastShowById.set(id, Date.now());
|
|
463
460
|
window.ezstandalone.showAds(id);
|
|
464
461
|
sessionDefinedIds.add(id);
|
|
@@ -534,7 +531,7 @@
|
|
|
534
531
|
return Array.from(new Set(out)).sort((a, b) => a - b);
|
|
535
532
|
}
|
|
536
533
|
|
|
537
|
-
function injectBetween(kindClass, items, interval, showFirst, kindPool, usedSet) {
|
|
534
|
+
function injectBetween(kindClass, items, interval, showFirst, kindPool, usedSet, liveArr) {
|
|
538
535
|
if (!items.length) return 0;
|
|
539
536
|
const targets = computeTargets(items.length, interval, showFirst);
|
|
540
537
|
|
|
@@ -555,7 +552,7 @@
|
|
|
555
552
|
|
|
556
553
|
if (findWrap(kindClass, afterPos)) continue;
|
|
557
554
|
|
|
558
|
-
const pick = pickId(kindPool, []);
|
|
555
|
+
const pick = pickId(kindPool, liveArr || []);
|
|
559
556
|
const id = pick.id;
|
|
560
557
|
if (!id) break;
|
|
561
558
|
|
|
@@ -581,7 +578,7 @@
|
|
|
581
578
|
callShowAdsWhenReady(id);
|
|
582
579
|
}
|
|
583
580
|
|
|
584
|
-
liveArr.push({ id, wrap });
|
|
581
|
+
if (liveArr) liveArr.push({ id, wrap });
|
|
585
582
|
if (wrap && (
|
|
586
583
|
(wrap.previousElementSibling && wrap.previousElementSibling.classList && wrap.previousElementSibling.classList.contains(WRAP_CLASS)) || (wrap.nextElementSibling && wrap.nextElementSibling.classList && wrap.nextElementSibling.classList.contains(WRAP_CLASS))
|
|
587
584
|
)) {
|
|
@@ -681,7 +678,7 @@
|
|
|
681
678
|
Math.max(1, parseInt(cfg.messageIntervalPosts, 10) || 3),
|
|
682
679
|
normalizeBool(cfg.showFirstMessageAd),
|
|
683
680
|
state.poolPosts,
|
|
684
|
-
state.usedPosts);
|
|
681
|
+
state.usedPosts, state.livePosts);
|
|
685
682
|
}
|
|
686
683
|
} else if (kind === 'categoryTopics') {
|
|
687
684
|
if (normalizeBool(cfg.enableBetweenAds)) {
|
|
@@ -689,7 +686,7 @@
|
|
|
689
686
|
Math.max(1, parseInt(cfg.intervalPosts, 10) || 6),
|
|
690
687
|
normalizeBool(cfg.showFirstTopicAd),
|
|
691
688
|
state.poolTopics,
|
|
692
|
-
state.usedTopics);
|
|
689
|
+
state.usedTopics, state.liveTopics);
|
|
693
690
|
}
|
|
694
691
|
} else if (kind === 'categories') {
|
|
695
692
|
if (normalizeBool(cfg.enableCategoryAds)) {
|
|
@@ -697,7 +694,7 @@
|
|
|
697
694
|
Math.max(1, parseInt(cfg.intervalCategories, 10) || 4),
|
|
698
695
|
normalizeBool(cfg.showFirstCategoryAd),
|
|
699
696
|
state.poolCategories,
|
|
700
|
-
state.usedCategories);
|
|
697
|
+
state.usedCategories, state.liveCategories);
|
|
701
698
|
}
|
|
702
699
|
}
|
|
703
700
|
|
package/public/style.css
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/* Ezoic Infinite Ads (NodeBB) - production safe */
|
|
2
|
+
/* Hide wrappers until ad actually fills to avoid blank gaps (e.g., CMP/consent issues) */
|
|
3
|
+
.ezoic-ad{
|
|
4
|
+
display:none;
|
|
5
|
+
height:auto !important;
|
|
6
|
+
min-height:0 !important;
|
|
7
|
+
padding:0 !important;
|
|
8
|
+
margin:0 !important;
|
|
9
|
+
width:100%;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/* Marked filled => show */
|
|
13
|
+
.ezoic-ad[data-ezoic-filled="1"]{
|
|
14
|
+
display:block;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* Placeholder must not reserve fixed height */
|
|
18
|
+
.ezoic-ad > [id^="ezoic-pub-ad-placeholder-"]{
|
|
19
|
+
height:auto !important;
|
|
20
|
+
min-height:0 !important;
|
|
21
|
+
margin:0 !important;
|
|
22
|
+
padding:0 !important;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Prevent baseline gaps under iframes/ins */
|
|
26
|
+
.ezoic-ad iframe,
|
|
27
|
+
.ezoic-ad ins{
|
|
28
|
+
display:block !important;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Remove empty spacer divs if any */
|
|
32
|
+
.ezoic-ad > div:empty{
|
|
33
|
+
display:none !important;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Defensive: wipe margins/paddings inside wrapper */
|
|
37
|
+
.ezoic-ad *{
|
|
38
|
+
margin:0 !important;
|
|
39
|
+
padding:0 !important;
|
|
40
|
+
}
|
package/style.css
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
NodeBB + Ezoic (standalone)
|
|
3
|
-
Goal: never reserve space until the ad is truly filled, and never keep a fixed/min height.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/* Hide wrappers until we detect the placeholder has content (prevents empty gaps if CMP/ads are blocked) */
|
|
7
|
-
.ezoic-ad {
|
|
8
|
-
display: none;
|
|
9
|
-
width: 100%;
|
|
10
|
-
height: auto !important;
|
|
11
|
-
min-height: 0 !important;
|
|
12
|
-
padding: 0 !important;
|
|
13
|
-
margin: 0 !important;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.ezoic-ad[data-ezoic-filled="1"] {
|
|
17
|
-
display: block;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/* The placeholder must not reserve space */
|
|
21
|
-
.ezoic-ad > [id^="ezoic-pub-ad-placeholder-"] {
|
|
22
|
-
height: auto !important;
|
|
23
|
-
min-height: 0 !important;
|
|
24
|
-
margin: 0 !important;
|
|
25
|
-
padding: 0 !important;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/* Avoid baseline gap under iframes/ins */
|
|
29
|
-
.ezoic-ad iframe,
|
|
30
|
-
.ezoic-ad ins {
|
|
31
|
-
display: block !important;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/* Remove empty spacer divs that sometimes get injected */
|
|
35
|
-
.ezoic-ad > div:empty {
|
|
36
|
-
display: none !important;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/* Keep internal margins/paddings from creating vertical gaps */
|
|
40
|
-
.ezoic-ad * {
|
|
41
|
-
margin: 0 !important;
|
|
42
|
-
padding: 0 !important;
|
|
43
|
-
}
|
|
File without changes
|
|
File without changes
|