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
+94 -10
View File
@@ -61,26 +61,96 @@ static/hyperscript/
end">
```
### Rule 4: Event Handler Externalization Guidelines (2025-11-20)
**Know what CAN and CANNOT be externalized**
#### ✅ **CAN Be Externalized:**
**Simple function calls without complex event inspection:**
```html
<!-- Navigation handlers -->
<a href="#section" _="on click call scrollToSection(event, 'section')">
<!-- Toggle handlers -->
<input _="on change call toggleCVLength(my.checked)">
<!-- Hover handlers -->
<button _="on mouseenter call syncPdfHover(true)
on mouseleave call syncPdfHover(false)">
```
**External function example:**
```hyperscript
def scrollToSection(event, sectionId)
call event.preventDefault()
set element to document.getElementById(sectionId)
if element then call element.scrollIntoView({behavior: 'smooth'}) end
end
```
#### ❌ **MUST Stay Inline:**
**Complex event handlers that inspect event properties:**
```html
<!-- Keyboard handlers with event.key, event.target inspection -->
<body _="on keydown
set tagName to event.target.tagName
set isInputField to (tagName is 'INPUT' or tagName is 'TEXTAREA')
if event.key is 'l' and not event.ctrlKey and not isInputField
halt the event
-- handler logic here
end
end">
```
**Why:** The `event` variable in `_=""` attributes is a hyperscript runtime variable. External `def` functions don't have direct access to this event context, causing scoping issues.
#### 🎯 **Optimization for Inline Handlers:**
**Use `then` chains to make inline code more compact:**
```hyperscript
-- Before (verbose)
if condition
do step1
do step2
do step3
end
-- After (compact with then chains)
if condition
do step1 then do step2 then do step3
end
```
**Example from body keyboard handler:**
```html
if event.key is '?' and not event.ctrlKey and not event.metaKey and not event.altKey and not isInputField
halt the event then set modal to #shortcuts-modal then if modal then call modal.showModal() end
end
```
## File Organization
```
static/hyperscript/
├── functions._hs → Core utilities (3 defs max)
├── toggles._hs → Toggle functions (3 defs max)
── hover._hs → Hover sync functions (3 defs max)
├── utils._hs → Core utilities (scroll, print, etc.)
├── toggles._hs → Toggle functions (CV length, icons, theme)
── hover-sync._hs → Hover sync functions (PDF, print, zoom)
├── navigation._hs → Navigation functions (scroll-to-section) [2025-11-20]
└── keyboard._hs → Keyboard handler reference (inline in body tag)
```
### Load Order in templates/index.html:
```html
<script type="text/hyperscript" src="/static/hyperscript/functions._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/utils._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/toggles._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/hover._hs"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
<script type="text/hyperscript" src="/static/hyperscript/hover-sync._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/keyboard._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/navigation._hs"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.14"></script>
```
## Required Functions
### Core Functions (functions._hs)
### Core Functions (utils._hs)
1. `printFriendly()` - Handle print-friendly view
2. `initScrollBehavior()` - Initialize scroll variables
3. `handleScroll()` - Manage scroll behavior and fixed button positioning
@@ -90,11 +160,14 @@ static/hyperscript/
2. `toggleIcons(showIcons)` - Show/hide icons
3. `toggleTheme(isClean)` - Switch between default/clean theme
### Hover Sync Functions (hover._hs)
### Hover Sync Functions (hover-sync._hs)
1. `syncPdfHover(show)` - Sync hover state across PDF buttons
2. `syncPrintHover(show)` - Sync hover state across print buttons
3. `highlightZoomControl(show)` - Highlight zoom control on hover
### Navigation Functions (navigation._hs) [2025-11-20]
1. `scrollToSection(event, sectionId)` - Smooth scroll to CV section
## Why These Rules Exist
### Maintainability
@@ -131,6 +204,17 @@ static/hyperscript/
---
**Last Updated**: 2025-01-17
**Hyperscript Version**: 0.9.12
## Recent Changes
### 2025-11-20: Event Handler Externalization Guidelines
- ✅ Added Rule 4: Clear guidelines on what can/cannot be externalized
- ✅ Navigation handlers successfully externalized (9 links → 1 function)
- ✅ Documented `then` chain optimization for inline handlers
- ✅ Updated file organization with navigation._hs
- ⚠️ Keyboard handlers documented to stay inline (event context requirement)
---
**Last Updated**: 2025-11-20
**Hyperscript Version**: 0.9.14+
**Status**: MANDATORY - ALWAYS FOLLOW