nodebb-plugin-ezoic-infinite 1.6.19 → 1.6.20
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 +95 -153
- package/public/style.css +2 -2
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1511,205 +1511,147 @@ function buildOrdinalMap(items) {
|
|
|
1511
1511
|
|
|
1512
1512
|
|
|
1513
1513
|
|
|
1514
|
-
// ===== V14.
|
|
1514
|
+
// ===== V14.3 reconcile by data-ezoic-after (upscroll only, no DOM scanning on downscroll) =====
|
|
1515
1515
|
(function () {
|
|
1516
|
-
var BETWEEN_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1517
1516
|
var HOST_CLASS = 'nodebb-ezoic-host';
|
|
1518
|
-
var
|
|
1517
|
+
var WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1519
1518
|
var TOPIC_LI_SEL = 'li[component="category/topic"]';
|
|
1520
|
-
|
|
1521
1519
|
var lastY = window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1522
1520
|
|
|
1523
|
-
function
|
|
1524
|
-
try { return String(Date.now()) + '-' + Math.random().toString(16).slice(2); } catch (e) { return String(Date.now()); }
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
function getScrollY() {
|
|
1521
|
+
function getY() {
|
|
1528
1522
|
return window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1529
1523
|
}
|
|
1530
1524
|
|
|
1531
|
-
function
|
|
1532
|
-
try { return !!(ul && ul.querySelector && ul.querySelector(TOPIC_LI_SEL)); } catch (e) { return false; }
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
function closestTopicList(node) {
|
|
1525
|
+
function getTopicList() {
|
|
1536
1526
|
try {
|
|
1537
|
-
var
|
|
1538
|
-
if (
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
if ((p.tagName === 'UL' || p.tagName === 'OL') && isTopicList(p)) return p;
|
|
1543
|
-
p = p.parentElement;
|
|
1544
|
-
}
|
|
1545
|
-
} catch (e) {}
|
|
1546
|
-
return null;
|
|
1527
|
+
var topicLi = document.querySelector(TOPIC_LI_SEL);
|
|
1528
|
+
if (!topicLi) return null;
|
|
1529
|
+
var ul = topicLi.closest ? topicLi.closest('ul,ol') : null;
|
|
1530
|
+
return ul;
|
|
1531
|
+
} catch (e) { return null; }
|
|
1547
1532
|
}
|
|
1548
1533
|
|
|
1549
|
-
function
|
|
1534
|
+
function ensureValidHostForBetween(wrap) {
|
|
1535
|
+
// Ensure ul/ol does not directly contain div wraps: wrap them in LI host.
|
|
1550
1536
|
try {
|
|
1551
|
-
|
|
1552
|
-
if (!
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
var
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1537
|
+
if (!wrap || wrap.nodeType !== 1) return null;
|
|
1538
|
+
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
|
+
|
|
1543
|
+
// If already inside host, return host
|
|
1544
|
+
var host = wrap.closest ? wrap.closest('li.' + HOST_CLASS) : null;
|
|
1545
|
+
if (host) return host;
|
|
1546
|
+
|
|
1547
|
+
// If direct child of UL/OL, create host and move wrap into it
|
|
1548
|
+
if (wrap.parentElement === ul) {
|
|
1549
|
+
host = document.createElement('li');
|
|
1550
|
+
host.className = HOST_CLASS;
|
|
1551
|
+
host.setAttribute('role', 'listitem');
|
|
1552
|
+
host.style.listStyle = 'none';
|
|
1553
|
+
host.style.width = '100%';
|
|
1554
|
+
ul.insertBefore(host, wrap);
|
|
1555
|
+
host.appendChild(wrap);
|
|
1556
|
+
try { wrap.style.width = '100%'; } catch (e) {}
|
|
1557
|
+
return host;
|
|
1562
1558
|
}
|
|
1563
1559
|
} catch (e) {}
|
|
1564
1560
|
return null;
|
|
1565
1561
|
}
|
|
1566
1562
|
|
|
1567
|
-
function
|
|
1563
|
+
function desiredAnchorByAfter(ul, afterNum) {
|
|
1564
|
+
// afterNum is like 6/12/18 etc. It means "after nth topic".
|
|
1565
|
+
// We'll locate the nth topic LI currently in DOM (1-indexed), then anchor after it.
|
|
1568
1566
|
try {
|
|
1569
|
-
if (!
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
var
|
|
1573
|
-
if (!
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
if (wrap.parentElement === ul) {
|
|
1579
|
-
host = document.createElement('li');
|
|
1580
|
-
host.className = HOST_CLASS;
|
|
1581
|
-
host.setAttribute('role', 'listitem');
|
|
1582
|
-
host.style.listStyle = 'none';
|
|
1583
|
-
host.style.width = '100%';
|
|
1584
|
-
ul.insertBefore(host, wrap);
|
|
1585
|
-
host.appendChild(wrap);
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
if (!host) return;
|
|
1590
|
-
|
|
1591
|
-
// Anchor = previous topic LI only
|
|
1592
|
-
var anchorLi = closestAnchorTopicLi(host, ul);
|
|
1593
|
-
if (!anchorLi) {
|
|
1594
|
-
host.setAttribute('data-ezoic-orphan', '1');
|
|
1595
|
-
return;
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
var t = anchorLi.getAttribute(TOKEN_ATTR);
|
|
1599
|
-
if (!t) {
|
|
1600
|
-
t = token();
|
|
1601
|
-
anchorLi.setAttribute(TOKEN_ATTR, t);
|
|
1602
|
-
}
|
|
1603
|
-
host.setAttribute(TOKEN_ATTR, t);
|
|
1604
|
-
host.removeAttribute('data-ezoic-orphan');
|
|
1605
|
-
} catch (e) {}
|
|
1567
|
+
if (!ul || !afterNum) return null;
|
|
1568
|
+
var n = parseInt(afterNum, 10);
|
|
1569
|
+
if (!n || n < 1) return null;
|
|
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; }
|
|
1606
1576
|
}
|
|
1607
1577
|
|
|
1608
|
-
function
|
|
1578
|
+
function reconcileHostsUpScroll() {
|
|
1579
|
+
var ul = getTopicList();
|
|
1580
|
+
if (!ul) return;
|
|
1581
|
+
|
|
1582
|
+
// 1) Repair invalid wraps (cheap)
|
|
1609
1583
|
try {
|
|
1610
|
-
|
|
1611
|
-
// Fix ul>div wraps
|
|
1612
|
-
var bad = ul.querySelectorAll(':scope > ' + BETWEEN_SEL);
|
|
1613
|
-
bad.forEach(function(wrap){ ensureHostAndTokenForWrap(wrap); });
|
|
1584
|
+
ul.querySelectorAll(':scope > ' + WRAP_SEL).forEach(function(w){ ensureValidHostForBetween(w); });
|
|
1614
1585
|
} catch (e) {}
|
|
1615
|
-
}
|
|
1616
1586
|
|
|
1617
|
-
|
|
1587
|
+
// 2) Only on upscroll: move hosts back to their after-index positions if they drifted.
|
|
1588
|
+
var y = getY();
|
|
1589
|
+
var dy = y - lastY;
|
|
1590
|
+
lastY = y;
|
|
1591
|
+
if (dy >= -10) return;
|
|
1592
|
+
|
|
1618
1593
|
try {
|
|
1619
|
-
if (!ul) return;
|
|
1620
1594
|
var hosts = ul.querySelectorAll('li.' + HOST_CLASS);
|
|
1621
1595
|
hosts.forEach(function(host){
|
|
1622
1596
|
try {
|
|
1623
|
-
var
|
|
1624
|
-
if (!
|
|
1625
|
-
} catch (e) {}
|
|
1626
|
-
});
|
|
1627
|
-
} catch (e) {}
|
|
1628
|
-
}
|
|
1597
|
+
var wrap = host.querySelector && host.querySelector(WRAP_SEL);
|
|
1598
|
+
if (!wrap) { host.remove(); return; }
|
|
1629
1599
|
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
if (host.getAttribute('data-ezoic-orphan') === '1') { host.remove(); return; }
|
|
1644
|
-
var t = host.getAttribute(TOKEN_ATTR);
|
|
1645
|
-
if (!t) { host.remove(); return; }
|
|
1646
|
-
var anchor = ul.querySelector(TOPIC_LI_SEL + '[' + TOKEN_ATTR + '="' + t + '"]');
|
|
1647
|
-
if (!anchor) { host.remove(); return; }
|
|
1648
|
-
if (host.previousElementSibling !== anchor) anchor.insertAdjacentElement('afterend', host);
|
|
1600
|
+
var afterNum = wrap.getAttribute('data-ezoic-after') || host.getAttribute('data-ezoic-after') || '';
|
|
1601
|
+
if (!afterNum) return;
|
|
1602
|
+
|
|
1603
|
+
var anchor = desiredAnchorByAfter(ul, afterNum);
|
|
1604
|
+
if (!anchor) {
|
|
1605
|
+
// if we can't anchor, remove to prevent piling
|
|
1606
|
+
host.remove();
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
if (host.previousElementSibling !== anchor) {
|
|
1611
|
+
anchor.insertAdjacentElement('afterend', host);
|
|
1612
|
+
}
|
|
1649
1613
|
} catch (e) {}
|
|
1650
1614
|
});
|
|
1651
1615
|
} catch (e) {}
|
|
1652
1616
|
}
|
|
1653
1617
|
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
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
|
+
});
|
|
1667
1633
|
}
|
|
1668
1634
|
|
|
1669
|
-
|
|
1670
|
-
|
|
1635
|
+
function init() {
|
|
1636
|
+
// initial repair only
|
|
1671
1637
|
try {
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
for (var i=0;i<muts.length;i++){
|
|
1675
|
-
var m = muts[i];
|
|
1676
|
-
if (m.addedNodes && m.addedNodes.length) {
|
|
1677
|
-
for (var j=0;j<m.addedNodes.length;j++){
|
|
1678
|
-
var n = m.addedNodes[j];
|
|
1679
|
-
if (!n || n.nodeType !== 1) continue;
|
|
1680
|
-
if (n.matches && n.matches(BETWEEN_SEL)) {
|
|
1681
|
-
ensureHostAndTokenForWrap(n);
|
|
1682
|
-
} else if (n.querySelector && n.querySelector(BETWEEN_SEL)) {
|
|
1683
|
-
n.querySelectorAll(BETWEEN_SEL).forEach(function(w){ ensureHostAndTokenForWrap(w); });
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
// light sweep on the container only
|
|
1687
|
-
sweepAll(m.target);
|
|
1688
|
-
break;
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
|
-
});
|
|
1692
|
-
mo.observe(document.documentElement || document.body, { childList: true, subtree: true });
|
|
1638
|
+
var ul = getTopicList();
|
|
1639
|
+
if (ul) ul.querySelectorAll(':scope > ' + WRAP_SEL).forEach(function(w){ ensureValidHostForBetween(w); });
|
|
1693
1640
|
} catch (e) {}
|
|
1694
|
-
}
|
|
1695
1641
|
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
sweepAll(document);
|
|
1699
|
-
window.addEventListener('scroll', function(){ sweepAll(document); }, { passive: true });
|
|
1700
|
-
window.addEventListener('resize', function(){ sweepAll(document); }, { passive: true });
|
|
1642
|
+
window.addEventListener('scroll', schedule, { passive: true });
|
|
1643
|
+
window.addEventListener('resize', schedule, { passive: true });
|
|
1701
1644
|
|
|
1702
1645
|
if (window.jQuery) {
|
|
1703
1646
|
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function(){
|
|
1704
|
-
setTimeout(
|
|
1705
|
-
setTimeout(
|
|
1647
|
+
setTimeout(schedule, 0);
|
|
1648
|
+
setTimeout(schedule, 300);
|
|
1706
1649
|
});
|
|
1707
1650
|
}
|
|
1708
|
-
installMO();
|
|
1709
1651
|
}
|
|
1710
1652
|
|
|
1711
1653
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
1712
1654
|
else init();
|
|
1713
1655
|
})();
|
|
1714
|
-
// ===== /V14.
|
|
1656
|
+
// ===== /V14.3 =====
|
|
1715
1657
|
|