|
| 1 | +var allMenus, navLinks, versionsLinks; |
| 2 | + |
| 3 | +// eslint-disable-next-line no-unused-vars |
| 4 | +function slugify(text) { |
| 5 | + return text |
| 6 | + .toString() |
| 7 | + .toLowerCase() |
| 8 | + .replace(/\s+/g, '-') // Replace spaces with - |
| 9 | + .replace(/[^\w-]+/g, '') // Remove all non-word chars |
| 10 | + .replace(/--+/g, '-') // Replace multiple - with single - |
| 11 | + .replace(/^-+/, '') // Trim - from start of text |
| 12 | + .replace(/-+$/, ''); // Trim - from end of text |
| 13 | +} |
| 14 | + |
| 15 | +function navigationFitScroll() { |
| 16 | + var scrollIntoView = window.sessionStorage.getItem('scrollIntoView'); |
| 17 | + if (true || scrollIntoView !== 'false') { |
| 18 | + var activeMenu = document.querySelector('.sidenav li.active'); |
| 19 | + if (activeMenu) activeMenu.parentNode.scrollIntoView(); |
| 20 | + } |
| 21 | + window.sessionStorage.removeItem('scrollIntoView'); |
| 22 | +} |
| 23 | + |
| 24 | +function buildPageToC() { |
| 25 | + var M = window.M; |
| 26 | + M.Sidenav.init(document.querySelectorAll('.sidenav')); |
| 27 | + // Initialize version selector |
| 28 | + M.Dropdown.init(document.querySelectorAll('.dropdown-trigger')); |
| 29 | + |
| 30 | + var Prism = window.Prism; |
| 31 | + Prism.highlightAll(); |
| 32 | + |
| 33 | + /* Generate table of contents */ |
| 34 | + if (document.querySelector('.toc') != null) { |
| 35 | + var tocbot = window.tocbot; |
| 36 | + tocbot.init({ |
| 37 | + // Where to render the table of contents |
| 38 | + tocSelector: '.toc', |
| 39 | + positionFixedSelector: '.toc', |
| 40 | + // Where to grab the headings to build the table of contents |
| 41 | + contentSelector: '.toc-content', |
| 42 | + // More options |
| 43 | + headingSelector: 'h2, h3, h4', |
| 44 | + includeHtml: true, |
| 45 | + collapseDepth: 2, |
| 46 | + hasInnerContainers: true, |
| 47 | + }); |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +function replaceContent(text) { |
| 52 | + var tocContainer = document.querySelector('.toc-container'); |
| 53 | + tocContainer.className = |
| 54 | + text.trim() !== '' |
| 55 | + ? 'toc-container col hide-on-small-only m3' |
| 56 | + : 'toc-container'; |
| 57 | + |
| 58 | + var tmpElement = document.createElement('div'); |
| 59 | + tmpElement.innerHTML = text; |
| 60 | + |
| 61 | + toggleDockBlocks(false); |
| 62 | + |
| 63 | + var content = document.querySelector('.DocSearch-content'); |
| 64 | + content.innerHTML = tmpElement.querySelector( |
| 65 | + '.DocSearch-content' |
| 66 | + ).innerHTML; |
| 67 | + |
| 68 | + window.scrollTo(0, 0); |
| 69 | + |
| 70 | + buildPageToC(); |
| 71 | + |
| 72 | + navigationFitScroll(); |
| 73 | +} |
| 74 | + |
| 75 | +function changeSelectedMenu() { |
| 76 | + var activeMenu = document.querySelector(`.sidenav li.active`); |
| 77 | + activeMenu && activeMenu.classList.remove('active'); |
| 78 | + allMenus |
| 79 | + .find(menuEl => menuEl.href === window.location.href) |
| 80 | + .parentNode.classList.add('active'); |
| 81 | +} |
| 82 | + |
| 83 | +function toggleDockBlocks(status) { |
| 84 | + var docBlock = document.querySelector('.docBlocks'); |
| 85 | + if (!docBlock) return; |
| 86 | + docBlock.style.display = status ? 'grid' : 'none'; |
| 87 | +} |
| 88 | + |
| 89 | +// Replace full page reloads by a fill of the content area |
| 90 | +// so that the side navigation keeps its state |
| 91 | +// use a global event listener to also catch links inside the content area |
| 92 | +document.addEventListener('click', event => { |
| 93 | + var link = event.target.closest('a'); |
| 94 | + if (!link) { |
| 95 | + return; // click not on a link |
| 96 | + } |
| 97 | + var location = document.location.href.split('#')[0]; |
| 98 | + var href = link.href; |
| 99 | + if (href.indexOf(`${location}#`) === 0) { |
| 100 | + return; // click on an anchor in the current page |
| 101 | + } |
| 102 | + if (!navLinks.includes(href)) { |
| 103 | + return; // not a navigation link |
| 104 | + } |
| 105 | + window.sessionStorage.setItem( |
| 106 | + 'scrollIntoView', |
| 107 | + link.closest('.sidenav') ? 'false' : 'true' |
| 108 | + ); |
| 109 | + // now we're sure it's an internal navigation link |
| 110 | + // transform it to an AJAX call |
| 111 | + event.preventDefault(); |
| 112 | + // update versions links |
| 113 | + var currentPage = href.split('/').pop(); |
| 114 | + versionsLinks.forEach(link => { |
| 115 | + link.href = |
| 116 | + link.href.substr(0, link.href.lastIndexOf('/') + 1) + currentPage; |
| 117 | + }); |
| 118 | + // fetch the new content |
| 119 | + fetch(href) |
| 120 | + .then(res => res.text()) |
| 121 | + .then(replaceContent); |
| 122 | + // change the URL |
| 123 | + window.history.pushState(null, null, href); |
| 124 | + changeSelectedMenu(); |
| 125 | +}); |
| 126 | + |
| 127 | +// make back button work again |
| 128 | +window.addEventListener('popstate', event => { |
| 129 | + if (document.location.href.indexOf('#') !== -1) { |
| 130 | + // popstate triggered by a click on an anchor, not back button |
| 131 | + return; |
| 132 | + } |
| 133 | + if (window.location.pathname === '/documentation.html') { |
| 134 | + document.querySelector('.DocSearch-content').innerHTML = ''; |
| 135 | + toggleDockBlocks(true); |
| 136 | + } else { |
| 137 | + // fetch the new content |
| 138 | + fetch(window.location.pathname) |
| 139 | + .then(res => res.text()) |
| 140 | + .then(replaceContent); |
| 141 | + } |
| 142 | + changeSelectedMenu(); |
| 143 | +}); |
| 144 | + |
| 145 | +window.addEventListener('DOMContentLoaded', () => { |
| 146 | + allMenus = Array.from(document.querySelectorAll(`.sidenav a.nav-link`)); |
| 147 | + navLinks = allMenus |
| 148 | + .filter(link => !link.classList.contains('external')) |
| 149 | + .map(link => link.href); |
| 150 | + versionsLinks = Array.from(document.querySelectorAll('#versions > li > a')); |
| 151 | + |
| 152 | + buildPageToC(); |
| 153 | + |
| 154 | + navigationFitScroll(); |
| 155 | +}); |
0 commit comments