nodebb-plugin-ezoic-infinite 1.6.1 → 1.6.2

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/public/client.js +73 -26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.6.1",
3
+ "version": "1.6.2",
4
4
  "description": "Production-ready Ezoic infinite ads integration for NodeBB 4.x",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -1345,22 +1345,35 @@ function buildOrdinalMap(items) {
1345
1345
 
1346
1346
 
1347
1347
 
1348
+
1348
1349
  // ===== CLEAN REFRACTOR: visibility manager for Ezoic wraps =====
1349
1350
  (function () {
1351
+ // v3 improvements:
1352
+ // - Faster global rendering: larger preload margin, higher show throughput.
1353
+ // - Reliable on UP-scroll: scroll-proximity scanner enqueues showAds for near-viewport wraps even if IO doesn't fire.
1354
+
1350
1355
  var BETWEEN_SELECTOR = '.nodebb-ezoic-wrap.ezoic-ad-between';
1351
1356
  var MESSAGE_SELECTOR = '.nodebb-ezoic-wrap.ezoic-ad-message';
1352
1357
  var WRAP_SELECTOR = BETWEEN_SELECTOR + ', ' + MESSAGE_SELECTOR;
1353
1358
 
1354
- var KEEP_MARGIN_BETWEEN_DESKTOP = 2600;
1355
- var KEEP_MARGIN_BETWEEN_MOBILE = 1900;
1359
+ // We never remove message wraps; only very conservative cleanup for between wraps.
1360
+ var KEEP_MARGIN_BETWEEN_DESKTOP = 3200;
1361
+ var KEEP_MARGIN_BETWEEN_MOBILE = 2300;
1356
1362
 
1357
- var SHOW_COOLDOWN_MS = 1200;
1358
- var MAX_SHOW_PER_TICK = 4;
1363
+ // Show tuning
1364
+ var SHOW_COOLDOWN_MS = 650; // faster re-show when coming back up
1365
+ var MAX_SHOW_PER_TICK = 10; // higher throughput for long scroll pages
1366
+
1367
+ // Proximity scan (fix up-scroll non-display)
1368
+ var PROXIMITY_SCAN_COOLDOWN_MS = 180;
1369
+ var PROXIMITY_MARGIN_DESKTOP = 1400; // px above+below viewport
1370
+ var PROXIMITY_MARGIN_MOBILE = 1100;
1359
1371
 
1360
1372
  function isMobile() {
1361
1373
  try { return window.matchMedia && window.matchMedia('(max-width: 767px)').matches; } catch (e) { return false; }
1362
1374
  }
1363
1375
  function keepMarginBetween() { return isMobile() ? KEEP_MARGIN_BETWEEN_MOBILE : KEEP_MARGIN_BETWEEN_DESKTOP; }
1376
+ function proximityMargin() { return isMobile() ? PROXIMITY_MARGIN_MOBILE : PROXIMITY_MARGIN_DESKTOP; }
1364
1377
 
1365
1378
  var lastShowById = Object.create(null);
1366
1379
  var showQueue = [];
@@ -1369,6 +1382,12 @@ function buildOrdinalMap(items) {
1369
1382
  function getWrapId(w) {
1370
1383
  try { return w.getAttribute('data-ezoic-wrapid'); } catch (e) { return null; }
1371
1384
  }
1385
+ function getPlaceholderId(w) {
1386
+ try {
1387
+ var ph = w.querySelector('[data-ezoic-id]');
1388
+ return ph ? ph.getAttribute('data-ezoic-id') : null;
1389
+ } catch (e) { return null; }
1390
+ }
1372
1391
 
1373
1392
  function enqueueShow(id) {
1374
1393
  if (!id) return;
@@ -1411,7 +1430,7 @@ function buildOrdinalMap(items) {
1411
1430
  if (removed >= 3) return;
1412
1431
  try {
1413
1432
  var lv = parseInt(w.getAttribute('data-last-visible') || '0', 10);
1414
- if (lv && (Date.now() - lv) < 12000) return;
1433
+ if (lv && (Date.now() - lv) < 15000) return;
1415
1434
 
1416
1435
  var r = w.getBoundingClientRect();
1417
1436
  if (r.bottom < -margin || r.top > ((window.innerHeight || 0) + margin)) {
@@ -1422,6 +1441,7 @@ function buildOrdinalMap(items) {
1422
1441
  });
1423
1442
  }
1424
1443
 
1444
+ // IntersectionObserver: preload well before viewport
1425
1445
  var io = null;
1426
1446
  function installIO() {
1427
1447
  if (io || typeof IntersectionObserver === 'undefined') return;
@@ -1432,22 +1452,17 @@ function buildOrdinalMap(items) {
1432
1452
  if (!e || !e.target) return;
1433
1453
  if (e.isIntersecting) {
1434
1454
  try { e.target.setAttribute('data-last-visible', String(Date.now())); } catch (err) {}
1435
-
1436
- var id = getWrapId(e.target);
1455
+ var id = getWrapId(e.target) || getPlaceholderId(e.target);
1437
1456
  if (id) enqueueShow(id);
1438
-
1439
- try {
1440
- var ph = e.target.querySelector('[data-ezoic-id]');
1441
- if (ph) enqueueShow(ph.getAttribute('data-ezoic-id'));
1442
- } catch (err) {}
1443
1457
  }
1444
1458
  });
1445
1459
  } catch (e) {}
1446
- }, { root: null, rootMargin: '900px 0px 900px 0px', threshold: 0.01 });
1460
+ }, { root: null, rootMargin: '1400px 0px 1400px 0px', threshold: 0.01 });
1447
1461
 
1448
1462
  try { document.querySelectorAll(WRAP_SELECTOR).forEach(function (w) { try { io.observe(w); } catch(e) {} }); } catch (e) {}
1449
1463
  }
1450
1464
 
1465
+ // Observe new wraps
1451
1466
  var moInstalled = false;
1452
1467
  function installMO() {
1453
1468
  if (moInstalled || typeof MutationObserver === 'undefined') return;
@@ -1465,7 +1480,8 @@ function buildOrdinalMap(items) {
1465
1480
 
1466
1481
  if (n.matches && n.matches(WRAP_SELECTOR)) {
1467
1482
  try { io.observe(n); } catch (e) {}
1468
- try { var id = getWrapId(n); if (id) enqueueShow(id); } catch (e) {}
1483
+ var id = getWrapId(n) || getPlaceholderId(n);
1484
+ if (id) enqueueShow(id);
1469
1485
  } else if (n.querySelectorAll) {
1470
1486
  var inner = n.querySelectorAll(WRAP_SELECTOR);
1471
1487
  for (var k = 0; k < inner.length; k++) {
@@ -1480,9 +1496,37 @@ function buildOrdinalMap(items) {
1480
1496
  try { mo.observe(document.documentElement || document.body, { childList: true, subtree: true }); } catch (e) {}
1481
1497
  }
1482
1498
 
1499
+ // Proximity scanner: ensures re-show on up-scroll even if IO doesn't trigger (e.g. cached intersection state)
1500
+ var lastScan = 0;
1501
+ function proximityScan() {
1502
+ var now = Date.now();
1503
+ if (now - lastScan < PROXIMITY_SCAN_COOLDOWN_MS) return;
1504
+ lastScan = now;
1505
+
1506
+ var margin = proximityMargin();
1507
+ var vh = window.innerHeight || document.documentElement.clientHeight || 0;
1508
+
1509
+ var wraps;
1510
+ try { wraps = document.querySelectorAll(WRAP_SELECTOR); } catch (e) { return; }
1511
+
1512
+ var budget = 12; // don't scan too heavy
1513
+ for (var i = 0; i < wraps.length && budget > 0; i++) {
1514
+ var w = wraps[i];
1515
+ try {
1516
+ var r = w.getBoundingClientRect();
1517
+ if (r.bottom >= -margin && r.top <= (vh + margin)) {
1518
+ var id = getWrapId(w) || getPlaceholderId(w);
1519
+ if (id) enqueueShow(id);
1520
+ budget--;
1521
+ }
1522
+ } catch (e) {}
1523
+ }
1524
+ }
1525
+
1526
+ // Sweep only between cleanup
1483
1527
  var sweepPending = false;
1484
1528
  var lastSweep = 0;
1485
- var SWEEP_COOLDOWN_MS = 600;
1529
+ var SWEEP_COOLDOWN_MS = 700;
1486
1530
 
1487
1531
  function scheduleSweep() {
1488
1532
  var now = Date.now();
@@ -1496,27 +1540,29 @@ function buildOrdinalMap(items) {
1496
1540
  });
1497
1541
  }
1498
1542
 
1543
+ function onScroll() {
1544
+ scheduleSweep();
1545
+ proximityScan();
1546
+ scheduleShowTick();
1547
+ }
1548
+
1499
1549
  function init() {
1500
1550
  installIO();
1501
1551
  installMO();
1502
1552
 
1503
- window.addEventListener('scroll', function () {
1504
- scheduleSweep();
1505
- scheduleShowTick();
1506
- }, { passive: true });
1507
-
1508
- window.addEventListener('resize', function () {
1509
- scheduleSweep();
1510
- scheduleShowTick();
1511
- }, { passive: true });
1553
+ window.addEventListener('scroll', onScroll, { passive: true });
1554
+ window.addEventListener('resize', onScroll, { passive: true });
1512
1555
 
1513
1556
  if (window.jQuery) {
1514
1557
  window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function () {
1515
- setTimeout(function () { installIO(); scheduleSweep(); scheduleShowTick(); }, 0);
1558
+ setTimeout(function () {
1559
+ installIO();
1560
+ onScroll();
1561
+ }, 0);
1516
1562
  });
1517
1563
  }
1518
1564
 
1519
- setTimeout(function () { installIO(); scheduleSweep(); scheduleShowTick(); }, 0);
1565
+ setTimeout(function () { installIO(); onScroll(); }, 0);
1520
1566
  }
1521
1567
 
1522
1568
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
@@ -1525,3 +1571,4 @@ function buildOrdinalMap(items) {
1525
1571
  // ===== /CLEAN REFRACTOR =====
1526
1572
 
1527
1573
 
1574
+