nodebb-plugin-ezoic-infinite 1.6.29 → 1.6.31
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 +123 -107
- package/public/style.css +11 -2
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1511,176 +1511,192 @@ function buildOrdinalMap(items) {
|
|
|
1511
1511
|
|
|
1512
1512
|
|
|
1513
1513
|
|
|
1514
|
-
|
|
1515
|
-
|
|
1514
|
+
|
|
1515
|
+
|
|
1516
|
+
|
|
1517
|
+
// ===== V17.3: keep injection; hide top pile on upscroll; rehome EMPTY hosts on downscroll =====
|
|
1518
|
+
(function(){
|
|
1516
1519
|
var TOPIC_LI_SEL = 'li[component="category/topic"]';
|
|
1517
1520
|
var BETWEEN_WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1518
1521
|
var HOST_CLASS = 'nodebb-ezoic-host';
|
|
1522
|
+
var PILED_ATTR = 'data-ezoic-piled';
|
|
1519
1523
|
|
|
1524
|
+
var lastY = window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1520
1525
|
var scheduled = false;
|
|
1521
1526
|
var lastRun = 0;
|
|
1522
|
-
var COOLDOWN =
|
|
1523
|
-
|
|
1524
|
-
var lastY = window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1527
|
+
var COOLDOWN = 120;
|
|
1525
1528
|
|
|
1526
|
-
function getY()
|
|
1527
|
-
return window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1528
|
-
}
|
|
1529
|
+
function getY(){ return window.pageYOffset || document.documentElement.scrollTop || 0; }
|
|
1529
1530
|
|
|
1530
|
-
function getTopicList()
|
|
1531
|
+
function getTopicList(){
|
|
1531
1532
|
try {
|
|
1532
1533
|
var li = document.querySelector(TOPIC_LI_SEL);
|
|
1533
1534
|
if (!li) return null;
|
|
1534
1535
|
return li.closest ? li.closest('ul,ol') : null;
|
|
1535
|
-
} catch
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
function isHost(node) {
|
|
1539
|
-
return !!(node && node.nodeType === 1 && node.tagName === 'LI' && node.classList && node.classList.contains(HOST_CLASS));
|
|
1536
|
+
} catch(e){ return null; }
|
|
1540
1537
|
}
|
|
1541
1538
|
|
|
1542
|
-
function ensureHostForWrap(wrap, ul)
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
if (!wrap || wrap.nodeType !== 1) return null;
|
|
1539
|
+
function ensureHostForWrap(wrap, ul){
|
|
1540
|
+
try{
|
|
1541
|
+
if (!wrap || wrap.nodeType!==1) return null;
|
|
1546
1542
|
if (!(wrap.matches && wrap.matches(BETWEEN_WRAP_SEL))) return null;
|
|
1547
1543
|
|
|
1548
|
-
var host = wrap.closest ? wrap.closest('li.'
|
|
1544
|
+
var host = wrap.closest ? wrap.closest('li.'+HOST_CLASS) : null;
|
|
1549
1545
|
if (host) return host;
|
|
1550
1546
|
|
|
1551
1547
|
if (!ul) ul = wrap.closest ? wrap.closest('ul,ol') : null;
|
|
1552
|
-
if (!ul || !(ul.tagName
|
|
1548
|
+
if (!ul || !(ul.tagName==='UL' || ul.tagName==='OL')) return null;
|
|
1553
1549
|
|
|
1554
|
-
if (wrap.parentElement === ul)
|
|
1550
|
+
if (wrap.parentElement === ul){
|
|
1555
1551
|
host = document.createElement('li');
|
|
1556
1552
|
host.className = HOST_CLASS;
|
|
1557
|
-
host.setAttribute('role',
|
|
1558
|
-
host.style.listStyle
|
|
1559
|
-
host.style.width
|
|
1553
|
+
host.setAttribute('role','listitem');
|
|
1554
|
+
host.style.listStyle='none';
|
|
1555
|
+
host.style.width='100%';
|
|
1556
|
+
// preserve after
|
|
1557
|
+
try {
|
|
1558
|
+
var after = wrap.getAttribute('data-ezoic-after');
|
|
1559
|
+
if (after) host.setAttribute('data-ezoic-after', after);
|
|
1560
|
+
} catch(e){}
|
|
1560
1561
|
ul.insertBefore(host, wrap);
|
|
1561
1562
|
host.appendChild(wrap);
|
|
1562
|
-
try { wrap.style.width
|
|
1563
|
+
try { wrap.style.width='100%'; } catch(e){}
|
|
1563
1564
|
return host;
|
|
1564
1565
|
}
|
|
1565
|
-
}
|
|
1566
|
+
}catch(e){}
|
|
1566
1567
|
return null;
|
|
1567
1568
|
}
|
|
1568
1569
|
|
|
1569
|
-
function
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
prev = prev.previousElementSibling;
|
|
1575
|
-
}
|
|
1576
|
-
} catch (e) {}
|
|
1577
|
-
return null;
|
|
1570
|
+
function hostHasAdContent(host){
|
|
1571
|
+
// iframes/amp ads mean it's already rendered; moving might reduce fill
|
|
1572
|
+
try{
|
|
1573
|
+
return !!(host.querySelector && host.querySelector('iframe, amp-ad, amp-iframe, .amp-ads, .ezoic-ad iframe'));
|
|
1574
|
+
}catch(e){ return false; }
|
|
1578
1575
|
}
|
|
1579
1576
|
|
|
1580
|
-
function
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
var isBetween = false;
|
|
1590
|
-
if (isHost(el)) isBetween = !!(el.querySelector && el.querySelector(BETWEEN_WRAP_SEL));
|
|
1591
|
-
else if (el.matches && el.matches(BETWEEN_WRAP_SEL)) isBetween = true;
|
|
1577
|
+
function nthTopic(ul, n){
|
|
1578
|
+
try{
|
|
1579
|
+
var topics = ul.querySelectorAll(TOPIC_LI_SEL);
|
|
1580
|
+
if (!topics || !topics.length) return null;
|
|
1581
|
+
if (n<1) n=1;
|
|
1582
|
+
if (n>topics.length) n=topics.length;
|
|
1583
|
+
return topics[n-1] || null;
|
|
1584
|
+
}catch(e){ return null; }
|
|
1585
|
+
}
|
|
1592
1586
|
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1587
|
+
function getAfter(host){
|
|
1588
|
+
try{
|
|
1589
|
+
var v = host.getAttribute('data-ezoic-after');
|
|
1590
|
+
if (!v){
|
|
1591
|
+
var wrap = host.querySelector && host.querySelector(BETWEEN_WRAP_SEL);
|
|
1592
|
+
if (wrap) v = wrap.getAttribute('data-ezoic-after');
|
|
1596
1593
|
}
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
return
|
|
1594
|
+
var n = parseInt(v,10);
|
|
1595
|
+
return isNaN(n)? null : n;
|
|
1596
|
+
}catch(e){ return null; }
|
|
1600
1597
|
}
|
|
1601
1598
|
|
|
1602
|
-
function
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
// Step 0: wrap invalid top-level between divs
|
|
1607
|
-
try { ul.querySelectorAll(':scope > ' + BETWEEN_WRAP_SEL).forEach(function(w){ ensureHostForWrap(w, ul); }); } catch(e){}
|
|
1608
|
-
|
|
1609
|
-
if (!detectTopPileUp(ul)) return;
|
|
1610
|
-
|
|
1611
|
-
// Only move hosts that are currently in the top region (first 60 list children).
|
|
1599
|
+
function detectAndHideTopPile(ul){
|
|
1600
|
+
// Hide piled hosts near top so user doesn't see the stack.
|
|
1601
|
+
try{
|
|
1612
1602
|
var kids = ul.children;
|
|
1613
1603
|
var limit = Math.min(kids.length, 60);
|
|
1604
|
+
var run = 0;
|
|
1614
1605
|
for (var i=0;i<limit;i++){
|
|
1615
1606
|
var el = kids[i];
|
|
1616
|
-
|
|
1617
|
-
var
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1607
|
+
var isBetweenHost = (el.tagName==='LI' && el.classList && el.classList.contains(HOST_CLASS) && el.querySelector && el.querySelector(BETWEEN_WRAP_SEL));
|
|
1608
|
+
var isTopic = (el.matches && el.matches(TOPIC_LI_SEL));
|
|
1609
|
+
if (isBetweenHost){
|
|
1610
|
+
run++;
|
|
1611
|
+
if (run>=2){
|
|
1612
|
+
// mark piled beyond the first
|
|
1613
|
+
el.setAttribute(PILED_ATTR,'1');
|
|
1614
|
+
}
|
|
1615
|
+
} else if (isTopic){
|
|
1616
|
+
run=0;
|
|
1617
|
+
} else {
|
|
1618
|
+
// reset on any non-topic
|
|
1625
1619
|
}
|
|
1626
1620
|
}
|
|
1627
|
-
}
|
|
1621
|
+
}catch(e){}
|
|
1628
1622
|
}
|
|
1629
1623
|
|
|
1630
|
-
function
|
|
1624
|
+
function rehomePiledEmptyOnDownscroll(ul){
|
|
1625
|
+
// On downscroll, try to move only EMPTY (not yet rendered) piled hosts to intended anchors and unhide them.
|
|
1626
|
+
try{
|
|
1627
|
+
var piled = ul.querySelectorAll('li.'+HOST_CLASS+'['+PILED_ATTR+'="1"]');
|
|
1628
|
+
if (!piled.length) return;
|
|
1629
|
+
|
|
1630
|
+
piled.forEach(function(host){
|
|
1631
|
+
try{
|
|
1632
|
+
// if it already has rendered ad, just unhide; do not move
|
|
1633
|
+
if (hostHasAdContent(host)){
|
|
1634
|
+
host.removeAttribute(PILED_ATTR);
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
var after = getAfter(host);
|
|
1638
|
+
var anchor = after!=null ? nthTopic(ul, after) : null;
|
|
1639
|
+
if (anchor){
|
|
1640
|
+
anchor.insertAdjacentElement('afterend', host);
|
|
1641
|
+
}
|
|
1642
|
+
host.removeAttribute(PILED_ATTR);
|
|
1643
|
+
}catch(e){}
|
|
1644
|
+
});
|
|
1645
|
+
}catch(e){}
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
function schedule(fn){
|
|
1631
1649
|
var now = Date.now();
|
|
1632
|
-
if (now
|
|
1650
|
+
if (now-lastRun < COOLDOWN) return;
|
|
1633
1651
|
if (scheduled) return;
|
|
1634
1652
|
scheduled = true;
|
|
1635
1653
|
requestAnimationFrame(function(){
|
|
1636
|
-
scheduled
|
|
1654
|
+
scheduled=false;
|
|
1637
1655
|
lastRun = Date.now();
|
|
1638
|
-
|
|
1639
|
-
var ul = getTopicList();
|
|
1640
|
-
if (!ul) return;
|
|
1641
|
-
redistributeTopPile(ul);
|
|
1642
|
-
} catch (e) {}
|
|
1656
|
+
fn();
|
|
1643
1657
|
});
|
|
1644
1658
|
}
|
|
1645
1659
|
|
|
1646
|
-
function onScroll()
|
|
1660
|
+
function onScroll(){
|
|
1647
1661
|
var y = getY();
|
|
1648
1662
|
var dy = y - lastY;
|
|
1649
1663
|
lastY = y;
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1664
|
+
var ul = getTopicList();
|
|
1665
|
+
if (!ul) return;
|
|
1666
|
+
|
|
1667
|
+
// always wrap invalid ul>div (cheap)
|
|
1668
|
+
try { ul.querySelectorAll(':scope > '+BETWEEN_WRAP_SEL).forEach(function(w){ ensureHostForWrap(w, ul); }); } catch(e){}
|
|
1669
|
+
|
|
1670
|
+
if (dy < -8 && y < 900){
|
|
1671
|
+
// upscroll near top: hide pile quickly (no moving)
|
|
1672
|
+
schedule(function(){ detectAndHideTopPile(ul); });
|
|
1673
|
+
} else if (dy > 8){
|
|
1674
|
+
// downscroll: rehome only empty piled hosts (safe) and unhide
|
|
1675
|
+
schedule(function(){ rehomePiledEmptyOnDownscroll(ul); });
|
|
1676
|
+
}
|
|
1653
1677
|
}
|
|
1654
1678
|
|
|
1655
|
-
function init()
|
|
1656
|
-
|
|
1657
|
-
schedule('init');
|
|
1658
|
-
|
|
1659
|
-
window.addEventListener('scroll', onScroll, { passive: true });
|
|
1679
|
+
function init(){
|
|
1680
|
+
window.addEventListener('scroll', onScroll, { passive:true });
|
|
1660
1681
|
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
if (typeof MutationObserver !== 'undefined') {
|
|
1664
|
-
var ul = getTopicList();
|
|
1665
|
-
if (ul) {
|
|
1666
|
-
var mo = new MutationObserver(function(){ /* no immediate redistribution */ });
|
|
1667
|
-
mo.observe(ul, { childList:true, subtree:true });
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
} catch (e) {}
|
|
1671
|
-
|
|
1672
|
-
if (window.jQuery) {
|
|
1673
|
-
try {
|
|
1682
|
+
if (window.jQuery){
|
|
1683
|
+
try{
|
|
1674
1684
|
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function(){
|
|
1675
|
-
//
|
|
1676
|
-
setTimeout(function(){
|
|
1685
|
+
// wrap invalids only
|
|
1686
|
+
setTimeout(function(){
|
|
1687
|
+
try{
|
|
1688
|
+
var ul = getTopicList();
|
|
1689
|
+
if (!ul) return;
|
|
1690
|
+
ul.querySelectorAll(':scope > '+BETWEEN_WRAP_SEL).forEach(function(w){ ensureHostForWrap(w, ul); });
|
|
1691
|
+
}catch(e){}
|
|
1692
|
+
}, 50);
|
|
1677
1693
|
});
|
|
1678
|
-
}
|
|
1694
|
+
}catch(e){}
|
|
1679
1695
|
}
|
|
1680
1696
|
}
|
|
1681
1697
|
|
|
1682
1698
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
1683
1699
|
else init();
|
|
1684
1700
|
})();
|
|
1685
|
-
// ===== /V17.
|
|
1701
|
+
// ===== /V17.3 =====
|
|
1686
1702
|
|
package/public/style.css
CHANGED
|
@@ -81,8 +81,17 @@
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
|
|
84
|
-
/* ===== V17
|
|
84
|
+
/* ===== V17 host styling ===== */
|
|
85
|
+
li.nodebb-ezoic-host { list-style: none; width: 100%; display: block; }
|
|
86
|
+
li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width: 100%; display: block; }
|
|
87
|
+
/* ===== /V17 ===== */
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
/* ===== V17.3 piled hide ===== */
|
|
92
|
+
li.nodebb-ezoic-host[data-ezoic-piled="1"] { display: none !important; }
|
|
93
|
+
/* keep host stable */
|
|
85
94
|
li.nodebb-ezoic-host { list-style:none; width:100%; display:block; }
|
|
86
95
|
li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width:100%; display:block; }
|
|
87
|
-
/* ===== /V17.
|
|
96
|
+
/* ===== /V17.3 ===== */
|
|
88
97
|
|