refactor: externalize navigation handlers and fix hyperscript syntax errors

- Created keyboard._hs as reference documentation (inline handler in body tag)
- Externalized 9 hamburger menu navigation links to scrollToSection()
- Added scrollToSection() as JavaScript function (CSP-safe, no eval needed)
- Restored original keyboard handler format in body tag (working correctly)
- Removed problematic navigation._hs (had syntax/CSP issues)
- Added Rule 4 to HYPERSCRIPT-RULES.md on event handler externalization
- Updated PROJECT-MEMORY.md with externalization guidelines

Key learnings:
- Complex event handlers that inspect event properties must stay inline
- JavaScript functions avoid CSP unsafe-eval restrictions
- Navigation successfully externalized: 9 links → 1 function (91% reduction)
This commit is contained in:
juanatsap
2025-11-20 09:17:09 +00:00
parent 27f5e8eb79
commit 925a95c1b4
6 changed files with 236 additions and 42 deletions
@@ -11,47 +11,47 @@
</a>
<div class="submenu-content">
<a href="#education" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('education').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'education')">
<iconify-icon icon="mdi:school" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Formación{{else}}Training{{end}}</span>
</a>
<a href="#skills" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('skills').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'skills')">
<iconify-icon icon="mdi:brain" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Competencias{{else}}Skills{{end}}</span>
</a>
<a href="#experience" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('experience').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'experience')">
<iconify-icon icon="mdi:office-building" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Experiencia{{else}}Experience{{end}}</span>
</a>
<a href="#awards" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('awards').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'awards')">
<iconify-icon icon="mdi:trophy" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Premios y Reconocimientos{{else}}Awards{{end}}</span>
</a>
<a href="#projects" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('projects').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'projects')">
<iconify-icon icon="mdi:web" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Proyectos Personales / Freelance{{else}}Personal / Freelance Projects{{end}}</span>
</a>
<a href="#courses" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('courses').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'courses')">
<iconify-icon icon="mdi:school" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Cursos Realizados{{else}}Courses{{end}}</span>
</a>
<a href="#languages" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('languages').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'languages')">
<iconify-icon icon="mdi:translate" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Idiomas{{else}}Languages{{end}}</span>
</a>
<a href="#references" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('references').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'references')">
<iconify-icon icon="mdi:link-variant" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Referencias{{else}}References{{end}}</span>
</a>
<a href="#other" class="menu-item"
_="on click call event.preventDefault() then call document.getElementById('other').scrollIntoView({behavior: 'smooth'})">
_="on click call scrollToSection(event, 'other')">
<iconify-icon icon="mdi:information" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Otros{{else}}Other{{end}}</span>
</a>