1//Wait for the HTML Document Object Model to load 2document.addEventListener("DOMContentLoaded", function (event) { 3 4 //Returns a string with an octothorpe in front 5 let anchor = document.location.hash; 6 7 let firstIndex; 8 9 const aboutPage = document.getElementById('about'); 10 const aboutContent = document.getElementById('narrower'); 11 const logo = document.getElementById('logo'); 12 const page = document.getElementById('page'); 13 14 //aboutGradient has to be a class 15 let aboutGradient = document.getElementsByClassName('aboutGradient'); 16 17 //Returns an array-like list 18 let expandables = document.getElementsByClassName('expandable'); 19 20 //Various tools for navigation 21 const navManager = { 22 //Changes URL to an anchor 23 pushTo: function (where) { 24 history.pushState({}, '', '#' + where); 25 }, 26 //Clears anchor, but leaves an octothorpe 27 pushClear: function () { 28 history.pushState({}, '', '#'); 29 }, 30 //Collapses a section on the about page 31 collapseSection: function (item) { 32 item.nextElementSibling.style.maxHeight = null; 33 34 //Switch writing to no opacity 35 item.nextElementSibling.classList.remove('active'); 36 37 //Remove diamond indicators 38 document.getElementById(item.id + 'Left').classList.remove('stay'); 39 40 document.getElementById(item.id + 'Right').classList.remove('stay'); 41 42 //Remove coloring 43 item.classList.remove('active'); 44 }, 45 //Expands section on the about page 46 expandSection: function (buttonName) { 47 const button = document.getElementById(buttonName); 48 const indicatorLeft = document.getElementById(buttonName + 'Left'); 49 const indicatorRight = document.getElementById(buttonName + 'Right'); 50 51 // Expand or contract section following button 52 const content = button.nextElementSibling; 53 if (content.style.maxHeight) { 54 navManager.collapseSection(button); 55 navManager.pushTo('about'); 56 content.classList.remove('active'); 57 } else { 58 content.style.maxHeight = content.scrollHeight + "px"; 59 button.classList.add('active'); 60 content.classList.add('active'); 61 indicatorLeft.classList.add('stay'); 62 indicatorRight.classList.add('stay'); 63 navManager.pushTo(buttonName); 64 } 65 66 //Collapse all other sections 67 [].forEach.call(expandables, function (item) { 68 if (item.id !== buttonName) { 69 navManager.collapseSection(item); 70 } 71 }) 72 }, 73 collapseAll: function () { 74 [].forEach.call(expandables, function (item) { 75 navManager.collapseSection(item); 76 }) 77 }, 78 79 //loading carousel is handled in siema onInit 80 loadCorrectPlace: function () { 81 if (anchor === '#about') { 82 loadAbout(); 83 } //Load one of the expandables 84 else if (anchor !== '' && !!document.querySelector('button' + anchor)) { 85 console.log('double bang'); 86 console.log(document.querySelector('button' + anchor)); 87 console.log(!!document.querySelector('button' + anchor)); 88 aboutPage.classList.add('visibleOnLoad'); 89 aboutContent.classList.add('visible'); 90 page.classList.add('showOverflow'); 91 logo.classList.add('inverted'); 92 93 navManager.expandSection(anchor.substr(1)); 94 } //No anchor or unknown anchor.Push to first element in slideshow 95 else if (firstIndex <= 0) { 96 setTimeout(function () { 97 siema.goTo(0); 98 navManager.pushTo(siema.innerElements[0].id); 99 }, 1000); 100 } 101 } 102 }; 103 104 //Returns a number 105 function getStartIndex() {
106 //Find the index of the figure that matches the anchor 107 firstIndex = Array.prototype.findIndex.call(document.querySelectorAll('figure'), function (item) { 108 return item.id === anchor.slice(1); 109 }); 110 111 //If the anchor was found, return its index. Otherwise, start carousel at 0 112 if (firstIndex > -1) { 113 return firstIndex; 114 } else { 115 return 0; 116 } 117 }; 118 119 function loadAbout() { 120 aboutPage.classList.add('visibleOnLoad'); 121 aboutContent.classList.add('visible'); 122 page.classList.add('showOverflow'); 123 logo.classList.add('inverted'); 124 125 console.log('loadAbout ' + aboutPage.classList.contains('visibleOnLoad')); 126 } 127 128 function showAbout() { 129 aboutPage.classList.add('visible'); 130 aboutContent.classList.add('visible'); 131 page.classList.add('showOverflow'); 132 logo.classList.add('inverted'); 133 navManager.pushTo('about'); 134 135 console.log('showAbout logo class list ' + logo.classList); 136 } 137 138 // Close the about page 139 function leaveAbout() { 140 aboutPage.classList.remove('visible'); 141 aboutPage.classList.remove('visibleOnLoad'); 142 aboutPage.classList.add('hidden'); 143 aboutContent.classList.remove('visible'); 144 page.classList.remove('showOverflow'); 145 logo.classList.remove('inverted'); 146 147 console.log('leaveAbout logo class list ' + logo.classList); 148 149 setTimeout(function () { 150 navManager.collapseAll() 151 }, 1050); 152 153 currentSlideName = siema.innerElements[siema.currentSlide].id; 154 navManager.pushTo(currentSlideName); 155 } 156 157 const siema = new Siema({ 158 loop: true, 159 duration: 1000, 160 easing: 'ease', 161 startIndex: getStartIndex(), 162 onInit: function () { 163 //First slide loaded shows up 164 this.innerElements[this.currentSlide].classList.add('show'); 165 console.log('siema init'); 166 console.log(document.location.hash); 167 console.log(aboutPage.classList); 168 console.log(aboutPage.classList.length); 169 console.log(aboutPage.classList.contains('visibleOnLoad')); 170console.log('java'); 171 [].forEach.call(aboutGradient, function (item) { 172 item.classList.add('hidden'); 173 console.log('hid'); 174 }) 175 176 }, 177 onChange: (function () { 178 /* Defined an Immediately Invoked Function Expression (IIFE) to create a closure 179 for outgoingSlide variable. That way, it doesn't have to be defined outside 180 the scope of the function.*/ 181 let outgoingSlide; 182 return function () { 183 const pieceTitle = this.innerElements[this.currentSlide].id; 184 navManager.pushTo(pieceTitle); 185 186 if (typeof outgoingSlide === 'undefined') { 187 if (firstIndex > -1) { 188 outgoingSlide = firstIndex; 189 } else { 190 outgoingSlide = 0; 191 } 192 } 193 194 //Fade out outgoing slide and fade in incoming slide 195 this.innerElements[outgoingSlide].classList.remove('show'); 196 this.innerElements[this.currentSlide].classList.add('show'); 197 198 //New slide is now old 199 outgoingSlide = this.currentSlide; 200 }; 201 })(), 202 }); 203 204 //Make figcaption text selectable on desktop by preventing Siema's functions 205 document.querySelectorAll('figcaption').forEach(function (el) { 206 el.addEventListener('mousedown', function (e) { 207 e.stopPropagation(); 208 }); 209 el.addEventListener('mousemove', function (e) { 210 e.stopPropagation(); 211 }); 212 el.addEventListener('touchstart', function (e) { 213 e.stopPropagation(); 214 }); 215 el.addEventListener('touchmove', function (e) { 216 e.stopPropagation(); 217 }); 218 }); 219 220 document.addEventListener('keydown', function (event) { 221 //Use arrow keys to navigate when about page not showing 222 if (aboutPage.classList.contains('visibleOnLoad') === false && aboutPage.classList.contains('visible') === false) { 223 if (event.code === 'ArrowLeft') { 224 siema.prev(); 225 } else if (event.code === 'ArrowRight') { 226 siema.next(); 227 } 228 } 229 230 //Use escape key to make about page go away 231 if (event.code === 'Escape') { 232 leaveAbout(); 233 } 234 }); 235 236 //Open site to anchor 237 window.addEventListener('load', function () { 238 navManager.loadCorrectPlace(); 239 240 }); 241 242 //Toggle about page 243 // 2023.02.05 Commenting this out now that siema is in separate page 244 // logo.addEventListener('click', function () { 245 246 // logo.classList.toggle('inverted'); 247 // currentSlideName = siema.innerElements[siema.currentSlide].id; 248 249 // if (aboutPage.classList.contains('visibleOnLoad') || aboutPage.classList.contains('visible')) { 250 // leaveAbout(); 251 252 // //show the first slide 253 // siema.innerElements[siema.currentSlide].classList.add('show'); 254 // } else { 255 // //No classes in list 256 // showAbout(); 257 // } 258 // }); 259 260 //Toggling expansions 261 document.body.addEventListener('click', function (e) { 262 if (e.target.nodeName === 'BUTTON') { 263 navManager.expandSection(e.target.id); 264 } 265 }) 266 267 // Find all tags using target="_blank" and inject rel="noreferrer noopener" 268 // From github, jasongfr/targetBlankVulnerabilityPatch.js 269 var aTags = document.querySelectorAll('[target]'); 270 var att = document.createAttribute('rel'); 271 att.value = 'noopener noreferrer';
272 aTags.forEach(function (tag) { 273 var nodeClone = att.cloneNode(true); 274 tag.setAttributeNode(nodeClone); 275 }); 276});
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.