Team Ai
Apppublic

defuse/security-reference-guide

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
script.js306 linesDownload Raw Back to root
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});