-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Luc edited this page Nov 20, 2025
·
2 revisions
Understanding the codebase structure and how the Accessibility Widget works.
The Accessibility Widget is a self-contained, client-side plugin built with vanilla JavaScript and CSS. It has no dependencies and works on any modern web browser.
- Self-Contained: No external dependencies (except Boxicons for icons)
- Isolated: Uses namespacing to avoid conflicts
- Modular: Features are organized into logical functions
- Performant: Optimized for speed and efficiency
- Accessible: Follows WCAG guidelines
accessibility-plugin/
βββ accessibility-plugin.js # Main plugin (1618 lines)
βββ accessibility-plugin.css # Styles (885 lines)
βββ accessibility-config.js # Configuration (67 lines)
(function() { 'use strict'; // Namespace isolation const ACCESSIBILITY_NAMESPACE = 'accessibilityPlugin'; // Default settings const defaultSettings = { ... }; // State management let currentState = { ... }; // Initialize on DOM ready function init() { ... } init(); // Expose API window.AccessibilityPlugin = { ... }; })();
The plugin uses a centralized state object:
let currentState = { fontSize: 100, contrast: 'normal', colorBlindness: 'none', // ... more settings };
State Flow:
- User changes setting β Update
currentState - Call
applySettings()β Apply to DOM - Call
savePreferences()β Save to localStorage
The widget is created dynamically:
function createWidget() { // Create container const widget = document.createElement('div'); widget.className = 'accessibility-widget'; // Create toggle button const button = createToggleButton(); // Create panel const panel = createPanel(); // Append to body document.body.appendChild(widget); }
Settings are applied to the DOM:
function applySettings() { // Apply font size document.body.style.fontSize = currentState.fontSize + '%'; // Apply contrast if (currentState.contrast === 'high') { document.body.classList.add('accessibility-contrast-high'); } // Apply color blindness filter applyColorBlindnessFilter(); // ... more settings }
All CSS is scoped to avoid conflicts:
/* Widget-specific classes */ .accessibility-widget { ... } .accessibility-panel { ... } .accessibility-toggle-btn { ... }
Widget is isolated from page styles:
.accessibility-widget { isolation: isolate !important; contain: none !important; z-index: 10000 !important; }
Mobile-first approach:
/* Base styles */ .accessibility-panel { width: 260px; } /* Mobile adjustments */ @media (max-width: 768px) { .accessibility-panel { width: calc(100vw - 20px); } }
function speakText(text) { if (!speechSynthesis) return; const utterance = new SpeechSynthesisUtterance(text); utterance.rate = currentState.ttsRate; utterance.pitch = currentState.ttsPitch; utterance.volume = currentState.ttsVolume; speechSynthesis.speak(utterance); }
function applyColorBlindnessFilter() { if (currentState.colorBlindness === 'none') { document.body.style.filter = ''; return; } // Create SVG filter const svg = createSVGFilter(); document.body.appendChild(svg); // Apply filter document.body.style.filter = 'url(#colorblind-filter)'; }
function enableReadingGuide() { const guide = document.createElement('div'); guide.className = 'accessibility-reading-guide'; document.addEventListener('mousemove', function(e) { guide.style.top = e.clientY + 'px'; }); document.body.appendChild(guide); }
// Default settings const defaultSettings = { ... }; // Current state let currentState = { ... }; // Load preferences function loadPreferences() { ... } // Save preferences function savePreferences() { ... }
// Create widget function createWidget() { ... } // Create controls function createControl() { ... } // Toggle panel function togglePanel() { ... }
// Apply all settings function applySettings() { ... } // Individual feature functions function applyFontSize() { ... } function applyContrast() { ... } function applyColorBlindnessFilter() { ... }
The plugin exposes a simple API:
window.AccessibilityPlugin = { toggle: togglePanel, reset: resetSettings, getSettings: function() { return { ...currentState }; }, setFontSize: function(size) { ... }, setContrast: function(mode) { ... }, // ... more methods };
Settings are saved to localStorage:
function savePreferences() { try { localStorage.setItem( 'accessibilitySettings', JSON.stringify(currentState) ); } catch (e) { console.error('Failed to save preferences:', e); } }
function loadPreferences() { try { const saved = localStorage.getItem('accessibilitySettings'); if (saved) { currentState = { ...currentState, ...JSON.parse(saved) }; } } catch (e) { console.error('Failed to load preferences:', e); } }
(function() { // Isolated scope // No global pollution })();
// Watch for settings changes function watchSettings() { let lastState = { ...currentState }; setInterval(function() { if (stateChanged(lastState, currentState)) { onSettingsChange(); lastState = { ...currentState }; } }, 100); }
// Create controls dynamically function createControl(label, key, options, value) { const control = document.createElement('div'); // ... build control return control; }
- No user input is directly inserted into DOM
- All text is properly escaped
- No eval() or similar dangerous functions
Works with Content Security Policy:
- No inline scripts required
- All code in external files
- No unsafe-eval
- Lazy Initialization: Widget created on DOM ready
- Event Delegation: Efficient event handling
- Debouncing: For frequent events (mousemove)
- CSS Isolation: Prevents style recalculation
- Minimal DOM Manipulation: Batch updates
- Color filters may impact large pages
- TTS uses browser APIs (efficient)
- localStorage is fast (synchronous)
- No heavy computations
-
Add to defaultSettings
const defaultSettings = { // ... existing myNewFeature: false };
-
Add to currentState
let currentState = { // ... existing myNewFeature: settings.myNewFeature };
-
Create UI Control
const control = createControl('My Feature', 'myNewFeature', [...], value);
-
Implement Logic
function applySettings() { // ... existing if (currentState.myNewFeature) { // Your logic } }
-
Add to API (optional)
window.AccessibilityPlugin = { // ... existing setMyNewFeature: function(value) { ... } };
User Action
β
Update currentState
β
Call applySettings()
β
Modify DOM
β
Call savePreferences()
β
Save to localStorage
- Constants and defaults
- State management
- Utility functions
- Feature implementations
- UI creation
- Event handlers
- Initialization
- API exports
-
Functions: camelCase (
applySettings) -
Variables: camelCase (
currentState) -
CSS Classes: kebab-case (
.accessibility-widget) -
Constants: UPPER_SNAKE_CASE (
ACCESSIBILITY_NAMESPACE)
- Check Development Setup
- Review Contributing guide
- Open an issue on GitHub
Last Updated: November 2025
- Installation Guide - Step-by-step installation instructions
- Quick Start Guide - Get up and running in 5 minutes
- Configuration Guide - Customize the plugin to your needs
- Features Overview - Complete list of all features
- JavaScript API - Programmatic control documentation
- Browser Compatibility - Supported browsers and features
- WordPress Integration - How to integrate with WordPress
- Customization Guide - Styling and theming
- Advanced Usage - Tips and tricks for power users
- Contributing - How to contribute to the project
- Development Setup - Set up your development environment
- Architecture - Understanding the codebase
- Troubleshooting - Common issues and solutions
- FAQ - Frequently asked questions
- Known Issues - Current limitations and workarounds