NavBarLinks.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { computed } from 'vue';
  2. import { useSiteData, useSiteDataByRoute, useRoute } from 'vitepress';
  3. import { inBrowser } from '/@app/utils';
  4. import NavBarLink from './NavBarLink.vue';
  5. import NavDropdownLink from './NavDropdownLink.vue';
  6. const platforms = ['GitHub', 'GitLab', 'Bitbucket'].map((platform) => [platform, new RegExp(platform, 'i')]);
  7. export default {
  8. components: {
  9. NavBarLink,
  10. NavDropdownLink
  11. },
  12. setup() {
  13. const siteDataByRoute = useSiteDataByRoute();
  14. const siteData = useSiteData();
  15. const route = useRoute();
  16. const repoInfo = computed(() => {
  17. const theme = siteData.value.themeConfig;
  18. const repo = theme.docsRepo || theme.repo;
  19. let text = theme.repoLabel;
  20. if (repo) {
  21. const link = /^https?:/.test(repo) ? repo : `https://github.com/${repo}`;
  22. if (!text) {
  23. // if no label is provided, deduce it from the repo url
  24. const repoHosts = link.match(/^https?:\/\/[^/]+/);
  25. if (repoHosts) {
  26. const repoHost = repoHosts[0];
  27. const foundPlatform = platforms.find(([_platform, re]) => re.test(repoHost));
  28. text = foundPlatform && foundPlatform[0];
  29. }
  30. }
  31. return { link, text: text || 'Source' };
  32. }
  33. return null;
  34. });
  35. const localeCandidates = computed(() => {
  36. const locales = siteData.value.themeConfig.locales;
  37. if (!locales) {
  38. return null;
  39. }
  40. const localeKeys = Object.keys(locales);
  41. if (localeKeys.length <= 1) {
  42. return null;
  43. }
  44. // handle site base
  45. const siteBase = inBrowser ? siteData.value.base : '/';
  46. const siteBaseWithoutSuffix = siteBase.endsWith('/')
  47. ? siteBase.slice(0, -1)
  48. : siteBase;
  49. // remove site base in browser env
  50. const routerPath = route.path.slice(siteBaseWithoutSuffix.length);
  51. const currentLangBase = localeKeys.find((v) => {
  52. if (v === '/') {
  53. return false;
  54. }
  55. return routerPath.startsWith(v);
  56. });
  57. const currentContentPath = currentLangBase
  58. ? routerPath.substring(currentLangBase.length - 1)
  59. : routerPath;
  60. const candidates = localeKeys.map((v) => {
  61. const localePath = v.endsWith('/') ? v.slice(0, -1) : v;
  62. return {
  63. text: locales[v].label || locales[v].lang,
  64. link: `${localePath}${currentContentPath}`
  65. };
  66. });
  67. const currentLangKey = currentLangBase ? currentLangBase : '/';
  68. const selectText = locales[currentLangKey].selectText
  69. ? locales[currentLangKey].selectText
  70. : 'Languages';
  71. return {
  72. text: selectText,
  73. items: candidates
  74. };
  75. });
  76. const navData = computed(() => {
  77. return siteDataByRoute.value.themeConfig.nav;
  78. });
  79. return {
  80. navData,
  81. repoInfo,
  82. localeCandidates
  83. };
  84. }
  85. };