nodebb-plugin-ezoic-infinite 1.6.33 → 1.6.34
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 -83
- package/public/style.css +3 -3
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1514,110 +1514,144 @@ function buildOrdinalMap(items) {
|
|
|
1514
1514
|
|
|
1515
1515
|
|
|
1516
1516
|
|
|
1517
|
-
// ===== V17.
|
|
1517
|
+
// ===== V17.3: keep injection; hide top pile on upscroll; rehome EMPTY hosts on downscroll =====
|
|
1518
1518
|
(function(){
|
|
1519
1519
|
var TOPIC_LI_SEL = 'li[component="category/topic"]';
|
|
1520
1520
|
var BETWEEN_WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1521
1521
|
var HOST_CLASS = 'nodebb-ezoic-host';
|
|
1522
1522
|
var PILED_ATTR = 'data-ezoic-piled';
|
|
1523
1523
|
|
|
1524
|
+
var lastY = window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1524
1525
|
var scheduled = false;
|
|
1525
1526
|
var lastRun = 0;
|
|
1526
|
-
var COOLDOWN =
|
|
1527
|
-
|
|
1528
|
-
var lastY = window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1527
|
+
var COOLDOWN = 120;
|
|
1529
1528
|
|
|
1530
1529
|
function getY(){ return window.pageYOffset || document.documentElement.scrollTop || 0; }
|
|
1531
1530
|
|
|
1532
1531
|
function getTopicList(){
|
|
1533
|
-
try{
|
|
1532
|
+
try {
|
|
1534
1533
|
var li = document.querySelector(TOPIC_LI_SEL);
|
|
1535
1534
|
if (!li) return null;
|
|
1536
1535
|
return li.closest ? li.closest('ul,ol') : null;
|
|
1537
|
-
}catch(e){ return null; }
|
|
1536
|
+
} catch(e){ return null; }
|
|
1538
1537
|
}
|
|
1539
1538
|
|
|
1540
|
-
function
|
|
1539
|
+
function ensureHostForWrap(wrap, ul){
|
|
1541
1540
|
try{
|
|
1542
|
-
if (!
|
|
1543
|
-
if (
|
|
1544
|
-
|
|
1545
|
-
|
|
1541
|
+
if (!wrap || wrap.nodeType!==1) return null;
|
|
1542
|
+
if (!(wrap.matches && wrap.matches(BETWEEN_WRAP_SEL))) return null;
|
|
1543
|
+
|
|
1544
|
+
var host = wrap.closest ? wrap.closest('li.'+HOST_CLASS) : null;
|
|
1545
|
+
if (host) return host;
|
|
1546
|
+
|
|
1547
|
+
if (!ul) ul = wrap.closest ? wrap.closest('ul,ol') : null;
|
|
1548
|
+
if (!ul || !(ul.tagName==='UL' || ul.tagName==='OL')) return null;
|
|
1549
|
+
|
|
1550
|
+
if (wrap.parentElement === ul){
|
|
1551
|
+
host = document.createElement('li');
|
|
1552
|
+
host.className = HOST_CLASS;
|
|
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){}
|
|
1561
|
+
ul.insertBefore(host, wrap);
|
|
1562
|
+
host.appendChild(wrap);
|
|
1563
|
+
try { wrap.style.width='100%'; } catch(e){}
|
|
1564
|
+
return host;
|
|
1546
1565
|
}
|
|
1547
1566
|
}catch(e){}
|
|
1548
|
-
return
|
|
1567
|
+
return null;
|
|
1549
1568
|
}
|
|
1550
1569
|
|
|
1551
|
-
function
|
|
1552
|
-
|
|
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; }
|
|
1553
1575
|
}
|
|
1554
1576
|
|
|
1555
|
-
function
|
|
1577
|
+
function nthTopic(ul, n){
|
|
1556
1578
|
try{
|
|
1557
|
-
|
|
1558
|
-
if (
|
|
1559
|
-
|
|
1560
|
-
|
|
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; }
|
|
1561
1585
|
}
|
|
1562
1586
|
|
|
1563
|
-
function
|
|
1587
|
+
function getAfter(host){
|
|
1564
1588
|
try{
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
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');
|
|
1593
|
+
}
|
|
1594
|
+
var n = parseInt(v,10);
|
|
1595
|
+
return isNaN(n)? null : n;
|
|
1596
|
+
}catch(e){ return null; }
|
|
1568
1597
|
}
|
|
1569
1598
|
|
|
1570
|
-
function
|
|
1571
|
-
//
|
|
1572
|
-
// This catches cases where virtualization moves some ads but not others.
|
|
1599
|
+
function detectAndHideTopPile(ul){
|
|
1600
|
+
// Hide piled hosts near top so user doesn't see the stack.
|
|
1573
1601
|
try{
|
|
1574
|
-
if (!ul) return;
|
|
1575
|
-
var vh = window.innerHeight || 800;
|
|
1576
|
-
var bandTop = -200; // slightly above viewport
|
|
1577
|
-
var bandBottom = vh * 1.6; // covers top area user sees when returning up
|
|
1578
|
-
|
|
1579
|
-
// collect candidates in band in DOM order
|
|
1580
1602
|
var kids = ul.children;
|
|
1581
|
-
var
|
|
1582
|
-
for (var i=0;i<kids.length;i++){
|
|
1583
|
-
var el = kids[i];
|
|
1584
|
-
if (!isBetweenNode(el) && !isTopicNode(el)) continue;
|
|
1585
|
-
// compute rect (cheap enough on limited band; stop after we've passed far below band)
|
|
1586
|
-
var r = el.getBoundingClientRect ? el.getBoundingClientRect() : null;
|
|
1587
|
-
if (!r) continue;
|
|
1588
|
-
if (r.top > bandBottom && candidates.length > 0) {
|
|
1589
|
-
// Once we've started collecting and we are past band, we can stop scanning further.
|
|
1590
|
-
break;
|
|
1591
|
-
}
|
|
1592
|
-
if (r.bottom < bandTop) continue;
|
|
1593
|
-
if (r.top > bandBottom) continue;
|
|
1594
|
-
|
|
1595
|
-
candidates.push(el);
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
// Now walk candidates and hide consecutive between nodes (keep first between in a run)
|
|
1603
|
+
var limit = Math.min(kids.length, 60);
|
|
1599
1604
|
var run = 0;
|
|
1600
|
-
for (var
|
|
1601
|
-
var
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
}
|
|
1606
|
-
if (isBetweenNode(el2)){
|
|
1605
|
+
for (var i=0;i<limit;i++){
|
|
1606
|
+
var el = kids[i];
|
|
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){
|
|
1607
1610
|
run++;
|
|
1608
|
-
|
|
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
|
|
1609
1619
|
}
|
|
1610
1620
|
}
|
|
1611
1621
|
}catch(e){}
|
|
1612
1622
|
}
|
|
1613
1623
|
|
|
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
|
+
|
|
1614
1648
|
function schedule(fn){
|
|
1615
1649
|
var now = Date.now();
|
|
1616
1650
|
if (now-lastRun < COOLDOWN) return;
|
|
1617
1651
|
if (scheduled) return;
|
|
1618
1652
|
scheduled = true;
|
|
1619
1653
|
requestAnimationFrame(function(){
|
|
1620
|
-
scheduled
|
|
1654
|
+
scheduled=false;
|
|
1621
1655
|
lastRun = Date.now();
|
|
1622
1656
|
fn();
|
|
1623
1657
|
});
|
|
@@ -1627,49 +1661,42 @@ function buildOrdinalMap(items) {
|
|
|
1627
1661
|
var y = getY();
|
|
1628
1662
|
var dy = y - lastY;
|
|
1629
1663
|
lastY = y;
|
|
1630
|
-
|
|
1631
1664
|
var ul = getTopicList();
|
|
1632
1665
|
if (!ul) return;
|
|
1633
1666
|
|
|
1634
|
-
//
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
//
|
|
1639
|
-
schedule(function(){
|
|
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); });
|
|
1640
1676
|
}
|
|
1641
1677
|
}
|
|
1642
1678
|
|
|
1643
1679
|
function init(){
|
|
1644
1680
|
window.addEventListener('scroll', onScroll, { passive:true });
|
|
1645
|
-
window.addEventListener('resize', function(){
|
|
1646
|
-
var ul = getTopicList();
|
|
1647
|
-
if (!ul) return;
|
|
1648
|
-
schedule(function(){ maskViewportPile(ul); });
|
|
1649
|
-
}, { passive:true });
|
|
1650
1681
|
|
|
1651
1682
|
if (window.jQuery){
|
|
1652
1683
|
try{
|
|
1653
1684
|
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function(){
|
|
1685
|
+
// wrap invalids only
|
|
1654
1686
|
setTimeout(function(){
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
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);
|
|
1659
1693
|
});
|
|
1660
1694
|
}catch(e){}
|
|
1661
1695
|
}
|
|
1662
|
-
|
|
1663
|
-
// initial
|
|
1664
|
-
setTimeout(function(){
|
|
1665
|
-
var ul = getTopicList();
|
|
1666
|
-
if (!ul) return;
|
|
1667
|
-
schedule(function(){ maskViewportPile(ul); });
|
|
1668
|
-
}, 250);
|
|
1669
1696
|
}
|
|
1670
1697
|
|
|
1671
1698
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
1672
1699
|
else init();
|
|
1673
1700
|
})();
|
|
1674
|
-
// ===== /V17.
|
|
1701
|
+
// ===== /V17.3 =====
|
|
1675
1702
|
|
package/public/style.css
CHANGED
|
@@ -88,10 +88,10 @@ li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width: 100%; displa
|
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
/* ===== V17.
|
|
92
|
-
[data-ezoic-piled="1"] { display: none !important; }
|
|
91
|
+
/* ===== V17.3 piled hide ===== */
|
|
92
|
+
li.nodebb-ezoic-host[data-ezoic-piled="1"] { display: none !important; }
|
|
93
93
|
/* keep host stable */
|
|
94
94
|
li.nodebb-ezoic-host { list-style:none; width:100%; display:block; }
|
|
95
95
|
li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width:100%; display:block; }
|
|
96
|
-
/* ===== /V17.
|
|
96
|
+
/* ===== /V17.3 ===== */
|
|
97
97
|
|