/** * Erga Accessibility Widget v2.0.0 (Full Feature Edition) * Open-source, lightweight, privacy-first accessibility widget. */ (function() { 'use strict'; if (window.ErgaWidgetInitialized) return; window.ErgaWidgetInitialized = true; const STORAGE_KEY = 'erga_accessibility_settings_v2'; let settings = { fontSizeMultiplier: 1.0, fontFamily: 'default', contrast: 'normal', grayscale: false, colorBlindness: 'none', animations: true, cursor: 'default', readingGuide: false, highlightLinks: false, highlightHeadings: false, textSpacing: false, hideImages: false, speechActive: false, lang: 'id' }; const t = { id: { title: 'Panel Aksesibilitas', subtitle: 'Sesuaikan tampilan website untuk kenyamanan Anda', reset: 'Atur Ulang', close: 'Tutup', tools: 'Alat Aksesibilitas', profiles: 'Profil Cepat', fontSize: 'Ukuran Font', fontFamily: 'Jenis Font', grayscale: 'Skala Abu-abu', contrast: 'Kontras Tinggi', colorBlindness: 'Buta Warna', animations: 'Matikan Animasi', cursor: 'Kursor Besar', readingGuide: 'Panduan Baca', highlightLinks: 'Sorot Tautan', highlightHeadings: 'Sorot Judul', textSpacing: 'Spasi Teks', hideImages: 'Sembunyikan Gambar', speech: 'Pembaca Suara (TTS)', profileDyslexia: 'Ramah Disleksia', profileAdhd: 'Ramah ADHD', profileVision: 'Low Vision', profileSeizure: 'Ramah Epilepsi' }, en: { title: 'Accessibility Panel', subtitle: 'Customize website view for your comfort', reset: 'Reset All', close: 'Close', tools: 'Accessibility Tools', profiles: 'Quick Profiles', fontSize: 'Font Size', fontFamily: 'Font Family', grayscale: 'Grayscale', contrast: 'High Contrast', colorBlindness: 'Color Blindness', animations: 'Stop Animations', cursor: 'Big Cursor', readingGuide: 'Reading Guide', highlightLinks: 'Highlight Links', highlightHeadings: 'Highlight Headings', textSpacing: 'Text Spacing', hideImages: 'Hide Images', speech: 'Text-to-Speech', profileDyslexia: 'Dyslexia Friendly', profileAdhd: 'ADHD Friendly', profileVision: 'Low Vision', profileSeizure: 'Seizure Safe' } }; function gettext(key) { const lang = settings.lang.startsWith('id') ? 'id' : 'en'; return t[lang][key] || t['en'][key] || key; } try { const saved = localStorage.getItem(STORAGE_KEY); if (saved) settings = { ...settings, ...JSON.parse(saved) }; } catch(e) {} const style = document.createElement('style'); style.id = 'erga-accessibility-styles'; document.head.appendChild(style); const guideEl = document.createElement('div'); guideEl.id = 'erga-reading-guide-bar'; document.body.appendChild(guideEl); function updateStyles() { let css = ''; if (settings.contrast === 'dark') { css += `html { filter: invert(1) hue-rotate(180deg) !important; background-color: #111 !important; }`; css += `img, video, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; }`; } else if (settings.contrast === 'yellow') { css += `body, html { background-color: #000 !important; color: #ff0 !important; } * { background-color: transparent !important; color: #ff0 !important; border-color: #ff0 !important; }`; } if (settings.grayscale) { css += `html { filter: grayscale(100%) !important; }`; } if (settings.colorBlindness === 'protanopia') { css += `html { filter: url('#protanopia-filter') !important; }`; } else if (settings.colorBlindness === 'deuteranopia') { css += `html { filter: url('#deuteranopia-filter') !important; }`; } if (settings.fontFamily === 'dyslexia') { css += `p, span, a, li, h1, h2, h3, h4, h5, h6 { font-family: Comic SansMS, Arial, sans-serif !important; letter-spacing: 0.08em !important; word-spacing: 0.1em !important; }`; } else if (settings.fontFamily === 'serif') { css += `p, span, a, li, h1, h2, h3, h4, h5, h6 { font-family: Georgia, serif !important; }`; } if (!settings.animations) { css += `*, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }`; } if (settings.cursor === 'big') { css += `*, button, a, input { cursor: url('data:image/svg+xml;utf8,'), auto !important; }`; } if (settings.highlightLinks) { css += `a { background-color: #ff0 !important; color: #000 !important; text-decoration: underline !important; font-weight: bold !important; }`; } if (settings.highlightHeadings) { css += `h1, h2, h3, h4, h5, h6 { background-color: rgba(255, 235, 59, 0.4) !important; border: 2px dashed #fbc02d !important; padding: 4px !important; }`; } if (settings.textSpacing) { css += `p, span, li, a { word-spacing: 0.25em !important; line-height: 1.8 !important; letter-spacing: 0.08em !important; }`; } if (settings.hideImages) { css += `img, svg, picture, video { visibility: hidden !important; }`; } guideEl.style.display = settings.readingGuide ? 'block' : 'none'; style.textContent = css; // Direct Font Size Scaler const textElements = document.querySelectorAll('p, span, a, h1, h2, h3, h4, h5, h6, li, button'); textElements.forEach(el => { if (el.closest('#erga-widget-container')) return; if (!el.dataset.baseFontSize) { const computedSize = window.getComputedStyle(el).fontSize; el.dataset.baseFontSize = parseFloat(computedSize) || 16; } const base = parseFloat(el.dataset.baseFontSize); el.style.fontSize = (base * settings.fontSizeMultiplier) + 'px'; }); // Text to Speech Handling if (settings.speechActive) { startTextToSpeech(); } else { stopTextToSpeech(); } try { localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)); } catch(e) {} } // SVG Filter for Color Blindness const svgFilters = document.createElement('div'); svgFilters.innerHTML = ` `; document.body.appendChild(svgFilters); // Reading Guide Mouse Follower document.addEventListener('mousemove', (e) => { if (settings.readingGuide) { guideEl.style.top = (e.clientY - 15) + 'px'; } }); // TTS Engine let utterance = null; function startTextToSpeech() { if (!('speechSynthesis' in window)) return; window.speechSynthesis.cancel(); const text = document.body.innerText.substring(0, 1500); // Ambil ringkasan teks halaman utterance = new SpeechSynthesisUtterance(text); utterance.lang = settings.lang.startsWith('id') ? 'id-ID' : 'en-US'; utterance.onend = () => { settings.speechActive = false; updateUIState(); }; window.speechSynthesis.speak(utterance); } function stopTextToSpeech() { if ('speechSynthesis' in window) { window.speechSynthesis.cancel(); } } const container = document.createElement('div'); container.id = 'erga-widget-container'; container.innerHTML = `