@ordojs/accessibility
Version:
Comprehensive accessibility system for OrdoJS with ARIA generation, automated testing, and screen reader support
1 lines • 13.9 kB
Source Map (JSON)
{"version":3,"sources":["../../src/screen-reader/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @fileoverview OrdoJS Accessibility - Screen Reader Module\n *\n * Screen reader support with announcements and live regions.\n */\n\nimport { EventEmitter } from 'events';\nimport type {\n LiveRegion,\n ScreenReaderAnnouncement,\n ScreenReaderConfig\n} from '../types/index.js';\n\n/**\n * Screen reader manager for handling announcements and live regions\n */\nexport class ScreenReaderManager extends EventEmitter {\n private config: ScreenReaderConfig;\n private announcements: Map<string, ScreenReaderAnnouncement>;\n private liveRegions: Map<string, LiveRegion>;\n private isInitialized: boolean;\n\n /**\n * Create a new ScreenReaderManager instance\n *\n * @param config - Screen reader configuration\n */\n constructor(config: ScreenReaderConfig) {\n super();\n\n this.config = config;\n this.announcements = new Map();\n this.liveRegions = new Map();\n this.isInitialized = false;\n }\n\n /**\n * Initialize the screen reader manager\n */\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n console.warn('Screen reader manager is already initialized');\n return;\n }\n\n try {\n // Initialize screen reader support\n await this.initializeScreenReader();\n\n this.isInitialized = true;\n console.log('Screen reader manager initialized successfully');\n\n this.emit('initialized');\n } catch (error) {\n console.error('Failed to initialize screen reader manager:', error);\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Announce message to screen readers\n *\n * @param message - Message to announce\n * @param options - Announcement options\n * @returns Announcement ID\n */\n announce(\n message: string,\n options: {\n priority?: 'polite' | 'assertive';\n type?: 'status' | 'alert' | 'log' | 'timer' | 'marquee' | 'progressbar';\n duration?: number;\n element?: string;\n context?: string;\n } = {}\n ): string {\n const announcementId = `announcement_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n const announcement: ScreenReaderAnnouncement = {\n id: announcementId,\n message,\n priority: options.priority || 'polite',\n type: options.type || 'status',\n timestamp: new Date()\n };\n\n // Set optional properties only if they have values\n if (options.duration !== undefined) {\n announcement.duration = options.duration;\n }\n if (options.element) {\n announcement.element = options.element;\n }\n if (options.context) {\n announcement.context = options.context;\n }\n\n this.announcements.set(announcementId, announcement);\n this.emit('announcementCreated', announcement);\n\n return announcementId;\n }\n\n /**\n * Create live region\n *\n * @param regionId - Region ID\n * @param element - Element selector\n * @param options - Region options\n * @returns Live region\n */\n createLiveRegion(\n regionId: string,\n element: string,\n options: {\n type?: 'status' | 'alert' | 'log' | 'timer' | 'marquee' | 'progressbar';\n priority?: 'polite' | 'assertive';\n atomic?: boolean;\n relevant?: 'additions' | 'removals' | 'text' | 'all';\n busy?: boolean;\n expanded?: boolean;\n controls?: string;\n describedBy?: string;\n label?: string;\n } = {}\n ): LiveRegion {\n const region: LiveRegion = {\n id: regionId,\n type: options.type || 'status',\n priority: options.priority || 'polite',\n element,\n content: '',\n atomic: options.atomic || false,\n relevant: options.relevant || 'additions',\n busy: options.busy || false\n };\n\n // Set optional properties\n if (options.expanded !== undefined) {\n region.expanded = options.expanded;\n }\n if (options.controls) {\n region.controls = options.controls;\n }\n if (options.describedBy) {\n region.describedBy = options.describedBy;\n }\n if (options.label) {\n region.label = options.label;\n }\n\n this.liveRegions.set(regionId, region);\n this.emit('liveRegionCreated', region);\n\n return region;\n }\n\n /**\n * Update live region content\n *\n * @param regionId - Region ID\n * @param content - New content\n * @param options - Update options\n */\n updateLiveRegion(\n regionId: string,\n content: string,\n options: {\n busy?: boolean;\n expanded?: boolean;\n } = {}\n ): void {\n const region = this.liveRegions.get(regionId);\n if (region) {\n region.content = content;\n\n if (options.busy !== undefined) {\n region.busy = options.busy;\n }\n if (options.expanded !== undefined) {\n region.expanded = options.expanded;\n }\n\n this.liveRegions.set(regionId, region);\n this.emit('liveRegionUpdated', region);\n }\n }\n\n /**\n * Remove live region\n *\n * @param regionId - Region ID\n */\n removeLiveRegion(regionId: string): void {\n const region = this.liveRegions.get(regionId);\n if (region) {\n this.liveRegions.delete(regionId);\n this.emit('liveRegionRemoved', region);\n }\n }\n\n /**\n * Get live region by ID\n *\n * @param regionId - Region ID\n * @returns Live region or undefined\n */\n getLiveRegion(regionId: string): LiveRegion | undefined {\n return this.liveRegions.get(regionId);\n }\n\n /**\n * Get all live regions\n *\n * @returns Array of live regions\n */\n getAllLiveRegions(): LiveRegion[] {\n return Array.from(this.liveRegions.values());\n }\n\n /**\n * Get announcement by ID\n *\n * @param announcementId - Announcement ID\n * @returns Announcement or undefined\n */\n getAnnouncement(announcementId: string): ScreenReaderAnnouncement | undefined {\n return this.announcements.get(announcementId);\n }\n\n /**\n * Get all announcements\n *\n * @returns Array of announcements\n */\n getAllAnnouncements(): ScreenReaderAnnouncement[] {\n return Array.from(this.announcements.values());\n }\n\n /**\n * Clear announcements\n */\n clearAnnouncements(): void {\n this.announcements.clear();\n this.emit('announcementsCleared');\n }\n\n /**\n * Get screen reader manager statistics\n *\n * @returns Statistics\n */\n getStats(): {\n totalAnnouncements: number;\n totalLiveRegions: number;\n announcementsByType: Record<string, number>;\n liveRegionsByType: Record<string, number>;\n } {\n const announcementsByType: Record<string, number> = {};\n const liveRegionsByType: Record<string, number> = {};\n\n // Count announcements by type\n for (const announcement of this.announcements.values()) {\n announcementsByType[announcement.type] = (announcementsByType[announcement.type] || 0) + 1;\n }\n\n // Count live regions by type\n for (const region of this.liveRegions.values()) {\n liveRegionsByType[region.type] = (liveRegionsByType[region.type] || 0) + 1;\n }\n\n return {\n totalAnnouncements: this.announcements.size,\n totalLiveRegions: this.liveRegions.size,\n announcementsByType,\n liveRegionsByType\n };\n }\n\n /**\n * Initialize screen reader support\n */\n private async initializeScreenReader(): Promise<void> {\n console.log('Initializing screen reader support...');\n\n // Set up announcements if enabled\n if (this.config.announcements) {\n this.setupAnnouncements();\n }\n\n // Set up live regions if enabled\n if (this.config.liveRegions) {\n this.setupLiveRegions();\n }\n\n // Set up ARIA support if enabled\n if (this.config.ariaLabels || this.config.ariaDescriptions || this.config.ariaLandmarks) {\n this.setupARIASupport();\n }\n }\n\n /**\n * Setup announcements\n */\n private setupAnnouncements(): void {\n // This is a simplified implementation\n // In a real implementation, you would set up announcement elements\n console.log('Setting up announcements...');\n }\n\n /**\n * Setup live regions\n */\n private setupLiveRegions(): void {\n // This is a simplified implementation\n // In a real implementation, you would set up live region elements\n console.log('Setting up live regions...');\n }\n\n /**\n * Setup ARIA support\n */\n private setupARIASupport(): void {\n // This is a simplified implementation\n // In a real implementation, you would set up ARIA attributes\n console.log('Setting up ARIA support...');\n }\n}\n"]}