nodebb-plugin-ezoic-infinite 1.6.18 → 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 +85 -110
- package/public/style.css +2 -2
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1511,172 +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
|
|
1519
|
-
var
|
|
1520
|
-
var
|
|
1521
|
-
var COOLDOWN = 120;
|
|
1517
|
+
var WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1518
|
+
var TOPIC_LI_SEL = 'li[component="category/topic"]';
|
|
1519
|
+
var lastY = window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1522
1520
|
|
|
1523
|
-
function
|
|
1524
|
-
|
|
1521
|
+
function getY() {
|
|
1522
|
+
return window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1525
1523
|
}
|
|
1526
1524
|
|
|
1527
|
-
function
|
|
1528
|
-
// Find the topic <li> that this wrap should be associated with:
|
|
1529
|
-
// prefer previous sibling <li> that is NOT a host, else climb to nearest previous in the list.
|
|
1525
|
+
function getTopicList() {
|
|
1530
1526
|
try {
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
if (host) cur = host;
|
|
1537
|
-
}
|
|
1538
|
-
// Find list container
|
|
1539
|
-
var ul = cur.parentElement;
|
|
1540
|
-
while (ul && !(ul.tagName === 'UL' || ul.tagName === 'OL')) ul = ul.parentElement;
|
|
1541
|
-
if (!ul) return null;
|
|
1542
|
-
|
|
1543
|
-
// Start from current element position within ul
|
|
1544
|
-
var prev = cur.previousElementSibling;
|
|
1545
|
-
while (prev) {
|
|
1546
|
-
if (prev.tagName === 'LI' && !(prev.classList && prev.classList.contains(HOST_CLASS))) return prev;
|
|
1547
|
-
prev = prev.previousElementSibling;
|
|
1548
|
-
}
|
|
1549
|
-
} catch (e) {}
|
|
1550
|
-
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; }
|
|
1551
1532
|
}
|
|
1552
1533
|
|
|
1553
|
-
function
|
|
1534
|
+
function ensureValidHostForBetween(wrap) {
|
|
1535
|
+
// Ensure ul/ol does not directly contain div wraps: wrap them in LI host.
|
|
1554
1536
|
try {
|
|
1555
|
-
if (!wrap || wrap.nodeType !== 1) return;
|
|
1556
|
-
if (!(wrap.matches && wrap.matches(
|
|
1557
|
-
|
|
1558
|
-
// Already in a host?
|
|
1559
|
-
var host = wrap.closest ? wrap.closest('li.' + HOST_CLASS) : null;
|
|
1537
|
+
if (!wrap || wrap.nodeType !== 1) return null;
|
|
1538
|
+
if (!(wrap.matches && wrap.matches(WRAP_SEL))) return null;
|
|
1560
1539
|
var ul = wrap.parentElement;
|
|
1561
1540
|
while (ul && !(ul.tagName === 'UL' || ul.tagName === 'OL')) ul = ul.parentElement;
|
|
1562
|
-
if (!ul) return;
|
|
1541
|
+
if (!ul) return null;
|
|
1563
1542
|
|
|
1564
|
-
//
|
|
1565
|
-
|
|
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) {
|
|
1566
1549
|
host = document.createElement('li');
|
|
1567
1550
|
host.className = HOST_CLASS;
|
|
1568
1551
|
host.setAttribute('role', 'listitem');
|
|
1569
1552
|
host.style.listStyle = 'none';
|
|
1570
1553
|
host.style.width = '100%';
|
|
1571
|
-
// Insert host at wrap position
|
|
1572
1554
|
ul.insertBefore(host, wrap);
|
|
1573
1555
|
host.appendChild(wrap);
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
ul.appendChild(host);
|
|
1577
|
-
}
|
|
1578
|
-
|
|
1579
|
-
// Tether to nearest topic li and tag both with same token
|
|
1580
|
-
var anchorLi = closestTopicLi(host) || closestTopicLi(wrap);
|
|
1581
|
-
if (anchorLi) {
|
|
1582
|
-
var t = anchorLi.getAttribute(TOKEN_ATTR);
|
|
1583
|
-
if (!t) {
|
|
1584
|
-
t = token();
|
|
1585
|
-
anchorLi.setAttribute(TOKEN_ATTR, t);
|
|
1586
|
-
}
|
|
1587
|
-
host.setAttribute(TOKEN_ATTR, t);
|
|
1588
|
-
// keep host just after anchor
|
|
1589
|
-
if (host.previousElementSibling !== anchorLi) {
|
|
1590
|
-
anchorLi.insertAdjacentElement('afterend', host);
|
|
1591
|
-
}
|
|
1592
|
-
} else {
|
|
1593
|
-
// No anchor -> it's dangerous; mark host so we can drop it later
|
|
1594
|
-
host.setAttribute('data-ezoic-orphan', '1');
|
|
1556
|
+
try { wrap.style.width = '100%'; } catch (e) {}
|
|
1557
|
+
return host;
|
|
1595
1558
|
}
|
|
1596
1559
|
} catch (e) {}
|
|
1560
|
+
return null;
|
|
1597
1561
|
}
|
|
1598
1562
|
|
|
1599
|
-
function
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
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.
|
|
1566
|
+
try {
|
|
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; }
|
|
1576
|
+
}
|
|
1603
1577
|
|
|
1578
|
+
function reconcileHostsUpScroll() {
|
|
1579
|
+
var ul = getTopicList();
|
|
1580
|
+
if (!ul) return;
|
|
1581
|
+
|
|
1582
|
+
// 1) Repair invalid wraps (cheap)
|
|
1604
1583
|
try {
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
bad.forEach(ensureHostForWrap);
|
|
1584
|
+
ul.querySelectorAll(':scope > ' + WRAP_SEL).forEach(function(w){ ensureValidHostForBetween(w); });
|
|
1585
|
+
} catch (e) {}
|
|
1608
1586
|
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
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;
|
|
1612
1592
|
|
|
1613
|
-
|
|
1614
|
-
var hosts =
|
|
1593
|
+
try {
|
|
1594
|
+
var hosts = ul.querySelectorAll('li.' + HOST_CLASS);
|
|
1615
1595
|
hosts.forEach(function(host){
|
|
1616
1596
|
try {
|
|
1617
|
-
var
|
|
1618
|
-
if (!
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1597
|
+
var wrap = host.querySelector && host.querySelector(WRAP_SEL);
|
|
1598
|
+
if (!wrap) { host.remove(); return; }
|
|
1599
|
+
|
|
1600
|
+
var afterNum = wrap.getAttribute('data-ezoic-after') || host.getAttribute('data-ezoic-after') || '';
|
|
1601
|
+
if (!afterNum) return;
|
|
1602
|
+
|
|
1603
|
+
var anchor = desiredAnchorByAfter(ul, afterNum);
|
|
1622
1604
|
if (!anchor) {
|
|
1605
|
+
// if we can't anchor, remove to prevent piling
|
|
1623
1606
|
host.remove();
|
|
1624
1607
|
return;
|
|
1625
1608
|
}
|
|
1609
|
+
|
|
1626
1610
|
if (host.previousElementSibling !== anchor) {
|
|
1627
1611
|
anchor.insertAdjacentElement('afterend', host);
|
|
1628
1612
|
}
|
|
1629
1613
|
} catch (e) {}
|
|
1630
1614
|
});
|
|
1631
|
-
|
|
1632
|
-
// 4) drop explicit orphans
|
|
1633
|
-
var orphans = document.querySelectorAll('li.' + HOST_CLASS + '[data-ezoic-orphan="1"]');
|
|
1634
|
-
orphans.forEach(function(h){ try { h.remove(); } catch(e) {} });
|
|
1635
1615
|
} catch (e) {}
|
|
1636
1616
|
}
|
|
1637
1617
|
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
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;
|
|
1641
1628
|
requestAnimationFrame(function(){
|
|
1642
|
-
|
|
1643
|
-
|
|
1629
|
+
pending = false;
|
|
1630
|
+
lastRun = Date.now();
|
|
1631
|
+
reconcileHostsUpScroll();
|
|
1644
1632
|
});
|
|
1645
1633
|
}
|
|
1646
1634
|
|
|
1647
|
-
function
|
|
1648
|
-
//
|
|
1635
|
+
function init() {
|
|
1636
|
+
// initial repair only
|
|
1649
1637
|
try {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
for (var i=0;i<muts.length;i++){
|
|
1653
|
-
var m = muts[i];
|
|
1654
|
-
if (m.addedNodes && m.addedNodes.length) { scheduleSweep(); break; }
|
|
1655
|
-
if (m.removedNodes && m.removedNodes.length) { scheduleSweep(); break; }
|
|
1656
|
-
}
|
|
1657
|
-
});
|
|
1658
|
-
mo.observe(document.documentElement || document.body, { childList: true, subtree: true });
|
|
1659
|
-
}
|
|
1638
|
+
var ul = getTopicList();
|
|
1639
|
+
if (ul) ul.querySelectorAll(':scope > ' + WRAP_SEL).forEach(function(w){ ensureValidHostForBetween(w); });
|
|
1660
1640
|
} catch (e) {}
|
|
1661
|
-
}
|
|
1662
1641
|
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
window.addEventListener('scroll', scheduleSweep, { passive: true });
|
|
1666
|
-
window.addEventListener('resize', scheduleSweep, { passive: true });
|
|
1642
|
+
window.addEventListener('scroll', schedule, { passive: true });
|
|
1643
|
+
window.addEventListener('resize', schedule, { passive: true });
|
|
1667
1644
|
|
|
1668
1645
|
if (window.jQuery) {
|
|
1669
1646
|
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function(){
|
|
1670
|
-
setTimeout(
|
|
1671
|
-
setTimeout(
|
|
1672
|
-
setTimeout(scheduleSweep, 900);
|
|
1647
|
+
setTimeout(schedule, 0);
|
|
1648
|
+
setTimeout(schedule, 300);
|
|
1673
1649
|
});
|
|
1674
1650
|
}
|
|
1675
|
-
installObservers();
|
|
1676
1651
|
}
|
|
1677
1652
|
|
|
1678
1653
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
1679
1654
|
else init();
|
|
1680
1655
|
})();
|
|
1681
|
-
// ===== /V14.
|
|
1656
|
+
// ===== /V14.3 =====
|
|
1682
1657
|
|