Replace verbose document.getElementById() and document.querySelectorAll()
with cleaner hyperscript syntax:
- #id for ID selectors
- .class and the first .class for class selectors
- <selector/> query literals for complex selectors
- #{variable} for dynamic ID interpolation
Files changed:
- utils._hs: scrollHeight, details, footer buttons, scrollToSection
- zoom._hs: all zoom control element selectors (14 changes)
- pdf-modal._hs: modal selector
- keyboard._hs: dynamic toggle and modal selectors
- contact-modal.html: response div and modal close
- index.html: ninja-keys bar selector
Replace 34-line IIFE/MutationObserver with:
- Hyperscript: on toggle if me.open call resetContactForm()
- 11-line resetContactForm() function
Also dispatches 'show' event from openModal() for ninja-keys integration.
All 7 contact form tests pass.
- Lazy load ninja-keys only on CMD+K press (0 requests on initial load)
- Use esm.sh bundled module (3 requests vs ~81 previously)
- Add esm.sh to CSP whitelist
- Implement HTML Invoker Commands API for modals:
- commandfor="modal-id" + command="show-modal" for opening
- commandfor="modal-id" + command="close" for closing
- Removes need for onclick handlers on modal buttons
- Refactor index.html into layout partials (head, body-scripts)
- Add comprehensive tests for both features
Implement a command palette accessible via CMD+K/Ctrl+K using the ninja-keys
web component. Features include:
- New /api/cmd-k endpoint serving dynamic CV entries (experiences, projects, courses)
- Language-aware responses with 1-hour cache headers
- Scroll-to-section functionality for quick navigation
- Enhanced keyboard shortcuts modal with CMD+K documentation
- Comprehensive test coverage for API and UI interactions
Also includes cleanup of deprecated debug test files and various UI polish
improvements to contact form, themes, and action bar components.
Plain text endpoint:
- Add /text route for plain text CV (for curl/AI crawlers)
- Use k3a/html2text library for HTML-to-text conversion
- Add Plain Text button to hamburger menu with UI translations
Contact form feature:
- Add ContactHandler with proper email service integration
- Add CSRF protection middleware
- Add rate limiting (5 submissions/hour per IP)
- Add honeypot and timing-based bot protection
- Add input validation with detailed error messages
- Add security logging middleware
- Add browser-only middleware for API protection
Code quality:
- Fix all golangci-lint errcheck warnings for w.Write calls
- Remove duplicate getClientIP functions
- Wire up ContactHandler in routes.Setup