fix: icon toggle real-time rendering + hyperscript architecture cleanup
CRITICAL FIX: Icon toggle now works without page refresh - Changed class name from 'show-logos' to 'show-icons' (CSS mismatch bug) - Updated localStorage key from 'cv-logos' to 'cv-icons' - Fixed toggleIcons() function in cv-functions.js HYPERSCRIPT ARCHITECTURE: - Moved 6 toggle functions from hyperscript to JavaScript (cv-functions.js) - Solves hyperscript 0.9.14 parser limitation (max 3 def statements total) - Upgraded hyperscript from 0.9.12 to 0.9.14 - Fixed operator precedence in keyboard shortcuts - Cleaned view-controls.html templates (inline → function calls) NEW FILES: - static/js/cv-functions.js - Global toggle functions (6 functions) - HYPERSCRIPT-RULES.md - Permanent architecture documentation - tests/mjs/0-zoom.test.mjs - Zoom functionality test - tests/mjs/1-toggles.test.mjs - Comprehensive toggle test with real-time verification - tests/TEST-SUMMARY.md - Test suite documentation TESTS: - Real-time DOM update verification (no refresh required) - Screenshot capture for visual regression - localStorage persistence validation - Toggle synchronization between action bar and menu BREAKING CHANGE: localStorage key changed from 'cv-logos' to 'cv-icons' Users may need to re-toggle icons preference on first load after update.
This commit is contained in:
@@ -126,111 +126,6 @@ def handleScroll()
|
||||
set :lastScroll to currentScroll
|
||||
end
|
||||
|
||||
-- ==============================================================================
|
||||
-- TOGGLE FUNCTIONS
|
||||
-- ==============================================================================
|
||||
|
||||
def toggleCVLength(isLong)
|
||||
set paper to the first .cv-paper
|
||||
set otherToggle to (#lengthToggle or #lengthToggleMenu)
|
||||
|
||||
if isLong is true
|
||||
remove .cv-short from paper
|
||||
add .cv-long to paper
|
||||
call localStorage.setItem('cv-length', 'long')
|
||||
if otherToggle exists set otherToggle's checked to true
|
||||
end
|
||||
|
||||
if isLong is false
|
||||
remove .cv-long from paper
|
||||
add .cv-short to paper
|
||||
call localStorage.setItem('cv-length', 'short')
|
||||
if otherToggle exists set otherToggle's checked to false
|
||||
end
|
||||
end
|
||||
|
||||
def toggleIcons(showIcons)
|
||||
set paper to the first .cv-paper
|
||||
set otherToggle to (#iconToggle or #iconToggleMenu)
|
||||
|
||||
if showIcons is true
|
||||
add .show-icons to paper
|
||||
call localStorage.setItem('cv-icons', 'true')
|
||||
if otherToggle exists set otherToggle's checked to true
|
||||
end
|
||||
|
||||
if showIcons is false
|
||||
remove .show-icons from paper
|
||||
call localStorage.setItem('cv-icons', 'false')
|
||||
if otherToggle exists set otherToggle's checked to false
|
||||
end
|
||||
end
|
||||
|
||||
def toggleTheme(isClean)
|
||||
set container to the first .cv-container
|
||||
set otherToggle to (#themeToggle or #themeToggleMenu)
|
||||
|
||||
if isClean is true
|
||||
add .theme-clean to container
|
||||
call localStorage.setItem('cv-theme', 'clean')
|
||||
if otherToggle exists set otherToggle's checked to true
|
||||
end
|
||||
|
||||
if isClean is false
|
||||
remove .theme-clean from container
|
||||
call localStorage.setItem('cv-theme', 'default')
|
||||
if otherToggle exists set otherToggle's checked to false
|
||||
end
|
||||
end
|
||||
|
||||
-- ==============================================================================
|
||||
-- HOVER SYNC FUNCTIONS
|
||||
-- ==============================================================================
|
||||
|
||||
def syncPdfHover(show)
|
||||
set pdfButtons to .pdf-download-button
|
||||
|
||||
if show is true
|
||||
for button in pdfButtons
|
||||
add .pdf-hover-sync to button
|
||||
end
|
||||
end
|
||||
|
||||
if show is false
|
||||
for button in pdfButtons
|
||||
remove .pdf-hover-sync from button
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def syncPrintHover(show)
|
||||
set printButtons to .print-button
|
||||
|
||||
if show is true
|
||||
for button in printButtons
|
||||
add .print-hover-sync to button
|
||||
end
|
||||
end
|
||||
|
||||
if show is false
|
||||
for button in printButtons
|
||||
remove .print-hover-sync from button
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def highlightZoomControl(show)
|
||||
set zoomWrapper to the first #zoom-wrapper
|
||||
|
||||
if show is true
|
||||
add .highlight to zoomWrapper
|
||||
end
|
||||
|
||||
if show is false
|
||||
remove .highlight from zoomWrapper
|
||||
end
|
||||
end
|
||||
|
||||
-- ==============================================================================
|
||||
-- KEYBOARD SHORTCUTS
|
||||
-- ==============================================================================
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* CV Site - Core Toggle Functions
|
||||
* =================================
|
||||
* Global JavaScript functions for CV toggles and interactions
|
||||
* These replace hyperscript def functions to avoid the 3-function parser limit
|
||||
*/
|
||||
|
||||
/**
|
||||
* Toggle CV Length (Short/Long)
|
||||
* @param {boolean} isLong - true for long CV, false for short
|
||||
*/
|
||||
function toggleCVLength(isLong) {
|
||||
const paper = document.querySelector('.cv-paper');
|
||||
const otherToggle = document.querySelector('#lengthToggle') || document.querySelector('#lengthToggleMenu');
|
||||
|
||||
if (isLong) {
|
||||
paper?.classList.remove('cv-short');
|
||||
paper?.classList.add('cv-long');
|
||||
localStorage.setItem('cv-length', 'long');
|
||||
if (otherToggle) otherToggle.checked = true;
|
||||
} else {
|
||||
paper?.classList.remove('cv-long');
|
||||
paper?.classList.add('cv-short');
|
||||
localStorage.setItem('cv-length', 'short');
|
||||
if (otherToggle) otherToggle.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle Icons Display
|
||||
* @param {boolean} showIcons - true to show icons, false to hide
|
||||
*/
|
||||
function toggleIcons(showIcons) {
|
||||
const paper = document.querySelector('.cv-paper');
|
||||
const otherToggle = document.querySelector('#iconToggle') || document.querySelector('#iconToggleMenu');
|
||||
|
||||
if (showIcons) {
|
||||
paper?.classList.add('show-icons');
|
||||
localStorage.setItem('cv-icons', 'true');
|
||||
if (otherToggle) otherToggle.checked = true;
|
||||
} else {
|
||||
paper?.classList.remove('show-icons');
|
||||
localStorage.setItem('cv-icons', 'false');
|
||||
if (otherToggle) otherToggle.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle Theme (Default/Clean)
|
||||
* @param {boolean} isClean - true for clean theme, false for default
|
||||
*/
|
||||
function toggleTheme(isClean) {
|
||||
const body = document.body;
|
||||
const otherToggle = document.querySelector('#themeToggle') || document.querySelector('#themeToggleMenu');
|
||||
|
||||
if (isClean) {
|
||||
body?.classList.add('theme-clean');
|
||||
localStorage.setItem('cv-theme', 'clean');
|
||||
if (otherToggle) otherToggle.checked = true;
|
||||
} else {
|
||||
body?.classList.remove('theme-clean');
|
||||
localStorage.setItem('cv-theme', 'default');
|
||||
if (otherToggle) otherToggle.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync PDF Button Hover State
|
||||
* @param {boolean} show - true to add hover class, false to remove
|
||||
*/
|
||||
function syncPdfHover(show) {
|
||||
const pdfButtons = document.querySelectorAll('.pdf-btn');
|
||||
|
||||
pdfButtons.forEach(button => {
|
||||
if (show) {
|
||||
button.classList.add('pdf-hover-sync');
|
||||
} else {
|
||||
button.classList.remove('pdf-hover-sync');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync Print Button Hover State
|
||||
* @param {boolean} show - true to add hover class, false to remove
|
||||
*/
|
||||
function syncPrintHover(show) {
|
||||
const printButtons = document.querySelectorAll('.print-btn');
|
||||
|
||||
printButtons.forEach(button => {
|
||||
if (show) {
|
||||
button.classList.add('print-hover-sync');
|
||||
} else {
|
||||
button.classList.remove('print-hover-sync');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight Zoom Control
|
||||
* @param {boolean} show - true to highlight, false to remove highlight
|
||||
*/
|
||||
function highlightZoomControl(show) {
|
||||
const zoomWrapper = document.querySelector('#zoom-wrapper');
|
||||
|
||||
if (show) {
|
||||
zoomWrapper?.classList.add('highlight');
|
||||
} else {
|
||||
zoomWrapper?.classList.remove('highlight');
|
||||
}
|
||||
}
|
||||
|
||||
// Make functions globally available
|
||||
window.toggleCVLength = toggleCVLength;
|
||||
window.toggleIcons = toggleIcons;
|
||||
window.toggleTheme = toggleTheme;
|
||||
window.syncPdfHover = syncPdfHover;
|
||||
window.syncPrintHover = syncPrintHover;
|
||||
window.highlightZoomControl = highlightZoomControl;
|
||||
Reference in New Issue
Block a user