PageSourceSearch

https://www.commune-nointel.fr/wp-content/plugins/hob-rgpd/assets/js/front.js?ver=1781167964

js commune-nointel.fr collected 2026-10-03 02:46:41 UTC 8,626 bytes, 299 lines download raw bytes

1/**
2 * HOB-RGPD — logique de consentement côté client.
3 *
4 * Transpose mod_hob_rgpd/tmpl/default.js (CLAUDE.md §3.3) avec deux améliorations :
5 *  - le consentement est indexé sur la clé de service (keyname), pas un id numérique ;
6 *  - les scripts neutralisés par le blocker sont réactivés dynamiquement, sans
7 *    rechargement de page (CLAUDE.md §7).
8 *
9 * @package HobRgpd
10 */
11( function () {
12	'use strict';
13
14	var config = window.hobRgpdConfig || { cookieName: 'hobConsentPrefs', cookieMaxAge: 31536000 };
15
16	var banner = document.getElementById( 'hob-rgpd-banner' );
17	var popup = document.getElementById( 'hob-rgpd-popup' );
18	var settingsIcon = document.getElementById( 'hob-rgpd-settings-icon' );
19	var toggles = Array.prototype.slice.call( document.querySelectorAll( '.hob-rgpd-toggle' ) );
20
21	/**
22	 * Lit la valeur d'un cookie.
23	 *
24	 * @param {string} name Nom du cookie.
25	 * @return {string|null}
26	 */
27	function readCookie( name ) {
28		var match = document.cookie.match( '(?:^|; )' + name.replace( /([.$?*|{}()\[\]\\\/+^])/g, '\\$1' ) + '=([^;]*)' );
29		return match ? match[ 1 ] : null;
30	}
31
32	// Services réellement actifs sur la page (le serveur n'a pas bloqué ceux à true au
33	// chargement, + ceux qu'on réactive dynamiquement ensuite). Sert à savoir si un choix
34	// RETIRE un service déjà chargé (→ rechargement nécessaire).
35	var activeServices = ( function () {
36		var out = {};
37		try {
38			var raw = readCookie( config.cookieName );
39			var prefs = raw ? JSON.parse( atob( raw ) ) : {};
40			Object.keys( prefs ).forEach( function ( key ) {
41				if ( prefs[ key ] ) {
42					out[ key ] = true;
43				}
44			} );
45		} catch ( e ) {} // eslint-disable-line no-empty
46		return out;
47	} )();
48
49	/**
50	 * Écrit le cookie de préférences lu par le serveur : base64(JSON {keyname:bool}).
51	 *
52	 * @param {Object} prefs Préférences par clé de service.
53	 */
54	function writeConsentCookie( prefs ) {
55		var encoded = btoa( JSON.stringify( prefs ) );
56		document.cookie = config.cookieName + '=' + encoded + ';path=/;max-age=' + config.cookieMaxAge + ';SameSite=Lax';
57	}
58
59	/**
60	 * Construit les préférences à partir de l'état courant des toggles.
61	 *
62	 * @return {Object}
63	 */
64	function prefsFromToggles() {
65		var prefs = {};
66		toggles.forEach( function ( input ) {
67			prefs[ input.dataset.serviceKey ] = input.checked;
68		} );
69		return prefs;
70	}
71
72	/**
73	 * Réactive les scripts/iframes neutralisés des services consentis.
74	 *
75	 * @param {Object} prefs Préférences par clé de service.
76	 */
77	function enableConsentedServices( prefs ) {
78		Object.keys( prefs ).forEach( function ( key ) {
79			if ( ! prefs[ key ] ) {
80				return;
81			}
82			var nodes = document.querySelectorAll( '[data-hob-service="' + key + '"]' );
83			Array.prototype.slice.call( nodes ).forEach( reactivateNode );
84			// Ce service est désormais actif sur la page.
85			activeServices[ key ] = true;
86		} );
87	}
88
89	/**
90	 * Reconstruit un nœud neutralisé en élément actif.
91	 *
92	 * @param {Element} el Élément neutralisé.
93	 */
94	function reactivateNode( el ) {
95		var tag = el.tagName.toLowerCase();
96
97		if ( 'script' === tag ) {
98			var script = document.createElement( 'script' );
99			Array.prototype.slice.call( el.attributes ).forEach( function ( attr ) {
100				if ( 'type' === attr.name || 'data-hob-service' === attr.name ) {
101					return;
102				}
103				if ( 'data-hob-src' === attr.name ) {
104					script.src = attr.value;
105				} else {
106					script.setAttribute( attr.name, attr.value );
107				}
108			} );
109			if ( ! el.getAttribute( 'data-hob-src' ) ) {
110				script.text = el.textContent;
111			}
112			el.parentNode.replaceChild( script, el );
113			return;
114		}
115
116		// iframe ou autre tag porteur de data-hob-src.
117		var src = el.getAttribute( 'data-hob-src' );
118		if ( src ) {
119			el.setAttribute( 'src', src );
120			el.removeAttribute( 'data-hob-src' );
121		}
122		el.removeAttribute( 'data-hob-service' );
123	}
124
125	/**
126	 * Applique un consentement complet (toggles + cookie + réactivation).
127	 *
128	 * @param {Object} prefs Préférences par clé de service.
129	 * @param {string} mode  'accepted' | 'rejected' | 'custom'.
130	 */
131	function applyConsent( prefs, mode ) {
132		try {
133			localStorage.setItem( 'hobConsent', mode );
134			localStorage.setItem( 'hobServicePrefs', JSON.stringify( prefs ) );
135		} catch ( e ) {
136			// localStorage indisponible (mode privé) : on continue avec le cookie.
137		}
138
139		writeConsentCookie( prefs );
140
141		// Si on RETIRE le consentement d'un service déjà actif (script/iframe chargé),
142		// on ne peut pas le décharger proprement → rechargement de la page.
143		var withdrawing = Object.keys( activeServices ).some( function ( key ) {
144			return true === activeServices[ key ] && false === prefs[ key ];
145		} );
146
147		if ( withdrawing ) {
148			window.location.reload();
149			return;
150		}
151
152		// Sinon (ajout de consentement) : réactivation dynamique, sans reload.
153		enableConsentedServices( prefs );
154		hideBanner();
155		closePopup();
156	}
157
158	/** Accepte tous les services. */
159	function acceptAll() {
160		var prefs = {};
161		toggles.forEach( function ( input ) {
162			input.checked = true;
163			prefs[ input.dataset.serviceKey ] = true;
164		} );
165		applyConsent( prefs, 'accepted' );
166	}
167
168	/** Refuse tous les services. */
169	function rejectAll() {
170		var prefs = {};
171		toggles.forEach( function ( input ) {
172			input.checked = false;
173			prefs[ input.dataset.serviceKey ] = false;
174		} );
175		applyConsent( prefs, 'rejected' );
176	}
177
178	/** Enregistre les choix individuels. */
179	function savePreferences() {
180		applyConsent( prefsFromToggles(), 'custom' );
181	}
182
183	/** Cache le bandeau et montre l'icône de réglages. */
184	function hideBanner() {
185		if ( banner ) {
186			banner.hidden = true;
187		}
188		if ( settingsIcon ) {
189			settingsIcon.hidden = false;
190		}
191	}
192
193	/** Ouvre la popup de préférences. */
194	function openPopup() {
195		if ( popup ) {
196			popup.hidden = false;
197		}
198	}
199
200	/** Ferme la popup de préférences. */
201	function closePopup() {
202		if ( popup ) {
203			popup.hidden = true;
204		}
205	}
206
207	/** Restaure l'état des toggles depuis les préférences enregistrées. */
208	function restoreSavedState() {
209		var consent = null;
210		var saved = {};
211		try {
212			consent = localStorage.getItem( 'hobConsent' );
213			saved = JSON.parse( localStorage.getItem( 'hobServicePrefs' ) || '{}' );
214		} catch ( e ) {
215			return false;
216		}
217
218		if ( ! consent ) {
219			return false;
220		}
221
222		toggles.forEach( function ( input ) {
223			input.checked = !! saved[ input.dataset.serviceKey ];
224		} );
225
226		// Réactive ce qui a déjà été consenti (utile si le serveur n'a pas encore vu le cookie).
227		enableConsentedServices( saved );
228		hideBanner();
229		return true;
230	}
231
232	/** Gestion des onglets de la popup. */
233	function initTabs() {
234		var tabs = Array.prototype.slice.call( document.querySelectorAll( '.hob-rgpd-tab' ) );
235		tabs.forEach( function ( tab ) {
236			tab.addEventListener( 'click', function () {
237				var target = tab.getAttribute( 'data-tab' );
238
239				tabs.forEach( function ( t ) {
240					t.classList.remove( 'is-active' );
241					t.setAttribute( 'aria-selected', 'false' );
242				} );
243				tab.classList.add( 'is-active' );
244				tab.setAttribute( 'aria-selected', 'true' );
245
246				Array.prototype.slice.call( document.querySelectorAll( '.hob-rgpd-panel' ) ).forEach( function ( panel ) {
247					var match = panel.id === target;
248					panel.classList.toggle( 'is-active', match );
249					panel.hidden = ! match;
250				} );
251			} );
252		} );
253	}
254
255	/** Branche tous les événements. */
256	function bindEvents() {
257		Array.prototype.slice.call( document.querySelectorAll( '.hob-accept-all' ) ).forEach( function ( btn ) {
258			btn.addEventListener( 'click', acceptAll );
259		} );
260		Array.prototype.slice.call( document.querySelectorAll( '.hob-reject-all' ) ).forEach( function ( btn ) {
261			btn.addEventListener( 'click', rejectAll );
262		} );
263		Array.prototype.slice.call( document.querySelectorAll( '.hob-manage' ) ).forEach( function ( btn ) {
264			btn.addEventListener( 'click', openPopup );
265		} );
266
267		var closeBtn = document.querySelector( '.hob-rgpd-popup-close' );
268		if ( closeBtn ) {
269			closeBtn.addEventListener( 'click', closePopup );
270		}
271		var saveBtn = document.querySelector( '.hob-save' );
272		if ( saveBtn ) {
273			saveBtn.addEventListener( 'click', savePreferences );
274		}
275		if ( settingsIcon ) {
276			settingsIcon.addEventListener( 'click', openPopup );
277		}
278
279		document.addEventListener( 'keydown', function ( event ) {
280			if ( 'Escape' === event.key ) {
281				closePopup();
282			}
283		} );
284
285		if ( popup ) {
286			popup.addEventListener( 'click', function ( event ) {
287				if ( event.target === popup ) {
288					closePopup();
289				}
290			} );
291		}
292	}
293
294	document.addEventListener( 'DOMContentLoaded', function () {
295		initTabs();
296		bindEvents();
297		restoreSavedState();
298	} );
299} )();

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.