nodebb-plugin-ezoic-infinite 1.6.40 → 1.6.41
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 +251 -273
- package/public/style.css +0 -12
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -498,48 +498,6 @@ 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
|
-
|
|
505
|
-
function collectEzoicIds(root) {
|
|
506
|
-
const ids = new Set();
|
|
507
|
-
if (!root || !root.querySelectorAll) return [];
|
|
508
|
-
// Common Ezoic placeholder ids
|
|
509
|
-
root.querySelectorAll('[id^="ezoic-pub-ad-placeholder-"]').forEach(el => ids.add(el.id));
|
|
510
|
-
// Some integrations keep ids on wrappers
|
|
511
|
-
root.querySelectorAll('[data-ezoic-id]').forEach(el => {
|
|
512
|
-
if (el.id) ids.add(el.id);
|
|
513
|
-
});
|
|
514
|
-
return Array.from(ids);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
function refreshAds(ids) {
|
|
518
|
-
clearTimeout(_refreshTimer);
|
|
519
|
-
_refreshTimer = setTimeout(() => {
|
|
520
|
-
try {
|
|
521
|
-
if (window.ezstandalone && typeof window.ezstandalone.showAds === 'function') {
|
|
522
|
-
// Prefer a full rescan; fall back to ids if supported.
|
|
523
|
-
try {
|
|
524
|
-
window.ezstandalone.showAds();
|
|
525
|
-
} catch (e) {
|
|
526
|
-
if (ids && ids.length) window.ezstandalone.showAds(ids);
|
|
527
|
-
}
|
|
528
|
-
if (window.__EZ_DEBUG) console.debug('[ezoic-infinite] refreshAds (ezstandalone)', { ids });
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
if (window.ez && typeof window.ez.showAds === 'function') {
|
|
532
|
-
try {
|
|
533
|
-
window.ez.showAds();
|
|
534
|
-
} catch (e) {
|
|
535
|
-
if (ids && ids.length) window.ez.showAds(ids);
|
|
536
|
-
}
|
|
537
|
-
if (window.__EZ_DEBUG) console.debug('[ezoic-infinite] refreshAds (ez)', { ids });
|
|
538
|
-
}
|
|
539
|
-
} catch (e) {}
|
|
540
|
-
}, 75);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
501
|
function primePlaceholderPool(allIds) {
|
|
544
502
|
try {
|
|
545
503
|
if (!Array.isArray(allIds) || !allIds.length) return;
|
|
@@ -1553,21 +1511,16 @@ function buildOrdinalMap(items) {
|
|
|
1553
1511
|
|
|
1554
1512
|
|
|
1555
1513
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
// ===== V17.8: No pile-up by design — keep "future" between slots pending/collapsed until their anchor topic exists =====
|
|
1514
|
+
// ===== V17 minimal pile-fix (no insert hooks) =====
|
|
1560
1515
|
(function () {
|
|
1516
|
+
// Goal: keep ad injection intact. Only repair when we detect "pile-up" of between wraps.
|
|
1561
1517
|
var TOPIC_LI_SEL = 'li[component="category/topic"]';
|
|
1562
1518
|
var BETWEEN_WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1563
1519
|
var HOST_CLASS = 'nodebb-ezoic-host';
|
|
1564
|
-
var PENDING_CLASS = 'nodebb-ezoic-pending';
|
|
1565
1520
|
|
|
1566
|
-
var ul = null;
|
|
1567
|
-
var mo = null;
|
|
1568
1521
|
var scheduled = false;
|
|
1569
1522
|
var lastRun = 0;
|
|
1570
|
-
var COOLDOWN =
|
|
1523
|
+
var COOLDOWN = 180;
|
|
1571
1524
|
|
|
1572
1525
|
function getTopicList() {
|
|
1573
1526
|
try {
|
|
@@ -1577,41 +1530,29 @@ function buildOrdinalMap(items) {
|
|
|
1577
1530
|
} catch (e) { return null; }
|
|
1578
1531
|
}
|
|
1579
1532
|
|
|
1580
|
-
function
|
|
1581
|
-
|
|
1582
|
-
function isHost(el) {
|
|
1583
|
-
return !!(el && el.nodeType === 1 && el.tagName === 'LI' && el.classList && el.classList.contains(HOST_CLASS));
|
|
1533
|
+
function isHost(node) {
|
|
1534
|
+
return !!(node && node.nodeType === 1 && node.tagName === 'LI' && node.classList && node.classList.contains(HOST_CLASS));
|
|
1584
1535
|
}
|
|
1585
1536
|
|
|
1586
|
-
function
|
|
1587
|
-
try { return !!(el && el.nodeType === 1 && el.matches && el.matches(BETWEEN_WRAP_SEL)); } catch(e){ return false; }
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
function ensureHostForWrap(wrap, ulEl) {
|
|
1591
|
-
// If Ezoic inserts ul > div..., wrap it into a LI to keep a valid list structure (less NodeBB churn).
|
|
1537
|
+
function ensureHostForWrap(wrap, ul) {
|
|
1592
1538
|
try {
|
|
1593
|
-
if (!wrap ||
|
|
1539
|
+
if (!wrap || wrap.nodeType !== 1) return null;
|
|
1540
|
+
if (!(wrap.matches && wrap.matches(BETWEEN_WRAP_SEL))) return null;
|
|
1541
|
+
|
|
1594
1542
|
var host = wrap.closest ? wrap.closest('li.' + HOST_CLASS) : null;
|
|
1595
1543
|
if (host) return host;
|
|
1596
1544
|
|
|
1597
|
-
|
|
1598
|
-
if (!
|
|
1545
|
+
if (!ul) ul = wrap.closest ? wrap.closest('ul,ol') : null;
|
|
1546
|
+
if (!ul || !(ul.tagName === 'UL' || ul.tagName === 'OL')) return null;
|
|
1599
1547
|
|
|
1600
|
-
if (
|
|
1548
|
+
// Only wrap if direct child of list (invalid / fragile)
|
|
1549
|
+
if (wrap.parentElement === ul) {
|
|
1601
1550
|
host = document.createElement('li');
|
|
1602
1551
|
host.className = HOST_CLASS;
|
|
1603
1552
|
host.setAttribute('role', 'listitem');
|
|
1604
1553
|
host.style.listStyle = 'none';
|
|
1605
1554
|
host.style.width = '100%';
|
|
1606
|
-
|
|
1607
|
-
try {
|
|
1608
|
-
var after = wrap.getAttribute('data-ezoic-after');
|
|
1609
|
-
if (after) host.setAttribute('data-ezoic-after', after);
|
|
1610
|
-
var pin = wrap.getAttribute('data-ezoic-pin');
|
|
1611
|
-
if (pin) host.setAttribute('data-ezoic-pin', pin);
|
|
1612
|
-
} catch (e) {}
|
|
1613
|
-
|
|
1614
|
-
ulEl.insertBefore(host, wrap);
|
|
1555
|
+
ul.insertBefore(host, wrap);
|
|
1615
1556
|
host.appendChild(wrap);
|
|
1616
1557
|
try { wrap.style.width = '100%'; } catch (e) {}
|
|
1617
1558
|
return host;
|
|
@@ -1620,259 +1561,296 @@ function buildOrdinalMap(items) {
|
|
|
1620
1561
|
return null;
|
|
1621
1562
|
}
|
|
1622
1563
|
|
|
1623
|
-
function
|
|
1564
|
+
function previousTopicLi(node) {
|
|
1624
1565
|
try {
|
|
1625
|
-
var
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1566
|
+
var prev = node.previousElementSibling;
|
|
1567
|
+
while (prev) {
|
|
1568
|
+
if (prev.matches && prev.matches(TOPIC_LI_SEL)) return prev;
|
|
1569
|
+
// skip other hosts/wraps
|
|
1570
|
+
prev = prev.previousElementSibling;
|
|
1630
1571
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
} catch (e) { return null; }
|
|
1634
|
-
}
|
|
1635
|
-
|
|
1636
|
-
function getTopics(ulEl) {
|
|
1637
|
-
try { return ulEl ? ulEl.querySelectorAll(TOPIC_LI_SEL) : []; } catch(e){ return []; }
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
function lastTopic(ulEl, topics) {
|
|
1641
|
-
try {
|
|
1642
|
-
topics = topics || getTopics(ulEl);
|
|
1643
|
-
return topics && topics.length ? topics[topics.length - 1] : null;
|
|
1644
|
-
} catch (e) { return null; }
|
|
1572
|
+
} catch (e) {}
|
|
1573
|
+
return null;
|
|
1645
1574
|
}
|
|
1646
1575
|
|
|
1647
|
-
function
|
|
1576
|
+
function detectPileUp(ul) {
|
|
1577
|
+
// Pile-up signature: 2+ between wraps/hosts adjacent with no topics between, often near top.
|
|
1648
1578
|
try {
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1579
|
+
var kids = ul.children;
|
|
1580
|
+
var run = 0;
|
|
1581
|
+
var maxRun = 0;
|
|
1582
|
+
for (var i = 0; i < kids.length; i++) {
|
|
1583
|
+
var el = kids[i];
|
|
1584
|
+
var isBetween = false;
|
|
1585
|
+
if (isHost(el)) {
|
|
1586
|
+
isBetween = !!(el.querySelector && el.querySelector(BETWEEN_WRAP_SEL));
|
|
1587
|
+
} else if (el.matches && el.matches(BETWEEN_WRAP_SEL)) {
|
|
1588
|
+
isBetween = true;
|
|
1589
|
+
}
|
|
1590
|
+
if (isBetween) {
|
|
1591
|
+
run++;
|
|
1592
|
+
if (run > maxRun) maxRun = run;
|
|
1593
|
+
} else if (el.matches && el.matches(TOPIC_LI_SEL)) {
|
|
1594
|
+
run = 0;
|
|
1595
|
+
} else {
|
|
1596
|
+
// other nodes reset lightly
|
|
1597
|
+
run = 0;
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
return maxRun >= 2;
|
|
1652
1601
|
} catch (e) {}
|
|
1602
|
+
return false;
|
|
1653
1603
|
}
|
|
1654
1604
|
|
|
1655
|
-
function
|
|
1605
|
+
function redistribute(ul) {
|
|
1656
1606
|
try {
|
|
1657
|
-
if (!
|
|
1658
|
-
ulEl = ulEl || ensureUL();
|
|
1659
|
-
if (!ulEl) return;
|
|
1607
|
+
if (!ul) return;
|
|
1660
1608
|
|
|
1661
|
-
|
|
1609
|
+
// Step 1: wrap any direct child between DIVs into LI hosts (makes list stable)
|
|
1610
|
+
ul.querySelectorAll(':scope > ' + BETWEEN_WRAP_SEL).forEach(function(w){ ensureHostForWrap(w, ul); });
|
|
1662
1611
|
|
|
1663
|
-
|
|
1664
|
-
if (!
|
|
1665
|
-
var lt = lastTopic(ulEl, topics);
|
|
1666
|
-
if (lt) moveAfter(host, lt);
|
|
1667
|
-
host.classList && host.classList.remove(PENDING_CLASS);
|
|
1668
|
-
return;
|
|
1669
|
-
}
|
|
1612
|
+
// Step 2: only act if we see pile-up (avoid touching infinite scroll during normal flow)
|
|
1613
|
+
if (!detectPileUp(ul)) return;
|
|
1670
1614
|
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
host.classList && host.classList.add(PENDING_CLASS);
|
|
1615
|
+
// Move each host to immediately after the closest previous topic LI at its current position.
|
|
1616
|
+
var hosts = ul.querySelectorAll(':scope > li.' + HOST_CLASS);
|
|
1617
|
+
hosts.forEach(function(host){
|
|
1675
1618
|
try {
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
return;
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
var anchor = topics[after - 1];
|
|
1682
|
-
if (anchor) moveAfter(host, anchor);
|
|
1683
|
-
if (host.classList && host.classList.contains(PENDING_CLASS)) {
|
|
1684
|
-
host.classList.remove(PENDING_CLASS);
|
|
1685
|
-
if (host.dataset && host.dataset.ezoicId) refreshAds([host.dataset.ezoicId]);
|
|
1686
|
-
}
|
|
1687
|
-
} catch (e) {}
|
|
1688
|
-
}
|
|
1689
|
-
|
|
1690
|
-
function reconcile() {
|
|
1691
|
-
var ulEl = ensureUL();
|
|
1692
|
-
if (!ulEl) return;
|
|
1693
|
-
|
|
1694
|
-
var topics = getTopics(ulEl);
|
|
1695
|
-
|
|
1696
|
-
try {
|
|
1697
|
-
ulEl.querySelectorAll(':scope > ' + BETWEEN_WRAP_SEL).forEach(function (w) {
|
|
1698
|
-
var h = ensureHostForWrap(w, ulEl);
|
|
1699
|
-
if (h) placeOrPend(h, ulEl, topics);
|
|
1700
|
-
});
|
|
1619
|
+
var wrap = host.querySelector && host.querySelector(BETWEEN_WRAP_SEL);
|
|
1620
|
+
if (!wrap) return;
|
|
1701
1621
|
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
});
|
|
1622
|
+
var anchor = previousTopicLi(host);
|
|
1623
|
+
if (!anchor) return; // if none, don't move (prevents yanking to top/bottom)
|
|
1705
1624
|
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1625
|
+
if (host.previousElementSibling !== anchor) {
|
|
1626
|
+
anchor.insertAdjacentElement('afterend', host);
|
|
1627
|
+
}
|
|
1628
|
+
} catch (e) {}
|
|
1709
1629
|
});
|
|
1710
1630
|
} catch (e) {}
|
|
1711
1631
|
}
|
|
1712
1632
|
|
|
1713
|
-
function
|
|
1633
|
+
function schedule(reason) {
|
|
1714
1634
|
var now = Date.now();
|
|
1715
|
-
if (scheduled) return;
|
|
1716
1635
|
if (now - lastRun < COOLDOWN) return;
|
|
1636
|
+
if (scheduled) return;
|
|
1717
1637
|
scheduled = true;
|
|
1718
|
-
lastRun = now;
|
|
1719
1638
|
requestAnimationFrame(function () {
|
|
1720
1639
|
scheduled = false;
|
|
1721
|
-
|
|
1640
|
+
lastRun = Date.now();
|
|
1641
|
+
try {
|
|
1642
|
+
var ul = getTopicList();
|
|
1643
|
+
if (!ul) return;
|
|
1644
|
+
redistribute(ul);
|
|
1645
|
+
} catch (e) {}
|
|
1722
1646
|
});
|
|
1723
1647
|
}
|
|
1724
1648
|
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
// the ad stack only reacts on the next scroll tick. This keeps blocks from
|
|
1728
|
-
// staying blank until the user nudges the page.
|
|
1729
|
-
var io = null;
|
|
1730
|
-
var observedPlaceholders = typeof WeakSet !== 'undefined' ? new WeakSet() : null;
|
|
1731
|
-
|
|
1732
|
-
function isEzoicPlaceholder(el) {
|
|
1733
|
-
return !!(el && el.id && el.id.indexOf('ezoic-pub-ad-placeholder-') === 0);
|
|
1734
|
-
}
|
|
1649
|
+
function init() {
|
|
1650
|
+
schedule('init');
|
|
1735
1651
|
|
|
1736
|
-
|
|
1652
|
+
// Observe only the topic list once available
|
|
1737
1653
|
try {
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1654
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
1655
|
+
var observeList = function(ul){
|
|
1656
|
+
if (!ul) return;
|
|
1657
|
+
var mo = new MutationObserver(function(muts){
|
|
1658
|
+
// schedule on any change; redistribute() itself is guarded by pile-up detection
|
|
1659
|
+
schedule('mo');
|
|
1660
|
+
});
|
|
1661
|
+
mo.observe(ul, { childList: true, subtree: true });
|
|
1662
|
+
};
|
|
1663
|
+
|
|
1664
|
+
var ul = getTopicList();
|
|
1665
|
+
if (ul) observeList(ul);
|
|
1666
|
+
else {
|
|
1667
|
+
var mo2 = new MutationObserver(function(){
|
|
1668
|
+
var u2 = getTopicList();
|
|
1669
|
+
if (u2) {
|
|
1670
|
+
try { observeList(u2); } catch(e){}
|
|
1671
|
+
try { mo2.disconnect(); } catch(e){}
|
|
1672
|
+
}
|
|
1673
|
+
});
|
|
1674
|
+
mo2.observe(document.documentElement || document.body, { childList: true, subtree: true });
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
} catch (e) {}
|
|
1678
|
+
|
|
1679
|
+
// NodeBB events: run after infinite scroll batches
|
|
1680
|
+
if (window.jQuery) {
|
|
1681
|
+
try {
|
|
1682
|
+
window.jQuery(window).on('action:ajaxify.end action:infiniteScroll.loaded', function(){
|
|
1683
|
+
setTimeout(function(){ schedule('event'); }, 50);
|
|
1684
|
+
setTimeout(function(){ schedule('event2'); }, 400);
|
|
1685
|
+
});
|
|
1686
|
+
} catch (e) {}
|
|
1741
1687
|
}
|
|
1742
1688
|
}
|
|
1743
1689
|
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
var last = 0;
|
|
1749
|
-
try { last = parseInt(ph.getAttribute('data-ez-poke-at') || '0', 10) || 0; } catch (e) {}
|
|
1750
|
-
if (now - last < 1200) return;
|
|
1751
|
-
try { ph.setAttribute('data-ez-poke-at', String(now)); } catch (e) {}
|
|
1690
|
+
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
1691
|
+
else init();
|
|
1692
|
+
})();
|
|
1693
|
+
// ===== /V17 =====
|
|
1752
1694
|
|
|
1753
|
-
|
|
1754
|
-
|
|
1695
|
+
// ===== V17.13: empty GPT "poke" (keeps V17 pile-fix intact) =====
|
|
1696
|
+
// Goal: some GPT containers render empty until a tiny scroll triggers a refresh.
|
|
1697
|
+
// This watcher detects visible empty GPT slots and triggers a lightweight refresh.
|
|
1698
|
+
(function () {
|
|
1699
|
+
var TAG = '[EZ EMPTY]';
|
|
1700
|
+
var seen = Object.create(null);
|
|
1701
|
+
|
|
1702
|
+
function dbg() {
|
|
1703
|
+
if (!window.__EZ_DEBUG) return;
|
|
1704
|
+
try { console.log.apply(console, arguments); } catch (e) {}
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
function throttle(fn, wait) {
|
|
1708
|
+
var t = 0;
|
|
1709
|
+
var timer = null;
|
|
1710
|
+
return function () {
|
|
1711
|
+
var now = Date.now();
|
|
1712
|
+
var args = arguments;
|
|
1713
|
+
if (now - t >= wait) {
|
|
1714
|
+
t = now;
|
|
1715
|
+
fn.apply(null, args);
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
if (timer) return;
|
|
1719
|
+
timer = setTimeout(function () {
|
|
1720
|
+
timer = null;
|
|
1721
|
+
t = Date.now();
|
|
1722
|
+
fn.apply(null, args);
|
|
1723
|
+
}, wait);
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1755
1726
|
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1727
|
+
function isVisible(el) {
|
|
1728
|
+
try {
|
|
1729
|
+
if (!el || el.nodeType !== 1) return false;
|
|
1730
|
+
var r = el.getBoundingClientRect();
|
|
1731
|
+
if (!r) return false;
|
|
1732
|
+
if (r.width <= 0 || r.height <= 0) return false;
|
|
1733
|
+
var vh = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
1734
|
+
var vw = window.innerWidth || document.documentElement.clientWidth || 0;
|
|
1735
|
+
if (vh <= 0 || vw <= 0) return false;
|
|
1736
|
+
return r.bottom > 0 && r.right > 0 && r.top < vh && r.left < vw;
|
|
1737
|
+
} catch (e) {}
|
|
1738
|
+
return false;
|
|
1739
|
+
}
|
|
1759
1740
|
|
|
1760
|
-
|
|
1761
|
-
|
|
1741
|
+
function slotHasFill(slot) {
|
|
1742
|
+
try {
|
|
1743
|
+
if (slot.querySelector && slot.querySelector('iframe')) return true;
|
|
1744
|
+
var cid = 'google_ads_iframe_';
|
|
1745
|
+
var any = slot.querySelector && slot.querySelector('[id^="' + cid + '"] iframe');
|
|
1746
|
+
return !!any;
|
|
1747
|
+
} catch (e) {}
|
|
1748
|
+
return false;
|
|
1749
|
+
}
|
|
1762
1750
|
|
|
1763
|
-
|
|
1751
|
+
function pokeRefresh() {
|
|
1752
|
+
try {
|
|
1753
|
+
if (window.ezstandalone && typeof window.ezstandalone.showAds === 'function') {
|
|
1754
|
+
window.ezstandalone.showAds();
|
|
1755
|
+
dbg(TAG, 'showAds called');
|
|
1756
|
+
return true;
|
|
1757
|
+
}
|
|
1758
|
+
} catch (e) {}
|
|
1764
1759
|
try { window.dispatchEvent(new Event('scroll')); } catch (e) {}
|
|
1765
1760
|
try { window.dispatchEvent(new Event('resize')); } catch (e) {}
|
|
1766
|
-
|
|
1767
|
-
// One re-try shortly after, in case the first request was dropped.
|
|
1768
|
-
setTimeout(function () {
|
|
1769
|
-
try {
|
|
1770
|
-
if (iframeCount(ph) === 0) {
|
|
1771
|
-
refreshAds([ph.id]);
|
|
1772
|
-
try { window.dispatchEvent(new Event('scroll')); } catch (e2) {}
|
|
1773
|
-
}
|
|
1774
|
-
} catch (e3) {}
|
|
1775
|
-
}, 450);
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
|
-
function ensureIO() {
|
|
1779
|
-
if (io) return;
|
|
1780
|
-
if (!('IntersectionObserver' in window)) return;
|
|
1781
|
-
io = new IntersectionObserver(function (entries) {
|
|
1782
|
-
for (var i = 0; i < entries.length; i++) {
|
|
1783
|
-
var e = entries[i];
|
|
1784
|
-
if (!e || !e.isIntersecting) continue;
|
|
1785
|
-
var ph = e.target;
|
|
1786
|
-
if (!isEzoicPlaceholder(ph)) continue;
|
|
1787
|
-
if (iframeCount(ph) === 0) {
|
|
1788
|
-
pokePlaceholder(ph, 'in-view');
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
}, { root: null, rootMargin: '200px 0px', threshold: 0.01 });
|
|
1761
|
+
return false;
|
|
1792
1762
|
}
|
|
1793
1763
|
|
|
1794
|
-
function
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
if (
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
if (
|
|
1804
|
-
|
|
1805
|
-
}
|
|
1806
|
-
try { io.observe(ph); } catch (e) {}
|
|
1807
|
-
}
|
|
1764
|
+
function checkSlot(slot) {
|
|
1765
|
+
try {
|
|
1766
|
+
if (!slot || !slot.id) return;
|
|
1767
|
+
if (slot.id.indexOf('div-gpt-ad-') !== 0) return;
|
|
1768
|
+
if (slotHasFill(slot)) return;
|
|
1769
|
+
if (!isVisible(slot)) return;
|
|
1770
|
+
|
|
1771
|
+
var k = slot.id;
|
|
1772
|
+
var now = Date.now();
|
|
1773
|
+
if (seen[k] && (now - seen[k]) < 2000) return;
|
|
1774
|
+
seen[k] = now;
|
|
1808
1775
|
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1776
|
+
setTimeout(function () {
|
|
1777
|
+
try {
|
|
1778
|
+
if (!slotHasFill(slot) && isVisible(slot)) {
|
|
1779
|
+
console.log(TAG, k);
|
|
1780
|
+
pokeRefresh();
|
|
1781
|
+
}
|
|
1782
|
+
} catch (e) {}
|
|
1783
|
+
}, 120);
|
|
1784
|
+
} catch (e) {}
|
|
1814
1785
|
}
|
|
1815
1786
|
|
|
1816
|
-
function
|
|
1817
|
-
|
|
1818
|
-
|
|
1787
|
+
function scan() {
|
|
1788
|
+
try {
|
|
1789
|
+
var slots = document.querySelectorAll('[id^="div-gpt-ad-"]');
|
|
1790
|
+
if (!slots || !slots.length) {
|
|
1791
|
+
dbg(TAG, 'none');
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
for (var i = 0; i < slots.length; i++) checkSlot(slots[i]);
|
|
1795
|
+
} catch (e) {}
|
|
1796
|
+
}
|
|
1819
1797
|
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
var
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
var
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1798
|
+
function observeNewSlots(io) {
|
|
1799
|
+
try {
|
|
1800
|
+
if (typeof MutationObserver === 'undefined') return;
|
|
1801
|
+
var mo = new MutationObserver(function (muts) {
|
|
1802
|
+
try {
|
|
1803
|
+
for (var i = 0; i < muts.length; i++) {
|
|
1804
|
+
var m = muts[i];
|
|
1805
|
+
if (!m.addedNodes) continue;
|
|
1806
|
+
for (var j = 0; j < m.addedNodes.length; j++) {
|
|
1807
|
+
var n = m.addedNodes[j];
|
|
1808
|
+
if (!n || n.nodeType !== 1) continue;
|
|
1809
|
+
if (n.id && n.id.indexOf('div-gpt-ad-') === 0) {
|
|
1810
|
+
try { io.observe(n); } catch (e) {}
|
|
1811
|
+
checkSlot(n);
|
|
1812
|
+
} else if (n.querySelectorAll) {
|
|
1813
|
+
var inner = n.querySelectorAll('[id^="div-gpt-ad-"]');
|
|
1814
|
+
for (var k = 0; k < inner.length; k++) {
|
|
1815
|
+
try { io.observe(inner[k]); } catch (e) {}
|
|
1816
|
+
checkSlot(inner[k]);
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1832
1820
|
}
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
mo.observe(ulEl, { childList: true, subtree: true });
|
|
1821
|
+
} catch (e) {}
|
|
1822
|
+
});
|
|
1823
|
+
mo.observe(document.documentElement || document.body, { childList: true, subtree: true });
|
|
1824
|
+
} catch (e) {}
|
|
1838
1825
|
}
|
|
1839
1826
|
|
|
1840
|
-
function
|
|
1841
|
-
|
|
1842
|
-
scheduleReconcile();
|
|
1843
|
-
// initial scan for placeholders already in the DOM
|
|
1844
|
-
scanPlaceholders(document);
|
|
1827
|
+
function initEmptyWatcher() {
|
|
1828
|
+
scan();
|
|
1845
1829
|
|
|
1846
|
-
if (window
|
|
1830
|
+
if ('IntersectionObserver' in window) {
|
|
1847
1831
|
try {
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
}
|
|
1832
|
+
var io = new IntersectionObserver(function (entries) {
|
|
1833
|
+
for (var i = 0; i < entries.length; i++) {
|
|
1834
|
+
var ent = entries[i];
|
|
1835
|
+
if (ent && ent.isIntersecting) checkSlot(ent.target);
|
|
1836
|
+
}
|
|
1837
|
+
}, { root: null, threshold: 0.12 });
|
|
1838
|
+
|
|
1839
|
+
var slots = document.querySelectorAll('[id^="div-gpt-ad-"]');
|
|
1840
|
+
for (var s = 0; s < slots.length; s++) {
|
|
1841
|
+
try { io.observe(slots[s]); } catch (e) {}
|
|
1842
|
+
}
|
|
1843
|
+
observeNewSlots(io);
|
|
1859
1844
|
} catch (e) {}
|
|
1860
1845
|
}
|
|
1861
1846
|
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
if (ensureUL()) {
|
|
1866
|
-
clearInterval(t);
|
|
1867
|
-
initObserver();
|
|
1868
|
-
scheduleReconcile();
|
|
1869
|
-
}
|
|
1870
|
-
if (tries > 30) clearInterval(t);
|
|
1871
|
-
}, 200);
|
|
1847
|
+
try { window.addEventListener('scroll', throttle(scan, 250), { passive: true }); } catch (e) {}
|
|
1848
|
+
try { window.addEventListener('resize', throttle(scan, 500)); } catch (e) {}
|
|
1849
|
+
try { document.addEventListener('visibilitychange', function () { if (!document.hidden) setTimeout(scan, 150); }); } catch (e) {}
|
|
1872
1850
|
}
|
|
1873
1851
|
|
|
1874
|
-
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded',
|
|
1875
|
-
else
|
|
1852
|
+
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initEmptyWatcher);
|
|
1853
|
+
else initEmptyWatcher();
|
|
1876
1854
|
})();
|
|
1877
|
-
// ===== /V17.
|
|
1855
|
+
// ===== /V17.13 =====
|
|
1878
1856
|
|
package/public/style.css
CHANGED
|
@@ -86,15 +86,3 @@ li.nodebb-ezoic-host { list-style: none; width: 100%; display: block; }
|
|
|
86
86
|
li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width: 100%; display: block; }
|
|
87
87
|
/* ===== /V17 ===== */
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
/* ===== V17.8 pending slots (prevents pile-up top/bottom) ===== */
|
|
92
|
-
li.nodebb-ezoic-host { list-style:none; width:100%; display:block; }
|
|
93
|
-
li.nodebb-ezoic-host > .nodebb-ezoic-wrap.ezoic-ad-between { width:100%; display:block; }
|
|
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 ===== */
|
|
100
|
-
|