diff options
Diffstat (limited to 'v_windows/v/cmd/tools/vdoc/resources/doc.js')
-rw-r--r-- | v_windows/v/cmd/tools/vdoc/resources/doc.js | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/v_windows/v/cmd/tools/vdoc/resources/doc.js b/v_windows/v/cmd/tools/vdoc/resources/doc.js new file mode 100644 index 0000000..c355d7e --- /dev/null +++ b/v_windows/v/cmd/tools/vdoc/resources/doc.js @@ -0,0 +1,235 @@ +(function () { + if (document.body.scrollIntoView) { + var docnav = document.querySelector('.doc-nav'); + var active = docnav.querySelector('li.active'); + if (active) { + active.scrollIntoView({ block: 'center', inline: 'nearest' }); + } + } + setupScrollSpy(); + setupMobileToggle(); + setupDarkMode(); + setupSearch(); + setupCollapse(); +})(); + +function setupScrollSpy() { + var sectionPositions = []; + var sections = document.querySelectorAll('section'); + sections.forEach(function (section) { + sectionPositions.push(section.offsetTop); + }); + var scrollPos = 0; + window.addEventListener('scroll', function (_) { + // Reset classes + document.querySelectorAll('.doc-toc a[class="active"]').forEach(function (link) { + link.classList.remove('active'); + }); + // Set current menu link as active + var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop; + for (var i = 0; i < sectionPositions.length; i++) { + var section = sections[i]; + var position = sectionPositions[i]; + if (position >= scrollPosition) { + var link = document.querySelector('.doc-toc a[href="#' + section.id + '"]'); + if (link) { + link.classList.add('active'); + var docToc = document.querySelector('.doc-toc'); + var tocHeight = docToc.clientHeight; + var scrollTop = docToc.scrollTop; + if ((document.body.getBoundingClientRect()).top < scrollPos && scrollTop < link.offsetTop - 10) { + docToc.scrollTop = link.clientHeight + link.offsetTop - tocHeight + 10; + } else if (scrollTop > link.offsetTop - 10) { + docToc.scrollTop = link.offsetTop - 10; + } + } + break; + } + } + scrollPos = (document.body.getBoundingClientRect()).top; + }); +} + +function setupMobileToggle() { + var toggle = document.getElementById('toggle-menu'); + toggle.addEventListener('click', function (_) { + var docNav = document.querySelector('.doc-nav'); + var isHidden = docNav.classList.contains('hidden'); + docNav.classList.toggle('hidden'); + var search = document.querySelector('.doc-nav > .search'); + console.log(search); + var searchHasResults = search.classList.contains('has-results'); + if (isHidden && searchHasResults) { + search.classList.remove('mobile-hidden'); + } else { + search.classList.add('mobile-hidden'); + } + var content = document.querySelector('.doc-nav .content'); + content.classList.toggle('hidden'); + content.classList.toggle('show'); + }); +} + +function setupDarkMode() { + var html = document.getElementsByTagName('html')[0]; + var darkModeToggle = document.getElementById('dark-mode-toggle'); + darkModeToggle.addEventListener('click', function () { + html.classList.toggle('dark'); + var isDarkModeEnabled = html.classList.contains('dark'); + localStorage.setItem('dark-mode', isDarkModeEnabled); + darkModeToggle.setAttribute('aria-checked', isDarkModeEnabled) + }); + // Check if css var() is supported and enable dark mode toggle + if (window.CSS && CSS.supports('color', 'var(--fake-var)')) { + darkModeToggle.style.visibility = 'unset'; + } +} + +function setupSearch() { + var searchInput = document.getElementById('search'); + var onInputChange = debounce(function (e) { + var searchValue = e.target.value.toLowerCase(); + var menu = document.querySelector('.doc-nav > .content'); + var search = document.querySelector('.doc-nav > .search'); + if (searchValue === '') { + // reset to default + menu.style.display = ''; + if (!search.classList.contains('hidden')) { + search.classList.add('hidden'); + search.classList.remove('has-results'); + } + } else if (searchValue.length >= 2) { + // search for less than 2 characters can display too much results + search.innerHTML = ''; + menu.style.display = 'none'; + if (search.classList.contains('hidden')) { + search.classList.remove('hidden'); + search.classList.remove('mobile-hidden'); + search.classList.add('has-results'); + } + // cache length for performance + var foundModule = false; + var searchModuleIndexLength = searchModuleIndex.length; + var ul = document.createElement('ul'); + search.appendChild(ul); + for (var i = 0; i < searchModuleIndexLength; i++) { + // no toLowerCase needed because modules are always lowercase + var title = searchModuleIndex[i]; + if (title.indexOf(searchValue) === -1) { + continue + } + foundModule = true; + // [description, link] + var data = searchModuleData[i]; + var description = data[0]; + var link = data[1]; + var el = createSearchResult({ + link: link, + title: title, + description: description, + badge: 'module', + }); + ul.appendChild(el); + } + if (foundModule) { + var hr = document.createElement('hr'); + hr.classList.add('separator'); + search.appendChild(hr); + } + var searchIndexLength = searchIndex.length; + var results = []; + for (var i = 0; i < searchIndexLength; i++) { + var title = searchIndex[i]; + if (title.toLowerCase().indexOf(searchValue) === -1) { + continue + } + // [badge, description, link] + var data = searchData[i]; + var badge = data[0]; + var description = data[1]; + var link = data[2]; + var prefix = data[3]; + results.push({ + badge: badge, + description: description, + link: link, + title: prefix + ' ' + title, + }); + } + results.sort(function (a, b) { + if (a.title < b.title) { + return -1; + } + if (a.title > b.title) { + return 1; + } + return 0; + }); + var ul = document.createElement('ul'); + search.appendChild(ul); + for (var i = 0; i < results.length; i++) { + var result = results[i]; + var el = createSearchResult(result); + ul.appendChild(el); + } + } + }); + searchInput.addEventListener('input', onInputChange); +} + +function createSearchResult(data) { + var li = document.createElement('li'); + li.classList.add('result'); + var a = document.createElement('a'); + a.href = data.link; + a.classList.add('link'); + li.appendChild(a); + var defintion = document.createElement('div'); + defintion.classList.add('definition'); + a.appendChild(defintion); + if (data.description) { + var description = document.createElement('div'); + description.classList.add('description'); + description.textContent = data.description; + a.appendChild(description); + } + var title = document.createElement('span'); + title.classList.add('title'); + title.textContent = data.title; + defintion.appendChild(title); + var badge = document.createElement('badge'); + badge.classList.add('badge'); + badge.textContent = data.badge; + defintion.appendChild(badge); + return li; +} + +function setupCollapse() { + var dropdownArrows = document.querySelectorAll('.dropdown-arrow'); + for (var i = 0; i < dropdownArrows.length; i++) { + var dropdownArrow = dropdownArrows[i]; + dropdownArrow.addEventListener('click', function (e) { + var parent = e.target.parentElement.parentElement.parentElement; + parent.classList.toggle('open'); + }); + } +} + +function debounce(func, timeout) { + var timer; + return (...args) => { + const next = () => func(...args); + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(next, timeout > 0 ? timeout : 300); + } +} + +document.addEventListener('keypress', (ev) => { + if (ev.key == '/') { + let search = document.getElementById('search'); + ev.preventDefault(); + search.focus(); + } +}); |