nodebb-plugin-ezoic-infinite 1.6.46 → 1.6.48
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 +111 -80
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1693,105 +1693,136 @@ 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
|
+
// NOTE: Calling ezstandalone.showAds() was triggering extra bidder requests
|
|
1704
|
+
// (and in your setup, surfacing ServiceWorker/CORS failures) which made
|
|
1705
|
+
// fills slower and created visible repositioning. We only do a tiny scroll
|
|
1706
|
+
// nudge here, because manual micro-scroll reliably triggers a fill.
|
|
1707
|
+
var microScrollCooldownUntil = 0;
|
|
1710
1708
|
|
|
1711
|
-
function
|
|
1712
|
-
|
|
1709
|
+
function now() { return Date.now ? Date.now() : +new Date(); }
|
|
1710
|
+
|
|
1711
|
+
function getSlotId(wrap) {
|
|
1712
|
+
try {
|
|
1713
|
+
var gpt = wrap.querySelector('[id^="div-gpt-ad-"]');
|
|
1714
|
+
return gpt ? gpt.id : null;
|
|
1715
|
+
} catch (e) { return null; }
|
|
1713
1716
|
}
|
|
1714
1717
|
|
|
1715
|
-
function
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
if (
|
|
1721
|
-
}
|
|
1722
|
-
return
|
|
1718
|
+
function hasAnyCreative(wrap) {
|
|
1719
|
+
try {
|
|
1720
|
+
// Any iframe (safeframe or normal) inside the wrap counts as rendered.
|
|
1721
|
+
if (wrap.querySelector('iframe')) return true;
|
|
1722
|
+
// Some formats use ins/amp/other nodes.
|
|
1723
|
+
if (wrap.querySelector('amp-ad, amp-embed, ins.adsbygoogle')) return true;
|
|
1724
|
+
} catch (e) {}
|
|
1725
|
+
return false;
|
|
1723
1726
|
}
|
|
1724
1727
|
|
|
1725
|
-
function
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1728
|
+
function microScrollNudge() {
|
|
1729
|
+
var t = now();
|
|
1730
|
+
if (t < microScrollCooldownUntil) return;
|
|
1731
|
+
microScrollCooldownUntil = t + 1200;
|
|
1732
|
+
|
|
1733
|
+
// Prefer a real 1px scroll + restore: this matches the observed manual fix.
|
|
1734
|
+
try {
|
|
1735
|
+
var y = window.pageYOffset || document.documentElement.scrollTop || 0;
|
|
1736
|
+
window.scrollTo(0, y + 1);
|
|
1737
|
+
(window.requestAnimationFrame || setTimeout)(function () {
|
|
1738
|
+
try { window.scrollTo(0, y); } catch (e) {}
|
|
1739
|
+
try { window.dispatchEvent(new Event('scroll')); } catch (e) {}
|
|
1740
|
+
}, 16);
|
|
1741
|
+
return;
|
|
1742
|
+
} catch (e) {}
|
|
1743
|
+
|
|
1744
|
+
// Fallback: nudge listeners.
|
|
1745
|
+
try { window.dispatchEvent(new Event('scroll')); } catch (e) {}
|
|
1731
1746
|
}
|
|
1732
1747
|
|
|
1733
|
-
function
|
|
1748
|
+
function scheduleCheck(wrap) {
|
|
1734
1749
|
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) {}
|
|
1750
|
+
if (!wrap || wrap.nodeType !== 1) return;
|
|
1751
|
+
if (hasAnyCreative(wrap)) return;
|
|
1752
|
+
|
|
1753
|
+
var meta = seen.get(wrap);
|
|
1754
|
+
var t = now();
|
|
1755
|
+
if (!meta) {
|
|
1756
|
+
meta = { firstSeen: t, checks: 0 };
|
|
1757
|
+
seen.set(wrap, meta);
|
|
1750
1758
|
}
|
|
1759
|
+
|
|
1760
|
+
// Give the normal pipeline time to render.
|
|
1761
|
+
if (meta.checks === 0) {
|
|
1762
|
+
setTimeout(function () { scheduleCheck(wrap); }, 700);
|
|
1763
|
+
meta.checks++;
|
|
1764
|
+
return;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
if (hasAnyCreative(wrap)) return;
|
|
1768
|
+
|
|
1769
|
+
// Still empty -> poke (micro-scroll only; no showAds/refresh calls).
|
|
1770
|
+
var id = getSlotId(wrap) || 'none';
|
|
1771
|
+
try { console.log('[EZ EMPTY]', id); } catch (e) {}
|
|
1772
|
+
microScrollNudge();
|
|
1773
|
+
|
|
1774
|
+
// Re-check once after the nudge, but do not loop.
|
|
1775
|
+
setTimeout(function () {
|
|
1776
|
+
if (!wrap.isConnected) return;
|
|
1777
|
+
if (hasAnyCreative(wrap)) return;
|
|
1778
|
+
// Still empty: leave it to the native pipeline; avoid repeated nudges.
|
|
1779
|
+
}, 900);
|
|
1751
1780
|
} catch (e) {}
|
|
1752
1781
|
}
|
|
1753
1782
|
|
|
1754
|
-
function
|
|
1783
|
+
function ensureIO() {
|
|
1784
|
+
if (io) return;
|
|
1785
|
+
if (!('IntersectionObserver' in window)) return;
|
|
1786
|
+
|
|
1787
|
+
io = new IntersectionObserver(function (entries) {
|
|
1788
|
+
for (var i = 0; i < entries.length; i++) {
|
|
1789
|
+
var e = entries[i];
|
|
1790
|
+
if (!e.isIntersecting) continue;
|
|
1791
|
+
scheduleCheck(e.target);
|
|
1792
|
+
}
|
|
1793
|
+
}, { root: null, rootMargin: '900px 0px 900px 0px', threshold: 0.01 });
|
|
1794
|
+
|
|
1795
|
+
// Observe existing wraps.
|
|
1755
1796
|
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;
|
|
1797
|
+
var wraps = document.querySelectorAll(BETWEEN_WRAP_SEL);
|
|
1798
|
+
for (var j = 0; j < wraps.length; j++) io.observe(wraps[j]);
|
|
1799
|
+
} catch (e) {}
|
|
1800
|
+
|
|
1801
|
+
// Observe new wraps.
|
|
1802
|
+
try {
|
|
1803
|
+
var mo = new MutationObserver(function (muts) {
|
|
1804
|
+
for (var k = 0; k < muts.length; k++) {
|
|
1805
|
+
var m = muts[k];
|
|
1806
|
+
if (!m.addedNodes) continue;
|
|
1807
|
+
for (var n = 0; n < m.addedNodes.length; n++) {
|
|
1808
|
+
var node = m.addedNodes[n];
|
|
1809
|
+
if (!node || node.nodeType !== 1) continue;
|
|
1810
|
+
if (node.matches && node.matches(BETWEEN_WRAP_SEL)) {
|
|
1811
|
+
io.observe(node);
|
|
1812
|
+
} else if (node.querySelectorAll) {
|
|
1813
|
+
var inner = node.querySelectorAll(BETWEEN_WRAP_SEL);
|
|
1814
|
+
for (var q = 0; q < inner.length; q++) io.observe(inner[q]);
|
|
1815
|
+
}
|
|
1780
1816
|
}
|
|
1781
|
-
// wrap somewhere inside
|
|
1782
|
-
var inner = n.querySelector ? n.querySelector(BETWEEN_WRAP_SEL) : null;
|
|
1783
|
-
if (inner) handleWrapInserted(ul, inner);
|
|
1784
1817
|
}
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
mo.observe(ul, { childList: true, subtree: true });
|
|
1818
|
+
});
|
|
1819
|
+
mo.observe(document.body, { childList: true, subtree: true });
|
|
1820
|
+
} catch (e) {}
|
|
1789
1821
|
}
|
|
1790
1822
|
|
|
1791
1823
|
if (document.readyState === 'loading') {
|
|
1792
|
-
document.addEventListener('DOMContentLoaded',
|
|
1824
|
+
document.addEventListener('DOMContentLoaded', ensureIO, { once: true });
|
|
1793
1825
|
} else {
|
|
1794
|
-
|
|
1826
|
+
ensureIO();
|
|
1795
1827
|
}
|
|
1796
1828
|
})();
|
|
1797
|
-
// ===== /V17.17 TOPFIX =====
|