nodebb-plugin-ezoic-infinite 1.6.24 → 1.6.26
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 +62 -223
- package/public/style.css +10 -3
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
function ezoicInsertAfterTopicHost(target, wrap, kindClass) {
|
|
5
|
+
try {
|
|
6
|
+
if (!target || !wrap) return false;
|
|
7
|
+
if (kindClass !== 'ezoic-ad-between') return false;
|
|
8
|
+
|
|
9
|
+
// Ensure we insert a LI host that looks like a topic item so NodeBB list virtualization keeps ordering.
|
|
10
|
+
var anchorLi = target.closest ? (target.closest('li[component="category/topic"]') || target.closest('li')) : null;
|
|
11
|
+
if (!anchorLi && target.tagName === 'LI') anchorLi = target;
|
|
12
|
+
if (!anchorLi) return false;
|
|
13
|
+
|
|
14
|
+
var ul = anchorLi.parentElement;
|
|
15
|
+
if (!ul || !(ul.tagName === 'UL' || ul.tagName === 'OL')) return false;
|
|
16
|
+
|
|
17
|
+
// If wrap already hosted, do nothing
|
|
18
|
+
var existingHost = wrap.closest ? wrap.closest('li.nodebb-ezoic-host') : null;
|
|
19
|
+
if (existingHost) return true;
|
|
20
|
+
|
|
21
|
+
var host = document.createElement('li');
|
|
22
|
+
host.className = 'nodebb-ezoic-host';
|
|
23
|
+
// mimic topic list item so NodeBB doesn't relocate it
|
|
24
|
+
host.setAttribute('component', 'category/topic');
|
|
25
|
+
host.setAttribute('data-ezoic-host', 'between');
|
|
26
|
+
host.style.listStyle = 'none';
|
|
27
|
+
host.style.width = '100%';
|
|
28
|
+
|
|
29
|
+
// Insert host after anchorLi
|
|
30
|
+
if (anchorLi.insertAdjacentElement) anchorLi.insertAdjacentElement('afterend', host);
|
|
31
|
+
else ul.insertBefore(host, anchorLi.nextSibling);
|
|
32
|
+
|
|
33
|
+
host.appendChild(wrap);
|
|
34
|
+
try { wrap.style.width = '100%'; } catch (e) {}
|
|
35
|
+
return true;
|
|
36
|
+
} catch (e) {}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
4
41
|
// Track scroll direction to avoid aggressive recycling when the user scrolls upward.
|
|
5
42
|
// Recycling while scrolling up is a common cause of ads "bunching" and a "disappearing too fast" feeling.
|
|
6
43
|
let lastScrollY = 0;
|
|
@@ -668,7 +705,8 @@ function globalGapFixInit() {
|
|
|
668
705
|
insertingIds.add(id);
|
|
669
706
|
try {
|
|
670
707
|
const wrap = buildWrap(id, kindClass, afterPos, !existingPh);
|
|
671
|
-
target
|
|
708
|
+
if (ezoicInsertAfterTopicHost(target, wrap, kindClass)) return;
|
|
709
|
+
target.insertAdjacentElement('afterend', wrap);
|
|
672
710
|
|
|
673
711
|
// If placeholder exists elsewhere (including pool), move it into the wrapper.
|
|
674
712
|
if (existingPh) {
|
|
@@ -1160,7 +1198,8 @@ function buildOrdinalMap(items) {
|
|
|
1160
1198
|
if (!anchorEl || !wrap || !wrap.isConnected) return null;
|
|
1161
1199
|
|
|
1162
1200
|
wrap.setAttribute('data-ezoic-after', String(afterPos));
|
|
1163
|
-
anchorEl
|
|
1201
|
+
if (ezoicInsertAfterTopicHost(anchorEl, wrap, kindClass)) return;
|
|
1202
|
+
anchorEl.insertAdjacentElement('afterend', wrap);
|
|
1164
1203
|
|
|
1165
1204
|
// Ensure minimal layout impact.
|
|
1166
1205
|
try { wrap.style.contain = 'layout style paint'; } catch (e) {}
|
|
@@ -1511,227 +1550,27 @@ function buildOrdinalMap(items) {
|
|
|
1511
1550
|
|
|
1512
1551
|
|
|
1513
1552
|
|
|
1514
|
-
// =====
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
var freezeUntil = 0;
|
|
1521
|
-
var pending = false;
|
|
1522
|
-
var queue = new Set();
|
|
1523
|
-
|
|
1524
|
-
function now() { return Date.now(); }
|
|
1525
|
-
|
|
1526
|
-
function getTopicList() {
|
|
1527
|
-
try {
|
|
1528
|
-
var topic = document.querySelector(TOPIC_LI_SEL);
|
|
1529
|
-
if (!topic) return null;
|
|
1530
|
-
return topic.closest ? topic.closest('ul,ol') : null;
|
|
1531
|
-
} catch (e) { return null; }
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
function isLoading() {
|
|
1535
|
-
try {
|
|
1536
|
-
if (now() < freezeUntil) return true;
|
|
1537
|
-
return !!document.querySelector('.infinite-loading, .infinite-scroll-loading, .loading-indicator, .spinner, .topic-loading');
|
|
1538
|
-
} catch (e) { return false; }
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
function ensureHostForWrap(wrap, ul) {
|
|
1542
|
-
try {
|
|
1543
|
-
if (!wrap || wrap.nodeType !== 1) return null;
|
|
1544
|
-
if (!(wrap.matches && wrap.matches(WRAP_SEL))) return null;
|
|
1545
|
-
var host = wrap.closest ? wrap.closest(HOST_SEL) : null;
|
|
1546
|
-
if (host) return host;
|
|
1547
|
-
ul = ul || (wrap.closest ? wrap.closest('ul,ol') : null);
|
|
1548
|
-
if (!ul) return null;
|
|
1549
|
-
if (wrap.parentElement === ul) {
|
|
1550
|
-
host = document.createElement('li');
|
|
1551
|
-
host.className = 'nodebb-ezoic-host';
|
|
1552
|
-
host.setAttribute('role', 'listitem');
|
|
1553
|
-
host.style.listStyle = 'none';
|
|
1554
|
-
host.style.width = '100%';
|
|
1555
|
-
ul.insertBefore(host, wrap);
|
|
1556
|
-
host.appendChild(wrap);
|
|
1557
|
-
try { wrap.style.width = '100%'; } catch (e) {}
|
|
1558
|
-
return host;
|
|
1559
|
-
}
|
|
1560
|
-
} catch (e) {}
|
|
1561
|
-
return null;
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1564
|
-
function nthTopic(ul, n) {
|
|
1565
|
-
try {
|
|
1566
|
-
var topics = ul.querySelectorAll(TOPIC_LI_SEL);
|
|
1567
|
-
if (!topics || !topics.length) return null;
|
|
1568
|
-
if (n < 1) n = 1;
|
|
1569
|
-
if (n > topics.length) n = topics.length;
|
|
1570
|
-
return topics[n-1] || null;
|
|
1571
|
-
} catch (e) { return null; }
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
function previousTopicLi(host) {
|
|
1575
|
-
try {
|
|
1576
|
-
var prev = host.previousElementSibling;
|
|
1577
|
-
while (prev) {
|
|
1578
|
-
if (prev.matches && prev.matches(TOPIC_LI_SEL)) return prev;
|
|
1579
|
-
prev = prev.previousElementSibling;
|
|
1580
|
-
}
|
|
1581
|
-
} catch (e) {}
|
|
1582
|
-
return null;
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
|
-
function placeHost(host, ul) {
|
|
1586
|
-
try {
|
|
1587
|
-
if (!host || host.nodeType !== 1) return;
|
|
1588
|
-
ul = ul || host.parentElement;
|
|
1589
|
-
if (!ul) return;
|
|
1590
|
-
|
|
1591
|
-
var wrap = host.querySelector && host.querySelector(WRAP_SEL);
|
|
1592
|
-
if (!wrap) { host.remove(); return; }
|
|
1593
|
-
|
|
1594
|
-
var after = wrap.getAttribute('data-ezoic-after');
|
|
1595
|
-
var anchor = null;
|
|
1596
|
-
|
|
1597
|
-
if (after) {
|
|
1598
|
-
anchor = nthTopic(ul, parseInt(after, 10));
|
|
1599
|
-
}
|
|
1600
|
-
if (!anchor) {
|
|
1601
|
-
anchor = previousTopicLi(host);
|
|
1602
|
-
}
|
|
1603
|
-
if (!anchor) {
|
|
1604
|
-
// Can't place reliably; if host drifted to top area, remove to avoid pile-up.
|
|
1605
|
-
// Otherwise keep as-is.
|
|
1606
|
-
var firstTopic = nthTopic(ul, 1);
|
|
1607
|
-
if (firstTopic && host !== firstTopic && host.compareDocumentPosition(firstTopic) & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
1608
|
-
host.remove();
|
|
1609
|
-
}
|
|
1610
|
-
return;
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
|
-
if (host.previousElementSibling !== anchor) {
|
|
1614
|
-
anchor.insertAdjacentElement('afterend', host);
|
|
1615
|
-
}
|
|
1616
|
-
} catch (e) {}
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1619
|
-
function drain() {
|
|
1620
|
-
pending = false;
|
|
1621
|
-
if (isLoading()) {
|
|
1622
|
-
// retry later
|
|
1623
|
-
scheduleDrain(250);
|
|
1624
|
-
return;
|
|
1625
|
-
}
|
|
1626
|
-
var ul = getTopicList();
|
|
1627
|
-
if (!ul) return;
|
|
1628
|
-
|
|
1629
|
-
// repair invalid ul>div once
|
|
1630
|
-
try {
|
|
1631
|
-
ul.querySelectorAll(':scope > ' + WRAP_SEL).forEach(function(w){
|
|
1632
|
-
var h = ensureHostForWrap(w, ul);
|
|
1633
|
-
if (h) queue.add(h);
|
|
1634
|
-
});
|
|
1635
|
-
} catch (e) {}
|
|
1636
|
-
|
|
1637
|
-
var count = 0;
|
|
1638
|
-
for (var host of Array.from(queue)) {
|
|
1639
|
-
queue.delete(host);
|
|
1640
|
-
placeHost(host, ul);
|
|
1641
|
-
count++;
|
|
1642
|
-
if (count >= 8) break; // keep it light
|
|
1643
|
-
}
|
|
1644
|
-
if (queue.size) scheduleDrain(60);
|
|
1645
|
-
}
|
|
1646
|
-
|
|
1647
|
-
function scheduleDrain(delay) {
|
|
1648
|
-
if (pending) return;
|
|
1649
|
-
pending = true;
|
|
1650
|
-
if (delay) {
|
|
1651
|
-
setTimeout(function(){ requestAnimationFrame(drain); }, delay);
|
|
1652
|
-
} else {
|
|
1653
|
-
requestAnimationFrame(drain);
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
|
|
1657
|
-
function enqueueFromNode(node) {
|
|
1658
|
-
try {
|
|
1659
|
-
if (!node || node.nodeType !== 1) return;
|
|
1660
|
-
var ul = getTopicList();
|
|
1661
|
-
if (!ul) return;
|
|
1662
|
-
|
|
1663
|
-
if (node.matches && node.matches(WRAP_SEL)) {
|
|
1664
|
-
var h = ensureHostForWrap(node, ul) || (node.closest ? node.closest(HOST_SEL) : null);
|
|
1665
|
-
if (h) queue.add(h);
|
|
1666
|
-
} else if (node.matches && node.matches(HOST_SEL)) {
|
|
1667
|
-
queue.add(node);
|
|
1668
|
-
} else if (node.querySelectorAll) {
|
|
1669
|
-
node.querySelectorAll(WRAP_SEL).forEach(function(w){
|
|
1670
|
-
var h2 = ensureHostForWrap(w, ul) || (w.closest ? w.closest(HOST_SEL) : null);
|
|
1671
|
-
if (h2) queue.add(h2);
|
|
1672
|
-
});
|
|
1673
|
-
node.querySelectorAll(HOST_SEL).forEach(function(h3){ queue.add(h3); });
|
|
1674
|
-
}
|
|
1675
|
-
} catch (e) {}
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
function init() {
|
|
1679
|
-
// initial scan (light)
|
|
1680
|
-
try {
|
|
1681
|
-
var ul = getTopicList();
|
|
1682
|
-
if (ul) {
|
|
1683
|
-
ul.querySelectorAll(WRAP_SEL).forEach(function(w){
|
|
1684
|
-
var h = ensureHostForWrap(w, ul) || (w.closest ? w.closest(HOST_SEL) : null);
|
|
1685
|
-
if (h) queue.add(h);
|
|
1686
|
-
});
|
|
1687
|
-
scheduleDrain(0);
|
|
1688
|
-
}
|
|
1689
|
-
} catch (e) {}
|
|
1690
|
-
|
|
1691
|
-
// Observe ONLY the topic list container once available
|
|
1692
|
-
try {
|
|
1693
|
-
if (typeof MutationObserver !== 'undefined') {
|
|
1694
|
-
var mo = new MutationObserver(function(muts){
|
|
1695
|
-
for (var i=0;i<muts.length;i++){
|
|
1696
|
-
var m = muts[i];
|
|
1697
|
-
if (m.addedNodes && m.addedNodes.length) {
|
|
1698
|
-
for (var j=0;j<m.addedNodes.length;j++){
|
|
1699
|
-
enqueueFromNode(m.addedNodes[j]);
|
|
1700
|
-
}
|
|
1701
|
-
scheduleDrain(0);
|
|
1702
|
-
}
|
|
1703
|
-
}
|
|
1704
|
-
});
|
|
1705
|
-
|
|
1706
|
-
var ul = getTopicList();
|
|
1707
|
-
if (ul) mo.observe(ul, { childList:true, subtree:true });
|
|
1708
|
-
else {
|
|
1709
|
-
// wait for ajaxify
|
|
1710
|
-
var mo2 = new MutationObserver(function(){
|
|
1711
|
-
var u2 = getTopicList();
|
|
1712
|
-
if (u2) {
|
|
1713
|
-
try { mo.observe(u2, { childList:true, subtree:true }); } catch(e){}
|
|
1714
|
-
try { mo2.disconnect(); } catch(e){}
|
|
1715
|
-
}
|
|
1716
|
-
});
|
|
1717
|
-
mo2.observe(document.documentElement || document.body, { childList:true, subtree:true });
|
|
1718
|
-
}
|
|
1719
|
-
}
|
|
1720
|
-
} catch (e) {}
|
|
1721
|
-
|
|
1722
|
-
if (window.jQuery) {
|
|
1553
|
+
// ===== V16 repair invalid UL children (between) =====
|
|
1554
|
+
function ezoicRepairBetweenHosts() {
|
|
1555
|
+
try {
|
|
1556
|
+
var bad = document.querySelectorAll('ul > div.nodebb-ezoic-wrap.ezoic-ad-between, ol > div.nodebb-ezoic-wrap.ezoic-ad-between');
|
|
1557
|
+
bad.forEach(function(wrap){
|
|
1723
1558
|
try {
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
setTimeout(function(){ scheduleDrain(0); }, 950);
|
|
1728
|
-
});
|
|
1559
|
+
var prev = wrap.previousElementSibling;
|
|
1560
|
+
if (!prev) return;
|
|
1561
|
+
ezoicInsertAfterTopicHost(prev, wrap, 'ezoic-ad-between');
|
|
1729
1562
|
} catch (e) {}
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1563
|
+
});
|
|
1564
|
+
} catch (e) {}
|
|
1565
|
+
}
|
|
1566
|
+
try { ezoicRepairBetweenHosts(); } catch (e) {}
|
|
1567
|
+
if (window.jQuery) {
|
|
1568
|
+
try {
|
|
1569
|
+
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function(){
|
|
1570
|
+
setTimeout(function(){ try { ezoicRepairBetweenHosts(); } catch(e) {} }, 0);
|
|
1571
|
+
setTimeout(function(){ try { ezoicRepairBetweenHosts(); } catch(e) {} }, 250);
|
|
1572
|
+
});
|
|
1573
|
+
} catch (e) {}
|
|
1574
|
+
}
|
|
1575
|
+
// ===== /V16 =====
|
|
1737
1576
|
|
package/public/style.css
CHANGED
|
@@ -81,7 +81,14 @@
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
|
|
84
|
-
/* =====
|
|
85
|
-
li.nodebb-ezoic-host
|
|
86
|
-
|
|
84
|
+
/* ===== V16 host topic li ===== */
|
|
85
|
+
li.nodebb-ezoic-host[component="category/topic"]{
|
|
86
|
+
list-style:none;
|
|
87
|
+
width:100%;
|
|
88
|
+
}
|
|
89
|
+
/* ensure host doesn't inherit topic card layout */
|
|
90
|
+
li.nodebb-ezoic-host[component="category/topic"] > .nodebb-ezoic-wrap.ezoic-ad-between{
|
|
91
|
+
width:100%;
|
|
92
|
+
}
|
|
93
|
+
/* ===== /V16 ===== */
|
|
87
94
|
|