wip
This commit is contained in:
+20
-107
@@ -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
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user