nodebb-plugin-ezoic-infinite 1.5.73 → 1.5.74

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.5.73",
3
+ "version": "1.5.74",
4
4
  "description": "Production-ready Ezoic infinite ads integration for NodeBB 4.x",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/public/client.js CHANGED
@@ -44,37 +44,100 @@ function isFilledNode(node) {
44
44
  return !!(node && node.querySelector && node.querySelector('iframe, ins, img, video, [data-google-container-id]'));
45
45
  }
46
46
 
47
- // Ezoic often sets inline min-height (e.g. 400px) for adaptive placements.
48
- // In NodeBB topics/messages this creates visible empty space under 250px creatives.
49
- // We tighten the outermost Ezoic container to the actual creative height once it exists.
47
+ // Ezoic injects inline `min-height:400px !important` on one or more nested wrappers.
48
+ // If the creative is 250px, this leaves ~150px empty space. Because it's inline+important,
49
+ // CSS alone cannot fix it reliably we must rewrite the inline style.
50
50
  function tightenEzoicMinHeight(wrap) {
51
51
  try {
52
52
  if (!wrap || !wrap.querySelector) return;
53
- const outer = wrap.querySelector('.ezoic-ad-adaptive') ||
54
- wrap.querySelector('.ezoic-ad[style*="min-height"]') ||
55
- wrap.querySelector('.ezoic-ad');
56
- if (!outer) return;
57
53
 
58
- const iframes = outer.querySelectorAll('iframe');
54
+ const iframes = wrap.querySelectorAll('iframe');
59
55
  if (!iframes || !iframes.length) return;
60
56
 
61
- let h = 0;
57
+ // Find the closest "big" ezoic container that carries the 400px min-height.
58
+ const firstIframe = iframes[0];
59
+ let refNode = null;
60
+ let p = firstIframe && firstIframe.parentElement;
61
+ while (p && p !== wrap) {
62
+ if (p.classList && p.classList.contains('ezoic-ad')) {
63
+ const st = (p.getAttribute('style') || '').toLowerCase();
64
+ if (st.includes('min-height:400') || st.includes('min-height: 400') || st.includes('min-height:400px')) {
65
+ refNode = p;
66
+ break;
67
+ }
68
+ }
69
+ p = p.parentElement;
70
+ }
71
+ if (!refNode) {
72
+ refNode = wrap.querySelector('.ezoic-ad-adaptive') || wrap.querySelector('.ezoic-ad') || wrap;
73
+ }
74
+
75
+ let refTop = 0;
76
+ try { refTop = refNode.getBoundingClientRect().top; } catch (e) { refTop = 0; }
77
+
78
+ // Compute the rendered height needed inside refNode (visible iframes only).
79
+ let maxBottom = 0;
62
80
  iframes.forEach((f) => {
63
- const ah = parseInt(f.getAttribute('height') || '0', 10);
64
- const oh = f.offsetHeight || 0;
65
- h = Math.max(h, ah, oh);
81
+ if (!f || !f.getBoundingClientRect) return;
82
+ const rect = f.getBoundingClientRect();
83
+ if (rect.width <= 1 || rect.height <= 1) return;
84
+ const bottom = rect.bottom - refTop;
85
+ maxBottom = Math.max(maxBottom, bottom);
66
86
  });
67
- if (!h) return;
68
87
 
69
- // Override inline min-height with a newer inline important.
70
- try { outer.style.setProperty('min-height', h + 'px', 'important'); } catch (e) { outer.style.minHeight = h + 'px'; }
71
- try { outer.style.setProperty('height', 'auto', 'important'); } catch (e) {}
88
+ // Fallback to attr/offset if layout metrics are not available.
89
+ if (!maxBottom) {
90
+ iframes.forEach((f) => {
91
+ const ah = parseInt(f.getAttribute('height') || '0', 10);
92
+ const oh = f.offsetHeight || 0;
93
+ maxBottom = Math.max(maxBottom, ah, oh);
94
+ });
95
+ }
96
+ if (!maxBottom) return;
97
+
98
+ // Account for the Ezoic badge (reportline) which is absolutely positioned.
99
+ const report = refNode.querySelector('.reportline');
100
+ if (report && report.offsetHeight) {
101
+ maxBottom += report.offsetHeight;
102
+ }
103
+
104
+ const h = Math.max(1, Math.ceil(maxBottom));
105
+
106
+ const tightenNode = (node) => {
107
+ if (!node || !node.style) return;
108
+ try { node.style.setProperty('min-height', h + 'px', 'important'); } catch (e) { node.style.minHeight = h + 'px'; }
109
+ try { node.style.setProperty('height', 'auto', 'important'); } catch (e) {}
110
+ try { node.style.setProperty('line-height', '0', 'important'); } catch (e) {}
111
+ };
112
+
113
+ // Tighten refNode and any ancestor ezoic-ad nodes with the problematic min-height.
114
+ let cur = refNode;
115
+ while (cur && cur !== wrap) {
116
+ if (cur.classList && cur.classList.contains('ezoic-ad')) {
117
+ const st = (cur.getAttribute('style') || '').toLowerCase();
118
+ if (st.includes('min-height:400') || st.includes('min-height: 400') || st.includes('min-height:400px')) {
119
+ tightenNode(cur);
120
+ }
121
+ }
122
+ cur = cur.parentElement;
123
+ }
124
+ tightenNode(refNode);
125
+
126
+ // Tighten any nested wrappers that also have the 400px min-height inline.
127
+ refNode.querySelectorAll('.ezoic-ad[style*="min-height"], .ezoic-ad-adaptive').forEach((n) => {
128
+ const st = (n.getAttribute('style') || '').toLowerCase();
129
+ if (st.includes('min-height:400') || st.includes('min-height: 400') || st.includes('min-height:400px')) {
130
+ tightenNode(n);
131
+ }
132
+ });
72
133
 
73
134
  // Mobile friendliness: avoid giant fixed widths causing overflow/reflow.
74
135
  if (isMobile()) {
75
- try { outer.style.setProperty('width', '100%', 'important'); } catch (e) {}
76
- try { outer.style.setProperty('max-width', '100%', 'important'); } catch (e) {}
77
- try { outer.style.setProperty('min-width', '0', 'important'); } catch (e) {}
136
+ [refNode].forEach((n) => {
137
+ try { n.style.setProperty('width', '100%', 'important'); } catch (e) {}
138
+ try { n.style.setProperty('max-width', '100%', 'important'); } catch (e) {}
139
+ try { n.style.setProperty('min-width', '0', 'important'); } catch (e) {}
140
+ });
78
141
  }
79
142
  } catch (e) {}
80
143
  }
package/public/style.css CHANGED
@@ -71,3 +71,11 @@
71
71
 
72
72
  /* Ensure Ezoic reportline doesn't affect layout */
73
73
  .nodebb-ezoic-wrap .reportline{position:absolute!important;}
74
+
75
+ /* Ezoic sometimes injects `position: sticky` inside placements. In long NodeBB topics,
76
+ this can create "gliding" and sudden disappear/reappear effects while scrolling.
77
+ We neutralize sticky positioning *inside our injected wrappers* only. */
78
+ .nodebb-ezoic-wrap .ezads-sticky-intradiv {
79
+ position: static !important;
80
+ top: auto !important;
81
+ }