nodebb-plugin-ezoic-infinite 1.6.41 → 1.6.42
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 +83 -162
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -1646,6 +1646,85 @@ function buildOrdinalMap(items) {
|
|
|
1646
1646
|
});
|
|
1647
1647
|
}
|
|
1648
1648
|
|
|
1649
|
+
// --- Empty ad "poke" helper ---
|
|
1650
|
+
// Some GPT safeframe creatives may remain visually blank until a small scroll/reflow happens.
|
|
1651
|
+
// We avoid calling showAds()/refresh() (which can hurt fill) and instead trigger a cheap reflow.
|
|
1652
|
+
var ezEmptySeen = Object.create(null);
|
|
1653
|
+
var ezEmptyPokeTimer = Object.create(null);
|
|
1654
|
+
|
|
1655
|
+
function inViewportLoose(el) {
|
|
1656
|
+
try {
|
|
1657
|
+
if (!el || !el.getBoundingClientRect) return false;
|
|
1658
|
+
var r = el.getBoundingClientRect();
|
|
1659
|
+
var vh = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
1660
|
+
// within 1.5 viewports from top/bottom
|
|
1661
|
+
return r.bottom > -vh * 0.5 && r.top < vh * 1.5;
|
|
1662
|
+
} catch (e) {
|
|
1663
|
+
return false;
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
function pokeReflowForDivId(divId) {
|
|
1668
|
+
try {
|
|
1669
|
+
var el = document.getElementById(divId);
|
|
1670
|
+
if (!el) return;
|
|
1671
|
+
if (!inViewportLoose(el)) return;
|
|
1672
|
+
|
|
1673
|
+
// Force a tiny reflow/paint on the closest wrapper
|
|
1674
|
+
var wrap = el.closest ? (el.closest('.ez-fixed-wrap') || el.parentElement) : el.parentElement;
|
|
1675
|
+
if (!wrap) wrap = el;
|
|
1676
|
+
|
|
1677
|
+
// Toggle visibility for one frame
|
|
1678
|
+
var prevVis = wrap.style.visibility;
|
|
1679
|
+
wrap.style.visibility = 'hidden';
|
|
1680
|
+
requestAnimationFrame(function(){
|
|
1681
|
+
wrap.style.visibility = prevVis || '';
|
|
1682
|
+
// Dispatch scroll/resize events without moving the page
|
|
1683
|
+
try { window.dispatchEvent(new Event('scroll')); } catch (e) {}
|
|
1684
|
+
try { window.dispatchEvent(new Event('resize')); } catch (e) {}
|
|
1685
|
+
});
|
|
1686
|
+
} catch (e) {}
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
function schedulePoke(divId) {
|
|
1690
|
+
try {
|
|
1691
|
+
if (!divId) return;
|
|
1692
|
+
var now = Date.now();
|
|
1693
|
+
// Cooldown per slot to avoid loops
|
|
1694
|
+
if (ezEmptySeen[divId] && now - ezEmptySeen[divId] < 15000) return;
|
|
1695
|
+
ezEmptySeen[divId] = now;
|
|
1696
|
+
|
|
1697
|
+
if (ezEmptyPokeTimer[divId]) return;
|
|
1698
|
+
ezEmptyPokeTimer[divId] = setTimeout(function(){
|
|
1699
|
+
ezEmptyPokeTimer[divId] = null;
|
|
1700
|
+
pokeReflowForDivId(divId);
|
|
1701
|
+
}, 350);
|
|
1702
|
+
} catch (e) {}
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
function initGptEmptyPoke() {
|
|
1706
|
+
try {
|
|
1707
|
+
if (!window.googletag || !googletag.cmd || !googletag.pubads) return;
|
|
1708
|
+
googletag.cmd.push(function(){
|
|
1709
|
+
try {
|
|
1710
|
+
var pub = googletag.pubads();
|
|
1711
|
+
if (!pub || !pub.addEventListener) return;
|
|
1712
|
+
pub.addEventListener('slotRenderEnded', function(e){
|
|
1713
|
+
try {
|
|
1714
|
+
if (!e) return;
|
|
1715
|
+
// divId is the GPT container id for the slot (e.g. div-gpt-ad-...)
|
|
1716
|
+
var divId = e.slot && e.slot.getSlotElementId ? e.slot.getSlotElementId() : (e.slotElementId || '');
|
|
1717
|
+
if (e.isEmpty) {
|
|
1718
|
+
if (divId) console.log('[EZ EMPTY]', divId);
|
|
1719
|
+
schedulePoke(divId);
|
|
1720
|
+
}
|
|
1721
|
+
} catch (err) {}
|
|
1722
|
+
});
|
|
1723
|
+
} catch (err2) {}
|
|
1724
|
+
});
|
|
1725
|
+
} catch (e) {}
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1649
1728
|
function init() {
|
|
1650
1729
|
schedule('init');
|
|
1651
1730
|
|
|
@@ -1685,6 +1764,10 @@ function buildOrdinalMap(items) {
|
|
|
1685
1764
|
});
|
|
1686
1765
|
} catch (e) {}
|
|
1687
1766
|
}
|
|
1767
|
+
|
|
1768
|
+
// Listen for GPT empty renders and apply a cheap reflow "poke".
|
|
1769
|
+
// This is intentionally non-invasive (no showAds/refresh) to preserve fill.
|
|
1770
|
+
initGptEmptyPoke();
|
|
1688
1771
|
}
|
|
1689
1772
|
|
|
1690
1773
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
|
@@ -1692,165 +1775,3 @@ function buildOrdinalMap(items) {
|
|
|
1692
1775
|
})();
|
|
1693
1776
|
// ===== /V17 =====
|
|
1694
1777
|
|
|
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
|
-
}
|
|
1726
|
-
|
|
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
|
-
}
|
|
1740
|
-
|
|
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
|
-
}
|
|
1750
|
-
|
|
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) {}
|
|
1759
|
-
try { window.dispatchEvent(new Event('scroll')); } catch (e) {}
|
|
1760
|
-
try { window.dispatchEvent(new Event('resize')); } catch (e) {}
|
|
1761
|
-
return false;
|
|
1762
|
-
}
|
|
1763
|
-
|
|
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;
|
|
1775
|
-
|
|
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) {}
|
|
1785
|
-
}
|
|
1786
|
-
|
|
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
|
-
}
|
|
1797
|
-
|
|
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
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
} catch (e) {}
|
|
1822
|
-
});
|
|
1823
|
-
mo.observe(document.documentElement || document.body, { childList: true, subtree: true });
|
|
1824
|
-
} catch (e) {}
|
|
1825
|
-
}
|
|
1826
|
-
|
|
1827
|
-
function initEmptyWatcher() {
|
|
1828
|
-
scan();
|
|
1829
|
-
|
|
1830
|
-
if ('IntersectionObserver' in window) {
|
|
1831
|
-
try {
|
|
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);
|
|
1844
|
-
} catch (e) {}
|
|
1845
|
-
}
|
|
1846
|
-
|
|
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) {}
|
|
1850
|
-
}
|
|
1851
|
-
|
|
1852
|
-
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initEmptyWatcher);
|
|
1853
|
-
else initEmptyWatcher();
|
|
1854
|
-
})();
|
|
1855
|
-
// ===== /V17.13 =====
|
|
1856
|
-
|