From 03c6feee6eb2f5a66579d1846acb2e829dac2cc5 Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Fri, 16 Feb 2024 10:21:59 +0100 Subject: [PATCH] BUGFIX: upgrade links plugin and fix bug in SidebarLink component Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- components/docs/Sidebar/SidebarLink.jsx | 2 +- lib/remark-plugins/links/index.js | 130 +++++++++++------------- lib/serialize.js | 9 +- 3 files changed, 63 insertions(+), 78 deletions(-) diff --git a/components/docs/Sidebar/SidebarLink.jsx b/components/docs/Sidebar/SidebarLink.jsx index 9e27c0a183f..245b60922d8 100644 --- a/components/docs/Sidebar/SidebarLink.jsx +++ b/components/docs/Sidebar/SidebarLink.jsx @@ -11,7 +11,7 @@ export default function SidebarLink({ setParentOpen }) { const router = useRouter() - const active = router.asPath === href + '/' + const active = router.asPath.split('?')[0].split('#')[0] === href + '/' const linkClasses = classNames({ 'flex text-dark-2 hover:text-blue-2 text-base py-2 transition ease-in-out duration-150 no-underline': true, 'font-medium opacity-60 w-full': active diff --git a/lib/remark-plugins/links/index.js b/lib/remark-plugins/links/index.js index f07b26e37c1..2139e8a34e2 100644 --- a/lib/remark-plugins/links/index.js +++ b/lib/remark-plugins/links/index.js @@ -1,101 +1,89 @@ // This file originates from https://github.com/zentered/next-product-docs on -// the branch "feat/cert-manager-adjustments" (commit f4fb801), copyright +// the branch "main" (commit fdcc8b5), copyright // Zentered 2022, licensed under the Apache 2.0 license. import { visit } from 'unist-util-visit' +import { resolve, sep } from 'node:path' export default function relativeLinks(options) { - if (!options || !options.prefix) { - throw Error('Missing required "prefix" option') - } - - let pathParts = [] let extensions = ['.mdx', '.md'] - const slug = options.slug - + const moduleRootPath = options.rootPath + const prefix = options.prefix if (options.extensions) { extensions = options.extensions } + /** + * This function takes an internal url and converts it into a web url. + * It handles relative and absolute paths. + * + * @param {*} node + * @returns node + */ function visitor(node) { - let nodePrefix = options.prefix - if (node && node.url && !node.url.startsWith('http')) { - if (process.env.DEBUG === 'true') { - // helps to identify "special cases" and add those to the tests - console.log(node.url, options) + if ( + node && + node.url && + !node.url.startsWith('http') && + !node.url.startsWith('mailto:') + ) { + // keep a copy of the original node url for comparison + const originalUrl = node.url + let rootPath = moduleRootPath + + if (options.debug) { + console.log(rootPath, node.url, options) } - // ignore mailto: links - if (node.url.startsWith('mailto:')) { - return + // remove the filename from the rootPath if it's an anchor link + if (!node.url.startsWith('#')) { + rootPath = rootPath.split('/').slice(0, -1).join('/') } - // handle relative paths - if (node.url.startsWith('#')) { - if (slug[0] === nodePrefix) { - pathParts = slug.slice(1) - } else { - pathParts = slug - } - } else if (slug && Array.isArray(slug)) { - if (slug[0] === nodePrefix) { - slug.shift() - } - const depth = (node.url.match(/\.\.\//g) || []).length - if (slug.length <= 1) { - pathParts = slug - } else if (depth >= slug.length) { - nodePrefix = '' - pathParts = [] - } else { - const removeLast = slug.length - depth - 1 - pathParts = slug.slice(0, removeLast) - } + // drop all extensions from root and node url + for (const ext of extensions) { + rootPath = rootPath.replace(ext, '') + node.url = node.url.replace(ext, '') } - if (node.url.startsWith('/')) { - node.url = node.url.replace('/', '') + // add prefix to rootPath if it has been passed + if (prefix && !rootPath.startsWith(`/${prefix}`)) { + rootPath = `/${prefix}${rootPath}` } - if (node.url.startsWith('./')) { - node.url = node.url.replace('./', '') + // drop README from root and node url + rootPath = rootPath.replace('/README', '') + node.url = node.url.replace('/README', '') + + // check if the depth of the node.url goes beyond the rootPath + const rootPathParts = rootPath.split(sep).slice(1) + const depth = (originalUrl.match(/\.\.\//g) || []).length + const skipPrefix = depth > 0 && rootPathParts.length === depth + const relative = resolve(rootPath, node.url) + if ( + !skipPrefix && + !relative.startsWith(`/${prefix}`) && + !originalUrl.startsWith('/') + ) { + node.url = `/${prefix}${relative}` + } else { + node.url = relative } - if (node.url.startsWith('../')) { - node.url = node.url.replace(/\.\.\//g, '') + if (options.debug) { + console.log(`rootPath: ${rootPath}`) + console.log(`nodeUrl: ${originalUrl}`) + console.log(`calculated URL: ${relative}`) } - let path = '' - if (pathParts) { - if (pathParts.length >= 1) { - if (pathParts[0] !== nodePrefix) { - path = nodePrefix + '/' + pathParts.join('/') - } - path += '/' - } else { - if (nodePrefix) { - path = nodePrefix + '/' - } + // add trailing slash and handle anchor link if needed + if (options.trailingSlash && originalUrl.includes('#')) { + if (!node.url.includes('/#')) { + node.url = node.url.replace('#', '/#') } - } - - node.url = `/${path}${node.url}` - - if (options.trailingSlash && node.url.includes('#')) { - node.url = node.url.replace('#', '/#') } else if (options.trailingSlash === true && !node.url.endsWith('/')) { node.url += '/' } - - for (const ext of extensions) { - if (node.url.includes(ext)) { - node.url = node.url.replace(ext, '') - } - } - - if (node.url.includes('README')) { - node.url = node.url.replace('README', '') - } } } @@ -104,4 +92,4 @@ export default function relativeLinks(options) { } return transform -} +} \ No newline at end of file diff --git a/lib/serialize.js b/lib/serialize.js index 1a277644ff4..2e47a0ab814 100644 --- a/lib/serialize.js +++ b/lib/serialize.js @@ -45,10 +45,6 @@ export async function pageProps({ params }) { return { notFound: true } - const inlineLinkSlugHelper = - params.slug?.length > 0 && route.path.endsWith('README.md') - ? params.slug?.concat(['README']) - : params.slug const manifestRoutes = cloneDeep(manifest.routes) replaceDefaultPath(manifestRoutes) @@ -121,9 +117,10 @@ export async function pageProps({ params }) { remarkInternalLinks, { prefix: docsFolder, - slug: inlineLinkSlugHelper, extensions: ['.mdx', '.md'], - trailingSlash: trailingSlash + trailingSlash: trailingSlash, + rootPath: route.path, + debug: (process.env.DEBUG === 'true') } ] ]