nodebb-plugin-ezoic-infinite 1.4.2 → 1.4.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 +104 -2
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -35,6 +35,11 @@
|
|
|
35
35
|
|
|
36
36
|
lastShowById: new Map(),
|
|
37
37
|
pendingById: new Set(),
|
|
38
|
+
retryById: new Map(),
|
|
39
|
+
retryTimer: null,
|
|
40
|
+
retryQueue: [],
|
|
41
|
+
retryQueueSet: new Set(),
|
|
42
|
+
retryQueueRunning: false,
|
|
38
43
|
|
|
39
44
|
scheduled: false,
|
|
40
45
|
timer: null,
|
|
@@ -234,6 +239,77 @@
|
|
|
234
239
|
} catch (e) {}
|
|
235
240
|
}
|
|
236
241
|
|
|
242
|
+
|
|
243
|
+
function isPlaceholderFilled(id) {
|
|
244
|
+
const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
245
|
+
if (!ph || !ph.isConnected) return false;
|
|
246
|
+
if (ph.childNodes && ph.childNodes.length > 0) return true;
|
|
247
|
+
const wrap = ph.parentElement;
|
|
248
|
+
if (wrap && wrap.querySelector && wrap.querySelector('iframe, ins, [id^="ezslot_"], [class*="ez"]')) return true;
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function scheduleRefill(delay = 350) {
|
|
253
|
+
clearTimeout(state.retryTimer);
|
|
254
|
+
state.retryTimer = setTimeout(refillUnfilled, delay);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function enqueueRetry(id) {
|
|
258
|
+
if (!id) return;
|
|
259
|
+
if (state.retryQueueSet.has(id)) return;
|
|
260
|
+
state.retryQueueSet.add(id);
|
|
261
|
+
state.retryQueue.push(id);
|
|
262
|
+
processRetryQueue();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function processRetryQueue() {
|
|
266
|
+
if (state.retryQueueRunning) return;
|
|
267
|
+
state.retryQueueRunning = true;
|
|
268
|
+
|
|
269
|
+
const step = () => {
|
|
270
|
+
const id = state.retryQueue.shift();
|
|
271
|
+
if (!id) {
|
|
272
|
+
state.retryQueueRunning = false;
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
state.retryQueueSet.delete(id);
|
|
276
|
+
callShowAdsWhenReady(id);
|
|
277
|
+
setTimeout(step, 950);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
step();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
function refillUnfilled() {
|
|
285
|
+
const wraps = Array.from(document.querySelectorAll(`.${WRAP_CLASS}`));
|
|
286
|
+
let scheduledAny = false;
|
|
287
|
+
|
|
288
|
+
for (const wrap of wraps) {
|
|
289
|
+
const ph = wrap.querySelector && wrap.querySelector(`[id^="${PLACEHOLDER_PREFIX}"]`);
|
|
290
|
+
if (!ph) continue;
|
|
291
|
+
const id = parseInt(ph.id.replace(PLACEHOLDER_PREFIX, ''), 10);
|
|
292
|
+
if (!Number.isFinite(id) || id <= 0) continue;
|
|
293
|
+
|
|
294
|
+
if (isPlaceholderFilled(id)) {
|
|
295
|
+
state.retryById.delete(id);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const tries = (state.retryById.get(id) || 0);
|
|
300
|
+
if (tries >= 8) continue;
|
|
301
|
+
|
|
302
|
+
const r = safeRect(wrap);
|
|
303
|
+
if (r && (r.top > window.innerHeight + 1200 || r.bottom < -1200)) continue;
|
|
304
|
+
|
|
305
|
+
state.retryById.set(id, tries + 1);
|
|
306
|
+
enqueueRetry(id);
|
|
307
|
+
scheduledAny = true;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (scheduledAny) scheduleRefill(700);
|
|
311
|
+
}
|
|
312
|
+
|
|
237
313
|
function callShowAdsWhenReady(id) {
|
|
238
314
|
if (!id) return;
|
|
239
315
|
|
|
@@ -346,6 +422,12 @@
|
|
|
346
422
|
const el = items[afterPos - 1];
|
|
347
423
|
if (!el || !el.isConnected) continue;
|
|
348
424
|
|
|
425
|
+
// Prevent adjacent ads (DOM-based, robust against virtualization)
|
|
426
|
+
const nextSibling = el.nextElementSibling;
|
|
427
|
+
if (nextSibling && nextSibling.classList && nextSibling.classList.contains(WRAP_CLASS)) {
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
|
|
349
431
|
// Prevent back-to-back at load
|
|
350
432
|
const prevWrap = findWrap(kindClass, afterPos - 1);
|
|
351
433
|
if (prevWrap) continue;
|
|
@@ -365,6 +447,7 @@
|
|
|
365
447
|
destroyPlaceholderIds([id]);
|
|
366
448
|
wrap = pick.recycled.wrap;
|
|
367
449
|
if (!moveWrapAfter(wrap, el, kindClass, afterPos)) continue;
|
|
450
|
+
setTimeout(() => { enqueueRetry(id); }, 250);
|
|
368
451
|
} else {
|
|
369
452
|
usedSet.add(id);
|
|
370
453
|
wrap = insertAfter(el, id, kindClass, afterPos);
|
|
@@ -372,7 +455,9 @@
|
|
|
372
455
|
}
|
|
373
456
|
|
|
374
457
|
liveArr.push({ id, wrap });
|
|
375
|
-
|
|
458
|
+
if (!(pick.recycled && pick.recycled.wrap)) {
|
|
459
|
+
callShowAdsWhenReady(id);
|
|
460
|
+
}
|
|
376
461
|
inserted += 1;
|
|
377
462
|
}
|
|
378
463
|
return inserted;
|
|
@@ -465,6 +550,7 @@
|
|
|
465
550
|
}
|
|
466
551
|
|
|
467
552
|
enforceNoAdjacentAds();
|
|
553
|
+
scheduleRefill(250);
|
|
468
554
|
|
|
469
555
|
// If nothing inserted and list isn't in DOM yet (first click), retry a bit
|
|
470
556
|
let count = 0;
|
|
@@ -540,4 +626,20 @@
|
|
|
540
626
|
state.pageKey = getPageKey();
|
|
541
627
|
scheduleRun();
|
|
542
628
|
setTimeout(scheduleRun, 250);
|
|
543
|
-
})()
|
|
629
|
+
})()
|
|
630
|
+
function bindScroll() {
|
|
631
|
+
if (state.__scrollBound) return;
|
|
632
|
+
state.__scrollBound = true;
|
|
633
|
+
let ticking = false;
|
|
634
|
+
window.addEventListener('scroll', () => {
|
|
635
|
+
if (ticking) return;
|
|
636
|
+
ticking = true;
|
|
637
|
+
window.requestAnimationFrame(() => {
|
|
638
|
+
ticking = false;
|
|
639
|
+
enforceNoAdjacentAds();
|
|
640
|
+
scheduleRefill(200);
|
|
641
|
+
});
|
|
642
|
+
}, { passive: true });
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
;
|