1(function() { 2 'use strict'; 3 4 document.addEventListener('DOMContentLoaded', function() { 5 // Language Segmented Control 6 const languageSegments = document.querySelectorAll('.language-segment'); 7 const segmentedControl = document.querySelector('.language-segmented-control'); 8 9 if (languageSegments.length === 0) return; 10 11 /** 12 * Set active language based on current URL 13 */ 14 function setActiveLanguage() { 15 if (languageSegments.length === 0) return; 16 17 const currentUrl = window.location.href; 18 const currentUrlNormalized = currentUrl.split('?')[0].replace(/\/$/, ''); 19 let activeFound = false; 20 21 // Method 1: Compare current URL with each language's URL 22 languageSegments.forEach(function(segment) { 23 const langUrl = segment.getAttribute('data-href'); 24 if (langUrl && langUrl !== '#') { 25 const langUrlNormalized = langUrl.split('?')[0].replace(/\/$/, ''); 26 if (langUrlNormalized === currentUrlNormalized) { 27 // Remove active from all 28 languageSegments.forEach(function(seg) { 29 seg.classList.remove('active'); 30 seg.setAttribute('aria-selected', 'false'); 31 }); 32 // Set this one as active 33 segment.classList.add('active'); 34 segment.setAttribute('aria-selected', 'true'); 35 activeFound = true; 36 } 37 } 38 }); 39 40 // Method 2: Use data-current-lang attribute from PHP if URL matching failed 41 if (!activeFound && segmentedControl) { 42 const currentLang = segmentedControl.getAttribute('data-current-lang'); 43 if (currentLang) { 44 languageSegments.forEach(function(segment) { 45 const langCode = segment.getAttribute('data-lang'); 46 if (langCode === currentLang) { 47 // Remove active from all 48 languageSegments.forEach(function(seg) { 49 seg.classList.remove('active'); 50 seg.setAttribute('aria-selected', 'false'); 51 }); 52 // Set this one as active 53 segment.classList.add('active'); 54 segment.setAttribute('aria-selected', 'true'); 55 activeFound = true; 56 } 57 }); 58 } 59 } 60 61 // Method 3: Check URL path for language slug 62 if (!activeFound) { 63 const currentPath = window.location.pathname; 64 languageSegments.forEach(function(segment) { 65 const langUrl = segment.getAttribute('data-href'); 66 if (langUrl && langUrl !== '#') { 67 try { 68 const urlObj = new URL(langUrl); 69 const langPath = urlObj.pathname; 70 // Check if current path matches or contains language path 71 if (currentPath === langPath || 72 currentPath.replace(/\/$/, '') === langPath.replace(/\/$/, '') || 73 currentPath.indexOf(langPath) === 0) { 74 // Remove active from all 75 languageSegments.forEach(function(seg) { 76 seg.classList.remove('active'); 77 seg.setAttribute('aria-selected', 'false'); 78 }); 79 // Set this one as active 80 segment.classList.add('active'); 81 segment.setAttribute('aria-selected', 'true'); 82 activeFound = true; 83 } 84 } catch (e) { 85 // URL parsing failed, skip 86 } 87 } 88 }); 89 } 90 } 91 92 // Set active language on page load 93 setActiveLanguage(); 94 95 // Also set on popstate (back/forward navigation) 96 window.addEventListener('popstate', setActiveLanguage); 97 98 // Click handler for language segments 99 languageSegments.forEach(function(segment) { 100 segment.addEventListener('click', function(e) { 101 e.preventDefault(); 102 103 // Don't do anything if this segment is already active 104 if (this.classList.contains('active')) { 105 return; 106 } 107 108 // Remove active class from all segments 109 languageSegments.forEach(function(seg) { 110 seg.classList.remove('active'); 111 seg.setAttribute('aria-selected', 'false'); 112 }); 113 114 // Add active class to clicked segment 115 this.classList.add('active'); 116 this.setAttribute('aria-selected', 'true'); 117 118 // Get the language code and URL 119 const langCode = this.getAttribute('data-lang'); 120 const langUrl = this.getAttribute('data-href'); 121 122 // Navigate to the translated page URL 123 if (langUrl && langUrl !== '#') { 124 window.location.href = langUrl; 125 } 126 }); 127 }); 128 129 // Keyboard navigation support 130 if (segmentedControl) { 131 segmentedControl.addEventListener('keydown', function(e) { 132 const segments = Array.from(languageSegments); 133 const currentIndex = segments.findIndex(function(seg) { 134 return seg.classList.contains('active'); 135 }); 136 137 let targetIndex = currentIndex; 138 139 if (e.key === 'ArrowLeft' && currentIndex > 0) { 140 targetIndex = currentIndex - 1; 141 } else if (e.key === 'ArrowRight' && currentIndex < segments.length - 1) { 142 targetIndex = currentIndex + 1; 143 } else if (e.key === 'Home') { 144 targetIndex = 0; 145 } else if (e.key === 'End') { 146 targetIndex = segments.length - 1; 147 } else { 148 return; // Not a key we handle 149 } 150 151 e.preventDefault(); 152 segments[targetIndex].click(); 153 segments[targetIndex].focus(); 154 }); 155 } 156 }); 157 158})(); 159
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.