1window.onGatsbyInitialClientRender = function() { 2/** 3 * Main JS file for theme behaviours 4 */ 5// Responsive video embeds 6let videoEmbeds = [ 7 'iframe[src*="youtube.com"]', 8 'iframe[src*="vimeo.com"]' 9]; 10reframe(videoEmbeds.join(',')); 11 12// Handle main navigation menu toggling on small screens 13function menuToggleHandler(e) { 14 e.preventDefault(); 15 document.body.classList.toggle('menu--opened'); 16} 17 18// Handle docs navigation menu toggling on small screens 19function docsNavToggleHandler(e) { 20 e.preventDefault(); 21 document.body.classList.toggle('docs-menu--opened'); 22} 23 24// Handle submenu toggling 25function submenuToggleHandler(e) { 26 e.preventDefault(); 27 this.parentNode.classList.toggle('active'); 28} 29 30window.addMainNavigationHandlers = function() { 31 const menuToggle = document.querySelectorAll('.menu-toggle'); 32 if (menuToggle) { 33 for (let i = 0; i < menuToggle.length; i++) { 34 menuToggle[i].addEventListener('click', menuToggleHandler, false); 35 } 36 } 37 38 const submenuToggle = document.querySelectorAll('.submenu-toggle'); 39 if (submenuToggle) { 40 for (let i = 0; i < submenuToggle.length; i++) { 41 submenuToggle[i].addEventListener('click', submenuToggleHandler, false); 42 } 43 } 44}; 45 46window.removeMainNavigationHandlers = function() { 47 // Remove nav related classes on page load 48 document.body.classList.remove('menu--opened'); 49 50 const menuToggle = document.querySelectorAll('.menu-toggle'); 51 if (menuToggle) { 52 for (let i = 0; i < menuToggle.length; i++) { 53 menuToggle[i].removeEventListener('click', menuToggleHandler, false); 54 } 55 } 56 57 const submenuToggle = document.querySelectorAll('.submenu-toggle'); 58 if (submenuToggle) { 59 for (let i = 0; i < submenuToggle.length; i++) { 60 submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); 61 } 62 } 63}; 64 65window.addDocsNavigationHandlers = function() { 66 const docsNavToggle = document.getElementById('docs-nav-toggle'); 67 if (docsNavToggle) { 68 docsNavToggle.addEventListener('click', docsNavToggleHandler, false); 69 } 70 71 const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); 72 if (docsSubmenuToggle) { 73 for (let i = 0; i < docsSubmenuToggle.length; i++) { 74 docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); 75 } 76 } 77}; 78 79window.removeDocsNavigationHandlers = function() { 80 // Remove docs nav related classes on page load 81 document.body.classList.remove('docs-menu--opened'); 82 83 const docsNavToggle = document.getElementById('docs-nav-toggle'); 84 if (docsNavToggle) { 85 docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); 86 } 87 88 const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); 89 if (docsSubmenuToggle) { 90 for (let i = 0; i < docsSubmenuToggle.length; i++) { 91 docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); 92 } 93 } 94}; 95 96window.addPageNavLinks = function() { 97 const pageToc = document.getElementById('page-nav-inside'); 98 const pageTocContainer = document.getElementById('page-nav-link-container'); 99 100 if (pageToc && pageTocContainer) { 101 const pageContent = document.querySelector('.type-docs .post-content'); 102 103 // Create in-page navigation 104 const headerLinks = getHeaderLinks({ 105 root: pageContent 106 }); 107 if (headerLinks.length > 0) { 108 pageToc.classList.add('has-links'); 109 renderHeaderLinks(pageTocContainer, headerLinks); 110 } 111 112 // Scroll to anchors 113 let scroll = new SmoothScroll('[data-scroll]'); 114 let hash = window.decodeURI(location.hash.replace('#', '')); 115 if (hash !== '') { 116 window.setTimeout( function(){ 117 let anchor = document.getElementById(hash); 118 if (anchor) { 119 scroll.animateScroll(anchor); 120 } 121 }, 0); 122 } 123 124 // Highlight current anchor 125 let pageTocLinks = pageTocContainer.getElementsByTagName('a'); 126 if (pageTocLinks.length > 0) { 127 let spy = new Gumshoe('#page-nav-inside a', { 128 nested: true, 129 nestedClass: 'active-parent'
130 }); 131 } 132 133 // Add link to page content headings 134 let pageHeadings = getElementsByTagNames(pageContent, ["h2", "h3"]); 135 for (let i = 0; i < pageHeadings.length; i++) { 136 let heading = pageHeadings[i]; 137 if (typeof heading.id !== "undefined" && heading.id !== "") { 138 heading.insertBefore(anchorForId(heading.id), heading.firstChild); 139 } 140 } 141 142 // Copy link url 143 let clipboard = new ClipboardJS('.hash-link', { 144 text: function(trigger) { 145 return window.location.href.replace(window.location.hash,"") + trigger.getAttribute('href'); 146 } 147 }); 148 } 149} 150 151window.removePageNavLinks = function() { 152 const pageToc = document.getElementById('page-nav-inside'); 153 const pageTocContainer = document.getElementById('page-nav-link-container'); 154 155 if (pageToc && pageTocContainer) { 156 pageToc.classList.remove('has-links'); 157 while (pageTocContainer.firstChild) { 158 pageTocContainer.removeChild(pageTocContainer.firstChild); 159 } 160 } 161} 162 163function getElementsByTagNames(root, tagNames) { 164 let elements = []; 165 for (let i = 0; i < root.children.length; i++) { 166 let element = root.children[i]; 167 let tagName = element.nodeName.toLowerCase(); 168 if (tagNames.includes(tagName)) { 169 elements.push(element); 170 } 171 elements = elements.concat(getElementsByTagNames(element, tagNames)); 172 } 173 return elements; 174} 175 176function createLinksForHeaderElements(elements) { 177 let result = []; 178 let stack = [ 179 { 180 level: 0, 181 children: result 182 } 183 ]; 184 let re = /^h(\d)$/; 185 for (let i = 0; i < elements.length; i++) { 186 let element = elements[i]; 187 let tagName = element.nodeName.toLowerCase(); 188 let match = re.exec(tagName); 189 if (!match) { 190 console.warn("can not create links to non header element"); 191 continue; 192 } 193 let headerLevel = parseInt(match[1], 10); 194 if (!element.id) { 195 if (!element.textContent) { 196 console.warn( 197 "can not create link to element without id and without text content" 198 ); 199 continue; 200 } 201 element.id = element.textContent 202 .toLowerCase() 203 .replace(/[^\w]+/g, "_") 204 .replace(/^_/, "") 205 .replace(/_$/, ""); 206 } 207 let link = document.createElement("a"); 208 link.href = "#" + element.id; 209 link.setAttribute('data-scroll', ''); 210 link.appendChild(document.createTextNode(element.textContent)); 211 let obj = { 212 id: element.id, 213 level: headerLevel, 214 textContent: element.textContent, 215 element: element, 216 link: link, 217 children: [] 218 }; 219 if (headerLevel > stack[stack.length - 1].level) { 220 stack[stack.length - 1].children.push(obj); 221 stack.push(obj); 222 } else { 223 while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { 224 stack.pop(); 225 } 226 stack[stack.length - 1].children.push(obj); 227 stack.push(obj); 228 } 229 } 230 return result; 231} 232 233function getHeaderLinks(options = {}) { 234 let tagNames = options.tagNames || ["h2", "h3"]; 235 let root = options.root || document.body; 236 let headerElements = getElementsByTagNames(root, tagNames); 237 return createLinksForHeaderElements(headerElements); 238} 239 240function renderHeaderLinks(element, links) { 241 if (links.length === 0) { 242 return; 243 } 244 let ulElm = document.createElement("ul"); 245 for (let i = 0; i < links.length; i++) { 246 let liElm = document.createElement("li"); 247 liElm.append(links[i].link); 248 if (links[i].children.length > 0) { 249 renderHeaderLinks(liElm, links[i].children); 250 } 251 ulElm.appendChild(liElm); 252 } 253 element.appendChild(ulElm); 254} 255 256function anchorForId(id) { 257 let anchor = document.createElement("a"); 258 anchor.setAttribute("class", "hash-link"); 259 anchor.setAttribute("data-scroll", ""); 260 anchor.href = "#" + id; 261 anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; 262 return anchor; 263} 264 265// Syntax Highlighter 266// Prism.highlightAll(); 267};
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.