1/* 83629-expert-unlock.js â Mur d'article gaté : CAPTURE D'E-MAIL, plus aucun déblocage. 2 3 REFONTE 16/08/2026. L'offre « 1 article EXPERT gratuit / semaine » est supprimée. Mesuré le 4 15/08 : elle divisait par deux le trafic vers /membership/ (110 -> 41 visites par semaine) et 5 par six les conversions du jour même, alors que 25 % des 909 abonnements résiliés du site 6 avaient duré moins d'un mois. Le compte gratuit reste proposé, pour ce qu'il donne vraiment 7 (veille, recueil, newsletter), jamais comme un moyen de lire l'article en cours. 8 9 â LE VERROU N'EST PAS ICI. Ce script ne fait plus aucun appel à /api/unlock ; c'est le worker 10 (front-83629, lib/expert-unlock.js) qui refuse de servir le contenu payant. Retirer un bouton 11 d'une page ne protège rien : l'endpoint reste appelable à la main. 12 13 â Ce script ne s'exécute que pour un membre FREE connecté (window.M83629_TIER === 'free'). 14 Tout libellé destiné au VISITEUR ANONYME vit dans partials/content-unlock.hbs, jamais ici. */ 15(function () { 16 'use strict'; 17 18 // Purge INCONDITIONNELLE du drapeau posé par la version précédente. Sans elle, les lecteurs 19 // inscrits avant la refonte conservaient dans leur navigateur une intention qui déclenchait 20 // un déblocage automatique au retour sur l'article. 21 try { localStorage.removeItem('m83629_unlock_intent'); } catch (e) {} 22 23 var gated = document.querySelector('.m83629-gated-body[data-post-slug]'); 24 if (!gated) return; 25 var slug = (gated.getAttribute('data-post-slug') || '').toLowerCase().replace(/[^a-z0-9-]/g, ''); 26 if (!slug) return; 27 var signupView = gated.querySelector('[data-signup-view]'); 28 var form = gated.querySelector('#m83629-signup-form'); 29 30 function ev(n) { try { if (typeof window.gtag_safe === 'function') window.gtag_safe(n, { slug: slug }); } catch (e) {} } 31 function articleTitle() { 32 var h = document.querySelector('.gh-post-page__title') || document.querySelector('article h1') || document.querySelector('h1'); 33 return ((h && h.textContent) || document.title || '').replace(/\s+/g, ' ').trim().slice(0, 180); 34 } 35 36 // VISITEUR : capter l'e-mail au submit pour l'e-mail de bienvenue (webhook member.added). 37 // NE bloque PAS Ghost (pas de preventDefault) : Portal gère l'inscription native en AJAX. 38 if (form) { 39 var submitBtn = form.querySelector('.m83629-signup__btn'); 40 form.addEventListener('submit', function () { 41 try { 42 var input = form.querySelector('[data-members-email]'); 43 var email = input ? String(input.value || '').trim() : ''; 44 if (email) { 45 fetch('/api/unlock-intent', { 46 method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, 47 body: JSON.stringify({ email: email, slug: slug, title: articleTitle() }) 48 }).catch(function () {}); 49 } 50 // Nom d'événement CONSERVà volontairement : il porte la série depuis juillet, la renommer 51 // couperait l'historique au moment précis où l'on veut mesurer l'effet de la refonte. 52 ev('expert_unlock_signup_submit'); 53 // Retour visuel obligatoire : Portal traite l'inscription en AJAX, sans rechargement. 54 // Mesuré 08-09/08/2026 : sans ce retour, 24 soumissions pour 5 personnes (on reclique). 55 if (!form.classList.contains('success')) { 56 form.classList.add('success'); 57 if (input) input.disabled = true; 58 if (submitBtn) submitBtn.disabled = true; 59 if (submitBtn) submitBtn.textContent = 'Lien envoyé â'; 60 var msg = document.createElement('p'); 61 msg.className = 'm83629-signup__success'; 62 msg.textContent = email 63 ? 'Compte créé. Vérifiez votre boîte mail (' + email + ') et cliquez sur le lien pour lâactiver.' 64 : 'Compte créé. Vérifiez votre boîte mail et cliquez sur le lien pour lâactiver.'; 65 form.parentNode.insertBefore(msg, form.nextSibling); 66 } 67 } catch (e) {} 68 }); 69 } 70 71 // Un membre FREE est déjà inscrit : lui proposer de créer un compte n'a aucun sens. On masque 72 // le bloc secondaire ; le bouton EXPERT du mur (SSR) reste seul, ce qui est le but recherché. 73 var n = 0; 74 (function wait() { 75 if (typeof window.M83629_TIER !== 'undefined' && window.M83629_TIER !== null) { 76 if (window.M83629_TIER === 'free' && signupView) { 77 signupView.hidden = true; 78 ev('expert_unlock_free_wall_shown'); 79 } 80 return; 81 } 82 if (n++ > 40) return; // ~4 s 83 setTimeout(wait, 100); 84 })(); 85})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.