PageSourceSearch

https://messanges40.fr/modules/mod_accessibility_widget/assets/js/accessibility.js?f03700

js messanges40.fr collected 2026-10-07 11:11:16 UTC 7,252 bytes, 210 lines download raw bytes

1(() => {
2  function initAccessibility() {
3    const toggle = document.getElementById('accessibility-toggle');
4    const menu = document.getElementById('accessibility-menu');
5    const contrast = document.getElementById('contrast-select');
6    const font = document.getElementById('font-select');
7    const lineheight = document.getElementById('lineheight-select');
8    const colorblind = document.getElementById('colorblindMode');
9    const resetBtn = document.getElementById('reset-accessibility');
10    
11    const announcer = document.getElementById('accessibility-announcer');
12    function announce(msg) {
13      if (announcer) announcer.textContent = msg;
14    }
15
16    if (!toggle || !menu) {
17      setTimeout(initAccessibility, 100);
18      return;
19    }
20    if (toggle.dataset.accessibilityInit) return;
21    toggle.dataset.accessibilityInit = true;
22
23    const WIDGET_SELECTOR = '#accessibility-widget';
24    let rotation = 0;
25
26    toggle.addEventListener('click', (e) => {
27      e.stopPropagation();
28      const isOpen = menu.classList.toggle('visible');
29      rotation += isOpen ? 360 : -360;
30      toggle.style.transform = `rotate(${rotation}deg) scale(1.1)`;
31      toggle.setAttribute('aria-expanded', isOpen);
32    });
33
34    document.addEventListener('click', (e) => {
35      if (!menu.contains(e.target) && !toggle.contains(e.target)) {
36        menu.classList.remove('visible');
37        toggle.setAttribute('aria-expanded', 'false');
38      }
39    });
40
41    document.addEventListener('keydown', (e) => {
42      if (e.key === 'Escape' && menu.classList.contains('visible')) {
43        menu.classList.remove('visible');
44        toggle.setAttribute('aria-expanded', 'false');
45      }
46    });
47
48    function loadState() {
49      try {
50        const saved = JSON.parse(localStorage.getItem('acc_prefs') || '{}');
51        return {
52          contrast: saved.contrast || 'default',
53          font: saved.font || 'default',
54          lineheight: saved.lineheight || 'default',
55          brightness: saved.brightness || 0,
56          colorblind: saved.colorblind || 'none'
57        };
58      } catch (e) {
59        return { contrast: 'default', font: 'default', lineheight: 'default', brightness: 0, colorblind: 'none' };
60      }
61    }
62
63    function saveState(state) {
64      try { localStorage.setItem('acc_prefs', JSON.stringify(state)); } catch(e){}
65    }
66
67    function applyState(state) {
68      document.body.classList.remove(
69        'contrast-high','contrast-invert',
70        'font-dyslexic','lineheight-large',
71        'assist-protanopia','assist-deuteranopia',
72        'assist-tritanopia','assist-achromatopsia'
73      );
74
75      if (state.contrast === 'high') document.body.classList.add('contrast-high');
76      if (state.contrast === 'invert') document.body.classList.add('contrast-invert');
77      if (state.font === 'dyslexic') document.body.classList.add('font-dyslexic');
78      if (state.lineheight === 'large') document.body.classList.add('lineheight-large');
79      if (state.colorblind && state.colorblind !== 'none') {
80        document.body.classList.add('assist-' + state.colorblind);
81      }
82
83      applyBrightness(state.brightness);
84    }
85
86    function parseRgbString(str) {
87      if (!str) return null;
88      const m = str.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([0-9.]+))?\)/);
89      if (!m) return null;
90      return { r: +m[1], g: +m[2], b: +m[3], a: m[4] !== undefined ? +m[4] : 1 };
91    }
92
93    function rgbObjToString(o) {
94      if (o.a !== undefined && o.a < 1) return `rgba(${o.r}, ${o.g}, ${o.b}, ${o.a})`;
95      return `rgb(${o.r}, ${o.g}, ${o.b})`;
96    }
97
98    function rgbToHsl(r,g,b){
99      r/=255; g/=255; b/=255;
100      const max=Math.max(r,g,b), min=Math.min(r,g,b);
101      let h=0,s=0,l=(max+min)/2;
102      if(max!==min){
103        const d=max-min;
104        s=l>0.5 ? d/(2-max-min) : d/(max+min);
105        switch(max){
106          case r: h=(g-b)/d + (g<b?6:0); break;
107          case g: h=(b-r)/d + 2; break;
108          case b: h=(r-g)/d + 4; break;
109        }
110        h/=6;
111      }
112      return [h,s,l];
113    }
114
115    function hslToRgb(h,s,l){
116      let r,g,b;
117      if(s===0) r=g=b=l;
118      else{
119        const hue2rgb=(p,q,t)=>{
120          if(t<0) t+=1;
121          if(t>1) t-=1;
122          if(t<1/6) return p+(q-p)*6*t;
123          if(t<1/2) return q;
124          if(t<2/3) return p+(q-p)*(2/3-t)*6;
125          return p;
126        };
127        const q=l<0.5?l*(1+s):l+s-l*s;
128        const p=2*l-q;
129        r=hue2rgb(p,q,h+1/3);
130        g=hue2rgb(p,q,h);
131        b=hue2rgb(p,q,h-1/3);
132      }
133      return [Math.round(r*255),Math.round(g*255),Math.round(b*255)];
134    }
135
136    function adjustLightness(rgbString, amount){
137      const p=parseRgbString(rgbString);
138      if(!p) return rgbString;
139
140      let [h,s,l]=rgbToHsl(p.r,p.g,p.b);
141
142      if(l <= 0.15 || l >= 0.85) return rgbString;
143
144      const DARK_SCALE=0.3,LIGHT_SCALE=0.9;
145      l += amount<0 ? (amount/100)*DARK_SCALE : (amount/100)*LIGHT_SCALE;
146      l=Math.max(0,Math.min(1,l));
147      const [nr,ng,nb]=hslToRgb(h,s,l);
148      return `rgb(${nr}, ${ng}, ${nb})`;
149    }
150
151    /* =======================================================
152       🔥 CORRECTION ICI : on ignore les éléments interactifs
153       ======================================================= */
154
155    function applyBrightness(amount){
156      document.querySelectorAll('*').forEach(el=>{
157        if(el.closest && el.closest(WIDGET_SELECTOR)) return;
158
159        // ❌ NE PAS toucher aux éléments interactifs
160        if (
161          el.matches('button, a, input, select, textarea') ||
162          el.closest('button, a, input, select, textarea') ||
163          el.classList.contains('btn') ||
164          el.classList.contains('sppb-btn') ||
165          el.getAttribute('role') === 'button'
166        ) {
167          return;
168        }
169
170        const style = getComputedStyle(el);
171
172        if(!el.dataset.originalColor && style.color)
173          el.dataset.originalColor = style.color;
174
175        if(!el.dataset.originalBg && style.backgroundColor)
176          el.dataset.originalBg = style.backgroundColor;
177
178        if(el.dataset.originalBg)
179          el.style.backgroundColor = adjustLightness(el.dataset.originalBg, amount);
180
181        if(el.dataset.originalColor)
182          el.style.color = adjustLightness(el.dataset.originalColor, amount);
183      });
184    }
185
186    const state=loadState();
187    applyState(state);
188
189    contrast?.addEventListener('change',()=>{state.contrast=contrast.value; applyState(state); saveState(state);});
190    font?.addEventListener('change',()=>{state.font=font.value; applyState(state); saveState(state);});
191    lineheight?.addEventListener('change',()=>{state.lineheight=lineheight.value; applyState(state); saveState(state);});
192    colorblind?.addEventListener('change',()=>{state.colorblind=colorblind.value; applyState(state); saveState(state);});
193
194    resetBtn?.addEventListener('click',()=> {
195      state.contrast='default';
196      state.font='default';
197      state.lineheight='default';
198      state.brightness=0;
199      state.colorblind='none';
200      applyState(state);
201      saveState(state);
202      applyBrightness(0);
203      announce('Préférences réinitialisées');
204    });
205  }
206
207  if(document.readyState==='loading')
208    document.addEventListener('DOMContentLoaded',initAccessibility);
209  else initAccessibility();
210})();

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.