nodebb-plugin-ezoic-infinite 1.6.86 → 1.6.87
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 +121 -117
- package/public/style.css +13 -24
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1,134 +1,138 @@
|
|
|
1
1
|
(function () {
|
|
2
|
-
|
|
2
|
+
'use strict';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
if (window.ezInfiniteInjected) return;
|
|
5
|
+
window.ezInfiniteInjected = true;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
let lastEnableTime = 0;
|
|
14
|
-
|
|
15
|
-
function getPool() {
|
|
16
|
-
let p = document.getElementById(POOL_ID);
|
|
17
|
-
if (!p) {
|
|
18
|
-
p = document.createElement('div');
|
|
19
|
-
p.id = POOL_ID;
|
|
20
|
-
p.style.display = 'none';
|
|
21
|
-
document.body.appendChild(p);
|
|
22
|
-
}
|
|
23
|
-
return p;
|
|
24
|
-
}
|
|
7
|
+
const WRAP_CLASS = 'nodebb-ezoic-wrap';
|
|
8
|
+
const POOL_ID = 'nodebb-ezoic-placeholder-pool';
|
|
9
|
+
|
|
10
|
+
let config = null;
|
|
11
|
+
let isInternalChange = false;
|
|
12
|
+
let activePlaceholders = new Set();
|
|
25
13
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// Si pas encore activé globalement
|
|
35
|
-
if (!window.ezstandalone.enabled) {
|
|
36
|
-
window.ezstandalone.enable();
|
|
37
|
-
window.ezstandalone.display();
|
|
38
|
-
lastEnableTime = Date.now();
|
|
39
|
-
} else {
|
|
40
|
-
// SECURITÉ : On attend au moins 2 secondes après un 'enable'
|
|
41
|
-
// avant d'autoriser un 'refresh' pour éviter l'erreur "same page"
|
|
42
|
-
const timeSinceEnable = Date.now() - lastEnableTime;
|
|
43
|
-
if (timeSinceEnable > 2000) {
|
|
44
|
-
window.ezstandalone.refresh();
|
|
45
|
-
} else {
|
|
46
|
-
// Si on est trop proche du enable, on retente dans 2.5s
|
|
47
|
-
setTimeout(function() {
|
|
48
|
-
window.ezstandalone.refresh();
|
|
49
|
-
}, 2500);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
});
|
|
14
|
+
function getPool() {
|
|
15
|
+
let p = document.getElementById(POOL_ID);
|
|
16
|
+
if (!p) {
|
|
17
|
+
p = document.createElement('div');
|
|
18
|
+
p.id = POOL_ID;
|
|
19
|
+
p.style.display = 'none';
|
|
20
|
+
document.body.appendChild(p);
|
|
53
21
|
}
|
|
22
|
+
return p;
|
|
23
|
+
}
|
|
54
24
|
|
|
55
|
-
|
|
56
|
-
|
|
25
|
+
// Utilisation stricte de la file d'attente CMD du zip
|
|
26
|
+
function callEzoic(id) {
|
|
27
|
+
if (typeof window.ezstandalone === 'undefined') return;
|
|
28
|
+
|
|
29
|
+
window.ezstandalone.cmd.push(function() {
|
|
30
|
+
// Si l'ID est déjà affiché, on ne fait rien pour éviter le spam de refresh
|
|
31
|
+
if (activePlaceholders.has(id)) {
|
|
32
|
+
window.ezstandalone.refresh();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
57
35
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const postItems = document.querySelectorAll('[component="post"]');
|
|
36
|
+
window.ezstandalone.define(id);
|
|
37
|
+
activePlaceholders.add(id);
|
|
61
38
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
39
|
+
if (!window.ezstandalone.enabled) {
|
|
40
|
+
window.ezstandalone.enable();
|
|
41
|
+
window.ezstandalone.display();
|
|
42
|
+
} else {
|
|
43
|
+
window.ezstandalone.refresh();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function redistribute() {
|
|
49
|
+
if (!config || config.excluded) return;
|
|
50
|
+
|
|
51
|
+
// Utilisation des sélecteurs exacts du zip V17 (Harmony/NodeBB 4)
|
|
52
|
+
const topicItems = document.querySelectorAll('li[component="category/topic"]');
|
|
53
|
+
const postItems = document.querySelectorAll('[component="post"][data-pid]');
|
|
54
|
+
|
|
55
|
+
// Injection pour la page d'accueil / catégories
|
|
56
|
+
if (topicItems.length > 0 && config.enableBetweenAds) {
|
|
57
|
+
inject(Array.from(topicItems), 'between', config.intervalPosts, config.showFirstTopicAd);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Injection pour les messages (topics)
|
|
61
|
+
if (postItems.length > 0 && config.enableMessageAds) {
|
|
62
|
+
inject(Array.from(postItems), 'message', config.messageIntervalPosts, config.showFirstMessageAd);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function inject(items, kind, interval, showFirst) {
|
|
67
|
+
const int = parseInt(interval, 10) || 10;
|
|
68
|
+
items.forEach((item, index) => {
|
|
69
|
+
const pos = index + 1;
|
|
70
|
+
const shouldHaveAd = (pos === 1 && showFirst) || (pos % int === 0);
|
|
71
|
+
|
|
72
|
+
const next = item.nextElementSibling;
|
|
73
|
+
if (shouldHaveAd && !(next && next.classList.contains(WRAP_CLASS))) {
|
|
74
|
+
const pool = getPool();
|
|
75
|
+
const available = pool.querySelector(`.${WRAP_CLASS}[data-kind="${kind}"]`);
|
|
66
76
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
if (available) {
|
|
78
|
+
isInternalChange = true;
|
|
79
|
+
// On insère l'élément comme dans le zip original
|
|
80
|
+
item.parentNode.insertBefore(available, item.nextSibling);
|
|
81
|
+
|
|
82
|
+
const pid = parseInt(available.getAttribute('data-placeholder-id'), 10);
|
|
83
|
+
callEzoic(pid);
|
|
84
|
+
|
|
85
|
+
setTimeout(() => { isInternalChange = false; }, 100);
|
|
70
86
|
}
|
|
71
|
-
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
72
90
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
function init() {
|
|
92
|
+
fetch('/api/plugins/ezoic-infinite/config')
|
|
93
|
+
.then(r => r.json())
|
|
94
|
+
.then(data => {
|
|
95
|
+
config = data;
|
|
96
|
+
const pool = getPool();
|
|
97
|
+
|
|
98
|
+
const setupPool = (raw, kind) => {
|
|
99
|
+
if (!raw) return;
|
|
100
|
+
raw.split(/[\s,]+/).filter(Boolean).forEach(id => {
|
|
101
|
+
if (!document.querySelector(`[data-placeholder-id="${id}"]`)) {
|
|
102
|
+
const d = document.createElement('div');
|
|
103
|
+
d.className = WRAP_CLASS;
|
|
104
|
+
d.setAttribute('data-kind', kind);
|
|
105
|
+
d.setAttribute('data-placeholder-id', id);
|
|
106
|
+
// Structure HTML propre
|
|
107
|
+
d.innerHTML = `<div id="ezoic-pub-ad-placeholder-${id}" class="ezoic-ad"></div>`;
|
|
108
|
+
pool.appendChild(d);
|
|
89
109
|
}
|
|
90
|
-
|
|
91
|
-
|
|
110
|
+
});
|
|
111
|
+
};
|
|
92
112
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
config = data;
|
|
98
|
-
const pool = getPool();
|
|
99
|
-
const setup = (raw, kind) => {
|
|
100
|
-
if (!raw) return;
|
|
101
|
-
raw.split(/[\s,]+/).filter(Boolean).forEach(id => {
|
|
102
|
-
if (!document.querySelector(`[data-placeholder-id="${id}"]`)) {
|
|
103
|
-
const d = document.createElement('div');
|
|
104
|
-
d.className = WRAP_CLASS;
|
|
105
|
-
d.setAttribute('data-kind', kind);
|
|
106
|
-
d.setAttribute('data-placeholder-id', id);
|
|
107
|
-
d.innerHTML = `<div id="ezoic-pub-ad-placeholder-${id}" class="ezoic-ad"></div>`;
|
|
108
|
-
pool.appendChild(d);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
};
|
|
112
|
-
setup(config.placeholderIds, 'between');
|
|
113
|
-
setup(config.messagePlaceholderIds, 'message');
|
|
114
|
-
|
|
115
|
-
redistribute();
|
|
116
|
-
|
|
117
|
-
const observer = new MutationObserver(() => {
|
|
118
|
-
if (!isInternalChange) redistribute();
|
|
119
|
-
});
|
|
120
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
|
121
|
-
});
|
|
122
|
-
}
|
|
113
|
+
setupPool(config.placeholderIds, 'between');
|
|
114
|
+
setupPool(config.messagePlaceholderIds, 'message');
|
|
115
|
+
|
|
116
|
+
redistribute();
|
|
123
117
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
// Observer pour l'infinite scroll (reprise du zip)
|
|
119
|
+
const observer = new MutationObserver(() => {
|
|
120
|
+
if (!isInternalChange) redistribute();
|
|
121
|
+
});
|
|
122
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Événements NodeBB pour gérer la navigation sans rechargement
|
|
127
|
+
if (window.jQuery) {
|
|
128
|
+
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function() {
|
|
129
|
+
setTimeout(redistribute, 500);
|
|
127
130
|
});
|
|
131
|
+
}
|
|
128
132
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
if (document.readyState === 'loading') {
|
|
134
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
135
|
+
} else {
|
|
136
|
+
init();
|
|
137
|
+
}
|
|
134
138
|
})();
|
package/public/style.css
CHANGED
|
@@ -1,31 +1,20 @@
|
|
|
1
|
-
/* Container principal */
|
|
2
1
|
.nodebb-ezoic-wrap {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
clear: both;
|
|
9
|
-
float: none !important;
|
|
2
|
+
display: block !important;
|
|
3
|
+
width: 100% !important;
|
|
4
|
+
margin: 30px 0 !important;
|
|
5
|
+
min-height: 250px;
|
|
6
|
+
clear: both;
|
|
10
7
|
}
|
|
11
8
|
|
|
12
|
-
/*
|
|
13
|
-
[component="category/topic"] {
|
|
14
|
-
|
|
9
|
+
/* Fix pour les listes de l'accueil Harmony */
|
|
10
|
+
li[component="category/topic"] + .nodebb-ezoic-wrap {
|
|
11
|
+
list-style: none;
|
|
12
|
+
padding: 15px;
|
|
13
|
+
background: rgba(0,0,0,0.02);
|
|
14
|
+
border-radius: 8px;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
background: transparent;
|
|
19
|
-
border-top: 1px solid rgba(0,0,0,0.05);
|
|
20
|
-
padding: 20px 0;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/* Cache si vraiment aucun contenu injecté après 5s */
|
|
17
|
+
/* Éviter les trous si la pub ne charge pas */
|
|
24
18
|
.nodebb-ezoic-wrap:empty {
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/* Empêche les doublons */
|
|
29
|
-
.nodebb-ezoic-wrap + .nodebb-ezoic-wrap {
|
|
30
|
-
display: none !important;
|
|
19
|
+
min-height: 1px;
|
|
31
20
|
}
|