This commit is contained in:
juanatsap
2025-11-12 23:07:44 +00:00
parent c99bb5590b
commit 15b73a915d
4 changed files with 139 additions and 111 deletions
+20 -107
View File
@@ -79,54 +79,18 @@
// Result: ~343 lines of JavaScript eliminated!
// =============================================================================
// PRINT & PDF
// PRINT & PDF - Now handled by Hyperscript in action-buttons.html
// =============================================================================
// Print Friendly - Apply Clean Theme + Short Version for minimal printing
window.printFriendly = function() {
const container = document.querySelector('.cv-container');
const paper = document.querySelector('.cv-paper');
const wasClean = container.classList.contains('theme-clean');
const wasLong = paper.classList.contains('cv-long');
// Store current zoom
const currentZoom = localStorage.getItem('cv-zoom') || '100';
// Apply clean theme for minimal print (no sidebars, no header, no icons)
if (!wasClean) {
container.classList.add('theme-clean');
}
// Force SHORT version for print (hide detailed content)
paper.classList.remove('cv-long');
paper.classList.add('cv-short');
// Temporarily reset zoom for printing
if (paper) {
paper.style.transform = 'scale(1)';
}
// Small delay to let CSS apply
setTimeout(() => {
window.print();
// Restore original theme and length after print dialog closes
setTimeout(() => {
if (!wasClean) {
container.classList.remove('theme-clean');
}
// Restore original length
if (wasLong) {
paper.classList.remove('cv-short');
paper.classList.add('cv-long');
}
// Restore zoom
if (paper && currentZoom !== '100') {
applyZoom(parseInt(currentZoom, 10), false);
}
}, 100);
}, 50);
};
// Print function moved to inline hyperscript on print button:
// - Stores current theme, length, and zoom state
// - Applies clean theme + short version for printing
// - Resets zoom to 100% for consistent print output
// - Calls window.print()
// - Restores original state after print dialog closes
// - Properly restores zoom by triggering slider input event (fixes Phase 5 bug)
//
// Result: ~44 lines of JavaScript eliminated!
// =============================================================================
// INITIALIZATION & PREFERENCES
@@ -153,68 +117,17 @@
}
// =============================================================================
// SCROLL BEHAVIOR
// SCROLL BEHAVIOR - Now handled by Hyperscript on <body> element
// =============================================================================
function initScrollBehavior() {
let lastScrollTop = 0;
let scrollThreshold = 100; // Start hiding after 100px scroll
window.addEventListener('scroll', function() {
const actionBar = document.querySelector('.action-bar');
const navMenu = document.querySelector('.navigation-menu');
const backToTopBtn = document.getElementById('back-to-top');
const infoBtn = document.querySelector('.info-button');
const currentScroll = window.pageYOffset || document.documentElement.scrollTop;
const isMenuOpen = navMenu.classList.contains('menu-open');
// Check if at bottom of page (within 50px threshold)
const scrollHeight = document.documentElement.scrollHeight;
const clientHeight = document.documentElement.clientHeight;
const isAtBottom = (scrollHeight - currentScroll - clientHeight) < 50;
// If scrolling up, reset the keepHeaderVisible flag
if (currentScroll < lastScrollTop) {
keepHeaderVisible = false;
}
// Hide/show header based on scroll direction
if (currentScroll > scrollThreshold) {
if (currentScroll > lastScrollTop && !keepHeaderVisible) {
// Scrolling down - hide header (only if keepHeaderVisible is false)
actionBar.classList.add('header-hidden');
// Only hide menu if it's open
if (isMenuOpen) {
navMenu.classList.add('header-hidden');
}
} else {
// Scrolling up - show header
actionBar.classList.remove('header-hidden');
// Only show menu if it's open
if (isMenuOpen) {
navMenu.classList.remove('header-hidden');
}
}
} else {
// At top - always show header
actionBar.classList.remove('header-hidden');
// Only affect menu if it's open
if (isMenuOpen) {
navMenu.classList.remove('header-hidden');
}
}
// Show/hide back to top button + at-bottom positioning
backToTopBtn.style.display = currentScroll > 300 ? 'flex' : 'none';
backToTopBtn?.classList.toggle('at-bottom', isAtBottom);
infoBtn?.classList.toggle('at-bottom', isAtBottom);
lastScrollTop = currentScroll <= 0 ? 0 : currentScroll;
}, false);
// Back to top - now uses native anchor link with CSS smooth scroll
// No click handler needed! Native <a href="#top"> with scroll-behavior: smooth
}
// Scroll behavior moved to inline hyperscript on body tag:
// - Header hide/show based on scroll direction (with 100px threshold)
// - Back-to-top button visibility (appears after 300px scroll)
// - At-bottom positioning for fixed buttons (within 50px of page bottom)
// - Menu visibility coordination when open
// - State tracking: lastScroll, scrollThreshold, keepHeaderVisible
//
// Result: ~59 lines of JavaScript eliminated!
// =============================================================================
// MODALS - Using Native <dialog> Element
@@ -319,7 +232,7 @@
document.addEventListener('DOMContentLoaded', function() {
initMenuSystem();
initPreferences();
initScrollBehavior();
// Scroll behavior now handled by hyperscript on <body>
initHTMXHandlers();
});
+55 -1
View File
@@ -101,7 +101,61 @@
}
</script>
</head>
<body {{if .ThemeClean}}class="theme-clean"{{end}}>
<body {{if .ThemeClean}}class="theme-clean"{{end}}
_="init
set :lastScroll to 0
set :scrollThreshold to 100
set :keepHeaderVisible to false
on scroll from window
set currentScroll to window.pageYOffset
set isMenuOpen to .navigation-menu.classList.contains('menu-open')
-- Calculate if at bottom (within 50px)
set scrollHeight to document.documentElement.scrollHeight
set clientHeight to document.documentElement.clientHeight
set isAtBottom to (scrollHeight - currentScroll - clientHeight) < 50
-- Reset keepHeaderVisible when scrolling up
if currentScroll < :lastScroll
set :keepHeaderVisible to false
end
-- Header visibility based on scroll direction
if currentScroll > :scrollThreshold
if currentScroll > :lastScroll and not :keepHeaderVisible
-- Scrolling down - hide header
add .header-hidden to .action-bar
if isMenuOpen then add .header-hidden to .navigation-menu end
else
-- Scrolling up - show header
remove .header-hidden from .action-bar
if isMenuOpen then remove .header-hidden from .navigation-menu end
end
else
-- At top - always show header
remove .header-hidden from .action-bar
if isMenuOpen then remove .header-hidden from .navigation-menu end
end
-- Back to top button visibility (show after 300px scroll)
if currentScroll > 300
set #back-to-top's *display to 'flex'
else
set #back-to-top's *display to 'none'
end
-- At-bottom positioning for fixed buttons
if isAtBottom
add .at-bottom to #back-to-top
add .at-bottom to #info-button
else
remove .at-bottom from #back-to-top
remove .at-bottom from #info-button
end
-- Update last scroll position
set :lastScroll to currentScroll">
<!-- Top anchor for back-to-top link -->
<div id="top"></div>
@@ -10,8 +10,42 @@
</button>
<button
class="action-btn print-btn"
onclick="printFriendly()"
aria-label="{{if eq .Lang "es"}}Imprimir amigable{{else}}Print Friendly{{end}}">
aria-label="{{if eq .Lang "es"}}Imprimir amigable{{else}}Print Friendly{{end}}"
_="on click
-- Store current state
set wasClean to .cv-container.classList.contains('theme-clean')
set wasLong to .cv-paper.classList.contains('cv-long')
set currentZoom to localStorage.getItem('cv-zoom') or '100'
-- Apply print-friendly settings
if not wasClean then add .theme-clean to .cv-container end
remove .cv-long from .cv-paper
add .cv-short to .cv-paper
-- Reset zoom for printing (directly set wrapper zoom to 1)
set #zoom-wrapper's *zoom to 1
-- Let CSS apply, then print
wait 50ms
call window.print()
-- Wait for print dialog to close, then restore
wait 100ms
-- Restore original theme
if not wasClean then remove .theme-clean from .cv-container end
-- Restore original length
if wasLong
remove .cv-short from .cv-paper
add .cv-long to .cv-paper
end
-- Restore original zoom by triggering slider input event
if currentZoom !== '100'
set #zoom-slider's value to currentZoom
send input to #zoom-slider
end">
<iconify-icon icon="mdi:leaf" width="18" height="18"></iconify-icon>
{{if eq .Lang "es"}}Imprimir amigable{{else}}Print Friendly{{end}}
</button>
@@ -158,7 +158,34 @@
<span>{{if eq .Lang "es"}}Descargar como PDF{{else}}Download as PDF{{end}}</span>
</button>
<button class="menu-action-btn" onclick="printFriendly()">
<button class="menu-action-btn"
_="on click
-- Store current state
set wasClean to .cv-container.classList.contains('theme-clean')
set wasLong to .cv-paper.classList.contains('cv-long')
set currentZoom to localStorage.getItem('cv-zoom') or '100'
-- Apply print-friendly settings
if not wasClean then add .theme-clean to .cv-container end
remove .cv-long from .cv-paper
add .cv-short to .cv-paper
set #zoom-wrapper's *zoom to 1
-- Print and restore
wait 50ms
call window.print()
wait 100ms
-- Restore original state
if not wasClean then remove .theme-clean from .cv-container end
if wasLong
remove .cv-short from .cv-paper
add .cv-long to .cv-paper
end
if currentZoom !== '100'
set #zoom-slider's value to currentZoom
send input to #zoom-slider
end">
<iconify-icon icon="mdi:leaf" width="20" height="20"></iconify-icon>
<span>{{if eq .Lang "es"}}Imprimir amigable{{else}}Print Friendly{{end}}</span>
</button>