Skip to content

Commit db0327e

Browse files
authored
Merge 1b4895d into d3b3cc4
2 parents d3b3cc4 + 1b4895d commit db0327e

32 files changed

+453
-289
lines changed

.eslintrc.cjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
module.exports = {
22
root: true,
33
extends: 'vuepress',
4+
5+
// FIXME: This should be added to `eslint-config-vuepress`
6+
globals: {
7+
__VUEPRESS_CLEAN_URL__: 'readonly',
8+
},
9+
410
overrides: [
511
{
612
files: ['*.ts', '*.vue', '*.cts'],
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Resolve Route FullPath
2+
3+
## Includes Query And Hash
4+
5+
- Search Query: {{ JSON.stringify(resolveRoute('/?query=1')) }}
6+
- Hash: {{ JSON.stringify(resolveRoute('/#hash')) }}
7+
- Search Query And Hash: {{ JSON.stringify(resolveRoute('/?query=1#hash')) }}
8+
- Permalink And Search Query: {{ JSON.stringify(resolveRoute('/routes/permalinks/ascii-non-ascii.md?query=1')) }}
9+
10+
<script setup>
11+
import { resolveRoute } from 'vuepress/client'
12+
</script>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect, test } from '@playwright/test'
2+
3+
const testCases = [
4+
{
5+
path: '/?query=1',
6+
notFound: false,
7+
},
8+
{
9+
path: '/#hash',
10+
notFound: false,
11+
},
12+
{
13+
path: '/?query=1#hash',
14+
notFound: false,
15+
},
16+
{
17+
path: encodeURI('/永久链接-ascii-中文/?query=1'),
18+
notFound: false,
19+
},
20+
]
21+
22+
test('should resolve routes when including both the query and hash', async ({
23+
page,
24+
}) => {
25+
const listItemsLocator = await page
26+
.locator('.e2e-theme-content #includes-query-and-hash + ul > li')
27+
.all()
28+
29+
for (const [index, li] of listItemsLocator.entries()) {
30+
const textContent = await li.textContent()
31+
const resolvedRoute = JSON.parse(/: (\{.*\})\s*$/.exec(textContent!)![1])
32+
expect(resolvedRoute.path).toEqual(testCases[index].path)
33+
expect(resolvedRoute.notFound).toEqual(testCases[index].notFound)
34+
}
35+
})

packages/bundler-vite/src/plugins/vuepressMainPlugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ const resolveDefine = async ({
205205
const define: UserConfig['define'] = {
206206
__VUEPRESS_VERSION__: JSON.stringify(app.version),
207207
__VUEPRESS_BASE__: JSON.stringify(app.options.base),
208+
__VUEPRESS_CLEAN_URL__: JSON.stringify(app.options.route.cleanUrl),
208209
__VUEPRESS_DEV__: JSON.stringify(!isBuild),
209210
__VUEPRESS_SSR__: JSON.stringify(isServer),
210211
// @see http://link.vuejs.org/feature-flags

packages/bundler-webpack/src/config/handlePluginDefine.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const handlePluginDefine = async ({
2121
{
2222
__VUEPRESS_VERSION__: JSON.stringify(app.version),
2323
__VUEPRESS_BASE__: JSON.stringify(app.options.base),
24+
__VUEPRESS_CLEAN_URL__: JSON.stringify(app.options.route.cleanUrl),
2425
__VUEPRESS_DEV__: JSON.stringify(!isBuild),
2526
__VUEPRESS_SSR__: JSON.stringify(isServer),
2627
// @see http://link.vuejs.org/feature-flags

packages/cli/src/commands/dev/watchPageFiles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const watchPageFiles = (app: App): FSWatcher[] => {
4141
app.pages.forEach((page) => addDeps(page))
4242

4343
// watch page files
44-
const pagesWatcher = chokidar.watch(app.options.pagePatterns, {
44+
const pagesWatcher = chokidar.watch(app.options.route.pagePatterns, {
4545
cwd: app.dir.source(),
4646
ignoreInitial: true,
4747
})

packages/client/src/components/RouteLink.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { computed, defineComponent, h } from 'vue'
22
import type { SlotsType, VNode } from 'vue'
33
import { useRoute, useRouter } from 'vue-router'
4-
import { resolveRoutePath } from '../router/index.js'
4+
import { resolveRouteFullPath } from '../router/index.js'
55

66
/**
77
* Forked from https://github.com/vuejs/router/blob/941b2131e80550009e5221d4db9f366b1fea3fd5/packages/router/src/RouterLink.ts#L293
@@ -91,7 +91,7 @@ export const RouteLink = defineComponent({
9191
const path = computed(() =>
9292
props.to.startsWith('#') || props.to.startsWith('?')
9393
? props.to
94-
: `${__VUEPRESS_BASE__}${resolveRoutePath(props.to, route.path).substring(1)}`,
94+
: `${__VUEPRESS_BASE__}${resolveRouteFullPath(props.to, route.path).substring(1)}`,
9595
)
9696

9797
return () =>

packages/client/src/router/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ export type { Router, RouteLocationNormalizedLoaded } from 'vue-router'
22
export { useRoute, useRouter } from 'vue-router'
33

44
export * from './resolveRoute.js'
5+
export * from './resolveRouteFullPath.js'
6+
export * from './resolveRouteKey.js'
57
export * from './resolveRoutePath.js'
Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { resolvePathInfo, resolveRoutePathWithExt } from '@vuepress/shared'
12
import { routes } from '../internal/routes.js'
23
import type { Route, RouteMeta } from '../types/index.js'
3-
import { resolveRoutePath } from './resolveRoutePath.js'
4+
import { resolveRouteKey } from './resolveRouteKey.js'
45

56
export interface ResolvedRoute<T extends RouteMeta = RouteMeta>
67
extends Route<T> {
@@ -15,15 +16,27 @@ export const resolveRoute = <T extends RouteMeta = RouteMeta>(
1516
path: string,
1617
currentPath?: string,
1718
): ResolvedRoute<T> => {
18-
const routePath = resolveRoutePath(path, currentPath)
19-
const route = routes.value[routePath] ?? {
20-
...routes.value['/404.html'],
21-
notFound: true,
19+
// get only the pathname from the path
20+
const [pathname, hashAndQueries] = resolvePathInfo(path)
21+
22+
// resolve the route path
23+
const routeKey = resolveRouteKey(pathname, currentPath)
24+
const routeFullPath = __VUEPRESS_CLEAN_URL__
25+
? routeKey
26+
: resolveRoutePathWithExt(routeKey) + hashAndQueries
27+
28+
// the route not found
29+
if (!routes.value[routeKey]) {
30+
return {
31+
...routes.value['/404'],
32+
path: routeFullPath,
33+
notFound: true,
34+
} as ResolvedRoute<T>
2235
}
2336

2437
return {
25-
path: routePath,
38+
...routes.value[routeKey],
39+
path: routeFullPath,
2640
notFound: false,
27-
...route,
2841
} as ResolvedRoute<T>
2942
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { resolvePathInfo } from '@vuepress/shared'
2+
import { resolveRoutePath } from './resolveRoutePath.js'
3+
4+
/**
5+
* Resolve route full path with given raw path
6+
*/
7+
export const resolveRouteFullPath = (
8+
path: string,
9+
currentPath?: string,
10+
): string => {
11+
const [pathname, hashAndQueries] = resolvePathInfo(path)
12+
13+
return resolveRoutePath(pathname, currentPath) + hashAndQueries
14+
}

0 commit comments

Comments
 (0)