nodebb-plugin-ezoic-infinite 1.7.69 → 1.7.71

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/public/client.js +27 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.7.69",
3
+ "version": "1.7.71",
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
@@ -40,8 +40,10 @@
40
40
  const SHOW_THROTTLE_MS = 900; // anti-spam showAds() par id
41
41
  const BURST_COOLDOWN_MS = 200; // délai min entre deux bursts
42
42
 
43
- const IO_MARGIN_DESKTOP = '800px 0px 800px 0px';
44
- const IO_MARGIN_MOBILE = '1200px 0px 1200px 0px';
43
+ // Marge asymétrique : précharge 1200px en bas, 0px en haut.
44
+ // Évite que AMP charge une pub déjà sortie du viewport vers le haut.
45
+ const IO_MARGIN_DESKTOP = '0px 0px 1200px 0px';
46
+ const IO_MARGIN_MOBILE = '0px 0px 1500px 0px';
45
47
 
46
48
  const SEL = {
47
49
  post: '[component="post"][data-pid]',
@@ -97,7 +99,10 @@
97
99
  const _BOOL_TRUE = new Set([true, 'true', 1, '1', 'on']);
98
100
  const normBool = v => _BOOL_TRUE.has(v);
99
101
  // isFilled : exclut l'img reportline Ezoic (ezoicbwa.png) — faux positif
100
- const isFilled = n => !!(n?.querySelector('iframe, ins, video, [data-google-container-id]'))
102
+ // data-ez-filled : marqué par watchFill() dès qu'Ezoic touche au placeholder
103
+ // (nécessaire pour les pubs AMP dont l'iframe est cross-origin et invisible)
104
+ const isFilled = n => !!(n?.closest?.('.nodebb-ezoic-wrap')?.getAttribute('data-ez-filled'))
105
+ || !!(n?.querySelector('iframe, ins, video, [data-google-container-id]'))
101
106
  || !!(n?.querySelector('img:not([src*="ezoicbwa"]):not([src*="ezodn.com"])'));
102
107
 
103
108
  function mutate(fn) {
@@ -274,7 +279,21 @@
274
279
  return w;
275
280
  }
276
281
 
277
- function insertAfter(el, id, klass, key) {
282
+ function watchFill(id, wrap) {
283
+ // Ezoic injecte du contenu dans le placeholder — on marque le wrap
284
+ // dès la première mutation, même pour les iframes AMP cross-origin.
285
+ const ph = document.getElementById(`${PH_PREFIX}${id}`);
286
+ if (!ph) return;
287
+ const obs = new MutationObserver(() => {
288
+ if (ph.childElementCount > 0 || ph.innerHTML.length > 20) {
289
+ wrap.setAttribute('data-ez-filled', '1');
290
+ obs.disconnect();
291
+ }
292
+ });
293
+ obs.observe(ph, { childList: true, subtree: true, attributes: true });
294
+ }
295
+
296
+ function insertAfter(el, id, klass, key) {
278
297
  if (!el?.insertAdjacentElement) return null;
279
298
  if (findWrap(key)) return null;
280
299
  if (S.mountedIds.has(id)) return null;
@@ -283,6 +302,7 @@
283
302
  mutate(() => el.insertAdjacentElement('afterend', w));
284
303
  S.mountedIds.add(id);
285
304
  S.wrapByKey.set(key, w);
305
+ watchFill(id, w);
286
306
  return w;
287
307
  }
288
308
 
@@ -404,7 +424,9 @@
404
424
  try {
405
425
  if (isBlocked()) { clearTimeout(timer); return release(); }
406
426
  const ph = document.getElementById(`${PH_PREFIX}${id}`);
407
- if (!ph?.isConnected || isFilled(ph)) { clearTimeout(timer); return release(); }
427
+ if (!ph?.isConnected) { clearTimeout(timer); return release(); }
428
+ const wrap = ph.closest?.(`.${WRAP_CLASS}`);
429
+ if (isFilled(ph) || wrap?.getAttribute('data-ez-filled')) { clearTimeout(timer); return release(); }
408
430
  const t = ts();
409
431
  if (t - (S.lastShow.get(id) ?? 0) < SHOW_THROTTLE_MS) { clearTimeout(timer); return release(); }
410
432
  S.lastShow.set(id, t);