- Add 'open' attribute to all <details> sections
- Ensure code examples are immediately visible to users
- No need to click to expand - documentation should be accessible
- Add TTS modal button example with openTTSModal() function
- Add translation modal button example with openTranslateModal() function
- Add standalone read page button example with readPageWithHermes() function
- Reorganize all sections to show live examples first, then code examples
- Improve documentation flow: demo first, then implementation details
- Add detailed feature lists and best-use-case descriptions
- Provide multiple implementation options for each feature (widget vs modal vs API)
- Update table of contents to reflect new organization
- Make it easy for people to add widgets to any webpage with clear examples
- Restore translate modal demo - it works fine on main app
- Add manual imports for openTranslateModal, openTTSModal, readPageWithHermes
- Ensure all widget functions are available globally for demo widgets
- Fix module loading issues that were causing "is not a function" errors
- Make translation modal work as isolated tool in demo
- Comment out entire smart dropdown section - no point advertising broken features
- Simplify translation section to only show working translation modal
- Update section title from "Translation Options" to "Translation Modal"
- Change "Live Examples" to "Live Example" (singular)
- Clean up code examples to only show working translate feature
- Remove confusing "two ways to translate" messaging
- Remove file upload references from system message
- Comment out smart-translate feature examples (not working yet)
- Disable smart translate demo with "Under Development" styling
- Keep traditional translate modal working
- Style disabled features with greyed-out appearance
- Fix demo page to only show working functionality
- Restore handleFileUpload import in widget-library.js to fix ReferenceError
- Keep all upload functionality code intact for future development
- Disable upload features in demo.html with "Under Development" messaging
- Remove upload from feature button examples but preserve the code
- Style disabled upload demo with greyed-out appearance
- Fix demo page functionality while maintaining upload code for future fixes
- Expand README language section with complete list of 19 supported languages
- Add native language names and language codes for each supported language
- Detail language features: manual selection, complete coverage, AI responses
- List comprehensive translation coverage areas (modals, buttons, messages, etc.)
- Update project structure to show language files with descriptions
- Remove auto-detection claims since feature is not working properly
- Change to accurate "manual selection" and "AI-powered translation"
- Fix demo.html to remove false auto-detection advertising
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix demo.html language count from 18 to 19 (verified by counting files)
- Remove "omni-directional" translation claims and use standard "Translation"
- Fix custom TTS example to use speakTextDirect instead of speakText (no Hermes preprocessing)
- Fix all demo functions to properly import modules dynamically
- Add missing imports for sendMessage, uploadFile, speakTextDirect, translateText
- Fix broken custom chat, TTS, file upload, page analysis, and translation examples
- Update README.rst and index.html language counts to accurate 19 languages
- Fix typo "transation" to "translation" in index.html
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Detect when model streaming is complete in all streaming locations
- Add syntax highlighting (hljs) to code blocks after streaming finishes
- Add copy buttons to code blocks after highlighting is applied
- Prevent duplicate copy buttons with CSS class detection
- Optimize performance by doing syntax highlighting and copy buttons only once per message
- Apply improvements to both modal streaming and standalone chat
- Add copy buttons to intro message generation as well
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created extensive README.rst with full project documentation
- Added brief documentation sections to index.html and demo.html
- Emphasized public domain licensing and open web philosophy
- Fixed branding to use lowercase uncloseai. and unturf.
- Points users to git repository for complete technical details
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add enforceModalTextColors() function with high CSS specificity
- Use !important declarations to override blog CSS
- Force dark text (#212529) on inputs, buttons, and general content
- Keep white text on user messages for proper contrast
- Add user-message class to user messages for targeted styling
- Prevents unreadable white text on white backgrounds on blog
- All delete buttons now call loadConversationHistory/saveConversationHistory
- Update both localStorage and chat.js module for consistency
- User message delete: filters by content match
- AI message delete: removes both user and AI messages in pair
- Historical message delete: removes by array index
- Intro message delete: filters by assistant role and content
- No more localStorage sync issues with deleted messages
- Chat TTS now uses speakTextDirect (no Hermes preprocessing, faster)
- Add download buttons (💾) next to all TTS buttons after processing
- Download buttons use generateTitleForTTS for smart filenames
- Read Page download now uses title generator instead of document.title
- Download buttons appear for user messages, AI responses, and historical messages
- Fallback filenames if title generation fails
- All TTS processing is now direct without Hermes delay
- Add try/catch with detailed error logging
- Check if sendMessage exists in imported module
- Log module contents if function not found
- Helps diagnose 'sendMessage(...) is not iterable' error
- Enhanced system prompt: MUST generate title, NEVER refuse
- Clear instructions for edge cases (empty, inappropriate, nonsensical text)
- Added fallback logic if Hermes returns empty or refusal messages
- Fallback uses first 30 chars of text or 'audio-file' as last resort
- Ensures downloads always have a valid filename
- Change sendMessage to async generator function with yield*
- Fixes 'Error: sendMessage(...) is not iterable' error
- Restores chat functionality in Hermes modal
- Fix TTS speed control: change default to 0.9, step by 0.05, max 2.0
- Apply playbackRate to audio element so speed actually works
- Add refreshModalUI() function to update UI when language changes
- Re-add upstream tokenizer API with simplified token counting
- Format token counts with commas (e.g., 8,432 tokens)
- Add getTokenCount() for simple integer token counts
- Language switching now refreshes modal UI without hard refresh
- extractSpokenTokens now detects if input is already markdown format
- Updated prompt to handle both markdown and HTML input
- Added markdown to plain text conversion in prompt (bold, links)
- processContentWithHermes now delegates to extractSpokenTokens
- Consistent processing pipeline whether from Batman button or Read Page
- Better reuse of extractWebpageContent markdown format
- Pre-clean HTML before sending to Hermes (remove scripts, styles, ads, iframes)
- Decode HTML entities ( & etc.) before Hermes processing
- Simplified, clearer system prompt focused on extraction tasks
- Post-process Hermes output with cleanTextForTTS() for final cleanup
- Reduces Hermes workload and improves extraction quality
- Three-stage pipeline: JS pre-clean → Hermes extraction → JS post-clean
- TTS modal now uses speakTextDirect() with simple JavaScript text cleaning
- No more Hermes preprocessing for modal text (faster, simpler)
- Read Page button still uses speakText() with Hermes for article extraction
- Reduced textarea height from 240px to 100px with vertical resize
- Added cleanTextForTTS() to remove markdown, HTML, and excess whitespace
- Modal gets instant TTS while Read Page gets intelligent content extraction
- Remove top, left, and transform properties
- Let dialog element use native browser centering
- Fixes positioning issues across different viewports
- Cleaner solution that works better with dialog element
- Enhanced system prompt to generate 5-10 word descriptive filenames
- Added robust text cleaning to remove quotes, special characters
- Limit filename length to 50 chars for filesystem compatibility
- Better dash-separated filename format like 'javascript-array-methods-guide.mp3'
- Enhanced system prompt to generate 3-5 word descriptive filenames
- Added robust text cleaning to remove quotes, special characters
- Limit filename length to 50 chars for filesystem compatibility
- Better dash-separated filename format like 'javascript-tutorial.mp3'
- Use generateTitleForTTS to create dash-separated filenames based on textarea content
- Hermes analyzes the text and generates descriptive filenames like 'hello-world-tts.mp3'
- Fallback to default filename if generation fails
- Add missing blobUrl to speakText return value
- TTS modal now correctly receives blobUrl for audio playback and download
- Fixes missing MP3 download and autoplay functionality
- Limit translation.js console output to 100 chars for long text (was showing 22KB)
- Add content filtering to TTS to prevent inappropriate content processing
- Enhance audio error handling with abort, stalled, and specific error types
- Add user-friendly error messages for audio playback failures
## Jest Configuration & Setup:
- Configure Jest with jsdom environment for DOM testing
- Set up test mocks for external dependencies (marked, hljs)
- Create test setup with localStorage, fetch, and dialog element mocks
- Add npm scripts for testing: test, test:watch, test:coverage, test:modals
- Update Makefile with Jest test targets and CI integration
## TTS Modal Tests (89 test cases):
- Modal creation, display, and structure validation
- Voice selection dropdown with 6+ voice options
- Speed control slider (0.5x-2.0x range)
- Audio generation with API integration testing
- Download functionality with blob handling
- Modal closing and cleanup
- Accessibility (ARIA, keyboard navigation, focus management)
- Error handling (API failures, malformed responses, network issues)
## Translate Modal Tests (85 test cases):
- Modal creation with source/target language selection
- Language detection and auto-population
- Translation API integration with streaming responses
- Copy functionality with clipboard API
- Text editing and retranslation
- Language swap functionality
- Modal state management
- Accessibility compliance
- Comprehensive error handling
## Embed Modal Tests (78 test cases):
- Main chat modal with conversation management
- Model loading and selection from endpoints
- Conversation history persistence with localStorage
- Real-time chat with streaming AI responses
- Message actions (copy, delete, TTS buttons)
- Action buttons with fallback modal opening
- Toggle functionality and state management
- User input handling (Enter key, send button)
- Accessibility and keyboard navigation
- Error handling for chat API, storage, and network issues
## Total: 252 comprehensive test cases covering:
- UI component creation and rendering
- User interaction and event handling
- API integration and streaming responses
- State management and persistence
- Accessibility compliance
- Error boundary testing
- Modal lifecycle management
- Cross-browser compatibility patterns
All tests include proper mocking, async handling, and cleanup for reliable CI execution.
- Add safety checks for window.openTTSModal and window.openTranslateModal availability
- Implement fallback dynamic imports if window functions not available
- Prevents "window.openTTSModal is not a function" and "window.openTranslateModal is not a function" errors
- Provides graceful error handling with user feedback if modal imports fail
- Resolves loading order dependency issues between ui.js and embed modal
This ensures modal buttons work regardless of script loading order.