accessibility-widgets 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +85 -35
  2. package/package.json +1 -1
  3. package/widget.js +278 -46
package/README.md CHANGED
@@ -4,9 +4,15 @@
4
4
  [![License: GPL](https://img.shields.io/badge/License-GPL-blue.svg)](https://opensource.org/licenses/GPL-3.0)
5
5
  [![CDN](https://img.shields.io/badge/CDN-unpkg-orange.svg)](https://unpkg.com/accessibility-widgets)
6
6
 
7
+ <a href="https://github.com/sponsors/sinanisler">
8
+ <img src="https://img.shields.io/badge/Consider_Supporting_My_Projects_❤-GitHub-d46" width="300" height="auto" />
9
+ </a>
10
+ <br><br>
11
+
7
12
  A comprehensive, zero-dependency accessibility widget that enhances web accessibility for all users. This lightweight, single-file JavaScript solution provides 14+ accessibility features to make your website instantly more inclusive and compliant with WCAG 2.1 AA, Section 508, and EN 301 549 standards.
13
+ <br><br>
8
14
 
9
- <img width="1277" height="989" alt="image" src="https://github.com/user-attachments/assets/f6abe245-9d92-4f53-941c-06b77bde1cac" />
15
+ <img width="1793" height="1028" alt="image" src="https://github.com/user-attachments/assets/610138f5-e60d-4297-b5e3-ea040f361209" />
10
16
 
11
17
 
12
18
  ## ⚡ Quick Start
@@ -151,28 +157,35 @@ window.ACCESSIBILITY_WIDGET_CONFIG = {
151
157
 
152
158
  ```javascript
153
159
  window.ACCESSIBILITY_WIDGET_CONFIG = {
154
- // ===== Feature Toggles =====
155
- enableHighContrast: true,
156
- enableBiggerText: true,
157
- enableTextSpacing: true,
158
- enablePauseAnimations: true,
159
- enableHideImages: true,
160
- enableDyslexiaFont: true,
161
- enableBiggerCursor: true,
162
- enableLineHeight: true,
163
- enableTextAlign: true,
164
- enableScreenReader: true,
165
- enableVoiceControl: true,
166
- enableFontSelection: true,
167
- enableColorFilter: true,
160
+ // ===== Core Feature Toggles =====
161
+ enableHighContrast: true, // 3-level high contrast mode
162
+ enableBiggerText: true, // 4-level text size control
163
+ enableTextSpacing: true, // 3-level text spacing
164
+ enablePauseAnimations: true, // Pause animations & reduced motion
165
+ enableHideImages: true, // Hide images toggle
166
+ enableDyslexiaFont: true, // Dyslexia-friendly fonts
167
+ enableBiggerCursor: true, // Large cursor
168
+ enableLineHeight: true, // 3-level line height (2em, 3em, 4em)
169
+ enableTextAlign: true, // Text alignment (left, center, right)
170
+
171
+ // ===== Advanced Features =====
172
+ enableScreenReader: true, // Built-in text-to-speech
173
+ enableVoiceControl: true, // Voice command control
174
+ enableFontSelection: true, // Font family selection
175
+ enableColorFilter: true, // Color blindness filters
168
176
 
169
177
  // ===== Widget Layout =====
170
178
  widgetWidth: '440px',
171
- widgetColumns: 2, // Grid columns (1-4)
179
+
180
+ // ===== Grid Configuration =====
181
+ gridLayout: {
182
+ columns: '1fr 1fr', // Default 2-column grid
183
+ gap: '10px' // Gap between grid items
184
+ },
172
185
 
173
186
  // ===== Position =====
174
187
  widgetPosition: {
175
- side: 'right', // 'left' or 'right'
188
+ side: 'right', // 'left' or 'right'
176
189
  right: '20px',
177
190
  left: '20px',
178
191
  bottom: '20px'
@@ -180,11 +193,11 @@ window.ACCESSIBILITY_WIDGET_CONFIG = {
180
193
 
181
194
  // ===== Colors =====
182
195
  colors: {
183
- primary: '#1663d7',
184
- secondary: '#ffffff',
185
- optionBg: '#ffffff',
186
- optionText: '#333333',
187
- optionIcon: '#000000'
196
+ primary: '#1663d7', // Header bg, main button, active borders
197
+ secondary: '#ffffff', // Main button icon, header text
198
+ optionBg: '#ffffff', // Option button background
199
+ optionText: '#333333', // Option button text
200
+ optionIcon: '#000000' // Option button icons
188
201
  },
189
202
 
190
203
  // ===== Button Styling =====
@@ -195,17 +208,37 @@ window.ACCESSIBILITY_WIDGET_CONFIG = {
195
208
  shadow: '0 4px 8px rgba(0, 0, 0, 0.2)'
196
209
  },
197
210
 
211
+ // ===== Menu Styling =====
212
+ menu: {
213
+ headerHeight: '70px',
214
+ padding: '0 10px 10px 10px',
215
+ optionPadding: '20px 10px',
216
+ optionMargin: '10px',
217
+ borderRadius: '8px',
218
+ fontSize: '16px',
219
+ titleFontSize: '16px',
220
+ closeButtonSize: '44px'
221
+ },
222
+
198
223
  // ===== Typography =====
199
224
  typography: {
200
225
  fontFamily: 'Arial, sans-serif',
201
226
  fontSize: '17px',
202
227
  titleFontSize: '22px',
203
- titleFontWeight: '700'
228
+ titleFontWeight: '700',
229
+ lineHeight: '1'
230
+ },
231
+
232
+ // ===== Animation =====
233
+ animation: {
234
+ transition: '0.2s',
235
+ hoverScale: '1.05'
204
236
  },
205
237
 
206
238
  // ===== Internationalization (i18n) =====
207
239
  lang: {
208
240
  accessibilityMenu: 'Accessibility Menu',
241
+ closeAccessibilityMenu: 'Close Accessibility Menu',
209
242
  accessibilityTools: 'Accessibility Tools',
210
243
  resetAllSettings: 'Reset All Settings',
211
244
  screenReader: 'Screen Reader',
@@ -220,21 +253,38 @@ window.ACCESSIBILITY_WIDGET_CONFIG = {
220
253
  colorFilter: 'Color Filter',
221
254
  textAlign: 'Text Align',
222
255
  textSize: 'Text Size',
223
- highContrast: 'High Contrast'
256
+ highContrast: 'High Contrast',
257
+ defaultFont: 'Default Font',
258
+ noFilter: 'No Filter',
259
+ default: 'Default',
260
+ screenReaderOn: 'Screen reader on',
261
+ screenReaderOff: 'Screen reader off',
262
+ voiceControlActivated: 'Voice control activated',
263
+ notSupportedBrowser: 'is not supported in this browser',
264
+ close: 'Close',
265
+ reset: 'Reset',
266
+ saturation: 'Saturation',
267
+ selectLanguage: 'Select Language'
224
268
  },
225
269
 
226
- // ===== Voice Commands =====
270
+ // ===== Voice Commands (Multi-language Support) =====
227
271
  voiceCommands: {
228
- showMenu: ['show menu', 'open menu'],
229
- highContrast: ['high contrast'],
230
- biggerText: ['bigger text', 'large text'],
231
- textSpacing: ['text spacing'],
232
- pauseAnimations: ['pause animations'],
233
- hideImages: ['hide images'],
234
- dyslexiaFont: ['dyslexia font'],
235
- biggerCursor: ['bigger cursor'],
236
- screenReader: ['screen reader'],
237
- resetAll: ['reset all', 'reset everything']
272
+ en: {
273
+ showMenu: ['show menu', 'open menu', 'accessibility menu', 'access menu'],
274
+ highContrast: ['high contrast', 'contrast', 'dark mode', 'increase contrast'],
275
+ biggerText: ['bigger text', 'large text', 'text size', 'increase text', 'bigger', 'larger text', 'text bigger', 'make text bigger', 'enlarge text'],
276
+ textSpacing: ['text spacing', 'spacing', 'letter spacing', 'text space'],
277
+ pauseAnimations: ['pause animations', 'stop animations', 'disable animations', 'no animations'],
278
+ hideImages: ['hide images', 'remove images', 'no images'],
279
+ dyslexiaFont: ['dyslexia friendly', 'dyslexia font', 'readable font', 'easy font'],
280
+ biggerCursor: ['bigger cursor', 'large cursor', 'cursor size', 'big cursor'],
281
+ lineHeight: ['line height', 'line spacing', 'space between lines', 'line space'],
282
+ textAlign: ['align text', 'text align', 'center text', 'alignment'],
283
+ screenReader: ['screen reader', 'read aloud', 'voice reader'],
284
+ voiceControl: ['voice command', 'voice control', 'voice commands'],
285
+ resetAll: ['reset all', 'reset everything', 'clear all', 'reset settings', 'reset']
286
+ },
287
+ // Additional languages: de, es, it, fr, ru, tr, ar, hi, zh-cn, jp available in widget
238
288
  }
239
289
  };
240
290
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "accessibility-widgets",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "A comprehensive, lightweight accessibility widget that enhances web accessibility for all users. Provides multiple accessibility features including screen reader support, voice control, high contrast mode, and more.",
5
5
  "main": "widget.js",
6
6
  "scripts": {
package/widget.js CHANGED
@@ -1,4 +1,4 @@
1
- /* ===========================================
1
+ /* ===========================================
2
2
 
3
3
  ACCESSIBILITY WIDGET
4
4
 
@@ -503,19 +503,171 @@ const DEFAULT_WIDGET_CONFIG = {
503
503
 
504
504
  // Voice Command Configuration - Developers can customize commands for different languages
505
505
  voiceCommands: {
506
- showMenu: ['show menu', 'open menu', 'accessibility menu'],
507
- highContrast: ['high contrast'],
508
- biggerText: ['bigger text', 'large text'],
509
- textSpacing: ['text spacing'],
510
- pauseAnimations: ['pause animations', 'stop animations'],
511
- hideImages: ['hide images'],
512
- dyslexiaFont: ['dyslexia friendly', 'dyslexia font'],
513
- biggerCursor: ['bigger cursor', 'large cursor'],
514
- lineHeight: ['line height'],
515
- textAlign: ['align text', 'text align'],
516
- screenReader: ['screen reader'],
517
- voiceControl: ['voice command', 'voice control'],
518
- resetAll: ['reset all', 'reset everything']
506
+ en: {
507
+ showMenu: ['show menu', 'open menu', 'accessibility menu', 'access menu'],
508
+ highContrast: ['high contrast', 'contrast', 'dark mode', 'increase contrast'],
509
+ biggerText: ['bigger text', 'large text', 'text size', 'increase text', 'bigger', 'larger text', 'text bigger', 'make text bigger', 'enlarge text'],
510
+ textSpacing: ['text spacing', 'spacing', 'letter spacing', 'text space'],
511
+ pauseAnimations: ['pause animations', 'stop animations', 'disable animations', 'no animations'],
512
+ hideImages: ['hide images', 'remove images', 'no images'],
513
+ dyslexiaFont: ['dyslexia friendly', 'dyslexia font', 'readable font', 'easy font'],
514
+ biggerCursor: ['bigger cursor', 'large cursor', 'cursor size', 'big cursor'],
515
+ lineHeight: ['line height', 'line spacing', 'space between lines', 'line space'],
516
+ textAlign: ['align text', 'text align', 'center text', 'alignment'],
517
+ screenReader: ['screen reader', 'read aloud', 'voice reader'],
518
+ voiceControl: ['voice command', 'voice control', 'voice commands'],
519
+ resetAll: ['reset all', 'reset everything', 'clear all', 'reset settings', 'reset']
520
+ },
521
+ de: {
522
+ showMenu: ['menü anzeigen', 'menü öffnen', 'barrierefreiheitsmenü', 'zugangsmenü'],
523
+ highContrast: ['hoher kontrast', 'kontrast', 'dunkler modus', 'kontrast erhöhen'],
524
+ biggerText: ['größerer text', 'großer text', 'textgröße', 'text vergrößern', 'größer', 'text größer'],
525
+ textSpacing: ['textabstand', 'abstand', 'buchstabenabstand', 'text abstand'],
526
+ pauseAnimations: ['animationen pausieren', 'animationen stoppen', 'animationen deaktivieren'],
527
+ hideImages: ['bilder ausblenden', 'bilder entfernen', 'keine bilder'],
528
+ dyslexiaFont: ['legasthenie freundlich', 'legasthenie schrift', 'lesbare schrift'],
529
+ biggerCursor: ['größerer cursor', 'großer cursor', 'cursor größe'],
530
+ lineHeight: ['zeilenhöhe', 'zeilenabstand', 'abstand zwischen zeilen'],
531
+ textAlign: ['text ausrichten', 'textausrichtung', 'text zentrieren'],
532
+ screenReader: ['screenreader', 'vorlesen', 'sprach reader'],
533
+ voiceControl: ['sprachbefehl', 'sprachsteuerung', 'sprachbefehle'],
534
+ resetAll: ['alles zurücksetzen', 'alle zurücksetzen', 'alle löschen', 'einstellungen zurücksetzen']
535
+ },
536
+ es: {
537
+ showMenu: ['mostrar menú', 'abrir menú', 'menú de accesibilidad', 'menú de acceso'],
538
+ highContrast: ['alto contraste', 'contraste', 'modo oscuro', 'aumentar contraste'],
539
+ biggerText: ['texto más grande', 'texto grande', 'tamaño de texto', 'aumentar texto', 'más grande'],
540
+ textSpacing: ['espaciado de texto', 'espaciado', 'espaciado de letras', 'espacio de texto'],
541
+ pauseAnimations: ['pausar animaciones', 'detener animaciones', 'desactivar animaciones'],
542
+ hideImages: ['ocultar imágenes', 'quitar imágenes', 'sin imágenes'],
543
+ dyslexiaFont: ['amigable para dislexia', 'fuente de dislexia', 'fuente legible'],
544
+ biggerCursor: ['cursor más grande', 'cursor grande', 'tamaño de cursor'],
545
+ lineHeight: ['altura de línea', 'espaciado de líneas', 'espacio entre líneas'],
546
+ textAlign: ['alinear texto', 'alineación de texto', 'centrar texto'],
547
+ screenReader: ['lector de pantalla', 'leer en voz alta', 'lector de voz'],
548
+ voiceControl: ['comando de voz', 'control de voz', 'comandos de voz'],
549
+ resetAll: ['restablecer todo', 'restablecer todo', 'borrar todo', 'restablecer configuración']
550
+ },
551
+ it: {
552
+ showMenu: ['mostra menu', 'apri menu', 'menu accessibilità', 'menu accesso'],
553
+ highContrast: ['alto contrasto', 'contrasto', 'modalità scura', 'aumenta contrasto'],
554
+ biggerText: ['testo più grande', 'testo grande', 'dimensione testo', 'aumenta testo', 'più grande'],
555
+ textSpacing: ['spaziatura testo', 'spaziatura', 'spaziatura lettere', 'spazio testo'],
556
+ pauseAnimations: ['pausa animazioni', 'ferma animazioni', 'disabilita animazioni'],
557
+ hideImages: ['nascondi immagini', 'rimuovi immagini', 'nessuna immagine'],
558
+ dyslexiaFont: ['adatto alla dislessia', 'font dislessia', 'font leggibile'],
559
+ biggerCursor: ['cursore più grande', 'cursore grande', 'dimensione cursore'],
560
+ lineHeight: ['altezza linea', 'spaziatura linee', 'spazio tra linee'],
561
+ textAlign: ['allinea testo', 'allineamento testo', 'centra testo'],
562
+ screenReader: ['lettore schermo', 'leggi ad alta voce', 'lettore vocale'],
563
+ voiceControl: ['comando vocale', 'controllo vocale', 'comandi vocali'],
564
+ resetAll: ['ripristina tutto', 'ripristina tutto', 'cancella tutto', 'ripristina impostazioni']
565
+ },
566
+ fr: {
567
+ showMenu: ['afficher menu', 'ouvrir menu', 'menu accessibilité', 'menu accès'],
568
+ highContrast: ['contraste élevé', 'contraste', 'mode sombre', 'augmenter contraste'],
569
+ biggerText: ['texte plus grand', 'grand texte', 'taille texte', 'augmenter texte', 'plus grand'],
570
+ textSpacing: ['espacement texte', 'espacement', 'espacement lettres', 'espace texte'],
571
+ pauseAnimations: ['mettre en pause animations', 'arrêter animations', 'désactiver animations'],
572
+ hideImages: ['masquer images', 'supprimer images', 'aucune image'],
573
+ dyslexiaFont: ['convivial dyslexie', 'police dyslexie', 'police lisible'],
574
+ biggerCursor: ['curseur plus grand', 'grand curseur', 'taille curseur'],
575
+ lineHeight: ['hauteur ligne', 'espacement lignes', 'espace entre lignes'],
576
+ textAlign: ['aligner texte', 'alignement texte', 'centrer texte'],
577
+ screenReader: ['lecteur écran', 'lire à haute voix', 'lecteur vocal'],
578
+ voiceControl: ['commande vocale', 'contrôle vocal', 'commandes vocales'],
579
+ resetAll: ['réinitialiser tout', 'réinitialiser tout', 'effacer tout', 'réinitialiser paramètres']
580
+ },
581
+ ru: {
582
+ showMenu: ['показать меню', 'открыть меню', 'меню доступности', 'меню доступа'],
583
+ highContrast: ['высокая контрастность', 'контрастность', 'темный режим', 'увеличить контрастность'],
584
+ biggerText: ['больший текст', 'большой текст', 'размер текста', 'увеличить текст', 'больше'],
585
+ textSpacing: ['межбуквенный интервал', 'интервал', 'интервал букв', 'пространство текста'],
586
+ pauseAnimations: ['приостановить анимацию', 'остановить анимацию', 'отключить анимацию'],
587
+ hideImages: ['скрыть изображения', 'убрать изображения', 'без изображений'],
588
+ dyslexiaFont: ['для дислексии', 'шрифт дислексии', 'читаемый шрифт'],
589
+ biggerCursor: ['увеличенный курсор', 'большой курсор', 'размер курсора'],
590
+ lineHeight: ['высота строки', 'интервал строк', 'пространство между строками'],
591
+ textAlign: ['выровнять текст', 'выравнивание текста', 'центрировать текст'],
592
+ screenReader: ['программа чтения', 'читать вслух', 'голосовой ридер'],
593
+ voiceControl: ['голосовая команда', 'голосовое управление', 'голосовые команды'],
594
+ resetAll: ['сбросить все', 'сбросить всё', 'очистить все', 'сбросить настройки']
595
+ },
596
+ tr: {
597
+ showMenu: ['menüyü göster', 'menü aç', 'erişilebilirlik menüsü', 'erişim menüsü'],
598
+ highContrast: ['yüksek kontrast', 'kontrast', 'karanlık mod', 'kontrastı artır'],
599
+ biggerText: ['daha büyük metin', 'büyük metin', 'metin boyutu', 'metni büyüt', 'daha büyük'],
600
+ textSpacing: ['metin aralığı', 'aralık', 'harf aralığı', 'metin boşluğu'],
601
+ pauseAnimations: ['animasyonları duraklat', 'animasyonları durdur', 'animasyonları kapat'],
602
+ hideImages: ['resimleri gizle', 'resimleri kaldır', 'resim yok'],
603
+ dyslexiaFont: ['disleksi dostu', 'disleksi yazı tipi', 'okunabilir yazı tipi'],
604
+ biggerCursor: ['daha büyük imleç', 'büyük imleç', 'imleç boyutu'],
605
+ lineHeight: ['satır yüksekliği', 'satır aralığı', 'satırlar arası boşluk'],
606
+ textAlign: ['metni hizala', 'metin hizalama', 'metni ortala'],
607
+ screenReader: ['ekran okuyucu', 'sesli oku', 'ses okuyucu'],
608
+ voiceControl: ['sesli komut', 'sesli kontrol', 'sesli komutlar'],
609
+ resetAll: ['hepsini sıfırla', 'tümünü sıfırla', 'hepsini temizle', 'ayarları sıfırla']
610
+ },
611
+ ar: {
612
+ showMenu: ['إظهار القائمة', 'فتح القائمة', 'قائمة إمكانية الوصول', 'قائمة الوصول'],
613
+ highContrast: ['تباين عالي', 'تباين', 'الوضع المظلم', 'زيادة التباين'],
614
+ biggerText: ['نص أكبر', 'نص كبير', 'حجم النص', 'تكبير النص', 'أكبر'],
615
+ textSpacing: ['تباعد النص', 'تباعد', 'تباعد الحروف', 'مساحة النص'],
616
+ pauseAnimations: ['إيقاف الرسوم المتحركة مؤقتا', 'إيقاف الرسوم المتحركة', 'تعطيل الرسوم المتحركة'],
617
+ hideImages: ['إخفاء الصور', 'إزالة الصور', 'بدون صور'],
618
+ dyslexiaFont: ['صديق لعسر القراءة', 'خط عسر القراءة', 'خط قابل للقراءة'],
619
+ biggerCursor: ['مؤشر أكبر', 'مؤشر كبير', 'حجم المؤشر'],
620
+ lineHeight: ['ارتفاع الخط', 'تباعد الأسطر', 'مساحة بين الأسطر'],
621
+ textAlign: ['محاذاة النص', 'محاذاة النص', 'توسيط النص'],
622
+ screenReader: ['قارئ الشاشة', 'اقرأ بصوت عالٍ', 'قارئ صوتي'],
623
+ voiceControl: ['الأمر الصوتي', 'التحكم الصوتي', 'الأوامر الصوتية'],
624
+ resetAll: ['إعادة تعيين الكل', 'إعادة تعيين جميع', 'مسح الكل', 'إعادة تعيين الإعدادات']
625
+ },
626
+ hi: {
627
+ showMenu: ['मेनू दिखाएं', 'मेनू खोलें', 'पहुंच मेनू', 'एक्सेस मेनू'],
628
+ highContrast: ['उच्च कंट्रास्ट', 'कंट्रास्ट', 'डार्क मोड', 'कंट्रास्ट बढ़ाएं'],
629
+ biggerText: ['बड़ा टेक्स्ट', 'बड़ा टेक्स्ट', 'टेक्स्ट का आकार', 'टेक्स्ट बढ़ाएं', 'बड़ा'],
630
+ textSpacing: ['टेक्स्ट स्पेसिंग', 'स्पेसिंग', 'अक्षर स्पेसिंग', 'टेक्स्ट स्पेस'],
631
+ pauseAnimations: ['एनिमेशन रोकें', 'एनिमेशन बंद करें', 'एनिमेशन अक्षम करें'],
632
+ hideImages: ['चित्र छिपाएं', 'चित्र हटाएं', 'कोई चित्र नहीं'],
633
+ dyslexiaFont: ['डिस्लेक्सिया के अनुकूल', 'डिस्लेक्सिया फ़ॉन्ट', 'पढ़ने योग्य फ़ॉन्ट'],
634
+ biggerCursor: ['बड़ा कर्सर', 'बड़ा कर्सर', 'कर्सर का आकार'],
635
+ lineHeight: ['लाइन की ऊंचाई', 'लाइन स्पेसिंग', 'लाइनों के बीच स्पेस'],
636
+ textAlign: ['टेक्स्ट अलाइन करें', 'टेक्स्ट संरेखण', 'टेक्स्ट केंद्र में करें'],
637
+ screenReader: ['स्क्रीन रीडर', 'जोर से पढ़ें', 'वॉयस रीडर'],
638
+ voiceControl: ['वॉयस कमांड', 'वॉयस नियंत्रण', 'वॉयस कमांड्स'],
639
+ resetAll: ['सभी रीसेट करें', 'सब कुछ रीसेट करें', 'सब साफ़ करें', 'सेटिंग्स रीसेट करें']
640
+ },
641
+ 'zh-cn': {
642
+ showMenu: ['显示菜单', '打开菜单', '辅助功能菜单', '访问菜单'],
643
+ highContrast: ['高对比度', '对比度', '暗模式', '增加对比度'],
644
+ biggerText: ['更大的文本', '大文本', '文本大小', '增大文本', '更大'],
645
+ textSpacing: ['文本间距', '间距', '字母间距', '文本空间'],
646
+ pauseAnimations: ['暂停动画', '停止动画', '禁用动画'],
647
+ hideImages: ['隐藏图片', '删除图片', '无图片'],
648
+ dyslexiaFont: ['阅读障碍友好', '阅读障碍字体', '可读字体'],
649
+ biggerCursor: ['更大的光标', '大光标', '光标大小'],
650
+ lineHeight: ['行高', '行间距', '行之间的空间'],
651
+ textAlign: ['对齐文本', '文本对齐', '居中文本'],
652
+ screenReader: ['屏幕阅读器', '大声朗读', '语音阅读器'],
653
+ voiceControl: ['语音命令', '语音控制', '语音命令'],
654
+ resetAll: ['重置全部', '重置所有', '清除全部', '重置设置']
655
+ },
656
+ jp: {
657
+ showMenu: ['メニューを表示', 'メニューを開く', 'アクセシビリティメニュー', 'アクセスメニュー'],
658
+ highContrast: ['ハイコントラスト', 'コントラスト', 'ダークモード', 'コントラストを上げる'],
659
+ biggerText: ['大きいテキスト', '大きなテキスト', 'テキストサイズ', 'テキストを大きく', 'より大きい'],
660
+ textSpacing: ['テキスト間隔', '間隔', '文字間隔', 'テキストスペース'],
661
+ pauseAnimations: ['アニメーション一時停止', 'アニメーション停止', 'アニメーション無効'],
662
+ hideImages: ['画像を非表示', '画像を削除', '画像なし'],
663
+ dyslexiaFont: ['ディスレクシア対応', 'ディスレクシアフォント', '読みやすいフォント'],
664
+ biggerCursor: ['大きいカーソル', '大きなカーソル', 'カーソルサイズ'],
665
+ lineHeight: ['行の高さ', '行間隔', '行間のスペース'],
666
+ textAlign: ['テキスト配置', 'テキスト配置', 'テキストを中央'],
667
+ screenReader: ['スクリーンリーダー', '音声で読む', '音声リーダー'],
668
+ voiceControl: ['音声コマンド', '音声制御', '音声コマンド'],
669
+ resetAll: ['すべてリセット', 'すべてリセット', 'すべてクリア', '設定をリセット']
670
+ }
519
671
  },
520
672
 
521
673
  // Grid Layout Configuration
@@ -1521,6 +1673,7 @@ function createActionButton(buttonText, actionFunction, iconSVG, optionsConfig =
1521
1673
  button.setAttribute('data-options-config', optionsConfig ? JSON.stringify(optionsConfig) : '');
1522
1674
  if (optionId) {
1523
1675
  button.setAttribute('data-accessibility-option-id', optionId);
1676
+ button.setAttribute('data-key', optionId); // Add data-key for voice commands
1524
1677
  }
1525
1678
 
1526
1679
  // Update initial status
@@ -1852,7 +2005,24 @@ const screenReader = {
1852
2005
  if (content.trim() !== '') {
1853
2006
  window.speechSynthesis.cancel();
1854
2007
  const speech = new SpeechSynthesisUtterance(content);
1855
- speech.lang = 'en-US';
2008
+
2009
+ // Set language based on current interface language
2010
+ let speechLang = 'en-US'; // default
2011
+ switch(currentLanguage) {
2012
+ case 'de': speechLang = 'de-DE'; break;
2013
+ case 'es': speechLang = 'es-ES'; break;
2014
+ case 'it': speechLang = 'it-IT'; break;
2015
+ case 'fr': speechLang = 'fr-FR'; break;
2016
+ case 'ru': speechLang = 'ru-RU'; break;
2017
+ case 'tr': speechLang = 'tr-TR'; break;
2018
+ case 'ar': speechLang = 'ar-SA'; break;
2019
+ case 'hi': speechLang = 'hi-IN'; break;
2020
+ case 'zh-cn': speechLang = 'zh-CN'; break;
2021
+ case 'jp': speechLang = 'ja-JP'; break;
2022
+ default: speechLang = 'en-US';
2023
+ }
2024
+ speech.lang = speechLang;
2025
+
1856
2026
  speech.onerror = function (event) {
1857
2027
  console.warn('Speech synthesis error:', event.error);
1858
2028
  };
@@ -1873,10 +2043,26 @@ const screenReader = {
1873
2043
  localStorage.setItem('screenReader', isActive);
1874
2044
 
1875
2045
  try {
2046
+ // Set language based on current interface language
2047
+ let speechLang = 'en-US'; // default
2048
+ switch(currentLanguage) {
2049
+ case 'de': speechLang = 'de-DE'; break;
2050
+ case 'es': speechLang = 'es-ES'; break;
2051
+ case 'it': speechLang = 'it-IT'; break;
2052
+ case 'fr': speechLang = 'fr-FR'; break;
2053
+ case 'ru': speechLang = 'ru-RU'; break;
2054
+ case 'tr': speechLang = 'tr-TR'; break;
2055
+ case 'ar': speechLang = 'ar-SA'; break;
2056
+ case 'hi': speechLang = 'hi-IN'; break;
2057
+ case 'zh-cn': speechLang = 'zh-CN'; break;
2058
+ case 'jp': speechLang = 'ja-JP'; break;
2059
+ default: speechLang = 'en-US';
2060
+ }
2061
+
1876
2062
  if (isActive) {
1877
2063
  document.addEventListener('focusin', screenReader.handleFocus);
1878
2064
  const feedbackSpeech = new SpeechSynthesisUtterance(getTranslation('screenReaderOn'));
1879
- feedbackSpeech.lang = 'en-US';
2065
+ feedbackSpeech.lang = speechLang;
1880
2066
  feedbackSpeech.onerror = function (event) {
1881
2067
  console.warn('Speech synthesis feedback error:', event.error);
1882
2068
  };
@@ -1885,7 +2071,7 @@ const screenReader = {
1885
2071
  document.removeEventListener('focusin', screenReader.handleFocus);
1886
2072
  window.speechSynthesis.cancel();
1887
2073
  const feedbackSpeech = new SpeechSynthesisUtterance(getTranslation('screenReaderOff'));
1888
- feedbackSpeech.lang = 'en-US';
2074
+ feedbackSpeech.lang = speechLang;
1889
2075
  feedbackSpeech.onerror = function (event) {
1890
2076
  console.warn('Speech synthesis feedback error:', event.error);
1891
2077
  };
@@ -1942,7 +2128,23 @@ const voiceControl = {
1942
2128
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
1943
2129
  voiceControl.recognition = new SpeechRecognition();
1944
2130
  voiceControl.recognition.interimResults = false;
1945
- voiceControl.recognition.lang = 'en-US';
2131
+
2132
+ // Set language based on current interface language
2133
+ let recognitionLang = 'en-US'; // default
2134
+ switch(currentLanguage) {
2135
+ case 'de': recognitionLang = 'de-DE'; break;
2136
+ case 'es': recognitionLang = 'es-ES'; break;
2137
+ case 'it': recognitionLang = 'it-IT'; break;
2138
+ case 'fr': recognitionLang = 'fr-FR'; break;
2139
+ case 'ru': recognitionLang = 'ru-RU'; break;
2140
+ case 'tr': recognitionLang = 'tr-TR'; break;
2141
+ case 'ar': recognitionLang = 'ar-SA'; break;
2142
+ case 'hi': recognitionLang = 'hi-IN'; break;
2143
+ case 'zh-cn': recognitionLang = 'zh-CN'; break;
2144
+ case 'jp': recognitionLang = 'ja-JP'; break;
2145
+ default: recognitionLang = 'en-US';
2146
+ }
2147
+ voiceControl.recognition.lang = recognitionLang;
1946
2148
  voiceControl.recognition.continuous = false;
1947
2149
 
1948
2150
  voiceControl.recognition.onstart = function () {
@@ -1990,62 +2192,92 @@ const voiceControl = {
1990
2192
  console.log(`Received command: ${command}`);
1991
2193
 
1992
2194
  try {
2195
+ // Normalize the command by removing extra spaces and making it lowercase
2196
+ const normalizedCommand = command.toLowerCase().trim().replace(/\s+/g, ' ');
2197
+
2198
+ // Get voice commands for current language, fallback to English
2199
+ const languageCommands = WIDGET_CONFIG.voiceCommands[currentLanguage] || WIDGET_CONFIG.voiceCommands['en'];
2200
+
1993
2201
  // Check for show menu commands
1994
- if (WIDGET_CONFIG.voiceCommands.showMenu.some(cmd => command.includes(cmd))) {
2202
+ if (languageCommands.showMenu.some(cmd => normalizedCommand.includes(cmd))) {
1995
2203
  if (!menuCache.button) menuCache.init();
1996
2204
  if (menuCache.button) {
1997
2205
  menuCache.button.click();
2206
+ console.log('Successfully opened menu');
1998
2207
  }
1999
2208
  return;
2000
2209
  }
2001
2210
 
2002
2211
  // Check for reset all commands
2003
- if (WIDGET_CONFIG.voiceCommands.resetAll.some(cmd => command.includes(cmd))) {
2212
+ if (languageCommands.resetAll.some(cmd => normalizedCommand.includes(cmd))) {
2004
2213
  resetAccessibilitySettings();
2214
+ console.log('Successfully reset all settings');
2005
2215
  return;
2006
2216
  }
2007
2217
 
2008
2218
  // Build dynamic command map based on configuration
2009
2219
  let localStorageKey = null;
2010
-
2011
- // Check each command group
2012
- if (WIDGET_CONFIG.voiceCommands.highContrast.some(cmd => command.includes(cmd))) {
2013
- localStorageKey = 'highContrast';
2014
- } else if (WIDGET_CONFIG.voiceCommands.biggerText.some(cmd => command.includes(cmd))) {
2015
- localStorageKey = 'biggerText';
2016
- } else if (WIDGET_CONFIG.voiceCommands.textSpacing.some(cmd => command.includes(cmd))) {
2017
- localStorageKey = 'textSpacing';
2018
- } else if (WIDGET_CONFIG.voiceCommands.pauseAnimations.some(cmd => command.includes(cmd))) {
2019
- localStorageKey = 'pauseAnimations';
2020
- } else if (WIDGET_CONFIG.voiceCommands.hideImages.some(cmd => command.includes(cmd))) {
2021
- localStorageKey = 'hideImages';
2022
- } else if (WIDGET_CONFIG.voiceCommands.dyslexiaFont.some(cmd => command.includes(cmd))) {
2023
- localStorageKey = 'dyslexiaFont';
2024
- } else if (WIDGET_CONFIG.voiceCommands.biggerCursor.some(cmd => command.includes(cmd))) {
2025
- localStorageKey = 'biggerCursor';
2026
- } else if (WIDGET_CONFIG.voiceCommands.lineHeight.some(cmd => command.includes(cmd))) {
2027
- localStorageKey = 'lineHeight';
2028
- } else if (WIDGET_CONFIG.voiceCommands.textAlign.some(cmd => command.includes(cmd))) {
2029
- localStorageKey = 'textAlign';
2030
- } else if (WIDGET_CONFIG.voiceCommands.screenReader.some(cmd => command.includes(cmd))) {
2031
- localStorageKey = 'screenReader';
2032
- } else if (WIDGET_CONFIG.voiceCommands.voiceControl.some(cmd => command.includes(cmd))) {
2033
- localStorageKey = 'voiceControl';
2220
+ let matchedCommand = null;
2221
+
2222
+ // Check each command group with better matching
2223
+ for (const [key, commands] of Object.entries(languageCommands)) {
2224
+ if (key === 'showMenu' || key === 'resetAll') continue; // Already handled above
2225
+
2226
+ const isMatch = commands.some(cmd => {
2227
+ // Check for exact matches first
2228
+ if (normalizedCommand.includes(cmd.toLowerCase())) {
2229
+ matchedCommand = cmd;
2230
+ return true;
2231
+ }
2232
+ // Check for partial word matches (at least 3 characters)
2233
+ const cmdWords = cmd.toLowerCase().split(' ');
2234
+ const inputWords = normalizedCommand.split(' ');
2235
+ return cmdWords.some(cmdWord =>
2236
+ cmdWord.length >= 3 && inputWords.some(inputWord =>
2237
+ inputWord.includes(cmdWord) || cmdWord.includes(inputWord)
2238
+ )
2239
+ );
2240
+ });
2241
+
2242
+ if (isMatch) {
2243
+ localStorageKey = key;
2244
+ break;
2245
+ }
2034
2246
  }
2035
2247
 
2036
2248
  if (localStorageKey) {
2037
2249
  // Use cached menu reference if available
2038
2250
  if (!menuCache.menu) menuCache.init();
2039
- const button = menuCache.menu?.querySelector(
2251
+
2252
+ // Try to find button by data-key first (toggle buttons)
2253
+ let button = menuCache.menu?.querySelector(
2040
2254
  `.snn-accessibility-option[data-key='${localStorageKey}']`
2041
2255
  );
2256
+
2257
+ // If not found, try to find by data-accessibility-option-id (action buttons)
2258
+ if (!button) {
2259
+ button = menuCache.menu?.querySelector(
2260
+ `.snn-accessibility-option[data-accessibility-option-id='${localStorageKey}']`
2261
+ );
2262
+ }
2263
+
2042
2264
  if (button) {
2043
2265
  button.click();
2266
+ console.log(`Successfully executed command: ${command} (matched: ${matchedCommand || localStorageKey})`);
2044
2267
  } else {
2045
- console.log('Button not found for command:', command);
2268
+ console.log('Button not found for command:', command, '(key:', localStorageKey, ')');
2046
2269
  }
2047
2270
  } else {
2048
2271
  console.log('Command not recognized:', command);
2272
+ // Provide helpful suggestions
2273
+ const availableCommands = Object.values(languageCommands).flat();
2274
+ const suggestions = availableCommands.filter(cmd =>
2275
+ cmd.toLowerCase().includes(normalizedCommand.split(' ')[0]) ||
2276
+ normalizedCommand.split(' ')[0].includes(cmd.toLowerCase().split(' ')[0])
2277
+ );
2278
+ if (suggestions.length > 0) {
2279
+ console.log('Did you mean one of these?', suggestions.slice(0, 3));
2280
+ }
2049
2281
  }
2050
2282
  } catch (error) {
2051
2283
  console.warn('Voice command handling error:', error);