nodebb-plugin-ezoic-infinite 0.5.4 → 0.5.6
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
CHANGED
package/public/client.js
CHANGED
|
@@ -24,17 +24,10 @@ function parsePool(raw) {
|
|
|
24
24
|
));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
* Harmony: the real post wrapper is usually [component="post"][data-pid]
|
|
29
|
-
* We must avoid counting nested nodes like component="post/parent" or other elements
|
|
30
|
-
* that can also carry data-pid in some setups.
|
|
31
|
-
*/
|
|
32
27
|
function getTopicPosts() {
|
|
33
28
|
const $primary = $('[component="post"][data-pid]');
|
|
34
29
|
if ($primary.length) return $primary.not('.ezoic-ad-post');
|
|
35
30
|
|
|
36
|
-
// Fallback: top-level nodes with data-pid that contain the post content,
|
|
37
|
-
// excluding nodes nested inside another data-pid container.
|
|
38
31
|
const $top = $('[data-pid]').filter(function () {
|
|
39
32
|
const $el = $(this);
|
|
40
33
|
const hasContent = $el.find('[component="post/content"]').length > 0;
|
|
@@ -46,27 +39,27 @@ function getTopicPosts() {
|
|
|
46
39
|
return $('.posts .post').not('.ezoic-ad-post');
|
|
47
40
|
}
|
|
48
41
|
|
|
42
|
+
function getCategoryTopicItems() {
|
|
43
|
+
return $('li[component="category/topic"]').not('.ezoic-ad-topic');
|
|
44
|
+
}
|
|
45
|
+
|
|
49
46
|
function tagName($el) {
|
|
50
47
|
return ($el && $el.length ? (($el.prop('tagName') || '').toUpperCase()) : '');
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
function removePlaceholdersByPool(pool) {
|
|
54
|
-
pool.forEach(id => $('
|
|
51
|
+
pool.forEach(id => $('[id="ezoic-pub-ad-placeholder-' + id + '"]').remove());
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
function removeAdWrappers() {
|
|
58
55
|
$('.ezoic-ad-post').remove();
|
|
59
56
|
$('.ezoic-ad-between').remove();
|
|
57
|
+
$('.ezoic-ad-topic').remove();
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
function computeWindowSlots(totalItems, interval, poolSize) {
|
|
63
|
-
// totalItems posts -> number of ad slots at positions interval, 2*interval, ...
|
|
64
61
|
const slots = Math.floor(totalItems / interval);
|
|
65
62
|
if (slots <= 0) return [];
|
|
66
|
-
|
|
67
|
-
// IMPORTANT:
|
|
68
|
-
// We cannot display more than poolSize ads at once because Ezoic placeholder IDs
|
|
69
|
-
// must be unique on the page. If slots > poolSize, we only render the latest poolSize slots.
|
|
70
63
|
const start = Math.max(1, slots - poolSize + 1);
|
|
71
64
|
const out = [];
|
|
72
65
|
for (let s = start; s <= slots; s++) out.push(s);
|
|
@@ -81,35 +74,35 @@ function makeWrapperLike($target, classes, innerHtml) {
|
|
|
81
74
|
return '<div class="' + classes + '" data-ezoic-ad="1">' + innerHtml + '</div>';
|
|
82
75
|
}
|
|
83
76
|
|
|
84
|
-
function
|
|
85
|
-
const total = $
|
|
86
|
-
const slotsToRender = computeWindowSlots(total, interval,
|
|
77
|
+
function insertBetweenGeneric($items, ids, interval, wrapperClass) {
|
|
78
|
+
const total = $items.length;
|
|
79
|
+
const slotsToRender = computeWindowSlots(total, interval, ids.length);
|
|
87
80
|
if (!slotsToRender.length) return [];
|
|
88
81
|
|
|
89
82
|
const activeIds = [];
|
|
90
83
|
for (let i = 0; i < slotsToRender.length; i++) {
|
|
91
84
|
const slotNumber = slotsToRender[i];
|
|
92
|
-
const id =
|
|
93
|
-
const index = slotNumber * interval - 1;
|
|
94
|
-
const $target = $
|
|
85
|
+
const id = ids[i];
|
|
86
|
+
const index = slotNumber * interval - 1;
|
|
87
|
+
const $target = $items.eq(index);
|
|
95
88
|
if (!$target.length) continue;
|
|
96
89
|
|
|
97
|
-
const html = makeWrapperLike($target,
|
|
90
|
+
const html = makeWrapperLike($target, wrapperClass, '<div id="ezoic-pub-ad-placeholder-' + id + '"></div>');
|
|
98
91
|
$target.after(html);
|
|
99
92
|
activeIds.push(id);
|
|
100
93
|
}
|
|
101
94
|
return activeIds;
|
|
102
95
|
}
|
|
103
96
|
|
|
104
|
-
function insertAdMessagesBetweenReplies($posts,
|
|
97
|
+
function insertAdMessagesBetweenReplies($posts, ids, interval) {
|
|
105
98
|
const total = $posts.length;
|
|
106
|
-
const slotsToRender = computeWindowSlots(total, interval,
|
|
99
|
+
const slotsToRender = computeWindowSlots(total, interval, ids.length);
|
|
107
100
|
if (!slotsToRender.length) return [];
|
|
108
101
|
|
|
109
102
|
const activeIds = [];
|
|
110
103
|
for (let i = 0; i < slotsToRender.length; i++) {
|
|
111
104
|
const slotNumber = slotsToRender[i];
|
|
112
|
-
const id =
|
|
105
|
+
const id = ids[i];
|
|
113
106
|
const index = slotNumber * interval - 1;
|
|
114
107
|
const $target = $posts.eq(index);
|
|
115
108
|
if (!$target.length) continue;
|
|
@@ -122,6 +115,18 @@ function insertAdMessagesBetweenReplies($posts, pool, interval) {
|
|
|
122
115
|
return activeIds;
|
|
123
116
|
}
|
|
124
117
|
|
|
118
|
+
function uniqueConcat(a, b) {
|
|
119
|
+
const seen = new Set();
|
|
120
|
+
const out = [];
|
|
121
|
+
[...a, ...b].forEach((x) => {
|
|
122
|
+
if (!seen.has(x)) {
|
|
123
|
+
seen.add(x);
|
|
124
|
+
out.push(x);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
|
|
125
130
|
async function refreshAds() {
|
|
126
131
|
let cfg;
|
|
127
132
|
try { cfg = await fetchConfig(); } catch (e) { return; }
|
|
@@ -134,24 +139,41 @@ async function refreshAds() {
|
|
|
134
139
|
const messageInterval = Math.max(1, parseInt(cfg.messageIntervalPosts, 10) || 3);
|
|
135
140
|
|
|
136
141
|
const $posts = getTopicPosts();
|
|
137
|
-
|
|
142
|
+
const $topicItems = getCategoryTopicItems();
|
|
143
|
+
|
|
144
|
+
if (!$posts.length && !$topicItems.length) return;
|
|
138
145
|
|
|
139
|
-
// Clean first
|
|
140
146
|
removeAdWrappers();
|
|
141
|
-
removePlaceholdersByPool(betweenPool);
|
|
142
|
-
|
|
147
|
+
removePlaceholdersByPool(uniqueConcat(betweenPool, messagePool));
|
|
148
|
+
|
|
149
|
+
const combinedUnique = uniqueConcat(betweenPool, messagePool);
|
|
143
150
|
|
|
144
151
|
const activeIds = [];
|
|
145
152
|
|
|
146
|
-
|
|
147
|
-
|
|
153
|
+
// Category topic list page: inject between topic items
|
|
154
|
+
if (!$posts.length && $topicItems.length) {
|
|
155
|
+
if (cfg.enableBetweenAds && betweenPool.length) {
|
|
156
|
+
activeIds.push(...insertBetweenGeneric($topicItems, combinedUnique.slice(0, betweenPool.length), betweenInterval, 'ezoic-ad-topic'));
|
|
157
|
+
}
|
|
148
158
|
}
|
|
149
159
|
|
|
150
|
-
|
|
151
|
-
|
|
160
|
+
// Topic page: inject between replies + message ads
|
|
161
|
+
if ($posts.length) {
|
|
162
|
+
let cursor = 0;
|
|
163
|
+
|
|
164
|
+
if (cfg.enableBetweenAds && betweenPool.length) {
|
|
165
|
+
const idsForBetween = combinedUnique.slice(cursor, cursor + betweenPool.length);
|
|
166
|
+
cursor += idsForBetween.length;
|
|
167
|
+
activeIds.push(...insertBetweenGeneric($posts, idsForBetween, betweenInterval, 'ezoic-ad-between'));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (cfg.enableMessageAds && messagePool.length) {
|
|
171
|
+
const idsForMessage = combinedUnique.slice(cursor, cursor + messagePool.length);
|
|
172
|
+
cursor += idsForMessage.length;
|
|
173
|
+
activeIds.push(...insertAdMessagesBetweenReplies($posts, idsForMessage, messageInterval));
|
|
174
|
+
}
|
|
152
175
|
}
|
|
153
176
|
|
|
154
|
-
// Ezoic render
|
|
155
177
|
if (activeIds.length && window.ezstandalone && typeof window.ezstandalone.destroyPlaceholders === 'function') {
|
|
156
178
|
try { window.ezstandalone.destroyPlaceholders(); } catch (e) {}
|
|
157
179
|
}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<div class="mb-3">
|
|
34
34
|
<label class="form-label" for="messagePlaceholderIds">Pool d’IDs Ezoic (message)</label>
|
|
35
35
|
<textarea id="messagePlaceholderIds" name="messagePlaceholderIds" class="form-control" rows="4">{messagePlaceholderIds}</textarea>
|
|
36
|
-
<p class="form-text">Pool séparé recommandé pour éviter la réutilisation d’IDs.</p>
|
|
36
|
+
<p class="form-text">Pool séparé recommandé pour éviter la réutilisation d’IDs. IMPORTANT : ne réutilise pas les mêmes IDs dans les deux pools.</p>
|
|
37
37
|
</div>
|
|
38
38
|
|
|
39
39
|
<div class="mb-3">
|