nodebb-plugin-ezoic-infinite 1.6.20 → 1.6.22
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 +110 -88
- package/public/style.css +2 -2
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1511,40 +1511,55 @@ function buildOrdinalMap(items) {
|
|
|
1511
1511
|
|
|
1512
1512
|
|
|
1513
1513
|
|
|
1514
|
-
// ===== V14.
|
|
1514
|
+
// ===== V14.1.2 IO reconcile (visible only) – minimal impact on infinite scroll =====
|
|
1515
1515
|
(function () {
|
|
1516
|
-
var HOST_CLASS = 'nodebb-ezoic-host';
|
|
1517
1516
|
var WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1518
|
-
var
|
|
1519
|
-
var
|
|
1517
|
+
var HOST_CLASS = 'nodebb-ezoic-host';
|
|
1518
|
+
var io = null;
|
|
1520
1519
|
|
|
1521
|
-
function
|
|
1522
|
-
|
|
1520
|
+
function getListContainer(node) {
|
|
1521
|
+
try {
|
|
1522
|
+
var ul = node && node.closest ? node.closest('ul,ol') : null;
|
|
1523
|
+
if (ul && (ul.tagName === 'UL' || ul.tagName === 'OL')) return ul;
|
|
1524
|
+
var p = node && node.parentElement;
|
|
1525
|
+
while (p) {
|
|
1526
|
+
if (p.tagName === 'UL' || p.tagName === 'OL') return p;
|
|
1527
|
+
p = p.parentElement;
|
|
1528
|
+
}
|
|
1529
|
+
} catch (e) {}
|
|
1530
|
+
return null;
|
|
1523
1531
|
}
|
|
1524
1532
|
|
|
1525
|
-
function
|
|
1533
|
+
function closestNonHostLi(node) {
|
|
1526
1534
|
try {
|
|
1527
|
-
var
|
|
1528
|
-
if (!
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1535
|
+
var cur = node;
|
|
1536
|
+
if (!cur) return null;
|
|
1537
|
+
// If inside host, start from host
|
|
1538
|
+
if (cur.closest) {
|
|
1539
|
+
var host = cur.closest('li.' + HOST_CLASS);
|
|
1540
|
+
if (host) cur = host;
|
|
1541
|
+
}
|
|
1542
|
+
var prev = cur.previousElementSibling;
|
|
1543
|
+
while (prev) {
|
|
1544
|
+
if (prev.tagName === 'LI' && !(prev.classList && prev.classList.contains(HOST_CLASS))) return prev;
|
|
1545
|
+
prev = prev.previousElementSibling;
|
|
1546
|
+
}
|
|
1547
|
+
} catch (e) {}
|
|
1548
|
+
return null;
|
|
1532
1549
|
}
|
|
1533
1550
|
|
|
1534
|
-
function
|
|
1535
|
-
//
|
|
1551
|
+
function ensureHostForWrap(wrap) {
|
|
1552
|
+
// Only repairs invalid UL>DIV. Does NOT move around the list except wrapping in-place.
|
|
1536
1553
|
try {
|
|
1537
1554
|
if (!wrap || wrap.nodeType !== 1) return null;
|
|
1538
1555
|
if (!(wrap.matches && wrap.matches(WRAP_SEL))) return null;
|
|
1539
|
-
var ul = wrap.parentElement;
|
|
1540
|
-
while (ul && !(ul.tagName === 'UL' || ul.tagName === 'OL')) ul = ul.parentElement;
|
|
1541
|
-
if (!ul) return null;
|
|
1542
1556
|
|
|
1543
|
-
// If already inside host, return host
|
|
1544
1557
|
var host = wrap.closest ? wrap.closest('li.' + HOST_CLASS) : null;
|
|
1545
1558
|
if (host) return host;
|
|
1546
1559
|
|
|
1547
|
-
|
|
1560
|
+
var ul = getListContainer(wrap);
|
|
1561
|
+
if (!ul) return null;
|
|
1562
|
+
|
|
1548
1563
|
if (wrap.parentElement === ul) {
|
|
1549
1564
|
host = document.createElement('li');
|
|
1550
1565
|
host.className = HOST_CLASS;
|
|
@@ -1560,98 +1575,105 @@ function buildOrdinalMap(items) {
|
|
|
1560
1575
|
return null;
|
|
1561
1576
|
}
|
|
1562
1577
|
|
|
1563
|
-
function
|
|
1564
|
-
//
|
|
1565
|
-
// We'll locate the nth topic LI currently in DOM (1-indexed), then anchor after it.
|
|
1578
|
+
function reconcileHostPosition(host) {
|
|
1579
|
+
// Moves ONLY the one host we are currently handling (visible or just inserted).
|
|
1566
1580
|
try {
|
|
1567
|
-
if (!
|
|
1568
|
-
var
|
|
1569
|
-
if (!
|
|
1570
|
-
var topics = ul.querySelectorAll(TOPIC_LI_SEL);
|
|
1571
|
-
if (!topics || !topics.length) return null;
|
|
1572
|
-
// clamp to range
|
|
1573
|
-
if (n > topics.length) n = topics.length;
|
|
1574
|
-
return topics[n - 1];
|
|
1575
|
-
} catch (e) { return null; }
|
|
1576
|
-
}
|
|
1581
|
+
if (!host || host.nodeType !== 1) return;
|
|
1582
|
+
var ul = getListContainer(host);
|
|
1583
|
+
if (!ul) return;
|
|
1577
1584
|
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1585
|
+
var anchorLi = closestNonHostLi(host);
|
|
1586
|
+
if (!anchorLi) return;
|
|
1587
|
+
|
|
1588
|
+
if (host.previousElementSibling !== anchorLi) {
|
|
1589
|
+
anchorLi.insertAdjacentElement('afterend', host);
|
|
1590
|
+
}
|
|
1591
|
+
} catch (e) {}
|
|
1592
|
+
}
|
|
1581
1593
|
|
|
1582
|
-
|
|
1594
|
+
function observeHost(host) {
|
|
1583
1595
|
try {
|
|
1584
|
-
|
|
1596
|
+
if (!host) return;
|
|
1597
|
+
if (!io) return;
|
|
1598
|
+
io.observe(host);
|
|
1585
1599
|
} catch (e) {}
|
|
1600
|
+
}
|
|
1586
1601
|
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1602
|
+
function initIO() {
|
|
1603
|
+
if (io || typeof IntersectionObserver === 'undefined') return;
|
|
1604
|
+
io = new IntersectionObserver(function (entries) {
|
|
1605
|
+
try {
|
|
1606
|
+
entries.forEach(function (e) {
|
|
1607
|
+
if (!e || !e.isIntersecting || !e.target) return;
|
|
1608
|
+
// When host is near viewport, reconcile once.
|
|
1609
|
+
reconcileHostPosition(e.target);
|
|
1610
|
+
});
|
|
1611
|
+
} catch (e) {}
|
|
1612
|
+
}, { root: null, rootMargin: '800px 0px 800px 0px', threshold: 0.01 });
|
|
1613
|
+
}
|
|
1592
1614
|
|
|
1615
|
+
function processWrap(wrap) {
|
|
1593
1616
|
try {
|
|
1594
|
-
var
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1617
|
+
var host = ensureHostForWrap(wrap) || (wrap.closest ? wrap.closest('li.' + HOST_CLASS) : null);
|
|
1618
|
+
if (host) {
|
|
1619
|
+
// reconcile immediately only for the newly processed node (cheap)
|
|
1620
|
+
reconcileHostPosition(host);
|
|
1621
|
+
observeHost(host);
|
|
1622
|
+
}
|
|
1623
|
+
} catch (e) {}
|
|
1624
|
+
}
|
|
1602
1625
|
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
}
|
|
1626
|
+
function scanInitial() {
|
|
1627
|
+
try {
|
|
1628
|
+
document.querySelectorAll(WRAP_SEL).forEach(processWrap);
|
|
1629
|
+
} catch (e) {}
|
|
1630
|
+
}
|
|
1609
1631
|
|
|
1610
|
-
|
|
1611
|
-
|
|
1632
|
+
function installMO() {
|
|
1633
|
+
try {
|
|
1634
|
+
if (typeof MutationObserver === 'undefined') return;
|
|
1635
|
+
var mo = new MutationObserver(function (muts) {
|
|
1636
|
+
try {
|
|
1637
|
+
for (var i = 0; i < muts.length; i++) {
|
|
1638
|
+
var m = muts[i];
|
|
1639
|
+
if (!m.addedNodes || !m.addedNodes.length) continue;
|
|
1640
|
+
|
|
1641
|
+
for (var j = 0; j < m.addedNodes.length; j++) {
|
|
1642
|
+
var n = m.addedNodes[j];
|
|
1643
|
+
if (!n || n.nodeType !== 1) continue;
|
|
1644
|
+
|
|
1645
|
+
if (n.matches && n.matches(WRAP_SEL)) {
|
|
1646
|
+
processWrap(n);
|
|
1647
|
+
} else if (n.querySelectorAll) {
|
|
1648
|
+
var inner = n.querySelectorAll(WRAP_SEL);
|
|
1649
|
+
if (inner && inner.length) inner.forEach(processWrap);
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1612
1652
|
}
|
|
1613
1653
|
} catch (e) {}
|
|
1614
1654
|
});
|
|
1655
|
+
mo.observe(document.documentElement || document.body, { childList: true, subtree: true });
|
|
1615
1656
|
} catch (e) {}
|
|
1616
1657
|
}
|
|
1617
1658
|
|
|
1618
|
-
// Throttled scheduler (scroll)
|
|
1619
|
-
var pending = false;
|
|
1620
|
-
var lastRun = 0;
|
|
1621
|
-
var COOLDOWN = 160;
|
|
1622
|
-
|
|
1623
|
-
function schedule() {
|
|
1624
|
-
var now = Date.now();
|
|
1625
|
-
if (now - lastRun < COOLDOWN) return;
|
|
1626
|
-
if (pending) return;
|
|
1627
|
-
pending = true;
|
|
1628
|
-
requestAnimationFrame(function(){
|
|
1629
|
-
pending = false;
|
|
1630
|
-
lastRun = Date.now();
|
|
1631
|
-
reconcileHostsUpScroll();
|
|
1632
|
-
});
|
|
1633
|
-
}
|
|
1634
|
-
|
|
1635
1659
|
function init() {
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
if (ul) ul.querySelectorAll(':scope > ' + WRAP_SEL).forEach(function(w){ ensureValidHostForBetween(w); });
|
|
1640
|
-
} catch (e) {}
|
|
1641
|
-
|
|
1642
|
-
window.addEventListener('scroll', schedule, { passive: true });
|
|
1643
|
-
window.addEventListener('resize', schedule, { passive: true });
|
|
1660
|
+
initIO();
|
|
1661
|
+
scanInitial();
|
|
1662
|
+
installMO();
|
|
1644
1663
|
|
|
1645
1664
|
if (window.jQuery) {
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1665
|
+
try {
|
|
1666
|
+
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function () {
|
|
1667
|
+
// do a light rescan (no scroll listeners)
|
|
1668
|
+
setTimeout(scanInitial, 0);
|
|
1669
|
+
setTimeout(scanInitial, 250);
|
|
1670
|
+
});
|
|
1671
|
+
} catch (e) {}
|
|
1650
1672
|
}
|
|
1651
1673
|
}
|
|
1652
1674
|
|
|
1653
1675
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
1654
1676
|
else init();
|
|
1655
1677
|
})();
|
|
1656
|
-
// ===== /V14.
|
|
1678
|
+
// ===== /V14.1.2 =====
|
|
1657
1679
|
|