defuse/security-reference-guide
0
1// Security Reference Guide - Interactive Features2 3document.addEventListener('DOMContentLoaded', function() {4 // Initialize Feather Icons5 feather.replace();6 7 // Mobile menu toggle8 const mobileMenuButton = document.getElementById('mobile-menu-button');9 const mobileMenu = document.getElementById('mobile-menu');10 11 if (mobileMenuButton && mobileMenu) {12 mobileMenuButton.addEventListener('click', function() {13 mobileMenu.classList.toggle('hidden');14 const icon = mobileMenuButton.querySelector('i');15 if (mobileMenu.classList.contains('hidden')) {16 icon.setAttribute('data-feather', 'menu');17 } else {18 icon.setAttribute('data-feather', 'x');19 }20 feather.replace();21 });22 }23 24 // Smooth scrolling for navigation links25 const navLinks = document.querySelectorAll('a[href^="#"]');26 navLinks.forEach(link => {27 link.addEventListener('click', function(e) {28 e.preventDefault();29 const targetId = this.getAttribute('href');30 const targetElement = document.querySelector(targetId);31 32 if (targetElement) {33 const offsetTop = targetElement.offsetTop - 80; // Account for fixed navbar34 window.scrollTo({35 top: offsetTop,36 behavior: 'smooth'37 });38 }39 40 // Close mobile menu if open41 if (mobileMenu && !mobileMenu.classList.contains('hidden')) {42 mobileMenu.classList.add('hidden');43 const icon = mobileMenuButton.querySelector('i');44 icon.setAttribute('data-feather', 'menu');45 feather.replace();46 }47 });48 });49 50 // Back to top button51 const backToTopButton = document.getElementById('back-to-top');52 53 function toggleBackToTopButton() {54 if (window.pageYOffset > 300) {55 backToTopButton.classList.remove('opacity-0', 'invisible');56 } else {57 backToTopButton.classList.add('opacity-0', 'invisible');58 }59 }60 61 if (backToTopButton) {62 backToTopButton.addEventListener('click', function() {63 window.scrollTo({64 top: 0,65 behavior: 'smooth'66 });67 });68 }69 70 // Scroll event listener71 window.addEventListener('scroll', toggleBackToTopButton);72 73 // Navbar background change on scroll74 const navbar = document.querySelector('nav');75 function updateNavbarBackground() {76 if (window.scrollY > 50) {77 navbar.classList.add('bg-black-900/98');78 navbar.classList.remove('bg-black-900/95');79 } else {80 navbar.classList.add('bg-black-900/95');81 navbar.classList.remove('bg-black-900/98');82 }83 }84 85 window.addEventListener('scroll', updateNavbarBackground);86 87 // Intersection Observer for fade-in animations88 const observerOptions = {89 threshold: 0.1,90 rootMargin: '0px 0px -50px 0px'91 };92 93 const observer = new IntersectionObserver(function(entries) {94 entries.forEach(entry => {95 if (entry.isIntersecting) {96 entry.target.classList.add('fade-in-up');97 observer.unobserve(entry.target);98 }99 });100 }, observerOptions);101 102 // Observe vulnerability cards103 const vulnerabilityCards = document.querySelectorAll('.vulnerability-card');104 vulnerabilityCards.forEach(card => {105 observer.observe(card);106 });107 108 // Observe sections109 const sections = document.querySelectorAll('section');110 sections.forEach(section => {111 observer.observe(section);112 });113 114 // Copy code functionality115 function addCopyButtons() {116 const codeBlocks = document.querySelectorAll('pre');117 codeBlocks.forEach(block => {118 const copyButton = document.createElement('button');119 copyButton.className = 'absolute top-2 right-2 bg-gray-700 hover:bg-gray-600 text-white px-3 py-1 rounded text-xs transition-colors';120 copyButton.innerHTML = '<i data-feather="copy" class="w-3 h-3"></i>';121 copyButton.title = 'Copy code';122 123 const container = document.createElement('div');124 container.className = 'relative';125 block.parentNode.insertBefore(container, block);126 container.appendChild(block);127 container.appendChild(copyButton);128 129 copyButton.addEventListener('click', function() {130 const codeText = block.textContent;131 navigator.clipboard.writeText(codeText).then(() => {132 const icon = copyButton.querySelector('i');133 icon.setAttribute('data-feather', 'check');134 feather.replace();135 136 setTimeout(() => {137 icon.setAttribute('data-feather', 'copy');138 feather.replace();139 }, 2000);140 }).catch(err => {141 console.error('Failed to copy text: ', err);142 });143 });144 });145 }146 147 // Initialize copy buttons after a short delay to ensure DOM is ready148 setTimeout(addCopyButtons, 1000);149 150 // Active navigation highlighting151 function updateActiveNavigation() {152 const sections = document.querySelectorAll('section[id]');153 const navLinks = document.querySelectorAll('nav a[href^="#"]');154 155 let currentSection = '';156 sections.forEach(section => {157 const sectionTop = section.offsetTop - 100;158 const sectionHeight = section.offsetHeight;159 160 if (window.pageYOffset >= sectionTop && window.pageYOffset < sectionTop + sectionHeight) {161 currentSection = section.getAttribute('id');162 }163 });164 165 navLinks.forEach(link => {166 link.classList.remove('text-accent-500');167 if (link.getAttribute('href') === `#${currentSection}`) {168 link.classList.add('text-accent-500');169 }170 });171 }172 173 window.addEventListener('scroll', updateActiveNavigation);174 175 // Keyboard navigation enhancements176 document.addEventListener('keydown', function(e) {177 // Alt + number keys for quick section navigation178 if (e.altKey) {179 switch(e.key) {180 case '1':181 e.preventDefault();182 document.querySelector('#overview')?.scrollIntoView({ behavior: 'smooth' });183 break;184 case '2':185 e.preventDefault();186 document.querySelector('#vulnerabilities')?.scrollIntoView({ behavior: 'smooth' });187 break;188 case '3':189 e.preventDefault();190 document.querySelector('#methodologies')?.scrollIntoView({ behavior: 'smooth' });191 break;192 case '4':193 e.preventDefault();194 document.querySelector('#resources')?.scrollIntoView({ behavior: 'smooth' });195 break;196 }197 }198 });199 200 // Print optimization201 window.addEventListener('beforeprint', function() {202 // Expand all collapsed sections for printing203 document.querySelectorAll('.hidden').forEach(element => {204 element.classList.remove('hidden');205 });206 });207 208 // Search functionality (basic implementation)209 function initializeSearch() {210 const searchInput = document.getElementById('search-input');211 if (!searchInput) return;212 213 searchInput.addEventListener('input', function() {214 const searchTerm = this.value.toLowerCase();215 const vulnerabilityCards = document.querySelectorAll('.vulnerability-card');216 217 vulnerabilityCards.forEach(card => {218 const title = card.querySelector('h3').textContent.toLowerCase();219 const content = card.textContent.toLowerCase();220 221 if (title.includes(searchTerm) || content.includes(searchTerm)) {222 card.style.display = 'block';223 } else {224 card.style.display = 'none';225 }226 });227 });228 }229 230 // Enhanced vulnerability filtering231 function initializeVulnerabilityFilters() {232 const filterButtons = document.querySelectorAll('[data-filter]');233 filterButtons.forEach(button => {234 button.addEventListener('click', function() {235 const filter = this.getAttribute('data-filter');236 const vulnerabilityCards = document.querySelectorAll('.vulnerability-card');237 238 vulnerabilityCards.forEach(card => {239 if (filter === 'all') {240 card.style.display = 'block';241 } else {242 const severity = card.querySelector('.bg-red-500, .bg-orange-500') ? 243 (card.querySelector('.bg-red-500') ? 'critical' : 'high') : 244 'medium';245 card.style.display = severity === filter ? 'block' : 'none';246 }247 });248 249 // Update active filter button250 filterButtons.forEach(btn => btn.classList.remove('bg-accent-500'));251 this.classList.add('bg-accent-500');252 });253 });254 }255 256 // Performance monitoring257 function logPerformanceMetrics() {258 if ('performance' in window) {259 window.addEventListener('load', function() {260 setTimeout(() => {261 const perfData = performance.getEntriesByType('navigation')[0];262 console.log('Page Load Time:', perfData.loadEventEnd - perfData.loadEventStart, 'ms');263 console.log('DOM Content Loaded:', perfData.domContentLoadedEventEnd - perfData.domContentLoadedEventStart, 'ms');264 }, 0);265 });266 }267 }268 269 // Initialize all features270 initializeSearch();271 initializeVulnerabilityFilters();272 logPerformanceMetrics();273 274 // Error handling for images275 document.querySelectorAll('img').forEach(img => {276 img.addEventListener('error', function() {277 this.style.display = 'none';278 console.warn('Failed to load image:', this.src);279 });280 });281 282 // Accessibility enhancements283 function enhanceAccessibility() {284 // Add skip link285 const skipLink = document.createElement('a');286 skipLink.href = '#main-content';287 skipLink.textContent = 'Skip to main content';288 skipLink.className = 'sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 bg-accent-500 text-white px-4 py-2 rounded z-50';289 document.body.insertBefore(skipLink, document.body.firstChild);290 291 // Add ARIA labels to navigation292 const nav = document.querySelector('nav');293 if (nav) nav.setAttribute('role', 'navigation');294 295 // Add main landmark296 const mainContent = document.querySelector('section');297 if (mainContent) {298 mainContent.setAttribute('id', 'main-content');299 mainContent.setAttribute('role', 'main');300 }301 }302 303 enhanceAccessibility();304 305 console.log('Security Reference Guide initialized successfully');306});