docs: Update skeleton loader implementation from hyperscript to JavaScript

MIGRATION SUMMARY:
- Moved skeleton loader logic from hyperscript to JavaScript (main.js)
- Changed from htmx:oobAfterSwap to htmx:afterSettle event
- Changed OOB swap from innerHTML to outerHTML for proper element replacement
- Added languageSwitching flag for state tracking
- Added 100ms delay after afterSettle for final render completion

DOCUMENTATION UPDATES:
- 2-MODERN-WEB-TECHNIQUES.md: Updated skeleton loader section with
This commit is contained in:
juanatsap
2025-11-18 19:32:28 +00:00
parent 65eb91b00b
commit 1f6f8e417e
13 changed files with 539 additions and 150 deletions
+62 -28
View File
@@ -1930,31 +1930,57 @@ Time 600ms+: opacity=NaN ← Element destroyed!
```
```javascript
// Language switch with skeleton loading
htmx.on('htmx:beforeSwap', function(evt) {
// Show skeletons BEFORE swap
document.querySelectorAll('.component-wrapper').forEach(wrapper => {
wrapper.classList.add('loading');
});
// static/js/main.js - Skeleton loader for language transitions
let languageSwitching = false;
// Add .loading class when language button is clicked
document.addEventListener('htmx:beforeRequest', function(evt) {
const element = evt.detail.elt;
if (element && element.classList && element.classList.contains('selector-btn')) {
// Set flag to track language switching
languageSwitching = true;
// Add loading class to page containers
const page1 = document.getElementById('cv-inner-content-page-1');
const page2 = document.getElementById('cv-inner-content-page-2');
if (page1) page1.classList.add('loading');
if (page2) page2.classList.add('loading');
}
});
htmx.on('htmx:afterSettle', function(evt) {
// Hide skeletons AFTER content settles
document.querySelectorAll('.component-wrapper').forEach(wrapper => {
wrapper.classList.remove('loading');
});
// Remove .loading class after language transition completes
document.addEventListener('htmx:afterSettle', function(evt) {
if (languageSwitching) {
// Wait for final render to complete
setTimeout(function() {
const page1 = document.getElementById('cv-inner-content-page-1');
const page2 = document.getElementById('cv-inner-content-page-2');
if (page1) page1.classList.remove('loading');
if (page2) page2.classList.remove('loading');
// Reset flag
languageSwitching = false;
}, 100);
}
});
```
**Architecture Pattern:**
1. **User clicks language toggle** → HTMX `beforeSwap` event fires
2. **JavaScript adds `.loading` class**Triggers CSS transition (actual-content opacity: 1 → 0, skeleton-content opacity: 0 → 1)
3. **Skeleton appears** → Smooth 250ms fade-in with shimmer animation
4. **HTMX fetches new language content** → Server renders and returns HTML
5. **HTMX swaps content** → New actual-content replaces old
6. **afterSettle event fires** → JavaScript removes `.loading` class
7. **Skeleton fades out**Smooth 250ms fade (skeleton opacity: 1 → 0, actual-content opacity: 0 → 1)
8. **Result** → Smooth, professional loading experience with zero layout shift
1. **User clicks language button** → HTMX `htmx:beforeRequest` event fires
2. **JavaScript detects `.selector-btn` click**Sets `languageSwitching` flag
3. **JavaScript adds `.loading` to parent containers** → Triggers CSS cascade to child `.component-wrapper` elements
4. **Skeleton appears** → CSS transition (actual-content opacity: 1 → 0, skeleton-content opacity: 0 → 1) + shimmer animation
5. **HTMX fetches new language content** → Server renders and returns HTML via OOB swaps
6. **HTMX swaps content** → Out-of-band (OOB) swap replaces page containers
7. **`htmx:afterSettle` event fires** → JavaScript waits 100ms for final render
8. **JavaScript removes `.loading` class** → CSS transition reverses (skeleton opacity: 1 → 0, actual-content opacity: 0 → 1)
9. **Result** → Smooth, professional loading experience with zero layout shift
**Why JavaScript Instead of Hyperscript:**
-**Reliable Playwright testing** - JavaScript event handlers work consistently in automated tests
-**Debugging** - Console.log statements provide clear execution tracking
-**Maintainability** - Standard JavaScript patterns familiar to all developers
-**Performance** - Direct DOM manipulation, no hyperscript parser overhead
**Benefits:**
-**Zero layout shift** - Skeletons match exact dimensions of actual content
@@ -1966,16 +1992,24 @@ htmx.on('htmx:afterSettle', function(evt) {
-**Reusable** - Works for any HTMX swap operation, not just language switch
**Implementation Locations:**
- **CSS:** `static/css/skeleton.css` (341 lines) - Complete skeleton system
- **Template:** `templates/partials/skeleton-loader.html` - Skeleton placeholders
- **Component wrappers:** Each CV section wrapped with `.component-wrapper`
- **HTMX events:** `static/js/main.js` - beforeSwap/afterSettle listeners
- **CSS:** `static/css/skeleton.css` - Complete skeleton system with shimmer animations
- **JavaScript:** `static/js/main.js` (lines 231-273) - HTMX event handlers for skeleton control
- **Templates:** `templates/partials/sections/header.html` - Component wrapper structure
- **Page Containers:** `templates/cv-content.html` - Parent containers receiving `.loading` class
- **Language Switch:** `templates/language-switch.html` - `.selector-btn` triggers skeleton display
**Testing:** Automated tests in `tests/mjs/12-skeleton-language-transitions.test.mjs` verify:
- Skeletons appear during language switch
- Content replaced without full page reload
- Skeletons removed after content loads
- Zero layout shift during transition
- ✅ Component wrapper structure (dual-state: actual + skeleton content)
- ✅ Skeleton CSS loaded (shimmer animation verified)
- ✅ First language switch (EN → ES) - Loading class added/removed
- ✅ Second language switch (ES → EN) - Consistent behavior
- ✅ Third language switch (EN → ES) - Regression check
- ✅ No stuck loading states (all containers clean after transition)
- ✅ JavaScript event handlers configured (languageSwitching flag)
**Test Results:** 7/7 tests pass - Complete validation of skeleton loader functionality
**Run Test:** `bun tests/mjs/12-skeleton-language-transitions.test.mjs`
**Pixel-Perfect Matching:**
@@ -2354,7 +2388,7 @@ set #shortcuts-button's *zoom to inverseZoom
3. `templates/partials/navigation/hamburger-menu.html`
- Removed conflicting hyperscript from show zoom button
4. `MODERN-WEB-TECHNIQUES.md`
4. `2-MODERN-WEB-TECHNIQUES.md`
- Updated documentation to reflect fixes
- Added technical lessons learned
+3 -3
View File
@@ -1190,7 +1190,7 @@ curl -H "Referer: https://evil.com/" \
**Current Configuration:**
- **Endpoint:** `/export/pdf`
- **Limit:** 3 requests per minute per IP
- **Window:** 1 minute (rolling)
- **Window:** 1 minute (rolling)
- **Response:** 429 Too Many Requests when exceeded
**Implementation:**
@@ -1266,7 +1266,7 @@ pdfRateLimiter := middleware.NewRateLimiter(5, 1*time.Hour)
- Input validation
- Error message sanitization (internal errors hidden)
- Timeouts on all operations
- Graceful shutdown
- Graceful shutdown
- Origin checking (prevents external hotlinking)
- Rate limiting (PDF endpoint: 3 requests/min per IP)
- IP-based tracking (supports reverse proxies)
@@ -1974,7 +1974,7 @@ go tool trace trace.out
---
**Last Updated:** November 12, 2025
**API Version:** 1.1.0
**API Version:** 1.1.0
**Documentation Version:** 1.1.0
### Support
+3 -3
View File
@@ -54,7 +54,7 @@ This CV/Resume application is designed to be easily customizable. You can adapt
### Tools Needed
- **Text editor**: VS Code, Sublime Text, or any editor
- **Go 1.25.1+**: For building and testing (see [DEPLOYMENT.md](DEPLOYMENT.md))
- **Go 1.25.1+**: For building and testing (see [8-DEPLOYMENT.md](8-DEPLOYMENT.md))
- **Git**: For version control (optional but recommended)
- **Browser**: For testing (Chrome/Firefox recommended)
@@ -1103,7 +1103,7 @@ open http://localhost:1999
- ✅ Comply with GDPR, CCPA, or local privacy laws
- ✅ Update privacy policy when changing analytics providers
**See [PRIVACY.md](PRIVACY.md) for privacy policy template.**
**See [10-PRIVACY.md](10-PRIVACY.md) for privacy policy template.**
---
@@ -1751,7 +1751,7 @@ python3 -m json.tool data/cv-en.json
After customization:
1. **Test thoroughly** with checklist above
2. **Generate PDF** and verify quality
3. **Deploy** using [DEPLOYMENT.md](DEPLOYMENT.md) guide
3. **Deploy** using [8-DEPLOYMENT.md](8-DEPLOYMENT.md) guide
4. **Set up CI/CD** for automatic deployments
5. **Share** your customized CV!
+1 -1
View File
@@ -1050,4 +1050,4 @@ curl http://localhost:1999/health
---
**For customization, see CUSTOMIZATION.md**
**For customization, see [7-CUSTOMIZATION.md](7-CUSTOMIZATION.md)**
+1 -1
View File
@@ -435,7 +435,7 @@ proxy_set_header X-Real-IP $remote_addr;
**Solution:** This is normal browser behavior. The middleware checks `Referer` header as fallback, which browsers do send for navigation.
For technical API details, see [3-API.md](3-API.md#security-protection).
---
## Known Security Considerations
+31 -31
View File
@@ -9,25 +9,25 @@
### For Developers
**Getting Started**
- [Architecture Overview](ARCHITECTURE.md) - System design and Go backend architecture
- [Modern Web Techniques](MODERN-WEB-TECHNIQUES.md) - Frontend architecture (HTMX, Hyperscript, CSS) ⭐
- [API Reference](API.md) - Complete API documentation with endpoints and responses
- [1. Architecture Overview](1-ARCHITECTURE.md) - System design and Go backend architecture
- [2. Modern Web Techniques](2-MODERN-WEB-TECHNIQUES.md) - Frontend architecture (HTMX, Hyperscript, CSS) ⭐
- [3. API Reference](3-API.md) - Complete API documentation with endpoints and responses
**Technical Implementation**
- [Hyperscript Rules](HYPERSCRIPT-RULES.md) - Hyperscript conventions and best practices
- [Zoom Implementation](ZOOM_IMPLEMENTATION.md) - Custom zoom feature technical details
- [4. Hyperscript Rules](4-HYPERSCRIPT-RULES.md) - Hyperscript conventions and best practices
- [5. Zoom Implementation](5-ZOOM-IMPLEMENTATION.md) - Custom zoom feature technical details
**Deployment & Operations**
- [Deployment Guide](DEPLOYMENT.md) - Production deployment instructions
- [Security Policies](SECURITY.md) - Security guidelines and vulnerability reporting
- [8. Deployment Guide](8-DEPLOYMENT.md) - Production deployment instructions
- [9. Security Policies](9-SECURITY.md) - Security guidelines and vulnerability reporting
---
### For Users & Customizers
- [User Guide](USER_GUIDE.md) - End-user documentation for CV features
- [Customization Guide](CUSTOMIZATION.md) - How to customize your CV content and styling
- [Privacy Policy](PRIVACY.md) - Data handling and privacy information
- [6. User Guide](6-USER-GUIDE.md) - End-user documentation for CV features
- [7. Customization Guide](7-CUSTOMIZATION.md) - How to customize your CV content and styling
- [10. Privacy Policy](10-PRIVACY.md) - Data handling and privacy information
---
@@ -35,23 +35,23 @@
### Core Technical Documentation
| Document | Purpose | Audience |
|----------|---------|----------|
| [ARCHITECTURE.md](ARCHITECTURE.md) | Go backend architecture, package structure, design patterns | Backend developers |
| [MODERN-WEB-TECHNIQUES.md](MODERN-WEB-TECHNIQUES.md) | HTMX/Hyperscript frontend architecture, component patterns, ADRs | Frontend developers |
| [API.md](API.md) | Complete API reference with all endpoints | API consumers, integrators |
| [ZOOM_IMPLEMENTATION.md](ZOOM_IMPLEMENTATION.md) | Zoom feature implementation details | Feature developers |
| [HYPERSCRIPT-RULES.md](HYPERSCRIPT-RULES.md) | Hyperscript coding conventions | Frontend developers |
| # | Document | Purpose | Audience |
|---|----------|---------|----------|
| 1 | [ARCHITECTURE.md](1-ARCHITECTURE.md) | Go backend architecture, package structure, design patterns | Backend developers |
| 2 | [MODERN-WEB-TECHNIQUES.md](2-MODERN-WEB-TECHNIQUES.md) | HTMX/Hyperscript frontend architecture, component patterns, ADRs | Frontend developers |
| 3 | [API.md](3-API.md) | Complete API reference with all endpoints | API consumers, integrators |
| 4 | [HYPERSCRIPT-RULES.md](4-HYPERSCRIPT-RULES.md) | Hyperscript coding conventions | Frontend developers |
| 5 | [ZOOM_IMPLEMENTATION.md](5-ZOOM-IMPLEMENTATION.md) | Zoom feature implementation details | Feature developers |
### User & Operations Documentation
| Document | Purpose | Audience |
|----------|---------|----------|
| [USER_GUIDE.md](USER_GUIDE.md) | End-user feature documentation | CV users |
| [CUSTOMIZATION.md](CUSTOMIZATION.md) | Content and style customization | CV customizers |
| [DEPLOYMENT.md](DEPLOYMENT.md) | Deployment instructions and operations | DevOps, site operators |
| [SECURITY.md](SECURITY.md) | Security policies and reporting | Security teams |
| [PRIVACY.md](PRIVACY.md) | Privacy policy and data handling | Legal, compliance |
| # | Document | Purpose | Audience |
|---|----------|---------|----------|
| 6 | [USER_GUIDE.md](6-USER-GUIDE.md) | End-user feature documentation | CV users |
| 7 | [CUSTOMIZATION.md](7-CUSTOMIZATION.md) | Content and style customization | CV customizers |
| 8 | [DEPLOYMENT.md](8-DEPLOYMENT.md) | Deployment instructions and operations | DevOps, site operators |
| 9 | [SECURITY.md](9-SECURITY.md) | Security policies and reporting | Security teams |
| 10 | [PRIVACY.md](10-PRIVACY.md) | Privacy policy and data handling | Legal, compliance |
---
@@ -85,25 +85,25 @@
### "I want to..."
**...understand the system architecture**
→ Start with [ARCHITECTURE.md](ARCHITECTURE.md) (backend) and [MODERN-WEB-TECHNIQUES.md](MODERN-WEB-TECHNIQUES.md) (frontend)
→ Start with [1-ARCHITECTURE.md](1-ARCHITECTURE.md) (backend) and [2-MODERN-WEB-TECHNIQUES.md](2-MODERN-WEB-TECHNIQUES.md) (frontend)
**...add a new feature**
→ Read [MODERN-WEB-TECHNIQUES.md](MODERN-WEB-TECHNIQUES.md) for frontend patterns, [API.md](API.md) for backend APIs
→ Read [2-MODERN-WEB-TECHNIQUES.md](2-MODERN-WEB-TECHNIQUES.md) for frontend patterns, [3-API.md](3-API.md) for backend APIs
**...customize my CV content**
→ Follow [CUSTOMIZATION.md](CUSTOMIZATION.md) for content and styling changes
→ Follow [7-CUSTOMIZATION.md](7-CUSTOMIZATION.md) for content and styling changes
**...deploy to production**
→ Use [DEPLOYMENT.md](DEPLOYMENT.md) for step-by-step deployment instructions
→ Use [8-DEPLOYMENT.md](8-DEPLOYMENT.md) for step-by-step deployment instructions
**...understand HTMX patterns**
→ Check [MODERN-WEB-TECHNIQUES.md](MODERN-WEB-TECHNIQUES.md) Section 6 (HTMX Patterns)
→ Check [2-MODERN-WEB-TECHNIQUES.md](2-MODERN-WEB-TECHNIQUES.md) Section 6 (HTMX Patterns)
**...write Hyperscript code**
→ Follow conventions in [HYPERSCRIPT-RULES.md](HYPERSCRIPT-RULES.md)
→ Follow conventions in [4-HYPERSCRIPT-RULES.md](4-HYPERSCRIPT-RULES.md)
**...report a security issue**
→ See [SECURITY.md](SECURITY.md) for responsible disclosure process
→ See [9-SECURITY.md](9-SECURITY.md) for responsible disclosure process
---