1/** 2 * @file 3 * Comportement du bouton WhatsApp flottant. 4 * 5 * - Mobile : l'état suit la position de scroll. Le texte est affiché en haut 6 * de page et se replie en picto dès qu'on scrolle ; il réapparaît en 7 * revenant en haut. 8 * - Desktop : version complète sur la 1re page de la visite (mémorisée en 9 * sessionStorage), sinon le bouton démarre replié ; le texte réapparaît 10 * ensuite au survol du picto (géré en CSS). 11 * - Cible du clic selon l'appareil : application WhatsApp (wa.me) sur mobile, 12 * URL personnalisée sur desktop. 13 * - Visibilité selon l'appareil ciblé (mobile / desktop / les deux). 14 */ 15(function (Drupal, once) { 16 'use strict'; 17 18 var SESSION_KEY = 'wa_btn_seen'; 19 var SCROLL_THRESHOLD = 60; 20 21 /** 22 * Détecte un appareil de type mobile/tactile. 23 * 24 * @return {boolean} 25 */ 26 function isMobile() { 27 var coarse = window.matchMedia && window.matchMedia('(pointer: coarse)').matches; 28 var ua = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); 29 return Boolean(coarse || ua); 30 } 31 32 function expand(btn) { 33 btn.classList.add('is-full'); 34 btn.classList.remove('is-collapsed'); 35 } 36 37 function collapse(btn) { 38 btn.classList.add('is-collapsed'); 39 btn.classList.remove('is-full'); 40 } 41 42 Drupal.behaviors.whatsappButton = { 43 attach: function (context) { 44 once('whatsapp-button', '.wa-btn', context).forEach(function (btn) { 45 var mobile = isMobile(); 46 var devices = btn.getAttribute('data-wa-devices') || 'both'; 47 48 // Visibilité selon l'appareil ciblé. 49 if ((devices === 'mobile' && !mobile) || (devices === 'desktop' && mobile)) { 50 if (btn.parentNode) { 51 btn.parentNode.removeChild(btn); 52 } 53 return; 54 } 55 56 // Cible du clic. 57 var phone = btn.getAttribute('data-wa-phone'); 58 var desktopUrl = btn.getAttribute('data-wa-desktop-url'); 59 if (mobile && phone) { 60 btn.setAttribute('href', 'https://wa.me/' + phone); 61 } 62 else if (!mobile && desktopUrl) { 63 btn.setAttribute('href', desktopUrl); 64 } 65 else if (phone) { 66 // Pas d'URL desktop renseignée : repli sur WhatsApp Web. 67 btn.setAttribute('href', 'https://wa.me/' + phone); 68 } 69 70 // Mobile : l'état suit la position de scroll. Texte affiché en haut de 71 // page, replié dès qu'on scrolle, et réaffiché en revenant en haut. 72 if (mobile) { 73 var updateByScroll = function () { 74 if (window.pageYOffset > SCROLL_THRESHOLD) { 75 collapse(btn); 76 } 77 else { 78 expand(btn); 79 } 80 }; 81 updateByScroll(); 82 window.addEventListener('scroll', updateByScroll, { passive: true }); 83 return; 84 } 85 86 // Desktop : complet seulement sur la 1re page de la visite. 87 var seen = false; 88 try { 89 seen = sessionStorage.getItem(SESSION_KEY) === '1'; 90 } 91 catch (e) { 92 // sessionStorage indisponible : on affiche la version complète. 93 } 94 95 if (seen) { 96 collapse(btn); 97 return; 98 } 99 100 expand(btn); 101 try { 102 sessionStorage.setItem(SESSION_KEY, '1'); 103 } 104 catch (e) { 105 // Ignoré. 106 } 107 108 // Repli au premier scroll ; le texte réapparaît ensuite au survol (CSS). 109 var onScroll = function () { 110 if (window.pageYOffset > SCROLL_THRESHOLD) { 111 collapse(btn); 112 window.removeEventListener('scroll', onScroll); 113 } 114 }; 115 window.addEventListener('scroll', onScroll, { passive: true }); 116 }); 117 } 118 }; 119 120})(Drupal, once);
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.