1document.addEventListener("DOMContentLoaded", function () { 2 if (typeof tippy !== "undefined") { 3 // Initialize tooltips for feature list items (uses template for HTML content) 4 const tooltipElements = document.querySelectorAll(".feature-with-tooltip"); 5 6 tooltipElements.forEach(function (element) { 7 const template = element.previousElementSibling; 8 if (template && template.classList.contains("tooltip-template")) { 9 tippy(element, { 10 allowHTML: true, 11 placement: "top", 12 theme: "dark", 13 arrow: true, 14 interactive: false, 15 maxWidth: 300, 16 content: template.innerHTML, 17 }); 18 } 19 }); 20 21 // Initialize tooltips for footnote tooltips (uses data-tippy-content for simple text) 22 tippy(".footnote-tooltip", { 23 placement: "top", 24 theme: "dark", 25 arrow: true, 26 interactive: false, 27 }); 28 } 29 30 // Add shadow to sticky comparison header only when it's actually sticky 31 function updateScrolledComparisonHeader() { 32 const comparisonHeader = document.querySelector( 33 ".comparison__shared-header" 34 ); 35 if (!comparisonHeader) { 36 return; 37 } 38 39 // Check if the header is actually in sticky position 40 // The header becomes sticky at top: 75px, so check if its top position equals 75px 41 const rect = comparisonHeader.getBoundingClientRect(); 42 const stickyTop = 75; // matches top: 75px in CSS 43 44 // Header is sticky when its top position equals the sticky top value 45 // Add a small tolerance (1px) for rounding 46 if (Math.abs(rect.top - stickyTop) < 1) { 47 comparisonHeader.classList.add("is-scrolled"); 48 } else { 49 comparisonHeader.classList.remove("is-scrolled"); 50 } 51 } 52 53 // Update sticky header section title based on which table is visible 54 function updateStickySectionTitle() { 55 const stickyTitle = document.querySelector( 56 ".comparison__sticky-section-title" 57 ); 58 if (!stickyTitle) { 59 return; 60 } 61 62 const sections = document.querySelectorAll(".comparison__table-section"); 63 const stickyHeader = document.querySelector(".comparison__shared-header"); 64 if (!stickyHeader) { 65 return; 66 } 67 68 const stickyHeaderRect = stickyHeader.getBoundingClientRect(); 69 const stickyTop = 75; // matches top: 75px in CSS 70 const isSticky = Math.abs(stickyHeaderRect.top - stickyTop) < 1; 71 72 // Only update title when header is sticky 73 if (!isSticky) { 74 stickyTitle.textContent = ""; 75 return; 76 } 77 78 // Find which section title is currently closest to or above the sticky header 79 let currentSection = null; 80 let closestDistance = Infinity; 81 82 sections.forEach((section) => { 83 const sectionTitle = section.querySelector( 84 ".comparison__table-section-title" 85 ); 86 if (!sectionTitle) { 87 return; 88 } 89 90 const titleRect = sectionTitle.getBoundingClientRect(); 91 const sectionRect = section.getBoundingClientRect(); 92 93 // Check if the section title is above or at the sticky header position 94 // We want to show the title of the section that's currently being viewed 95 if (titleRect.bottom <= stickyTop + 150) { 96 // Section title is above or near the sticky header 97 const distance = Math.abs(titleRect.bottom - stickyTop); 98 if (distance < closestDistance) { 99 closestDistance = distance; 100 currentSection = sectionTitle; 101 } 102 } else if ( 103 sectionRect.top <= stickyTop + 50 && 104 sectionRect.bottom > stickyTop 105 ) { 106 // Section is currently visible at the sticky header position 107 const distance = Math.abs(sectionRect.top - stickyTop); 108 if (distance < closestDistance) { 109 closestDistance = distance; 110 currentSection = sectionTitle; 111 } 112 } 113 }); 114 115 // Update the sticky header title 116 if (currentSection) { 117 const newTitle = currentSection.textContent.trim(); 118 if (stickyTitle.textContent !== newTitle) { 119 stickyTitle.textContent = newTitle; 120 } 121 } 122 } 123 124 // Throttle scroll events for better performance 125 let scrollTimeout; 126 127 function handleScroll() { 128 if (scrollTimeout) { 129 cancelAnimationFrame(scrollTimeout); 130 } 131 scrollTimeout = requestAnimationFrame(() => { 132 updateScrolledComparisonHeader(); 133 updateStickySectionTitle(); 134 }); 135 } 136 137 // Set up scroll listener and initialize on page load 138 window.addEventListener("scroll", handleScroll, { passive: true }); 139 updateScrolledComparisonHeader(); 140 updateStickySectionTitle(); 141});
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.