1/* Practice Pages Common JavaScript */ 2/* Used by: company.htm, topic.htm */ 3 4// Theme Toggle 5function toggleTheme() { 6 const body = document.body; 7 const toggleBtn = document.querySelector('.tp-theme-toggle'); 8 9 body.classList.toggle('dark-theme'); 10 11 if (body.classList.contains('dark-theme')) { 12 toggleBtn.innerHTML = '<i class="fa-sharp fa-light fa-sun"></i>'; 13 localStorage.setItem('theme', 'dark'); 14 } else { 15 toggleBtn.innerHTML = '<i class="fa-sharp fa-light fa-moon"></i>'; 16 localStorage.setItem('theme', 'light'); 17 } 18} 19 20// Check LocalStorage on page load for theme 21document.addEventListener('DOMContentLoaded', function() { 22 const savedTheme = localStorage.getItem('theme'); 23 const toggleBtn = document.querySelector('.tp-theme-toggle'); 24 25 if (savedTheme === 'dark') { 26 document.body.classList.add('dark-theme'); 27 if (toggleBtn) { 28 toggleBtn.innerHTML = '<i class="fa-sharp fa-light fa-sun"></i>'; 29 } 30 } 31 32 // Check for scroll to problems section flag 33 if (sessionStorage.getItem('scrollToProblems') === 'true') { 34 sessionStorage.removeItem('scrollToProblems'); 35 36 // Wait a bit for page to fully render 37 setTimeout(function() { 38 const target = document.getElementById('companyProblemsSection') || 39 document.getElementById('topicProblemsSection'); 40 if (target) { 41 const headerOffset = 80; 42 const elementPosition = target.getBoundingClientRect().top; 43 const offsetPosition = elementPosition + window.pageYOffset - headerOffset; 44 45 window.scrollTo({ 46 top: offsetPosition, 47 behavior: 'smooth' 48 }); 49 } 50 }, 100); 51 } 52}); 53 54// Build clean page URL (for company, topic, or all problems) 55function buildPageUrl(page, entityId, entityType) { 56 // Handle "all problems" page (no entityId) 57 if (!entityId || entityId === '') { 58 if (page <= 1) { 59 return '/problems'; 60 } 61 return '/problems/' + page; 62 } 63 64 const basePath = entityType === 'topic' ? '/topic/' : '/company/'; 65 if (page <= 1) { 66 return basePath + entityId; 67 } 68 return basePath + entityId + '/' + page; 69} 70 71// Initialize Swiper for stats slider 72function initStatsSlider() { 73 if (typeof Swiper !== 'undefined' && document.querySelector('.practice-stats-slider')) { 74 new Swiper('.practice-stats-slider', { 75 slidesPerView: 'auto', 76 spaceBetween: 16, 77 freeMode: true, 78 grabCursor: true, 79 breakpoints: { 80 320: { slidesPerView: 2, spaceBetween: 10 }, 81 480: { slidesPerView: 3, spaceBetween: 12 }, 82 768: { slidesPerView: 4, spaceBetween: 14 }, 83 1024: { slidesPerView: 5, spaceBetween: 16 }, 84 1200: { slidesPerView: 6, spaceBetween: 16 } 85 } 86 }); 87 } 88} 89 90// Initialize banner slider 91function initBannerSlider() { 92 if (typeof Swiper !== 'undefined' && document.querySelector('.banner-swiper')) { 93 new Swiper('.banner-swiper', { 94 slidesPerView: 1, 95 spaceBetween: 20, 96 loop: true, 97 autoplay: { 98 delay: 5000, 99 disableOnInteraction: false, 100 }, 101 pagination: { 102 el: '.swiper-pagination', 103 clickable: true, 104 }, 105 navigation: { 106 nextEl: '.practice-nav-next', 107 prevEl: '.practice-nav-prev', 108 }, 109 breakpoints: { 110 768: { 111 slidesPerView: 2, 112 spaceBetween: 20 113 }, 114 1024: { 115 slidesPerView: 3, 116 spaceBetween: 24 117 } 118 } 119 }); 120 } 121} 122 123// Scroll to section with offset 124function scrollToSection(sectionId) { 125 const target = document.getElementById(sectionId); 126 if (target) { 127 const headerOffset = 80; 128 const elementPosition = target.getBoundingClientRect().top; 129 const offsetPosition = elementPosition + window.pageYOffset - headerOffset; 130 131 window.scrollTo({ 132 top: offsetPosition, 133 behavior: 'smooth' 134 }); 135 } 136} 137 138// Start Practicing button handler 139function initStartPracticingBtn() { 140 const btn = document.getElementById('startPracticingBtn'); 141 if (btn) { 142 btn.addEventListener('click', function(e) { 143 e.preventDefault(); 144 this.classList.add('loading'); 145 146 const targetId = this.getAttribute('href').replace('#', ''); 147 scrollToSection(targetId); 148 149 setTimeout(() => { 150 this.classList.remove('loading'); 151 }, 800); 152 }); 153 } 154} 155 156// Add spinner to card/link on click 157function initCardSpinners() { 158 // Topic cards (both grid and expanded) 159 const topicCards = document.querySelectorAll('.card[href*="/topic/"], .card-small[href*="/topic/"]'); 160 topicCards.forEach(card => { 161 card.addEventListener('click', function(e) { 162 // Don't add spinner to "See All" button 163 if (this.id === 'seeAllBtn') return; 164 165 const h4 = this.querySelector('h4'); 166 if (h4) { 167 h4.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Loading...'; 168 } 169 }); 170 }); 171
172 // Company stat cards in slider 173 const companyCards = document.querySelectorAll('.practice-stat-card[href*="/company/"]'); 174 companyCards.forEach(card => { 175 card.addEventListener('click', function(e) { 176 const valueEl = this.querySelector('.practice-stat-value'); 177 const labelEl = this.querySelector('.practice-stat-label'); 178 if (valueEl) { 179 valueEl.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i>'; 180 } 181 if (labelEl) { 182 labelEl.textContent = 'Loading...'; 183 } 184 }); 185 }); 186 187 // Proto6 tutorial cards 188 const tutorialCards = document.querySelectorAll('.proto6-card'); 189 tutorialCards.forEach(card => { 190 card.addEventListener('click', function(e) { 191 const h4 = this.querySelector('h4'); 192 if (h4) { 193 h4.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Loading...'; 194 } 195 }); 196 }); 197 198 // Proto6 category items (sidebar) 199 const catItems = document.querySelectorAll('.proto6-cat-item'); 200 catItems.forEach(item => { 201 item.addEventListener('click', function(e) { 202 // Show spinner 203 const text = this.childNodes[0].textContent.trim(); 204 this.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Loading... <span class="count">' + (this.querySelector('.count')?.textContent || '') + '</span>'; 205 }); 206 }); 207} 208 209// Initialize all common functionality 210document.addEventListener('DOMContentLoaded', function() { 211 initStatsSlider(); 212 initBannerSlider(); 213 initStartPracticingBtn(); 214 initCardSpinners(); 215});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.