|
26 | 26 | </svg> |
27 | 27 | </a> |
28 | 28 | {% endif %} |
29 | | - <a class="header-logo-link" href="{{ '/' | relative_url }}" aria-label="JSONC home"> |
30 | | - <img class="header-logo" src="{{ '/assets/logo.png' | relative_url }}" alt="JSONC logo"> |
31 | | - </a> |
32 | | - <h1 class="project-name">{{ page.title | default: site.title | default: site.github.repository_name }}</h1> |
33 | | - <h2 class="project-tagline">{{ page.description | default: site.description | default: site.github.project_tagline }}</h2> |
| 29 | + <div class="header-inner"> |
| 30 | + <a class="header-logo-link" href="{{ '/' | relative_url }}" aria-label="JSONC home"> |
| 31 | + <img class="header-logo" src="{{ '/assets/logo.png' | relative_url }}" alt="JSONC logo"> |
| 32 | + </a> |
| 33 | + <h1 class="project-name">{{ page.title | default: site.title | default: site.github.repository_name }}</h1> |
| 34 | + </div> |
34 | 35 | {% if site.show_downloads %} |
35 | 36 | <a href="{{ site.github.zip_url }}" class="btn">Download .zip</a> |
36 | 37 | <a href="{{ site.github.tar_url }}" class="btn">Download .tar.gz</a> |
37 | 38 | {% endif %} |
38 | 39 | </header> |
39 | 40 |
|
40 | | - <main id="content" class="main-content" role="main"> |
41 | | - {{ content }} |
| 41 | + <button class="toc-toggle" aria-label="Open table of contents" aria-expanded="false" aria-controls="toc"> |
| 42 | + <span class="toc-toggle-bar"></span> |
| 43 | + <span class="toc-toggle-bar"></span> |
| 44 | + <span class="toc-toggle-bar"></span> |
| 45 | + </button> |
| 46 | + <div class="toc-backdrop" aria-hidden="true"></div> |
| 47 | + |
| 48 | + <div class="page-body"> |
| 49 | + <nav id="toc" class="toc-sidebar" aria-label="Table of contents"> |
| 50 | + <div class="toc-inner"> |
| 51 | + <p class="toc-title">Contents</p> |
| 52 | + <ol class="toc-list"></ol> |
| 53 | + </div> |
| 54 | + </nav> |
| 55 | + |
| 56 | + <main id="content" class="main-content" role="main"> |
| 57 | + {{ content }} |
42 | 58 |
|
43 | 59 | <footer class="site-footer"> |
44 | 60 | {% if site.github.is_project_page %} |
45 | 61 | <span class="site-footer-owner"><a href="{{ site.github.repository_url }}">{{ site.github.repository_name }}</a> is maintained by <a href="{{ site.github.owner_url }}">{{ site.github.owner_name }}</a>.</span> |
46 | 62 | {% endif %} |
47 | 63 | <span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a>.</span> |
48 | 64 | </footer> |
49 | | - </main> |
| 65 | + </main> |
| 66 | + </div> |
50 | 67 | </body> |
51 | 68 | <script>hljs.highlightAll();</script> |
52 | 69 |
|
| 70 | + <!-- TOC burger toggle --> |
| 71 | + <script> |
| 72 | + (function () { |
| 73 | + var btn = document.querySelector('.toc-toggle'); |
| 74 | + var toc = document.getElementById('toc'); |
| 75 | + var backdrop = document.querySelector('.toc-backdrop'); |
| 76 | + function openToc() { |
| 77 | + toc.classList.add('toc-open'); |
| 78 | + backdrop.classList.add('toc-backdrop-visible'); |
| 79 | + btn.setAttribute('aria-expanded', 'true'); |
| 80 | + document.body.style.overflow = 'hidden'; |
| 81 | + } |
| 82 | + function closeToc() { |
| 83 | + toc.classList.remove('toc-open'); |
| 84 | + backdrop.classList.remove('toc-backdrop-visible'); |
| 85 | + btn.setAttribute('aria-expanded', 'false'); |
| 86 | + document.body.style.overflow = ''; |
| 87 | + } |
| 88 | + btn.addEventListener('click', function () { |
| 89 | + toc.classList.contains('toc-open') ? closeToc() : openToc(); |
| 90 | + }); |
| 91 | + backdrop.addEventListener('click', closeToc); |
| 92 | + toc.addEventListener('click', function (e) { |
| 93 | + if (e.target.tagName === 'A') closeToc(); |
| 94 | + }); |
| 95 | + })(); |
| 96 | + </script> |
| 97 | + |
| 98 | + <!-- Table of Contents --> |
| 99 | + <script> |
| 100 | + (function () { |
| 101 | + const headings = document.querySelectorAll('.main-content h2, .main-content h3'); |
| 102 | + const tocList = document.querySelector('.toc-list'); |
| 103 | + if (!tocList || headings.length === 0) return; |
| 104 | + |
| 105 | + let currentH2Item = null; |
| 106 | + headings.forEach(function (heading) { |
| 107 | + if (!heading.id) { |
| 108 | + heading.id = heading.textContent.trim().toLowerCase() |
| 109 | + .replace(/[^\w\s-]/g, '').replace(/\s+/g, '-'); |
| 110 | + } |
| 111 | + const link = document.createElement('a'); |
| 112 | + link.href = '#' + heading.id; |
| 113 | + link.textContent = heading.textContent; |
| 114 | + |
| 115 | + const li = document.createElement('li'); |
| 116 | + li.appendChild(link); |
| 117 | + |
| 118 | + if (heading.tagName === 'H2') { |
| 119 | + li.classList.add('toc-h2'); |
| 120 | + tocList.appendChild(li); |
| 121 | + currentH2Item = li; |
| 122 | + } else { |
| 123 | + li.classList.add('toc-h3'); |
| 124 | + let subList = currentH2Item && currentH2Item.querySelector('ol'); |
| 125 | + if (!subList) { |
| 126 | + subList = document.createElement('ol'); |
| 127 | + if (currentH2Item) currentH2Item.appendChild(subList); |
| 128 | + else tocList.appendChild(subList); |
| 129 | + } |
| 130 | + subList.appendChild(li); |
| 131 | + } |
| 132 | + }); |
| 133 | + |
| 134 | + // Highlight active section on scroll |
| 135 | + const allLinks = tocList.querySelectorAll('a'); |
| 136 | + const observer = new IntersectionObserver(function (entries) { |
| 137 | + entries.forEach(function (entry) { |
| 138 | + if (entry.isIntersecting) { |
| 139 | + allLinks.forEach(function (a) { a.classList.remove('toc-active'); }); |
| 140 | + const active = tocList.querySelector('a[href="#' + entry.target.id + '"]'); |
| 141 | + if (active) active.classList.add('toc-active'); |
| 142 | + } |
| 143 | + }); |
| 144 | + }, { rootMargin: '0px 0px -80% 0px' }); |
| 145 | + |
| 146 | + headings.forEach(function (h) { observer.observe(h); }); |
| 147 | + })(); |
| 148 | + </script> |
| 149 | + |
53 | 150 | <!-- Invalid syntax highlighting--> |
54 | 151 | <script> |
55 | 152 | function markInvalidNumbers(codeBlock) { |
|
0 commit comments