nodebb-plugin-ezoic-infinite 1.5.71 → 1.5.72
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 +66 -5
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
// Smoothness caps
|
|
13
13
|
const MAX_INSERTS_PER_RUN = 3;
|
|
14
14
|
|
|
15
|
+
// Keep empty (unfilled) wraps alive for a while. Topics/messages can fill late (auction/CMP).
|
|
16
|
+
// Pruning too early makes ads look like they "disappear" while scrolling.
|
|
17
|
+
const KEEP_EMPTY_WRAP_MS = 30000;
|
|
18
|
+
|
|
15
19
|
// Preload margins
|
|
16
20
|
const PRELOAD_MARGIN_DESKTOP = '2600px 0px 2600px 0px';
|
|
17
21
|
const PRELOAD_MARGIN_MOBILE = '1500px 0px 1500px 0px';
|
|
@@ -207,6 +211,22 @@
|
|
|
207
211
|
return el;
|
|
208
212
|
}
|
|
209
213
|
|
|
214
|
+
function primePlaceholderPool(allIds) {
|
|
215
|
+
try {
|
|
216
|
+
if (!Array.isArray(allIds) || !allIds.length) return;
|
|
217
|
+
const pool = getPoolEl();
|
|
218
|
+
for (const id of allIds) {
|
|
219
|
+
if (!id) continue;
|
|
220
|
+
const domId = `${PLACEHOLDER_PREFIX}${id}`;
|
|
221
|
+
if (document.getElementById(domId)) continue;
|
|
222
|
+
const ph = document.createElement('div');
|
|
223
|
+
ph.id = domId;
|
|
224
|
+
ph.setAttribute('data-ezoic-id', String(id));
|
|
225
|
+
pool.appendChild(ph);
|
|
226
|
+
}
|
|
227
|
+
} catch (e) {}
|
|
228
|
+
}
|
|
229
|
+
|
|
210
230
|
function isInPool(ph) {
|
|
211
231
|
try { return !!(ph && ph.closest && ph.closest('#' + POOL_ID)); } catch (e) { return false; }
|
|
212
232
|
}
|
|
@@ -319,6 +339,13 @@
|
|
|
319
339
|
if (!state.allTopics.length) state.allTopics = parsePool(cfg.placeholderIds);
|
|
320
340
|
if (!state.allPosts.length) state.allPosts = parsePool(cfg.messagePlaceholderIds);
|
|
321
341
|
if (!state.allCategories.length) state.allCategories = parsePool(cfg.categoryPlaceholderIds);
|
|
342
|
+
|
|
343
|
+
// Create placeholders up-front in an offscreen pool.
|
|
344
|
+
// Ezoic may attempt to define/show ids during load; if they don't exist yet,
|
|
345
|
+
// it can spam errors and sometimes short-circuit. Pooling keeps ids existing without layout.
|
|
346
|
+
primePlaceholderPool(state.allTopics);
|
|
347
|
+
primePlaceholderPool(state.allPosts);
|
|
348
|
+
primePlaceholderPool(state.allCategories);
|
|
322
349
|
}
|
|
323
350
|
|
|
324
351
|
// ---------------- insertion primitives ----------------
|
|
@@ -328,6 +355,7 @@
|
|
|
328
355
|
wrap.className = `${WRAP_CLASS} ${kindClass}`;
|
|
329
356
|
wrap.setAttribute('data-ezoic-after', String(afterPos));
|
|
330
357
|
wrap.setAttribute('data-ezoic-wrapid', String(id));
|
|
358
|
+
wrap.setAttribute('data-created', String(now()));
|
|
331
359
|
wrap.style.width = '100%';
|
|
332
360
|
|
|
333
361
|
if (createPlaceholder) {
|
|
@@ -398,12 +426,12 @@
|
|
|
398
426
|
const hasNearbyItem = (wrap) => {
|
|
399
427
|
// NodeBB/skins can inject separators/spacers; be tolerant.
|
|
400
428
|
let prev = wrap.previousElementSibling;
|
|
401
|
-
for (let i = 0; i <
|
|
429
|
+
for (let i = 0; i < 14 && prev; i++) {
|
|
402
430
|
if (itemSet.has(prev)) return true;
|
|
403
431
|
prev = prev.previousElementSibling;
|
|
404
432
|
}
|
|
405
433
|
let next = wrap.nextElementSibling;
|
|
406
|
-
for (let i = 0; i <
|
|
434
|
+
for (let i = 0; i < 14 && next; i++) {
|
|
407
435
|
if (itemSet.has(next)) return true;
|
|
408
436
|
next = next.nextElementSibling;
|
|
409
437
|
}
|
|
@@ -412,6 +440,13 @@
|
|
|
412
440
|
|
|
413
441
|
wraps.forEach((wrap) => {
|
|
414
442
|
if (isFilled(wrap)) return; // never prune filled ads
|
|
443
|
+
|
|
444
|
+
// Never prune a fresh wrap: it may fill late.
|
|
445
|
+
try {
|
|
446
|
+
const created = parseInt(wrap.getAttribute('data-created') || '0', 10);
|
|
447
|
+
if (created && (now() - created) < KEEP_EMPTY_WRAP_MS) return;
|
|
448
|
+
} catch (e) {}
|
|
449
|
+
|
|
415
450
|
if (hasNearbyItem(wrap)) return;
|
|
416
451
|
|
|
417
452
|
withInternalDomChange(() => releaseWrapNode(wrap));
|
|
@@ -428,13 +463,32 @@
|
|
|
428
463
|
|
|
429
464
|
const isWrap = (el) => !!(el && el.classList && el.classList.contains(WRAP_CLASS));
|
|
430
465
|
|
|
466
|
+
const isFilled = (wrap) => {
|
|
467
|
+
return !!(wrap && wrap.querySelector && wrap.querySelector('iframe, ins, img, video, [data-google-container-id]'));
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
const isFresh = (wrap) => {
|
|
471
|
+
try {
|
|
472
|
+
const created = parseInt(wrap.getAttribute('data-created') || '0', 10);
|
|
473
|
+
return created && (now() - created) < KEEP_EMPTY_WRAP_MS;
|
|
474
|
+
} catch (e) {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
|
|
431
479
|
let removed = 0;
|
|
432
480
|
for (const w of wraps) {
|
|
433
481
|
let prev = w.previousElementSibling;
|
|
434
482
|
for (let i = 0; i < 3 && prev; i++) {
|
|
435
483
|
if (isWrap(prev)) {
|
|
436
|
-
|
|
437
|
-
|
|
484
|
+
// Don't decluster two "fresh" empty wraps — it can reduce fill on slow auctions.
|
|
485
|
+
// Only decluster when at least one is filled, or when the newer one is stale.
|
|
486
|
+
const prevFilled = isFilled(prev);
|
|
487
|
+
const curFilled = isFilled(w);
|
|
488
|
+
if (prevFilled || curFilled || !isFresh(w)) {
|
|
489
|
+
withInternalDomChange(() => releaseWrapNode(w));
|
|
490
|
+
removed++;
|
|
491
|
+
}
|
|
438
492
|
break;
|
|
439
493
|
}
|
|
440
494
|
prev = prev.previousElementSibling;
|
|
@@ -545,10 +599,17 @@
|
|
|
545
599
|
if (!ph2 || !ph2.isConnected) return;
|
|
546
600
|
const w2 = ph2.closest ? ph2.closest(`.${WRAP_CLASS}`) : null;
|
|
547
601
|
if (!w2) return;
|
|
602
|
+
|
|
603
|
+
// Don't collapse "fresh" placements; slow auctions/CMP can fill late.
|
|
604
|
+
try {
|
|
605
|
+
const created = parseInt(w2.getAttribute('data-created') || '0', 10);
|
|
606
|
+
if (created && (now() - created) < KEEP_EMPTY_WRAP_MS) return;
|
|
607
|
+
} catch (e) {}
|
|
608
|
+
|
|
548
609
|
const hasAd = !!(ph2.querySelector && ph2.querySelector('iframe, ins, img, .ez-ad, .ezoic-ad'));
|
|
549
610
|
if (!hasAd) w2.classList.add('is-empty');
|
|
550
611
|
} catch (e) {}
|
|
551
|
-
},
|
|
612
|
+
}, 15000);
|
|
552
613
|
} catch (e) {}
|
|
553
614
|
}
|
|
554
615
|
|