nodebb-plugin-ezoic-infinite 1.6.46 → 1.6.47
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 +105 -80
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1693,105 +1693,130 @@ function buildOrdinalMap(items) {
|
|
|
1693
1693
|
// ===== /V17 =====
|
|
1694
1694
|
|
|
1695
1695
|
|
|
1696
|
-
// ===== V17.17 TOPFIX (minimal, non-invasive) =====
|
|
1697
|
-
// Goal: prevent "between" ad wrappers from being inserted at the very top of the topic list
|
|
1698
|
-
// (before any real topic LI), without moving or re-wrapping existing GPT containers.
|
|
1699
|
-
// We only:
|
|
1700
|
-
// 1) If a between wrapper is inserted as the first child and a topic LI exists, move its host
|
|
1701
|
-
// to after the first topic LI (one-time).
|
|
1702
|
-
// 2) If no topic LI exists yet, mark it with data-ezoic-after="1" and leave it in place.
|
|
1703
|
-
// This avoids the heavier "pending pool" logic that can reduce fill.
|
|
1704
|
-
(function(){
|
|
1705
|
-
'use strict';
|
|
1706
1696
|
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1697
|
+
// ===== V17 empty-refresh (no move) =====
|
|
1698
|
+
// Goal: if a between-ad is visible but still has no ad iframe, gently poke Ezoic/GPT to render.
|
|
1699
|
+
(function () {
|
|
1700
|
+
var BETWEEN_WRAP_SEL = 'div.nodebb-ezoic-wrap.ezoic-ad-between';
|
|
1701
|
+
var seen = new WeakMap();
|
|
1702
|
+
var io = null;
|
|
1703
|
+
var showAdsCooldownUntil = 0;
|
|
1710
1704
|
|
|
1711
|
-
function
|
|
1712
|
-
|
|
1705
|
+
function now() { return Date.now ? Date.now() : +new Date(); }
|
|
1706
|
+
|
|
1707
|
+
function getSlotId(wrap) {
|
|
1708
|
+
try {
|
|
1709
|
+
var gpt = wrap.querySelector('[id^="div-gpt-ad-"]');
|
|
1710
|
+
return gpt ? gpt.id : null;
|
|
1711
|
+
} catch (e) { return null; }
|
|
1713
1712
|
}
|
|
1714
1713
|
|
|
1715
|
-
function
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
if (
|
|
1721
|
-
}
|
|
1722
|
-
return
|
|
1714
|
+
function hasAnyCreative(wrap) {
|
|
1715
|
+
try {
|
|
1716
|
+
// Any iframe (safeframe or normal) inside the wrap counts as rendered.
|
|
1717
|
+
if (wrap.querySelector('iframe')) return true;
|
|
1718
|
+
// Some formats use ins/amp/other nodes.
|
|
1719
|
+
if (wrap.querySelector('amp-ad, amp-embed, ins.adsbygoogle')) return true;
|
|
1720
|
+
} catch (e) {}
|
|
1721
|
+
return false;
|
|
1723
1722
|
}
|
|
1724
1723
|
|
|
1725
|
-
function
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1724
|
+
function safeShowAds() {
|
|
1725
|
+
var t = now();
|
|
1726
|
+
if (t < showAdsCooldownUntil) return;
|
|
1727
|
+
showAdsCooldownUntil = t + 1200;
|
|
1728
|
+
|
|
1729
|
+
try {
|
|
1730
|
+
if (window.ezstandalone && typeof window.ezstandalone.showAds === 'function') {
|
|
1731
|
+
window.ezstandalone.showAds();
|
|
1732
|
+
return;
|
|
1733
|
+
}
|
|
1734
|
+
} catch (e) {}
|
|
1735
|
+
|
|
1736
|
+
// Fallback: nudge common listeners.
|
|
1737
|
+
try { window.dispatchEvent(new Event('scroll')); } catch (e) {}
|
|
1738
|
+
try { window.dispatchEvent(new Event('resize')); } catch (e) {}
|
|
1731
1739
|
}
|
|
1732
1740
|
|
|
1733
|
-
function
|
|
1741
|
+
function scheduleCheck(wrap) {
|
|
1734
1742
|
try {
|
|
1735
|
-
if (!
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
if (
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
var anchor = firstTopicLi(ul);
|
|
1744
|
-
if (anchor) {
|
|
1745
|
-
// One-time move to just after first topic LI
|
|
1746
|
-
anchor.insertAdjacentElement('afterend', host);
|
|
1747
|
-
} else {
|
|
1748
|
-
// No anchor yet: mark to discourage top placement; do not move later
|
|
1749
|
-
try { wrap.setAttribute('data-ezoic-after', '1'); } catch(e) {}
|
|
1743
|
+
if (!wrap || wrap.nodeType !== 1) return;
|
|
1744
|
+
if (hasAnyCreative(wrap)) return;
|
|
1745
|
+
|
|
1746
|
+
var meta = seen.get(wrap);
|
|
1747
|
+
var t = now();
|
|
1748
|
+
if (!meta) {
|
|
1749
|
+
meta = { firstSeen: t, checks: 0 };
|
|
1750
|
+
seen.set(wrap, meta);
|
|
1750
1751
|
}
|
|
1752
|
+
|
|
1753
|
+
// Give the normal pipeline time to render.
|
|
1754
|
+
if (meta.checks === 0) {
|
|
1755
|
+
setTimeout(function () { scheduleCheck(wrap); }, 700);
|
|
1756
|
+
meta.checks++;
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
if (hasAnyCreative(wrap)) return;
|
|
1761
|
+
|
|
1762
|
+
// Still empty -> poke.
|
|
1763
|
+
var id = getSlotId(wrap) || 'none';
|
|
1764
|
+
try { console.log('[EZ EMPTY]', id); } catch (e) {}
|
|
1765
|
+
safeShowAds();
|
|
1766
|
+
|
|
1767
|
+
// One more re-check shortly after the poke.
|
|
1768
|
+
setTimeout(function () {
|
|
1769
|
+
if (!wrap.isConnected) return;
|
|
1770
|
+
if (hasAnyCreative(wrap)) return;
|
|
1771
|
+
// If still empty after a poke, try once more (but do not loop forever).
|
|
1772
|
+
safeShowAds();
|
|
1773
|
+
}, 900);
|
|
1751
1774
|
} catch (e) {}
|
|
1752
1775
|
}
|
|
1753
1776
|
|
|
1754
|
-
function
|
|
1777
|
+
function ensureIO() {
|
|
1778
|
+
if (io) return;
|
|
1779
|
+
if (!('IntersectionObserver' in window)) return;
|
|
1780
|
+
|
|
1781
|
+
io = new IntersectionObserver(function (entries) {
|
|
1782
|
+
for (var i = 0; i < entries.length; i++) {
|
|
1783
|
+
var e = entries[i];
|
|
1784
|
+
if (!e.isIntersecting) continue;
|
|
1785
|
+
scheduleCheck(e.target);
|
|
1786
|
+
}
|
|
1787
|
+
}, { root: null, rootMargin: '900px 0px 900px 0px', threshold: 0.01 });
|
|
1788
|
+
|
|
1789
|
+
// Observe existing wraps.
|
|
1755
1790
|
try {
|
|
1756
|
-
var wraps =
|
|
1757
|
-
wraps.
|
|
1758
|
-
} catch(e) {}
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
// direct wrap
|
|
1777
|
-
if (n.matches && n.matches(BETWEEN_WRAP_SEL)) {
|
|
1778
|
-
handleWrapInserted(ul, n);
|
|
1779
|
-
continue;
|
|
1791
|
+
var wraps = document.querySelectorAll(BETWEEN_WRAP_SEL);
|
|
1792
|
+
for (var j = 0; j < wraps.length; j++) io.observe(wraps[j]);
|
|
1793
|
+
} catch (e) {}
|
|
1794
|
+
|
|
1795
|
+
// Observe new wraps.
|
|
1796
|
+
try {
|
|
1797
|
+
var mo = new MutationObserver(function (muts) {
|
|
1798
|
+
for (var k = 0; k < muts.length; k++) {
|
|
1799
|
+
var m = muts[k];
|
|
1800
|
+
if (!m.addedNodes) continue;
|
|
1801
|
+
for (var n = 0; n < m.addedNodes.length; n++) {
|
|
1802
|
+
var node = m.addedNodes[n];
|
|
1803
|
+
if (!node || node.nodeType !== 1) continue;
|
|
1804
|
+
if (node.matches && node.matches(BETWEEN_WRAP_SEL)) {
|
|
1805
|
+
io.observe(node);
|
|
1806
|
+
} else if (node.querySelectorAll) {
|
|
1807
|
+
var inner = node.querySelectorAll(BETWEEN_WRAP_SEL);
|
|
1808
|
+
for (var q = 0; q < inner.length; q++) io.observe(inner[q]);
|
|
1809
|
+
}
|
|
1780
1810
|
}
|
|
1781
|
-
// wrap somewhere inside
|
|
1782
|
-
var inner = n.querySelector ? n.querySelector(BETWEEN_WRAP_SEL) : null;
|
|
1783
|
-
if (inner) handleWrapInserted(ul, inner);
|
|
1784
1811
|
}
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
mo.observe(ul, { childList: true, subtree: true });
|
|
1812
|
+
});
|
|
1813
|
+
mo.observe(document.body, { childList: true, subtree: true });
|
|
1814
|
+
} catch (e) {}
|
|
1789
1815
|
}
|
|
1790
1816
|
|
|
1791
1817
|
if (document.readyState === 'loading') {
|
|
1792
|
-
document.addEventListener('DOMContentLoaded',
|
|
1818
|
+
document.addEventListener('DOMContentLoaded', ensureIO, { once: true });
|
|
1793
1819
|
} else {
|
|
1794
|
-
|
|
1820
|
+
ensureIO();
|
|
1795
1821
|
}
|
|
1796
1822
|
})();
|
|
1797
|
-
// ===== /V17.17 TOPFIX =====
|