nodebb-plugin-ezoic-infinite 0.6.3 → 0.6.4
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 +51 -12
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -10,23 +10,23 @@ let debounceTimer;
|
|
|
10
10
|
let inFlight = false;
|
|
11
11
|
let rerunRequested = false;
|
|
12
12
|
|
|
13
|
-
//
|
|
13
|
+
// Per-page incremental state
|
|
14
14
|
let pageKey = null;
|
|
15
|
-
let injectedSlots = new Set();
|
|
16
|
-
let usedIds = new Set();
|
|
15
|
+
let injectedSlots = new Set(); // slot numbers already injected on this page
|
|
16
|
+
let usedIds = new Set(); // IDs currently present in DOM
|
|
17
|
+
let adsFIFO = []; // [{slot, id, selector}] in insertion order (oldest first)
|
|
17
18
|
|
|
18
19
|
function resetPageState() {
|
|
19
20
|
injectedSlots = new Set();
|
|
20
21
|
usedIds = new Set();
|
|
22
|
+
adsFIFO = [];
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
function currentPageKey() {
|
|
24
|
-
// Stable key per ajaxified page
|
|
25
26
|
try {
|
|
26
27
|
if (ajaxify && ajaxify.data) {
|
|
27
28
|
if (ajaxify.data.tid) return 'topic:' + ajaxify.data.tid;
|
|
28
29
|
if (ajaxify.data.cid) return 'category:' + ajaxify.data.cid;
|
|
29
|
-
if (ajaxify.data.template) return 'tpl:' + ajaxify.data.template + ':' + (ajaxify.data.url || window.location.pathname);
|
|
30
30
|
}
|
|
31
31
|
} catch (e) {}
|
|
32
32
|
return window.location.pathname;
|
|
@@ -86,6 +86,10 @@ function makeWrapperLike($target, classes, innerHtml, attrs) {
|
|
|
86
86
|
return '<div class="' + classes + '"' + attrStr + '>' + innerHtml + '</div>';
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
function cleanupWrappersOnNav() {
|
|
90
|
+
$('.ezoic-ad-post, .ezoic-ad-between, .ezoic-ad-topic').remove();
|
|
91
|
+
}
|
|
92
|
+
|
|
89
93
|
function pickNextId(pool) {
|
|
90
94
|
for (const id of pool) {
|
|
91
95
|
if (!usedIds.has(id)) return id;
|
|
@@ -111,7 +115,7 @@ function callEzoic(ids) {
|
|
|
111
115
|
|
|
112
116
|
window.ezstandalone.cmd.push(function () { run(); });
|
|
113
117
|
|
|
114
|
-
//
|
|
118
|
+
// Retry (Ezoic can load late)
|
|
115
119
|
let tries = 0;
|
|
116
120
|
const maxTries = 6;
|
|
117
121
|
const timer = setInterval(function () {
|
|
@@ -120,6 +124,21 @@ function callEzoic(ids) {
|
|
|
120
124
|
}, 800);
|
|
121
125
|
}
|
|
122
126
|
|
|
127
|
+
function fifoEvictIfNeeded(poolSize) {
|
|
128
|
+
// Keep at most poolSize ads in DOM: remove oldest when we exceed pool capacity.
|
|
129
|
+
// This makes ads "follow" the scroll (new ads appear, oldest disappear) without jumping positions.
|
|
130
|
+
while (adsFIFO.length > poolSize) {
|
|
131
|
+
const old = adsFIFO.shift();
|
|
132
|
+
if (!old) break;
|
|
133
|
+
|
|
134
|
+
const $el = $(old.selector);
|
|
135
|
+
if ($el.length) $el.remove();
|
|
136
|
+
|
|
137
|
+
injectedSlots.delete(old.slot);
|
|
138
|
+
usedIds.delete(old.id);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
123
142
|
function injectBetweenIncremental($items, pool, interval, wrapperClass) {
|
|
124
143
|
const total = $items.length;
|
|
125
144
|
const maxSlot = Math.floor(total / interval);
|
|
@@ -136,18 +155,29 @@ function injectBetweenIncremental($items, pool, interval, wrapperClass) {
|
|
|
136
155
|
|
|
137
156
|
const id = pickNextId(pool);
|
|
138
157
|
if (!id) {
|
|
139
|
-
//
|
|
158
|
+
// No free IDs right now; stop. Oldest will be evicted once new ads can be created.
|
|
140
159
|
break;
|
|
141
160
|
}
|
|
142
161
|
|
|
143
162
|
const placeholder = '<div id="ezoic-pub-ad-placeholder-' + id + '"></div>';
|
|
144
|
-
const
|
|
163
|
+
const selector = '.ezoic-ad-topic[data-ezoic-slot="' + slot + '"][data-ezoic-id="' + id + '"]';
|
|
164
|
+
const html = makeWrapperLike(
|
|
165
|
+
$target,
|
|
166
|
+
wrapperClass,
|
|
167
|
+
placeholder,
|
|
168
|
+
'data-ezoic-slot="' + slot + '" data-ezoic-id="' + id + '"'
|
|
169
|
+
);
|
|
145
170
|
|
|
146
171
|
$target.after(html);
|
|
147
172
|
|
|
148
173
|
injectedSlots.add(slot);
|
|
149
174
|
usedIds.add(id);
|
|
175
|
+
adsFIFO.push({ slot: slot, id: id, selector: selector });
|
|
176
|
+
|
|
150
177
|
newIds.push(id);
|
|
178
|
+
|
|
179
|
+
// Enforce capacity immediately (prevents runaway and keeps ads near viewport)
|
|
180
|
+
fifoEvictIfNeeded(pool.length);
|
|
151
181
|
}
|
|
152
182
|
|
|
153
183
|
return newIds;
|
|
@@ -171,26 +201,35 @@ function injectMessageIncremental($posts, pool, interval) {
|
|
|
171
201
|
if (!id) break;
|
|
172
202
|
|
|
173
203
|
const inner = '<div class="content"><div id="ezoic-pub-ad-placeholder-' + id + '"></div></div>';
|
|
174
|
-
const
|
|
204
|
+
const selector = '.ezoic-ad-post[data-ezoic-slot="' + slot + '"][data-ezoic-id="' + id + '"]';
|
|
205
|
+
const html = makeWrapperLike(
|
|
206
|
+
$target,
|
|
207
|
+
'post ezoic-ad-post',
|
|
208
|
+
inner,
|
|
209
|
+
'data-ezoic-slot="' + slot + '" data-ezoic-id="' + id + '"'
|
|
210
|
+
);
|
|
175
211
|
|
|
176
212
|
$target.after(html);
|
|
177
213
|
|
|
178
214
|
injectedSlots.add(slot);
|
|
179
215
|
usedIds.add(id);
|
|
216
|
+
adsFIFO.push({ slot: slot, id: id, selector: selector });
|
|
217
|
+
|
|
180
218
|
newIds.push(id);
|
|
219
|
+
|
|
220
|
+
fifoEvictIfNeeded(pool.length);
|
|
181
221
|
}
|
|
182
222
|
|
|
183
223
|
return newIds;
|
|
184
224
|
}
|
|
185
225
|
|
|
186
226
|
async function refreshAds() {
|
|
187
|
-
//
|
|
227
|
+
// Reset state on navigation
|
|
188
228
|
const key = currentPageKey();
|
|
189
229
|
if (pageKey !== key) {
|
|
190
230
|
pageKey = key;
|
|
191
231
|
resetPageState();
|
|
192
|
-
|
|
193
|
-
$('.ezoic-ad-post, .ezoic-ad-between, .ezoic-ad-topic').remove();
|
|
232
|
+
cleanupWrappersOnNav();
|
|
194
233
|
}
|
|
195
234
|
|
|
196
235
|
if (inFlight) { rerunRequested = true; return; }
|