nodebb-plugin-ezoic-infinite 1.7.70 → 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 +23 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-ezoic-infinite",
3
- "version": "1.7.70",
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
@@ -99,7 +99,10 @@
99
99
  const _BOOL_TRUE = new Set([true, 'true', 1, '1', 'on']);
100
100
  const normBool = v => _BOOL_TRUE.has(v);
101
101
  // isFilled : exclut l'img reportline Ezoic (ezoicbwa.png) — faux positif
102
- 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]'))
103
106
  || !!(n?.querySelector('img:not([src*="ezoicbwa"]):not([src*="ezodn.com"])'));
104
107
 
105
108
  function mutate(fn) {
@@ -276,7 +279,21 @@
276
279
  return w;
277
280
  }
278
281
 
279
- 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) {
280
297
  if (!el?.insertAdjacentElement) return null;
281
298
  if (findWrap(key)) return null;
282
299
  if (S.mountedIds.has(id)) return null;
@@ -285,6 +302,7 @@
285
302
  mutate(() => el.insertAdjacentElement('afterend', w));
286
303
  S.mountedIds.add(id);
287
304
  S.wrapByKey.set(key, w);
305
+ watchFill(id, w);
288
306
  return w;
289
307
  }
290
308
 
@@ -406,7 +424,9 @@
406
424
  try {
407
425
  if (isBlocked()) { clearTimeout(timer); return release(); }
408
426
  const ph = document.getElementById(`${PH_PREFIX}${id}`);
409
- 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(); }
410
430
  const t = ts();
411
431
  if (t - (S.lastShow.get(id) ?? 0) < SHOW_THROTTLE_MS) { clearTimeout(timer); return release(); }
412
432
  S.lastShow.set(id, t);