jekyll-vitepress-theme 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -76,14 +76,17 @@
76
76
  var mode = readMode();
77
77
  applyMode(mode);
78
78
 
79
+ // Use Turbo only for explicit frame-targeted doc visits.
80
+ if (window.Turbo && window.Turbo.session) {
81
+ window.Turbo.session.drive = false;
82
+ }
83
+
79
84
  function cycleMode() {
80
- if (mode === 'auto') {
81
- mode = 'dark';
82
- } else if (mode === 'dark') {
83
- mode = 'light';
84
- } else {
85
- mode = 'auto';
86
- }
85
+ var isDark = root.classList.contains('dark');
86
+ var nextMode = isDark ? 'light' : 'dark';
87
+ var systemMode = mediaQuery.matches ? 'dark' : 'light';
88
+
89
+ mode = nextMode === systemMode ? 'auto' : nextMode;
87
90
  writeMode(mode);
88
91
  applyModeWithoutTransitions(mode);
89
92
  }
@@ -551,6 +554,7 @@
551
554
  var searchInput = document.getElementById('vp-search-input');
552
555
  var searchResults = document.getElementById('vp-search-results');
553
556
  var searchIndexUrl = searchRoot ? searchRoot.getAttribute('data-search-index-url') : null;
557
+ var searchFrameTarget = searchRoot ? searchRoot.getAttribute('data-search-frame-target') : '';
554
558
 
555
559
  var searchOpen = false;
556
560
  var searchItems = [];
@@ -729,11 +733,16 @@
729
733
  var title = escapeHtml(item.title || item.url || 'Untitled');
730
734
  var url = escapeHtml(item.url || '/');
731
735
  var snippet = escapeHtml(buildSnippet(item, terms));
736
+ var turboAttributes = searchFrameTarget && url !== '/'
737
+ ? ' data-turbo="true" data-turbo-frame="' + escapeHtml(searchFrameTarget) + '" data-turbo-action="advance"'
738
+ : '';
732
739
 
733
740
  return (
734
741
  '<a class="VPSearchResult" role="option" href="' +
735
742
  url +
736
- '">' +
743
+ '"' +
744
+ turboAttributes +
745
+ '>' +
737
746
  '<span class="title">' +
738
747
  title +
739
748
  '</span>' +
@@ -840,7 +849,7 @@
840
849
  if (event.key === 'Enter') {
841
850
  var links = searchResults ? Array.from(searchResults.querySelectorAll('.VPSearchResult')) : [];
842
851
  if (links.length && activeResultIndex >= 0) {
843
- window.location.href = links[activeResultIndex].getAttribute('href');
852
+ links[activeResultIndex].click();
844
853
  }
845
854
  }
846
855
  });
@@ -1251,51 +1260,61 @@
1251
1260
  }
1252
1261
 
1253
1262
  var copyMdBtn = document.querySelector('.copy-md-btn');
1254
- if (copyMdBtn) {
1255
- copyMdBtn.addEventListener('click', function () {
1256
- copyPageMarkdown(copyMdBtn);
1257
- });
1258
- }
1259
-
1260
- // Dropdown toggle
1261
1263
  var toggle = document.querySelector('.copy-md-toggle');
1262
1264
  var dropdown = document.querySelector('.copy-md-dropdown');
1263
- if (toggle && dropdown) {
1264
- toggle.addEventListener('click', function (e) {
1265
- e.stopPropagation();
1266
- var open = !dropdown.hidden;
1267
- dropdown.hidden = !dropdown.hidden;
1268
- toggle.setAttribute('aria-expanded', !open);
1269
- });
1265
+ var dropdownCopy = dropdown ? dropdown.querySelector('[data-action="copy"]') : null;
1270
1266
 
1271
- // Copy from dropdown item
1272
- var dropdownCopy = dropdown.querySelector('[data-action="copy"]');
1273
- if (dropdownCopy) {
1274
- dropdownCopy.addEventListener('click', function () {
1275
- dropdown.hidden = true;
1276
- toggle.setAttribute('aria-expanded', 'false');
1267
+ function bindCopyPageControls() {
1268
+ if (copyMdBtn && !copyMdBtn.hasAttribute('data-vp-bound')) {
1269
+ copyMdBtn.setAttribute('data-vp-bound', 'true');
1270
+ copyMdBtn.addEventListener('click', function () {
1277
1271
  copyPageMarkdown(copyMdBtn);
1278
1272
  });
1279
1273
  }
1280
1274
 
1281
- // Close on outside click
1282
- document.addEventListener('click', function (e) {
1283
- if (!dropdown.hidden && !dropdown.contains(e.target) && !toggle.contains(e.target)) {
1284
- dropdown.hidden = true;
1285
- toggle.setAttribute('aria-expanded', 'false');
1286
- }
1287
- });
1275
+ if (toggle && dropdown && !toggle.hasAttribute('data-vp-bound')) {
1276
+ toggle.setAttribute('data-vp-bound', 'true');
1277
+ toggle.addEventListener('click', function (e) {
1278
+ e.stopPropagation();
1279
+ var open = !dropdown.hidden;
1280
+ dropdown.hidden = !dropdown.hidden;
1281
+ toggle.setAttribute('aria-expanded', String(!open));
1282
+ });
1283
+ }
1288
1284
 
1289
- // Close on Escape
1290
- document.addEventListener('keydown', function (e) {
1291
- if (e.key === 'Escape' && !dropdown.hidden) {
1285
+ dropdownCopy = dropdown ? dropdown.querySelector('[data-action="copy"]') : null;
1286
+ if (dropdownCopy && !dropdownCopy.hasAttribute('data-vp-bound')) {
1287
+ dropdownCopy.setAttribute('data-vp-bound', 'true');
1288
+ dropdownCopy.addEventListener('click', function () {
1292
1289
  dropdown.hidden = true;
1293
- toggle.setAttribute('aria-expanded', 'false');
1294
- toggle.focus();
1295
- }
1296
- });
1290
+ if (toggle) {
1291
+ toggle.setAttribute('aria-expanded', 'false');
1292
+ }
1293
+ copyPageMarkdown(copyMdBtn);
1294
+ });
1295
+ }
1297
1296
  }
1298
1297
 
1298
+ bindCopyPageControls();
1299
+
1300
+ document.addEventListener('click', function (e) {
1301
+ if (!dropdown || !toggle || dropdown.hidden) {
1302
+ return;
1303
+ }
1304
+ if (!dropdown.contains(e.target) && !toggle.contains(e.target)) {
1305
+ dropdown.hidden = true;
1306
+ toggle.setAttribute('aria-expanded', 'false');
1307
+ }
1308
+ });
1309
+
1310
+ document.addEventListener('keydown', function (e) {
1311
+ if (e.key === 'Escape' && dropdown && toggle && !dropdown.hidden) {
1312
+ dropdown.hidden = true;
1313
+ toggle.setAttribute('aria-expanded', 'false');
1314
+ toggle.focus();
1315
+ }
1316
+ });
1317
+
1299
1318
  var content = document.querySelector('.vp-doc');
1300
1319
  if (!content) {
1301
1320
  return;
@@ -1586,9 +1605,17 @@
1586
1605
  scrollToHashWithOffset(hash, true);
1587
1606
  }
1588
1607
 
1589
- document.querySelectorAll('.outline-link').forEach(function (link) {
1590
- link.addEventListener('click', handleOutlineLinkClick);
1591
- });
1608
+ function bindOutlineLinkHandlers() {
1609
+ document.querySelectorAll('.outline-link').forEach(function (link) {
1610
+ if (link.hasAttribute('data-vp-bound')) {
1611
+ return;
1612
+ }
1613
+ link.setAttribute('data-vp-bound', 'true');
1614
+ link.addEventListener('click', handleOutlineLinkClick);
1615
+ });
1616
+ }
1617
+
1618
+ bindOutlineLinkHandlers();
1592
1619
 
1593
1620
  if (window.location.hash) {
1594
1621
  window.requestAnimationFrame(function () {
@@ -1707,4 +1734,238 @@
1707
1734
  });
1708
1735
  });
1709
1736
  }
1737
+
1738
+ function normalizePathname(path) {
1739
+ var value = String(path || '').trim();
1740
+ if (!value) {
1741
+ return '/';
1742
+ }
1743
+ value = value.replace(/[?#].*$/, '');
1744
+ if (value.length > 1) {
1745
+ value = value.replace(/\/+$/, '');
1746
+ }
1747
+ return value || '/';
1748
+ }
1749
+
1750
+ function shouldTargetDocFrameLink(link) {
1751
+ if (!link) {
1752
+ return false;
1753
+ }
1754
+
1755
+ var href = link.getAttribute('href');
1756
+ if (!href || href.charAt(0) === '#') {
1757
+ return false;
1758
+ }
1759
+
1760
+ if (link.hasAttribute('target') || link.hasAttribute('download') || link.getAttribute('data-turbo') === 'false') {
1761
+ return false;
1762
+ }
1763
+
1764
+ var url;
1765
+ try {
1766
+ url = new URL(href, window.location.href);
1767
+ } catch (error) {
1768
+ return false;
1769
+ }
1770
+
1771
+ if (url.origin !== window.location.origin) {
1772
+ return false;
1773
+ }
1774
+
1775
+ var currentPath = normalizePathname(window.location.pathname);
1776
+ var targetPath = normalizePathname(url.pathname);
1777
+ if (targetPath === '/' || (targetPath === currentPath && url.hash)) {
1778
+ return false;
1779
+ }
1780
+
1781
+ var lastSegment = targetPath.split('/').pop();
1782
+ var hasExtension = lastSegment && lastSegment.indexOf('.') > -1;
1783
+ if (hasExtension && !/\.html?$/.test(lastSegment)) {
1784
+ return false;
1785
+ }
1786
+
1787
+ return true;
1788
+ }
1789
+
1790
+ function enhanceDocFrameLinks() {
1791
+ document.querySelectorAll('.vp-doc a[href], .VPDocFooter .pager-link').forEach(function (link) {
1792
+ if (!shouldTargetDocFrameLink(link)) {
1793
+ return;
1794
+ }
1795
+ link.setAttribute('data-turbo', 'true');
1796
+ link.setAttribute('data-turbo-frame', 'vp-content-frame');
1797
+ link.setAttribute('data-turbo-action', 'advance');
1798
+ });
1799
+ }
1800
+
1801
+ function syncPersistentNavState() {
1802
+ var frameState = document.getElementById('vp-page-state');
1803
+ if (!frameState) {
1804
+ return;
1805
+ }
1806
+
1807
+ var currentPath = normalizePathname(frameState.getAttribute('data-url') || window.location.pathname);
1808
+ var currentCollection = frameState.getAttribute('data-collection') || '';
1809
+ var currentTitle = frameState.getAttribute('data-title') || '';
1810
+
1811
+ if (currentTitle) {
1812
+ document.title = currentTitle;
1813
+ }
1814
+
1815
+ document.querySelectorAll('[data-vp-sidebar-link]').forEach(function (link) {
1816
+ var item = link.closest('.VPSidebarItem.level-1.is-link');
1817
+ var active = normalizePathname(link.getAttribute('href')) === currentPath;
1818
+ if (item) {
1819
+ item.classList.toggle('is-active', active);
1820
+ }
1821
+ });
1822
+
1823
+ document.querySelectorAll('[data-vp-sidebar-group]').forEach(function (group) {
1824
+ var hasActiveLink = !!group.querySelector('.VPSidebarItem.level-1.is-link.is-active');
1825
+ group.classList.toggle('has-active', hasActiveLink);
1826
+ });
1827
+
1828
+ document.querySelectorAll('[data-vp-nav-link]').forEach(function (link) {
1829
+ var collections = (link.getAttribute('data-collections') || '').split('|').filter(Boolean);
1830
+ var active = collections.indexOf(currentCollection) >= 0 ||
1831
+ normalizePathname(link.getAttribute('href')) === currentPath;
1832
+ link.classList.toggle('active', active);
1833
+ });
1834
+ }
1835
+
1836
+ function refreshDocPageState() {
1837
+ copyMdBtn = document.querySelector('.copy-md-btn');
1838
+ toggle = document.querySelector('.copy-md-toggle');
1839
+ dropdown = document.querySelector('.copy-md-dropdown');
1840
+ dropdownCopy = dropdown ? dropdown.querySelector('[data-action="copy"]') : null;
1841
+ bindCopyPageControls();
1842
+
1843
+ addCopyButtons();
1844
+ alignCopyPageButtonWithHeading();
1845
+ enhanceDocFrameLinks();
1846
+
1847
+ content = document.querySelector('.vp-doc');
1848
+ if (!content) {
1849
+ return;
1850
+ }
1851
+
1852
+ content.querySelectorAll('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').forEach(function (heading) {
1853
+ if (heading.querySelector('.header-anchor')) {
1854
+ return;
1855
+ }
1856
+
1857
+ var title = heading.textContent ? heading.textContent.trim() : heading.id;
1858
+ var anchor = document.createElement('a');
1859
+ anchor.className = 'header-anchor';
1860
+ anchor.href = '#' + heading.id;
1861
+ anchor.setAttribute('aria-label', 'Permalink to "' + title + '"');
1862
+ anchor.textContent = '\u200B';
1863
+
1864
+ heading.appendChild(document.createTextNode(' '));
1865
+ heading.appendChild(anchor);
1866
+ });
1867
+
1868
+ headings = Array.from(content.querySelectorAll('h2[id], h3[id]'));
1869
+ asideOutline = document.querySelector('.VPDocAsideOutline');
1870
+ localNav = document.getElementById('vp-local-nav');
1871
+ localOutlineDropdown = document.getElementById('vp-local-outline-dropdown');
1872
+ localOutlineButton = document.getElementById('vp-local-outline-button');
1873
+ localOutlineItems = document.querySelector('#vp-local-outline-dropdown .items');
1874
+ localOutlineContainer = document.querySelector('#vp-local-outline-dropdown .outline .VPDocOutlineItem');
1875
+ localTopLink = document.getElementById('vp-local-top-link');
1876
+ returnToTopLabel = localTopLink && localTopLink.textContent ? localTopLink.textContent.trim() : 'Return to top';
1877
+ marker = document.getElementById('vp-outline-marker');
1878
+ hasOutline = headings.length > 0;
1879
+ localOutlineOpen = false;
1880
+
1881
+ if (!hasOutline) {
1882
+ replaceOutline('.VPDocAsideOutline .VPDocOutlineItem.root', [], true);
1883
+ replaceOutline('#vp-local-outline-dropdown .outline .VPDocOutlineItem', [], true);
1884
+
1885
+ if (asideOutline) {
1886
+ asideOutline.classList.remove('has-outline');
1887
+ }
1888
+
1889
+ if (localNav) {
1890
+ localNav.classList.add('empty');
1891
+ }
1892
+
1893
+ if (localOutlineButton) {
1894
+ var text = localOutlineButton.querySelector('.menu-text');
1895
+ var icon = localOutlineButton.querySelector('.icon');
1896
+ if (text) {
1897
+ text.textContent = returnToTopLabel;
1898
+ }
1899
+ if (icon) {
1900
+ icon.style.display = 'none';
1901
+ }
1902
+ }
1903
+ } else {
1904
+ if (localNav) {
1905
+ localNav.classList.remove('empty');
1906
+ }
1907
+
1908
+ if (asideOutline) {
1909
+ asideOutline.classList.add('has-outline');
1910
+ }
1911
+
1912
+ if (localOutlineButton) {
1913
+ var menuText = localOutlineButton.querySelector('.menu-text');
1914
+ var menuIcon = localOutlineButton.querySelector('.icon');
1915
+ if (menuText) {
1916
+ menuText.textContent = document.getElementById('doc-outline-aria-label')
1917
+ ? document.getElementById('doc-outline-aria-label').textContent.trim()
1918
+ : menuText.textContent;
1919
+ }
1920
+ if (menuIcon) {
1921
+ menuIcon.style.display = '';
1922
+ }
1923
+ }
1924
+
1925
+ var tree = createOutlineTree(headings);
1926
+ replaceOutline('.VPDocAsideOutline .VPDocOutlineItem.root', tree, true);
1927
+ replaceOutline('#vp-local-outline-dropdown .outline .VPDocOutlineItem', tree, true);
1928
+ }
1929
+
1930
+ if (localOutlineButton) {
1931
+ localOutlineButton.classList.remove('open');
1932
+ localOutlineButton.setAttribute('aria-expanded', 'false');
1933
+ }
1934
+
1935
+ if (localOutlineItems) {
1936
+ localOutlineItems.hidden = true;
1937
+ }
1938
+
1939
+ bindOutlineLinkHandlers();
1940
+ syncLocalOutlineViewportHeight();
1941
+ syncActiveHeading();
1942
+ }
1943
+
1944
+ enhanceDocFrameLinks();
1945
+ syncPersistentNavState();
1946
+
1947
+ if (window.Turbo) {
1948
+ document.addEventListener('turbo:frame-load', function (event) {
1949
+ if (!event.target || event.target.id !== 'vp-content-frame') {
1950
+ return;
1951
+ }
1952
+
1953
+ syncPersistentNavState();
1954
+ refreshDocPageState();
1955
+
1956
+ if (window.location.hash) {
1957
+ scrollToHashWithOffset(window.location.hash, false);
1958
+ } else {
1959
+ window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
1960
+ activateOutlineHash(null);
1961
+ }
1962
+
1963
+ syncActiveHeading();
1964
+ syncNavTop();
1965
+
1966
+ if (window.innerWidth < 960 && sidebarOpen) {
1967
+ setSidebarOpen(false);
1968
+ }
1969
+ });
1970
+ }
1710
1971
  })();