From a35b745513fb790f31ea338d53605d2c75c12520 Mon Sep 17 00:00:00 2001 From: Rodger Jordas Date: Wed, 23 Feb 2022 10:56:14 +0800 Subject: [PATCH] Add link to preview next version of the website Next version of the website uses the Vuepress 2.x and content is updated to include Vue 3 compatible projects. Relates to #58 --- NOTICE | 43 +++ content/.vuepress/theme/components/Home.vue | 200 ++++++++++++++ .../.vuepress/theme/components/NavLink.vue | 90 +++++++ content/.vuepress/theme/index.js | 3 + content/.vuepress/theme/util/index.js | 244 ++++++++++++++++++ content/index.md | 2 +- 6 files changed, 581 insertions(+), 1 deletion(-) create mode 100644 NOTICE create mode 100644 content/.vuepress/theme/components/Home.vue create mode 100644 content/.vuepress/theme/components/NavLink.vue create mode 100644 content/.vuepress/theme/index.js create mode 100644 content/.vuepress/theme/util/index.js diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..c4eb32ba --- /dev/null +++ b/NOTICE @@ -0,0 +1,43 @@ +Homepage theme and associated utilities are based on the official Vuepress default theme which is +licensed under the terms of the MIT License: + +- content/.vuepress/theme/components/Home.vue +- content/.vuepress/theme/components/NavLink.vue +- content/.vuepress/theme/util/index.js + + + + +================================================================================ + + + + +-------------------------------- +Vuepress's MIT License +-------------------------------- + + + + +The MIT License (MIT) + +Copyright (c) 2018-present, Yuxi (Evan) You + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/content/.vuepress/theme/components/Home.vue b/content/.vuepress/theme/components/Home.vue new file mode 100644 index 00000000..3bf3e21b --- /dev/null +++ b/content/.vuepress/theme/components/Home.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/content/.vuepress/theme/components/NavLink.vue b/content/.vuepress/theme/components/NavLink.vue new file mode 100644 index 00000000..f7e65a44 --- /dev/null +++ b/content/.vuepress/theme/components/NavLink.vue @@ -0,0 +1,90 @@ + + + diff --git a/content/.vuepress/theme/index.js b/content/.vuepress/theme/index.js new file mode 100644 index 00000000..85eb83a9 --- /dev/null +++ b/content/.vuepress/theme/index.js @@ -0,0 +1,3 @@ +module.exports = { + extend: '@vuepress/theme-default', +}; diff --git a/content/.vuepress/theme/util/index.js b/content/.vuepress/theme/util/index.js new file mode 100644 index 00000000..92fcd3b3 --- /dev/null +++ b/content/.vuepress/theme/util/index.js @@ -0,0 +1,244 @@ +export const hashRE = /#.*$/ +export const extRE = /\.(md|html)$/ +export const endingSlashRE = /\/$/ +export const outboundRE = /^[a-z]+:/i + +export function normalize (path) { + return decodeURI(path) + .replace(hashRE, '') + .replace(extRE, '') +} + +export function getHash (path) { + const match = path.match(hashRE) + if (match) { + return match[0] + } +} + +export function isExternal (path) { + return outboundRE.test(path) +} + +export function isMailto (path) { + return /^mailto:/.test(path) +} + +export function isTel (path) { + return /^tel:/.test(path) +} + +export function ensureExt (path) { + if (isExternal(path)) { + return path + } + const hashMatch = path.match(hashRE) + const hash = hashMatch ? hashMatch[0] : '' + const normalized = normalize(path) + + if (endingSlashRE.test(normalized)) { + return path + } + return normalized + '.html' + hash +} + +export function isActive (route, path) { + const routeHash = decodeURIComponent(route.hash) + const linkHash = getHash(path) + if (linkHash && routeHash !== linkHash) { + return false + } + const routePath = normalize(route.path) + const pagePath = normalize(path) + return routePath === pagePath +} + +export function resolvePage (pages, rawPath, base) { + if (isExternal(rawPath)) { + return { + type: 'external', + path: rawPath + } + } + if (base) { + rawPath = resolvePath(rawPath, base) + } + const path = normalize(rawPath) + for (let i = 0; i < pages.length; i++) { + if (normalize(pages[i].regularPath) === path) { + return Object.assign({}, pages[i], { + type: 'page', + path: ensureExt(pages[i].path) + }) + } + } + console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`) + return {} +} + +function resolvePath (relative, base, append) { + const firstChar = relative.charAt(0) + if (firstChar === '/') { + return relative + } + + if (firstChar === '?' || firstChar === '#') { + return base + relative + } + + const stack = base.split('/') + + // remove trailing segment if: + // - not appending + // - appending to trailing slash (last segment is empty) + if (!append || !stack[stack.length - 1]) { + stack.pop() + } + + // resolve relative path + const segments = relative.replace(/^\//, '').split('/') + for (let i = 0; i < segments.length; i++) { + const segment = segments[i] + if (segment === '..') { + stack.pop() + } else if (segment !== '.') { + stack.push(segment) + } + } + + // ensure leading slash + if (stack[0] !== '') { + stack.unshift('') + } + + return stack.join('/') +} + +/** + * @param { Page } page + * @param { string } regularPath + * @param { SiteData } site + * @param { string } localePath + * @returns { SidebarGroup } + */ +export function resolveSidebarItems (page, regularPath, site, localePath) { + const { pages, themeConfig } = site + + const localeConfig = localePath && themeConfig.locales + ? themeConfig.locales[localePath] || themeConfig + : themeConfig + + const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar + if (pageSidebarConfig === 'auto') { + return resolveHeaders(page) + } + + const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar + if (!sidebarConfig) { + return [] + } else { + const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig) + if (config === 'auto') { + return resolveHeaders(page) + } + return config + ? config.map(item => resolveItem(item, pages, base)) + : [] + } +} + +/** + * @param { Page } page + * @returns { SidebarGroup } + */ +function resolveHeaders (page) { + const headers = groupHeaders(page.headers || []) + return [{ + type: 'group', + collapsable: false, + title: page.title, + path: null, + children: headers.map(h => ({ + type: 'auto', + title: h.title, + basePath: page.path, + path: page.path + '#' + h.slug, + children: h.children || [] + })) + }] +} + +export function groupHeaders (headers) { + // group h3s under h2 + headers = headers.map(h => Object.assign({}, h)) + let lastH2 + headers.forEach(h => { + if (h.level === 2) { + lastH2 = h + } else if (lastH2) { + (lastH2.children || (lastH2.children = [])).push(h) + } + }) + return headers.filter(h => h.level === 2) +} + +export function resolveNavLinkItem (linkItem) { + return Object.assign(linkItem, { + type: linkItem.items && linkItem.items.length ? 'links' : 'link' + }) +} + +/** + * @param { Route } route + * @param { Array | Array | [link: string]: SidebarConfig } config + * @returns { base: string, config: SidebarConfig } + */ +export function resolveMatchingConfig (regularPath, config) { + if (Array.isArray(config)) { + return { + base: '/', + config: config + } + } + for (const base in config) { + if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) { + return { + base, + config: config[base] + } + } + } + return {} +} + +function ensureEndingSlash (path) { + return /(\.html|\/)$/.test(path) + ? path + : path + '/' +} + +function resolveItem (item, pages, base, groupDepth = 1) { + if (typeof item === 'string') { + return resolvePage(pages, item, base) + } else if (Array.isArray(item)) { + return Object.assign(resolvePage(pages, item[0], base), { + title: item[1] + }) + } else { + const children = item.children || [] + if (children.length === 0 && item.path) { + return Object.assign(resolvePage(pages, item.path, base), { + title: item.title + }) + } + return { + type: 'group', + path: item.path, + title: item.title, + sidebarDepth: item.sidebarDepth, + initialOpenGroupIndex: item.initialOpenGroupIndex, + children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)), + collapsable: item.collapsable !== false + } + } +} diff --git a/content/index.md b/content/index.md index f517db6e..520195c4 100644 --- a/content/index.md +++ b/content/index.md @@ -1,7 +1,7 @@ --- home: true heroImage: /hero.png -actionText: Get Started → +actionText: Continue → actionLink: /resources/official-resources meta: - name: description