nodebb-plugin-ezoic-infinite 1.6.36 → 1.6.38
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 +112 -165
- package/public/style.css +7 -2
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -498,6 +498,25 @@ function globalGapFixInit() {
|
|
|
498
498
|
return el;
|
|
499
499
|
}
|
|
500
500
|
|
|
501
|
+
// Best-effort refresh for Ezoic standalone when we defer placement.
|
|
502
|
+
// Some stacks won't fill ads if a placeholder is rendered while collapsed/0px.
|
|
503
|
+
let _refreshTimer = null;
|
|
504
|
+
function refreshAds(ids) {
|
|
505
|
+
if (!ids || !ids.length) return;
|
|
506
|
+
clearTimeout(_refreshTimer);
|
|
507
|
+
_refreshTimer = setTimeout(() => {
|
|
508
|
+
try {
|
|
509
|
+
if (window.ezstandalone && typeof window.ezstandalone.showAds === 'function') {
|
|
510
|
+
window.ezstandalone.showAds(ids);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
if (window.ez && typeof window.ez.showAds === 'function') {
|
|
514
|
+
window.ez.showAds(ids);
|
|
515
|
+
}
|
|
516
|
+
} catch (e) {}
|
|
517
|
+
}, 50);
|
|
518
|
+
}
|
|
519
|
+
|
|
501
520
|
function primePlaceholderPool(allIds) {
|
|
502
521
|
try {
|
|
503
522
|
if (!Array.isArray(allIds) || !allIds.length) return;
|
|
@@ -1514,20 +1533,18 @@ function buildOrdinalMap(items) {
|
|
|
1514
1533
|
|
|
1515
1534
|
|
|
1516
1535
|
|
|
1517
|
-
// ===== V17.
|
|
1536
|
+
// ===== V17.8: No pile-up by design — keep "future" between slots pending/collapsed until their anchor topic exists =====
|
|
1518
1537
|
(function () {
|
|
1519
1538
|
var TOPIC_LI_SEL = 'li[component="category/topic"]';
|
|
1520
1539
|
var BETWEEN_WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1521
1540
|
var HOST_CLASS = 'nodebb-ezoic-host';
|
|
1522
|
-
var
|
|
1541
|
+
var PENDING_CLASS = 'nodebb-ezoic-pending';
|
|
1523
1542
|
|
|
1524
1543
|
var ul = null;
|
|
1525
1544
|
var mo = null;
|
|
1526
|
-
|
|
1527
|
-
var
|
|
1528
|
-
var
|
|
1529
|
-
var lastFlush = 0;
|
|
1530
|
-
var FLUSH_COOLDOWN = 60;
|
|
1545
|
+
var scheduled = false;
|
|
1546
|
+
var lastRun = 0;
|
|
1547
|
+
var COOLDOWN = 80;
|
|
1531
1548
|
|
|
1532
1549
|
function getTopicList() {
|
|
1533
1550
|
try {
|
|
@@ -1543,12 +1560,14 @@ function buildOrdinalMap(items) {
|
|
|
1543
1560
|
return !!(el && el.nodeType === 1 && el.tagName === 'LI' && el.classList && el.classList.contains(HOST_CLASS));
|
|
1544
1561
|
}
|
|
1545
1562
|
|
|
1563
|
+
function isBetweenWrap(el) {
|
|
1564
|
+
try { return !!(el && el.nodeType === 1 && el.matches && el.matches(BETWEEN_WRAP_SEL)); } catch(e){ return false; }
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1546
1567
|
function ensureHostForWrap(wrap, ulEl) {
|
|
1547
|
-
//
|
|
1568
|
+
// If Ezoic inserts ul > div..., wrap it into a LI to keep a valid list structure (less NodeBB churn).
|
|
1548
1569
|
try {
|
|
1549
|
-
if (!wrap || wrap
|
|
1550
|
-
if (!(wrap.matches && wrap.matches(BETWEEN_WRAP_SEL))) return null;
|
|
1551
|
-
|
|
1570
|
+
if (!wrap || !isBetweenWrap(wrap)) return null;
|
|
1552
1571
|
var host = wrap.closest ? wrap.closest('li.' + HOST_CLASS) : null;
|
|
1553
1572
|
if (host) return host;
|
|
1554
1573
|
|
|
@@ -1561,10 +1580,14 @@ function buildOrdinalMap(items) {
|
|
|
1561
1580
|
host.setAttribute('role', 'listitem');
|
|
1562
1581
|
host.style.listStyle = 'none';
|
|
1563
1582
|
host.style.width = '100%';
|
|
1583
|
+
|
|
1564
1584
|
try {
|
|
1565
1585
|
var after = wrap.getAttribute('data-ezoic-after');
|
|
1566
1586
|
if (after) host.setAttribute('data-ezoic-after', after);
|
|
1587
|
+
var pin = wrap.getAttribute('data-ezoic-pin');
|
|
1588
|
+
if (pin) host.setAttribute('data-ezoic-pin', pin);
|
|
1567
1589
|
} catch (e) {}
|
|
1590
|
+
|
|
1568
1591
|
ulEl.insertBefore(host, wrap);
|
|
1569
1592
|
host.appendChild(wrap);
|
|
1570
1593
|
try { wrap.style.width = '100%'; } catch (e) {}
|
|
@@ -1574,227 +1597,151 @@ function buildOrdinalMap(items) {
|
|
|
1574
1597
|
return null;
|
|
1575
1598
|
}
|
|
1576
1599
|
|
|
1577
|
-
function
|
|
1600
|
+
function getAfter(el) {
|
|
1578
1601
|
try {
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
if (
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
if (a) {
|
|
1585
|
-
var href = a.getAttribute('href') || '';
|
|
1586
|
-
var m = href.match(/\\/topic\\/(\\d+)(\\/|$)/);
|
|
1587
|
-
if (m) return m[1];
|
|
1602
|
+
var v = null;
|
|
1603
|
+
if (el && el.getAttribute) v = el.getAttribute('data-ezoic-after');
|
|
1604
|
+
if (!v && el && el.querySelector) {
|
|
1605
|
+
var w = el.querySelector(BETWEEN_WRAP_SEL);
|
|
1606
|
+
if (w) v = w.getAttribute('data-ezoic-after');
|
|
1588
1607
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1608
|
+
var n = parseInt(v, 10);
|
|
1609
|
+
return isNaN(n) ? null : n;
|
|
1610
|
+
} catch (e) { return null; }
|
|
1591
1611
|
}
|
|
1592
1612
|
|
|
1593
|
-
function
|
|
1594
|
-
try {
|
|
1595
|
-
var cur = node;
|
|
1596
|
-
if (!cur) return null;
|
|
1597
|
-
if (cur.closest) {
|
|
1598
|
-
var h = cur.closest('li.' + HOST_CLASS);
|
|
1599
|
-
if (h) cur = h;
|
|
1600
|
-
}
|
|
1601
|
-
var prev = cur.previousElementSibling;
|
|
1602
|
-
while (prev) {
|
|
1603
|
-
if (prev.matches && prev.matches(TOPIC_LI_SEL)) return prev;
|
|
1604
|
-
prev = prev.previousElementSibling;
|
|
1605
|
-
}
|
|
1606
|
-
} catch (e) {}
|
|
1607
|
-
return null;
|
|
1613
|
+
function getTopics(ulEl) {
|
|
1614
|
+
try { return ulEl ? ulEl.querySelectorAll(TOPIC_LI_SEL) : []; } catch(e){ return []; }
|
|
1608
1615
|
}
|
|
1609
1616
|
|
|
1610
|
-
function
|
|
1617
|
+
function lastTopic(ulEl, topics) {
|
|
1611
1618
|
try {
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
TOPIC_LI_SEL + '[data-topic-id="' + tid + '"], ' +
|
|
1616
|
-
TOPIC_LI_SEL + '[data-topicid="' + tid + '"]'
|
|
1617
|
-
);
|
|
1618
|
-
if (q) return q;
|
|
1619
|
-
|
|
1620
|
-
var topics = ulEl.querySelectorAll(TOPIC_LI_SEL);
|
|
1621
|
-
for (var i=0;i<topics.length;i++){
|
|
1622
|
-
var t = getTidFromTopicLi(topics[i]);
|
|
1623
|
-
if (t === tid) return topics[i];
|
|
1624
|
-
}
|
|
1625
|
-
} catch (e) {}
|
|
1626
|
-
return null;
|
|
1619
|
+
topics = topics || getTopics(ulEl);
|
|
1620
|
+
return topics && topics.length ? topics[topics.length - 1] : null;
|
|
1621
|
+
} catch (e) { return null; }
|
|
1627
1622
|
}
|
|
1628
1623
|
|
|
1629
|
-
function
|
|
1624
|
+
function moveAfter(node, anchor) {
|
|
1630
1625
|
try {
|
|
1631
|
-
if (!
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
if (el.matches && el.matches(BETWEEN_WRAP_SEL)) {
|
|
1635
|
-
var h = el.closest ? el.closest('li.' + HOST_CLASS) : null;
|
|
1636
|
-
if (h) el = h;
|
|
1637
|
-
}
|
|
1638
|
-
if (!isHost(el) && !(el.matches && el.matches(BETWEEN_WRAP_SEL))) return;
|
|
1639
|
-
|
|
1640
|
-
if (el.getAttribute && el.getAttribute(ANCHOR_ATTR)) return;
|
|
1641
|
-
|
|
1642
|
-
var prevTopic = closestPrevTopicLi(el);
|
|
1643
|
-
if (!prevTopic) return;
|
|
1644
|
-
var tid = getTidFromTopicLi(prevTopic);
|
|
1645
|
-
if (!tid) return;
|
|
1646
|
-
|
|
1647
|
-
el.setAttribute(ANCHOR_ATTR, tid);
|
|
1626
|
+
if (!node || !anchor || !anchor.insertAdjacentElement) return;
|
|
1627
|
+
if (node.previousElementSibling === anchor) return;
|
|
1628
|
+
anchor.insertAdjacentElement('afterend', node);
|
|
1648
1629
|
} catch (e) {}
|
|
1649
1630
|
}
|
|
1650
1631
|
|
|
1651
|
-
function
|
|
1632
|
+
function placeOrPend(host, ulEl, topics) {
|
|
1652
1633
|
try {
|
|
1634
|
+
if (!host) return;
|
|
1653
1635
|
ulEl = ulEl || ensureUL();
|
|
1654
1636
|
if (!ulEl) return;
|
|
1655
1637
|
|
|
1656
|
-
|
|
1638
|
+
topics = topics || getTopics(ulEl);
|
|
1657
1639
|
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
if (isHost(el)) {
|
|
1664
|
-
rememberAnchor(el);
|
|
1665
|
-
var tid = el.getAttribute(ANCHOR_ATTR);
|
|
1666
|
-
if (!tid) return;
|
|
1667
|
-
var anchorTopic = topicLiByTid(ulEl, tid);
|
|
1668
|
-
if (!anchorTopic) return;
|
|
1669
|
-
if (el.previousElementSibling !== anchorTopic) {
|
|
1670
|
-
anchorTopic.insertAdjacentElement('afterend', el);
|
|
1671
|
-
}
|
|
1640
|
+
var after = getAfter(host);
|
|
1641
|
+
if (!after) {
|
|
1642
|
+
var lt = lastTopic(ulEl, topics);
|
|
1643
|
+
if (lt) moveAfter(host, lt);
|
|
1644
|
+
host.classList && host.classList.remove(PENDING_CLASS);
|
|
1672
1645
|
return;
|
|
1673
1646
|
}
|
|
1674
1647
|
|
|
1675
|
-
if (
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
anchor2.insertAdjacentElement('afterend', el);
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
} catch (e) {}
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
function enqueue(node) {
|
|
1689
|
-
try {
|
|
1690
|
-
if (!node || node.nodeType !== 1) return;
|
|
1691
|
-
|
|
1692
|
-
if (isHost(node) || (node.matches && node.matches(BETWEEN_WRAP_SEL))) {
|
|
1693
|
-
queue.add(node);
|
|
1694
|
-
scheduleFlush();
|
|
1648
|
+
if (after > topics.length) {
|
|
1649
|
+
// Defer placement until the anchor exists.
|
|
1650
|
+
// Keeping a placeholder in a collapsed/0px container can prevent ad fill on some stacks.
|
|
1651
|
+
host.classList && host.classList.add(PENDING_CLASS);
|
|
1652
|
+
try {
|
|
1653
|
+
getPoolEl().appendChild(host);
|
|
1654
|
+
} catch (e) {}
|
|
1695
1655
|
return;
|
|
1696
1656
|
}
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
if (
|
|
1657
|
+
|
|
1658
|
+
var anchor = topics[after - 1];
|
|
1659
|
+
if (anchor) moveAfter(host, anchor);
|
|
1660
|
+
if (host.classList && host.classList.contains(PENDING_CLASS)) {
|
|
1661
|
+
host.classList.remove(PENDING_CLASS);
|
|
1662
|
+
if (host.dataset && host.dataset.ezoicId) refreshAds([host.dataset.ezoicId]);
|
|
1703
1663
|
}
|
|
1704
1664
|
} catch (e) {}
|
|
1705
1665
|
}
|
|
1706
1666
|
|
|
1707
|
-
function
|
|
1708
|
-
pending = false;
|
|
1667
|
+
function reconcile() {
|
|
1709
1668
|
var ulEl = ensureUL();
|
|
1710
1669
|
if (!ulEl) return;
|
|
1711
1670
|
|
|
1712
|
-
|
|
1671
|
+
var topics = getTopics(ulEl);
|
|
1672
|
+
|
|
1713
1673
|
try {
|
|
1714
|
-
ulEl.querySelectorAll(':scope > ' + BETWEEN_WRAP_SEL).forEach(function(w){
|
|
1715
|
-
var
|
|
1716
|
-
if (
|
|
1674
|
+
ulEl.querySelectorAll(':scope > ' + BETWEEN_WRAP_SEL).forEach(function (w) {
|
|
1675
|
+
var h = ensureHostForWrap(w, ulEl);
|
|
1676
|
+
if (h) placeOrPend(h, ulEl, topics);
|
|
1717
1677
|
});
|
|
1718
|
-
ulEl.querySelectorAll('li.' + HOST_CLASS).forEach(function(h){ rememberAnchor(h); });
|
|
1719
|
-
ulEl.querySelectorAll(BETWEEN_WRAP_SEL).forEach(function(w){ rememberAnchor(w); });
|
|
1720
|
-
} catch (e) {}
|
|
1721
1678
|
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1679
|
+
ulEl.querySelectorAll('li.' + HOST_CLASS).forEach(function (h) {
|
|
1680
|
+
placeOrPend(h, ulEl, topics);
|
|
1681
|
+
});
|
|
1682
|
+
|
|
1683
|
+
ulEl.querySelectorAll(BETWEEN_WRAP_SEL).forEach(function (w) {
|
|
1684
|
+
var h = ensureHostForWrap(w, ulEl) || (w.closest ? w.closest('li.' + HOST_CLASS) : null);
|
|
1685
|
+
if (h) placeOrPend(h, ulEl, topics);
|
|
1686
|
+
});
|
|
1687
|
+
} catch (e) {}
|
|
1730
1688
|
}
|
|
1731
1689
|
|
|
1732
|
-
function
|
|
1690
|
+
function scheduleReconcile() {
|
|
1733
1691
|
var now = Date.now();
|
|
1734
|
-
if (
|
|
1735
|
-
if (now -
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
requestAnimationFrame(
|
|
1692
|
+
if (scheduled) return;
|
|
1693
|
+
if (now - lastRun < COOLDOWN) return;
|
|
1694
|
+
scheduled = true;
|
|
1695
|
+
lastRun = now;
|
|
1696
|
+
requestAnimationFrame(function () {
|
|
1697
|
+
scheduled = false;
|
|
1698
|
+
reconcile();
|
|
1699
|
+
});
|
|
1739
1700
|
}
|
|
1740
1701
|
|
|
1741
1702
|
function initObserver() {
|
|
1742
1703
|
var ulEl = ensureUL();
|
|
1743
1704
|
if (!ulEl || mo) return;
|
|
1744
1705
|
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
ulEl.querySelectorAll(BETWEEN_WRAP_SEL).forEach(function(w){
|
|
1748
|
-
var host = ensureHostForWrap(w, ulEl) || (w.closest ? w.closest('li.' + HOST_CLASS) : null);
|
|
1749
|
-
rememberAnchor(host || w);
|
|
1750
|
-
});
|
|
1751
|
-
} catch (e) {}
|
|
1752
|
-
|
|
1753
|
-
mo = new MutationObserver(function(muts){
|
|
1754
|
-
try {
|
|
1755
|
-
for (var i=0;i<muts.length;i++){
|
|
1756
|
-
var m = muts[i];
|
|
1757
|
-
if (m.addedNodes && m.addedNodes.length) {
|
|
1758
|
-
for (var j=0;j<m.addedNodes.length;j++) enqueue(m.addedNodes[j]);
|
|
1759
|
-
}
|
|
1760
|
-
if (m.target) enqueue(m.target);
|
|
1761
|
-
}
|
|
1762
|
-
} catch (e) {}
|
|
1706
|
+
mo = new MutationObserver(function () {
|
|
1707
|
+
scheduleReconcile();
|
|
1763
1708
|
});
|
|
1764
|
-
|
|
1709
|
+
|
|
1710
|
+
mo.observe(ulEl, { childList: true, subtree: true });
|
|
1765
1711
|
}
|
|
1766
1712
|
|
|
1767
1713
|
function init() {
|
|
1768
1714
|
initObserver();
|
|
1769
|
-
|
|
1715
|
+
scheduleReconcile();
|
|
1770
1716
|
|
|
1771
1717
|
if (window.jQuery) {
|
|
1772
1718
|
try {
|
|
1773
|
-
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function(){
|
|
1719
|
+
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function () {
|
|
1774
1720
|
ul = null;
|
|
1775
|
-
try { if (mo)
|
|
1721
|
+
try { if (mo) mo.disconnect(); } catch (e) {}
|
|
1776
1722
|
mo = null;
|
|
1777
1723
|
initObserver();
|
|
1778
|
-
|
|
1779
|
-
setTimeout(
|
|
1724
|
+
scheduleReconcile();
|
|
1725
|
+
setTimeout(scheduleReconcile, 120);
|
|
1726
|
+
setTimeout(scheduleReconcile, 500);
|
|
1780
1727
|
});
|
|
1781
1728
|
} catch (e) {}
|
|
1782
1729
|
}
|
|
1783
1730
|
|
|
1784
1731
|
var tries = 0;
|
|
1785
|
-
var t = setInterval(function(){
|
|
1732
|
+
var t = setInterval(function () {
|
|
1786
1733
|
tries++;
|
|
1787
1734
|
if (ensureUL()) {
|
|
1788
1735
|
clearInterval(t);
|
|
1789
1736
|
initObserver();
|
|
1790
|
-
|
|
1737
|
+
scheduleReconcile();
|
|
1791
1738
|
}
|
|
1792
|
-
if (tries >
|
|
1739
|
+
if (tries > 30) clearInterval(t);
|
|
1793
1740
|
}, 200);
|
|
1794
1741
|
}
|
|
1795
1742
|
|
|
1796
1743
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
1797
1744
|
else init();
|
|
1798
1745
|
})();
|
|
1799
|
-
// ===== /V17.
|
|
1746
|
+
// ===== /V17.8 =====
|
|
1800
1747
|
|
package/public/style.css
CHANGED
|
@@ -88,8 +88,13 @@ li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width: 100%; displa
|
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
/* ===== V17.
|
|
91
|
+
/* ===== V17.8 pending slots (prevents pile-up top/bottom) ===== */
|
|
92
92
|
li.nodebb-ezoic-host { list-style:none; width:100%; display:block; }
|
|
93
93
|
li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width:100%; display:block; }
|
|
94
|
-
|
|
94
|
+
|
|
95
|
+
/* slots whose anchor topic isn't loaded yet */
|
|
96
|
+
li.nodebb-ezoic-host.nodebb-ezoic-pending{
|
|
97
|
+
display: none !important;
|
|
98
|
+
}
|
|
99
|
+
/* ===== /V17.8 ===== */
|
|
95
100
|
|