PageSourceSearch

https://www.maville.com/design/js/cookiewall.js?version=202600766

js maville.com collected 2026-09-24 08:51:16 UTC 10,382 bytes, 284 lines download raw bytes

1/**
2 * Bandeau de reconsentement cookies — source unique desktop + mobile.
3 *
4 * Remplace le markup #r-cookies-wall qui était dupliqué dans les têtières, les
5 * pieds de page et les modèles mobiles, ainsi que la logique dupliquée entre
6 * design/js/commun.js et design/mob_js/scripts.js. Les libellés, le markup, le
7 * style et le comportement ne vivent plus qu'ici.
8 *
9 * Le bandeau s'affiche quand l'utilisateur a refusé les traceurs dans la CMP
10 * Didomi. Un seul niveau (plus de repli), un seul bouton qui renvoie vers la
11 * CMP (plus d'acceptation directe), et deux façons de le fermer :
12 * - la croix : masquage mémorisé 6 mois, durée de conservation du refus
13 *   recommandée par la CNIL, alignée sur celle du choix Didomi ;
14 * - 20 s d'affichage sans action : masquage mémorisé 48 h seulement, une
15 *   disparition automatique n'étant pas un choix du visiteur.
16 * Le défilement ne ferme pas le bandeau : en mobile, un simple geste le
17 * retirait avant qu'il soit lu.
18 *
19 * Un nouveau refus exprimé dans la CMP ré-arme le masquage en cours, avec sa
20 * durée, au lieu de réafficher le bandeau.
21 *
22 * Mise en conformité demandée par le comité RGPD (09/2026) : suppression du
23 * bandeau réduit, du bouton d'acceptation unique et des formulations
24 * incitatives assimilables à des dark patterns.
25 */
26(function () {
27	'use strict';
28
29	// La têtière et le pied de page chargent tous deux ce script : on ne garde
30	// que la première exécution.
31	if (window.MVI_CookieWall) {
32		return;
33	}
34
35	var TEXTES = {
36		titre: 'Pourquoi dire oui aux cookies ?',
37		message: 'Vous avez refusé les cookies. Ils nous permettent de vous proposer des contenus adaptés à votre lieu de vie, des publicités correspondant à vos centres d’intérêt et de mesurer l’audience du site. Vous pouvez modifier votre choix à tout moment.',
38		bouton: 'Modifier mes choix cookies',
39		fermer: 'Fermer ce message'
40	};
41
42	var FINALITE_DIDOMI = 'cookies';
43	var NOM_COOKIE = 'mvi_cw_hide';
44	var DELAI_AFFICHAGE = 20000; // avant disparition automatique, en ms
45	var DUREE_CROIX = 15768000;  // masquage après la croix : 6 mois, en secondes
46	var DUREE_DELAI = 172800;    // masquage après disparition automatique : 48 h, en secondes
47
48	// Valeur du cookie : la fermeture à l'origine du masquage. Le préfixe « 1 »
49	// fait lire ces valeurs comme un masquage par la version du 14/09/2026 (test
50	// indexOf('mvi_cw_hide=1')), qu'une page aux blocs encore en cache peut
51	// exécuter quelque temps après un déploiement.
52	var PAR_CROIX = '1-croix';
53	var PAR_DELAI = '1-delai';
54	// Valeur posée 6 mois par cette version quelle que soit la fermeture, le plus
55	// souvent le défilement : ramenée à un masquage court (voir plus bas).
56	var VALEUR_V1 = '1';
57
58	var bandeau = null;
59	var minuteur = null;
60
61	/* -------------------------------------------------- mémorisation du choix */
62
63	/**
64	 * Domaine de dépôt du cookie : partagé entre les villes du réseau
65	 * (rennes.maville.com, nantes.maville.com…) pour ne pas redemander à chaque
66	 * site. Ailleurs (préprod, local), cookie limité à l'hôte courant.
67	 */
68	function domaineCookie() {
69		return /(^|\.)maville\.com$/.test(location.hostname) ? '; domain=.maville.com' : '';
70	}
71
72	function lisCookie() {
73		var trouve = document.cookie.match(new RegExp('(?:^|;\\s*)' + NOM_COOKIE + '=([^;]*)'));
74		return trouve ? trouve[1] : '';
75	}
76
77	/** Fermeture à l'origine du masquage en cours (PAR_CROIX ou PAR_DELAI), '' sinon. */
78	function masquage() {
79		var valeur = lisCookie();
80		return PAR_CROIX === valeur || PAR_DELAI === valeur ? valeur : '';
81	}
82
83	function estMasque() {
84		return '' !== masquage();
85	}
86
87	/** Mémorise le masquage dû à la fermeture `par`, pour la durée qui lui correspond. */
88	function memoriseMasquage(par) {
89		var duree = PAR_CROIX === par ? DUREE_CROIX : DUREE_DELAI;
90		var secure = 'https:' === location.protocol ? '; secure' : '';
91		document.cookie = NOM_COOKIE + '=' + par + '; max-age=' + duree + '; path=/'
92			+ domaineCookie() + '; samesite=lax' + secure;
93	}
94
95	/* ------------------------------------------------------------------ style */
96
97	function injecteStyle() {
98		// Taille de base en px : le CSS mobile impose body{font-size:0}, et une
99		// base en em rendrait invisible le texte du bandeau (enfant de body).
100		var css = [
101			'.mvi-cw{position:fixed;bottom:0;left:0;width:100%;z-index:100000;',
102			'background-color:#FF4200;color:#fff;font-size:16px;',
103			'box-shadow:0 -4px 8px rgba(0,0,0,.2);box-sizing:border-box}',
104			'.mvi-cw *{box-sizing:border-box}',
105			'.mvi-cw__grid{display:flex;align-items:center;justify-content:space-between;',
106			'gap:16px;max-width:1190px;margin:auto;padding:16px 48px 16px 16px}',
107			'.mvi-cw__title{margin:0 0 4px;font-size:1.2em;line-height:1.3;color:#fff}',
108			'.mvi-cw__message{margin:0;font-size:.85em;line-height:1.4}',
109			'.mvi-cw__btn{flex:0 0 auto;display:inline-block;padding:10px 16px;',
110			'border:1px solid #fff;border-radius:8px;background-color:#fff;color:#FF4200;',
111			'font-size:.9em;font-weight:700;text-align:center;text-decoration:none;cursor:pointer}',
112			'.mvi-cw__btn:hover,.mvi-cw__btn:focus{background-color:#f2f2f2;color:#FF4200;text-decoration:none}',
113			'.mvi-cw__close{position:absolute;top:8px;right:8px;width:32px;height:32px;',
114			'padding:0;border:none;border-radius:50%;background-color:transparent;color:#fff;',
115			'font-size:24px;line-height:32px;
115cursor:pointer}',
116			'.mvi-cw__close:hover,.mvi-cw__close:focus{background-color:rgba(255,255,255,.2)}',
117			'@media (max-width:767px){',
118			'.mvi-cw{font-size:17px}',
119			'.mvi-cw__grid{flex-direction:column;align-items:stretch;gap:10px;padding:14px 16px 18px}',
120			'.mvi-cw__title{padding-right:32px}',
121			'.mvi-cw__message{font-size:.82em}',
122			'.mvi-cw__btn{width:100%}}'
123		].join('');
124
125		var style = document.createElement('style');
126		style.setAttribute('type', 'text/css');
127		style.appendChild(document.createTextNode(css));
128		document.getElementsByTagName('head')[0].appendChild(style);
129	}
130
131	/* ---------------------------------------------------------------- markup  */
132
133	function construit() {
134		var el = document.createElement('aside');
135		el.className = 'mvi-cw';
136		el.id = 'mvi-cw';
137		el.setAttribute('role', 'complementary');
138		el.setAttribute('aria-label', 'Information sur les cookies');
139
140		var grille = document.createElement('div');
141		grille.className = 'mvi-cw__grid';
142
143		var texte = document.createElement('div');
144		texte.className = 'mvi-cw__content';
145
146		var titre = document.createElement('h2');
147		titre.className = 'mvi-cw__title';
148		titre.appendChild(document.createTextNode(TEXTES.titre));
149
150		var message = document.createElement('p');
151		message.className = 'mvi-cw__message';
152		message.appendChild(document.createTextNode(TEXTES.message));
153
154		texte.appendChild(titre);
155		texte.appendChild(message);
156
157		var bouton = document.createElement('button');
158		bouton.className = 'mvi-cw__btn';
159		bouton.setAttribute('type', 'button');
160		bouton.appendChild(document.createTextNode(TEXTES.bouton));
161		bouton.onclick = function () {
162			if (window.Didomi && window.Didomi.preferences) {
163				window.Didomi.preferences.show();
164			}
165			return false;
166		};
167
168		var croix = document.createElement('button');
169		croix.className = 'mvi-cw__close';
170		croix.setAttribute('type', 'button');
171		croix.setAttribute('aria-label', TEXTES.fermer);
172		croix.setAttribute('title', TEXTES.fermer);
173		croix.innerHTML = '×';
174		croix.onclick = function () {
175			ferme();
176			return false;
177		};
178
179		grille.appendChild(texte);
180		grille.appendChild(bouton);
181		el.appendChild(grille);
182		el.appendChild(croix);
183
184		return el;
185	}
186
187	/* ------------------------------------------------------------ affichage  */
188
189	function affiche() {
190		if (bandeau || estMasque()) {
191			return;
192		}
193
194		injecteStyle();
195		bandeau = construit();
196		document.body.appendChild(bandeau);
197
198		minuteur = window.setTimeout(disparait, DELAI_AFFICHAGE);
199	}
200
201	/** Fermeture par la croix : choix explicite du visiteur, mémorisé 6 mois. */
202	function ferme() {
203		masqueSansMemoriser();
204		memoriseMasquage(PAR_CROIX);
205	}
206
207	/**
208	 * Disparition automatique : masquage court, le visiteur n'ayant rien choisi.
209	 * Sans mémorisation, le bandeau reviendrait à chaque page, ce que les
210	 * recommandations du comité RGPD visent précisément à supprimer. Une croix
211	 * cliquée entre-temps dans un autre onglet garde ses 6 mois.
212	 */
213	function disparait() {
214		masqueSansMemoriser();
215		if (PAR_CROIX !== masquage()) {
216			memoriseMasquage(PAR_DELAI);
217		}
218	}
219
220	function masqueSansMemoriser() {
221		window.clearTimeout(minuteur);
222
223		if (bandeau && bandeau.parentNode) {
224			bandeau.parentNode.removeChild(bandeau);
225		}
226		bandeau = null;
227	}
228
229	/* --------------------------------------------------------------- Didomi  */
230
231	// Cookie de la version du 14/09/2026 (voir VALEUR_V1) : sa fermeture est
232	// inconnue, il est traité comme une disparition automatique.
233	if (VALEUR_V1 === lisCookie()) {
234		memoriseMasquage(PAR_DELAI);
235	}
236
237	// Masquage lu dès le chargement, par sécurité. Au retrait du consentement, un
238	// tag GTM (GTM-M55VGXP, tag 117) supprime les cookies hors de sa liste
239	// blanche avant l'appel des listeners Didomi : si ce cookie en sortait,
240	// masquage() y lirait un cookie déjà effacé.
241	var masqueAuChargement = masquage();
242
243	function refuse() {
244		return window.Didomi && false === window.Didomi.getUserConsentStatusForPurpose(FINALITE_DIDOMI);
245	}
246
247	window.didomiOnReady = window.didomiOnReady || [];
248	window.didomiOnReady.push(function () {
249		if (refuse()) {
250			affiche();
251		}
252	});
253
254	window.didomiEventListeners = window.didomiEventListeners || [];
255	window.didomiEventListeners.push({
256		event: 'consent.changed',
257		listener: function () {
258			if (refuse()) {
259				// Refus exprimé depuis la CMP. Bandeau déjà masqué : on ré-arme ce
260				// masquage, avec sa durée, sans le réafficher. Cela recrée aussi
261				// le cookie s'il a été purgé par GTM (voir masqueAuChargement).
262				var par = masquage() || masqueAuChargement;
263				if (par) {
264					memoriseMasquage(par);
265					return;
266				}
267
268				// Sinon le bandeau a lieu d'être ; affiche ne fait rien s'il
269				// est encore à l'écran.
270				affiche();
271				return;
272			}
273
274			// Consentement donné : le bandeau n'a plus lieu d'être.
275			masqueSansMemoriser();
276		}
277	});
278
279	window.MVI_CookieWall = {
280		affiche: affiche,
281		ferme: ferme,
282		estMasque: estMasque
283	};
284}());

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.