1// Checking if FontAwesome is loaded then provide icons/ make visisble -- for pseudo font awesome elements 2const isElementLoaded = async selector => { 3 while ( document.querySelector(selector) === null) { 4 await new Promise( resolve => requestAnimationFrame(resolve) ) 5 } 6 return document.querySelector(selector); 7}; 8isElementLoaded('.fa-sharp').then((selector) => { 9 // Add class to body 10 document.body.className += ' font-awesome-loaded'; 11}); 12 13// On scroll up, sticky nav on desktop 14(() => { 15 const header = document.getElementById('site-header'); 16 const subnavigation = document.getElementById('subnavigation'); 17 if (!header) return; 18 19 const THRESHOLD = 120; 20 let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop || 0; 21 let ticking = false; 22 23 function applyTopState() { 24 header.classList.add('sticky-lg-top'); 25 header.classList.remove('unstuck'); 26 if (subnavigation) { 27 subnavigation.classList.remove('sticky-lg-top'); 28 subnavigation.classList.add('unstuck'); 29 } 30 } 31 32 function applyScrollDownState() { 33 header.classList.remove('sticky-lg-top'); 34 header.classList.add('unstuck'); 35 if (subnavigation) { 36 subnavigation.classList.add('sticky-lg-top'); 37 subnavigation.classList.remove('unstuck'); 38 } 39 } 40 41 function applyScrollUpState() { 42 header.classList.add('sticky-lg-top'); 43 header.classList.remove('unstuck'); 44 if (subnavigation) { 45 subnavigation.classList.remove('sticky-lg-top'); 46 subnavigation.classList.add('unstuck'); 47 } 48 } 49 50 function updateStickyOnScroll() { 51 const currentScroll = Math.max( 52 window.pageYOffset || document.documentElement.scrollTop || 0, 53 0 54 ); 55 56 // Page is at the very top 57 if (currentScroll === 0) { 58 applyTopState(); 59 lastScrollTop = 0; 60 return; 61 } 62 63 // Only flip states after the threshold (keeps behavior near top stable) 64 if (currentScroll > THRESHOLD) { 65 if (currentScroll > lastScrollTop) { 66 applyScrollDownState(); 67 } else { 68 applyScrollUpState(); 69 } 70 } 71 72 lastScrollTop = currentScroll; 73 } 74 75 function onScroll() { 76 if (ticking) return; 77 ticking = true; 78 requestAnimationFrame(() => { 79 updateStickyOnScroll(); 80 ticking = false; 81 }); 82 } 83 84 // Initialize on load (covers third-party instant scrolls too) 85 document.addEventListener('DOMContentLoaded', updateStickyOnScroll, { once: true }); 86 window.addEventListener('load', updateStickyOnScroll, { once: true }); 87 88 // Respond to any scrolls (user or scripts) 89 window.addEventListener('scroll', onScroll, { passive: true }); 90})(); 91 92// Sidenav Toggle 93$(document).ready(function(){ 94 // Add "active" class to side nav items 95 var full_path = location.href.split("#")[0]; 96 console.log(full_path); 97 $("#side-navigation a").each(function(){ 98 var $this = $(this); 99 if($this.prop("href") == full_path) { 100 $this.addClass("active"); 101 } else if($this.prop("href").split("#")[0] == full_path + 'index.html') { 102 $this.addClass("active"); 103 } 104 }); 105 106 // Add side-navigation-toggle if applicable 107 $('#side-navigation ul li').each(function() { 108 if($(this).has('ul').length) { 109 $(this).addClass('side-navigation-toggle'); 110 } 111 }); 112 // Toggle Functionality 113 $('#side-navigation ul li.side-navigation-toggle ul li a.active').closest('#side-navigation ul li.side-navigation-toggle').addClass('opened'); 114 115 $('#side-navigation ul li.side-navigation-toggle > a').on('click', function(event) { 116 event.preventDefault(); 117 $(this).closest('#side-navigation ul li.side-navigation-toggle').toggleClass('opened'); 118 }); 119}); 120 121// Subnavigation Toggle 122$(document).ready(function(){ 123 // Add "active" class to side nav items 124 var full_path = location.href.split("#")[0]; 125 console.log(full_path); 126 $("#sub-navigation-menu a").each(function(){ 127 var $this = $(this); 128 if($this.prop("href") == full_path) { 129 $this.addClass("active"); 130 } else if($this.prop("href").split("#")[0] == full_path + 'index.html') { 131 $this.addClass("active"); 132 } 133 }); 134 135 // Add side-navigation-toggle if applicable 136 $('#sub-navigation-menu ul li').each(function() { 137 if($(this).has('ul').length) { 138 $(this).addClass('subnavigation-toggle'); 139 } 140 }); 141 // Toggle Functionality 142 $('#sub-navigation-menu ul li.subnavigation-toggle > a').on('click', function(event) { 143 event.preventDefault(); 144 if ($(this).closest('#sub-navigation-menu ul li.subnavigation-toggle').hasClass("opened")) { 145 $(this).closest('#sub-navigation-menu ul li.subnavigation-toggle').removeClass('opened'); 146 } else { 147 $("#sub-navigation-menu ul li.subnavigation-toggle").removeClass("opened"); 148 $(this).closest('#sub-navigation-menu ul li.subnavigation-toggle').addClass('opened'); 149 } 150 151 }); 152 // Off element click to close 153 $(document).on("click", function(e) { 154 if ($(e.target).is("#sub-navigation-menu ul li.subnavigation-toggle ul li a, #sub-navigation-menu ul li.subnavigation-toggle a") === false) { 155 $("#sub-navigation-menu ul li.subnavigation-toggle").removeClass("opened"); 156 } 157 }); 158 159 // Add active class if child for toggle 160 $('#sub-navigation-menu .subnavigation-toggle').has('a.active').addClass('active'); 161}); 162 163// Reset Match Height based on AOS Animations 164// Function to observe class changes 165/* Removed bc causing jumping on page scroll at some sizes 166function observeAOSAnimation() { 167 // Select the elements you want to observe 168 const elements = document.querySelectorAll('.aos-init'); 169
170 elements.forEach((element) => { 171 // Create a new MutationObserver 172 const observer = new MutationObserver((mutationsList) => { 173 for (const mutation of mutationsList) { 174 if (mutation.type === 'attributes' && mutation.attributeName === 'class') { 175 // Check if 'aos-animate' class has been added 176 if (element.classList.contains('aos-animate')) { 177 // Update matchHeight when the class is added 178 $.fn.matchHeight._update(); 179 } 180 } 181 } 182 }); 183 184 // Start observing the element for attribute changes (specifically class changes) 185 observer.observe(element, { attributes: true }); 186 }); 187}*/ 188 189// Match Height 190$(document).ready(function(){ 191 $('.match-height-all').matchHeight({ 192 byRow: false, 193 property: 'min-height' 194 }); 195 196 $('.match-height-row').matchHeight({ 197 byRow: true, 198 property: 'min-height' 199 }); 200 // Call the observer function 201 observeAOSAnimation(); 202}); 203 204 205 206// Copy to Clipboard 207var clipboard = new ClipboardJS('.hartnell-copy-button'); 208// fire class change on success 209clipboard.on('success', function(e) { 210 var trigger = e.trigger; 211 $(e.trigger).addClass('copied'); 212 213 setTimeout(function(e) { 214 $(trigger).removeClass('copied'); 215 }, 1000); 216}); 217 218// Modal Hack/ Fix for Bootstrap 5 219$(document).ready(function() { 220 $('.modal').appendTo("body"); 221}); 222 223// Force Smooth Scrolling on Page Load 224document.addEventListener("DOMContentLoaded", function() { 225 if (window.location.hash) { 226 const element = document.querySelector(window.location.hash); 227 if (element) { 228 element.scrollIntoView({ behavior: "smooth" }); 229 console.log('scrolling'); 230 } 231 } 232}); 233 234// Close offcanvas on mobile if translate button clicked 235document.getElementById('mobile-translate-btn').addEventListener('click', function () { 236 const offcanvasEl = document.getElementById('mobile-nav'); 237 const offcanvas = bootstrap.Offcanvas.getInstance(offcanvasEl) 238 || new bootstrap.Offcanvas(offcanvasEl); 239 240 offcanvas.hide(); 241});
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.