ba44b435e7
Inline Hyperscript Refactoring: - Body tag keyboard handlers: 20→8 lines (using helper functions) - Zoom control handlers: 85→35 lines (using zoom._hs) - PDF modal card selection: 90→6 lines (3 identical blocks eliminated) New Hyperscript Files: - zoom._hs: handleZoomInput, handleZoomReset, initZoomControl - pdf-modal._hs: selectPdfCard, handlePdfCardKey JavaScript Elimination (232 lines removed): - cv-functions.js: REMOVED - hyperscript defs are globally available - scroll-at-bottom-handler.js: REMOVED - duplicate of handleScroll() - footer-buttons-interaction.js: REMOVED - moved to hyperscript Added Tests: - 32-hyperscript-multi-src.test.mjs: Verifies multi-file loading - 33-keyboard-shortcuts-refactored.test.mjs: Keyboard shortcuts - 34-hyperscript-refactor-comprehensive.test.mjs: Full test suite Key Findings: - No hyperscript multi-file bug in 0.9.14 - Hyperscript def statements are globally accessible - Previous refactoring failures were syntax errors, not library bugs
77 lines
3.2 KiB
HTML
77 lines
3.2 KiB
HTML
{{define "zoom-control"}}
|
|
<!-- Zoom Control (Fixed Bottom Center, Draggable) - Hyperscript Enhanced -->
|
|
<div id="zoom-control" class="zoom-control no-print zoom-hidden" role="group" aria-label="{{if eq .Lang "es"}}Control de zoom{{else}}Zoom control{{end}}"
|
|
_="on load call initZoomControl(me)
|
|
|
|
on mousedown(clientX, clientY)
|
|
set target to event.target
|
|
set tag to target.tagName
|
|
if tag is 'INPUT' or tag is 'BUTTON' then exit end
|
|
if target.classList.contains('zoom-slider') or target.classList.contains('zoom-close-btn') or target.classList.contains('zoom-reset-btn') or target.classList.contains('zoom-value') then exit end
|
|
if target.closest('.zoom-close-btn') or target.closest('.zoom-reset-btn') then exit end
|
|
set :isDragging to true
|
|
set my *transition to 'none'
|
|
set rect to my getBoundingClientRect()
|
|
set :initialX to clientX - rect.left
|
|
set :initialY to clientY - rect.top
|
|
halt the event
|
|
|
|
on mousemove(clientX, clientY) from document
|
|
if :isDragging is not true then exit end
|
|
halt the event
|
|
set currentX to clientX - :initialX
|
|
set currentY to clientY - :initialY
|
|
set maxX to window.innerWidth - my offsetWidth
|
|
set maxY to window.innerHeight - my offsetHeight
|
|
set currentX to Math.max(0, Math.min(currentX, maxX))
|
|
set currentY to Math.max(0, Math.min(currentY, maxY))
|
|
set my *left to `${currentX}px`
|
|
set my *bottom to `${window.innerHeight - currentY - my offsetHeight}px`
|
|
set my *transform to 'none'
|
|
|
|
on mouseup from document
|
|
if :isDragging is not true then exit end
|
|
set :isDragging to false
|
|
set my *transition to 'all 0.3s ease'
|
|
set position to { bottom: my *bottom, left: my *left }
|
|
set localStorage['cv-zoom-position'] to JSON.stringify(position)">
|
|
|
|
<button
|
|
id="zoom-close"
|
|
class="zoom-close-btn"
|
|
aria-label="{{if eq .Lang "es"}}Cerrar control de zoom{{else}}Close zoom control{{end}}"
|
|
title="{{if eq .Lang "es"}}Cerrar{{else}}Close{{end}}">
|
|
<iconify-icon icon="mdi:close" width="16" height="16" style="pointer-events: none;"></iconify-icon>
|
|
</button>
|
|
|
|
<span class="zoom-value zoom-value-min" aria-hidden="true">25</span>
|
|
|
|
<input
|
|
type="range"
|
|
id="zoom-slider"
|
|
class="zoom-slider"
|
|
min="25"
|
|
max="300"
|
|
step="1"
|
|
value="100"
|
|
aria-label="{{if eq .Lang "es"}}Ajustar nivel de zoom del CV{{else}}Adjust CV zoom level{{end}}"
|
|
aria-valuemin="25"
|
|
aria-valuemax="300"
|
|
aria-valuenow="100"
|
|
aria-valuetext="100%"
|
|
_="on input call handleZoomInput(me)">
|
|
|
|
<span class="zoom-value zoom-value-max" aria-hidden="true">300</span>
|
|
|
|
<button
|
|
id="zoom-reset"
|
|
class="zoom-reset-btn"
|
|
aria-label="{{if eq .Lang "es"}}Restablecer zoom al 100%{{else}}Reset zoom to 100%{{end}}"
|
|
title="{{if eq .Lang "es"}}Restablecer{{else}}Reset{{end}}"
|
|
aria-live="polite"
|
|
_="on click call handleZoomReset()">
|
|
<span id="zoom-value-current">100</span>
|
|
</button>
|
|
</div>
|
|
{{end}}
|