nodebb-plugin-ezoic-infinite 1.5.35 → 1.5.37
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 +100 -7
- package/public/style.css +18 -1
package/package.json
CHANGED
package/public/client.js
CHANGED
|
@@ -11,18 +11,21 @@
|
|
|
11
11
|
const MAX_INSERTS_PER_RUN = 3;
|
|
12
12
|
|
|
13
13
|
// Preload before viewport (earlier load for smoother scroll)
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
// Preload far enough ahead that fast scroll doesn't outrun ad loading.
|
|
15
|
+
// Slightly more aggressive margins to reduce “I scrolled past it before it loaded”.
|
|
16
|
+
const PRELOAD_MARGIN_DESKTOP = '4200px 0px 4200px 0px';
|
|
17
|
+
const PRELOAD_MARGIN_MOBILE = '2400px 0px 2400px 0px';
|
|
16
18
|
|
|
17
19
|
// When the user scrolls very fast, temporarily preload more aggressively.
|
|
18
20
|
// This helps ensure ads are already in-flight before the user reaches them.
|
|
19
|
-
const PRELOAD_MARGIN_DESKTOP_BOOST = '
|
|
20
|
-
const PRELOAD_MARGIN_MOBILE_BOOST = '
|
|
21
|
+
const PRELOAD_MARGIN_DESKTOP_BOOST = '6500px 0px 6500px 0px';
|
|
22
|
+
const PRELOAD_MARGIN_MOBILE_BOOST = '4200px 0px 4200px 0px';
|
|
21
23
|
const BOOST_DURATION_MS = 2500;
|
|
22
24
|
const BOOST_SPEED_PX_PER_MS = 2.2; // ~2200px/s
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
+
// Allow a bit more parallelism; the perf profile can still dial this down on low-end devices.
|
|
27
|
+
const MAX_INFLIGHT_DESKTOP = 5;
|
|
28
|
+
const MAX_INFLIGHT_MOBILE = 4;
|
|
26
29
|
|
|
27
30
|
|
|
28
31
|
// Adaptive performance profile (device/network aware)
|
|
@@ -599,6 +602,9 @@ function startShow(id) {
|
|
|
599
602
|
try { ez.showAds(id); } catch (e) {}
|
|
600
603
|
try { state.usedOnce && state.usedOnce.add(id); } catch (e) {}
|
|
601
604
|
|
|
605
|
+
// Tighten any oversized reserved height once the creative is in the DOM.
|
|
606
|
+
try { scheduleTighten(id); } catch (e) {}
|
|
607
|
+
|
|
602
608
|
setTimeout(() => { clearTimeout(hardTimer); release(); }, 650);
|
|
603
609
|
};
|
|
604
610
|
|
|
@@ -613,6 +619,83 @@ function startShow(id) {
|
|
|
613
619
|
});
|
|
614
620
|
}
|
|
615
621
|
|
|
622
|
+
// ---------- height normalization (reduce empty space) ----------
|
|
623
|
+
// Some Ezoic / GPT wrappers reserve a larger min-height (e.g., 400px) than the rendered creative (e.g., 250px),
|
|
624
|
+
// leaving visible empty space. We “tighten” the reserved min-height to the actual iframe/container height after load.
|
|
625
|
+
const _heightObsByPlaceholder = new Map();
|
|
626
|
+
|
|
627
|
+
function tightenEzoicHeightFor(id) {
|
|
628
|
+
try {
|
|
629
|
+
const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
630
|
+
if (!ph || !ph.isConnected) return;
|
|
631
|
+
|
|
632
|
+
const ad = ph.querySelector('span.ezoic-ad');
|
|
633
|
+
if (!ad) return;
|
|
634
|
+
|
|
635
|
+
// Prefer the safeframe/container size if present.
|
|
636
|
+
let h = 0;
|
|
637
|
+
const container = ad.querySelector('div[id$="__container__"]');
|
|
638
|
+
if (container) {
|
|
639
|
+
const r = container.getBoundingClientRect();
|
|
640
|
+
if (r && r.height) h = Math.max(h, r.height);
|
|
641
|
+
}
|
|
642
|
+
const iframe = ad.querySelector('iframe');
|
|
643
|
+
if (iframe) {
|
|
644
|
+
const r2 = iframe.getBoundingClientRect();
|
|
645
|
+
if (r2 && r2.height) h = Math.max(h, r2.height);
|
|
646
|
+
const attrH = parseInt(iframe.getAttribute('height') || '', 10);
|
|
647
|
+
if (Number.isFinite(attrH) && attrH > 0) h = Math.max(h, attrH);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Fall back to inner wrapper height.
|
|
651
|
+
if (!h) {
|
|
652
|
+
const inner = ad.firstElementChild;
|
|
653
|
+
if (inner) {
|
|
654
|
+
const r3 = inner.getBoundingClientRect();
|
|
655
|
+
if (r3 && r3.height) h = Math.max(h, r3.height);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if (!h || h < 10) return;
|
|
660
|
+
const px = `${Math.ceil(h)}px`;
|
|
661
|
+
|
|
662
|
+
// Override inline min-height with an inline !important value.
|
|
663
|
+
try { ad.style.setProperty('min-height', px, 'important'); } catch (e) {}
|
|
664
|
+
// Keep height auto so responsive creatives can expand if needed.
|
|
665
|
+
try { ad.style.setProperty('height', 'auto', 'important'); } catch (e) {}
|
|
666
|
+
} catch (e) {}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
function ensureHeightObserver(id) {
|
|
670
|
+
try {
|
|
671
|
+
if (_heightObsByPlaceholder.has(id)) return;
|
|
672
|
+
const ph = document.getElementById(`${PLACEHOLDER_PREFIX}${id}`);
|
|
673
|
+
if (!ph || !ph.isConnected) return;
|
|
674
|
+
|
|
675
|
+
const ro = (typeof ResizeObserver === 'function') ? new ResizeObserver(() => {
|
|
676
|
+
tightenEzoicHeightFor(id);
|
|
677
|
+
}) : null;
|
|
678
|
+
|
|
679
|
+
if (ro) {
|
|
680
|
+
const ad = ph.querySelector('span.ezoic-ad');
|
|
681
|
+
const container = ad && ad.querySelector && ad.querySelector('div[id$="__container__"]');
|
|
682
|
+
const iframe = ad && ad.querySelector && ad.querySelector('iframe');
|
|
683
|
+
try { if (container) ro.observe(container); } catch (e) {}
|
|
684
|
+
try { if (iframe) ro.observe(iframe); } catch (e) {}
|
|
685
|
+
try { if (ad) ro.observe(ad); } catch (e) {}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
_heightObsByPlaceholder.set(id, ro || true);
|
|
689
|
+
} catch (e) {}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
function scheduleTighten(id) {
|
|
693
|
+
// Run a couple of times (creatives may resize after initial load)
|
|
694
|
+
try { setTimeout(() => tightenEzoicHeightFor(id), 250); } catch (e) {}
|
|
695
|
+
try { setTimeout(() => tightenEzoicHeightFor(id), 1100); } catch (e) {}
|
|
696
|
+
try { ensureHeightObserver(id); } catch (e) {}
|
|
697
|
+
}
|
|
698
|
+
|
|
616
699
|
|
|
617
700
|
// ---------- preload / above-the-fold ----------
|
|
618
701
|
|
|
@@ -665,7 +748,9 @@ function startShow(id) {
|
|
|
665
748
|
// If already near the fold, arm & fire immediately
|
|
666
749
|
try {
|
|
667
750
|
const r = wrap.getBoundingClientRect();
|
|
668
|
-
|
|
751
|
+
// Fire early enough that the ad is likely ready when the user reaches it.
|
|
752
|
+
// During boost (fast scroll), preload even farther.
|
|
753
|
+
const screens = isBoosted() ? 6.0 : 4.0;
|
|
669
754
|
const h = (window.innerHeight || 800);
|
|
670
755
|
if (r.top < screens * h && r.bottom > -screens * h) {
|
|
671
756
|
armPlaceholder(wrap, id);
|
|
@@ -871,6 +956,14 @@ function startShow(id) {
|
|
|
871
956
|
// reset perf profile cache
|
|
872
957
|
state.perfProfile = null;
|
|
873
958
|
|
|
959
|
+
// disconnect any ResizeObservers used for height tightening
|
|
960
|
+
try {
|
|
961
|
+
for (const v of _heightObsByPlaceholder.values()) {
|
|
962
|
+
try { v && v.disconnect && v.disconnect(); } catch (e) {}
|
|
963
|
+
}
|
|
964
|
+
_heightObsByPlaceholder.clear();
|
|
965
|
+
} catch (e) {}
|
|
966
|
+
|
|
874
967
|
// reset state
|
|
875
968
|
state.cfg = null;
|
|
876
969
|
state.allTopics = [];
|
package/public/style.css
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
/* Minimal styling for injected Ezoic wrappers.
|
|
2
2
|
Spacing (margins/padding) is intentionally NOT forced here, because it can be
|
|
3
3
|
configured inside Ezoic and may vary by placement/device.
|
|
4
|
+
|
|
5
|
+
Goals:
|
|
6
|
+
- prevent flex/centering styles from parent lists from affecting ad internals
|
|
7
|
+
- reduce layout jank when iframes resize during scroll
|
|
4
8
|
*/
|
|
5
9
|
|
|
6
10
|
.ezoic-ad {
|
|
7
|
-
display: block;
|
|
11
|
+
display: block !important;
|
|
12
|
+
position: relative;
|
|
8
13
|
width: 100%;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
|
|
16
|
+
/* limit how far layout/paint changes propagate */
|
|
17
|
+
contain: layout paint style;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Keep ad content aligned to the top (avoids the "slides to bottom" look) */
|
|
21
|
+
.ezoic-ad iframe,
|
|
22
|
+
.ezoic-ad ins,
|
|
23
|
+
.ezoic-ad > div {
|
|
24
|
+
display: block !important;
|
|
25
|
+
vertical-align: top !important;
|
|
9
26
|
}
|