Skip to content

Commit

Permalink
feat(web): no longer escapes slashes in URL
Browse files Browse the repository at this point in the history
  • Loading branch information
stevapple committed Oct 23, 2024
1 parent ac00857 commit be07a8d
Show file tree
Hide file tree
Showing 5 changed files with 8 additions and 121 deletions.
14 changes: 2 additions & 12 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import Help from './pages/Help'
import Home from './pages/Home'
import NotFound from './pages/NotFound'
import Upload from './pages/Upload'
import EscapeSlashForDocsPath from './pages/EscapeSlashForDocsPath'
import { MessageBannerProvider } from './data-providers/MessageBannerProvider'
import { SearchProvider } from './data-providers/SearchProvider'

Expand Down Expand Up @@ -54,17 +53,8 @@ function App(): JSX.Element {
element: <Docs />
},
{
path: ':page',
children: [
{
path: '',
element: <Docs />
},
{
path: '*',
element: <EscapeSlashForDocsPath />
}
]
path: '*',
element: <Docs />
}
]
}
Expand Down
13 changes: 6 additions & 7 deletions web/src/pages/Docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export default function Docs(): JSX.Element {
const [loadingFailed, setLoadingFailed] = useState<boolean>(false)

const project = useRef(params.project ?? '')
const page = useRef(params.page ?? 'index.html')
const hash = useRef(location.hash.split('?')[0] ?? '')
const page = useRef(params['*'] ?? '')
const hash = useRef(location.hash)

const [version, setVersion] = useState<string>(params.version ?? 'latest')
const [hideUi, setHideUi] = useState<boolean>(
Expand Down Expand Up @@ -91,10 +91,9 @@ export default function Docs(): JSX.Element {
})()
}, [project])

/** Encodes the url for the current page, and escapes the path part to avoid
* redirecting to escapeSlashForDocsPath.
/** Encodes the url for the current page.
* @example
* getUrl('project', 'version', 'path/to/page.html', '#hash', false) -> '#/project/version/path%2Fto%2Fpage.html#hash'
* getUrl('project', 'version', 'path/to/page.html', '#hash', false) -> '/project/version/path/to/page.html#hash'
*/
const getUrl = (
project: string,
Expand All @@ -103,7 +102,7 @@ export default function Docs(): JSX.Element {
hash: string,
hideUi: boolean
): string => {
return `/${project}/${version}/${encodeURIComponent(page)}${hash}${hideUi ? '?hide-ui=true' : ''}`
return `/${project}/${version}/${encodeURI(page)}${hash}${hideUi ? '?hide-ui=true' : ''}`
}

const updateUrl = (newVersion: string, hideUi: boolean): void => {
Expand Down Expand Up @@ -149,7 +148,7 @@ export default function Docs(): JSX.Element {
useEffect(() => {
const urlProject = params.project ?? ''
const urlVersion = params.version ?? 'latest'
const urlPage = params.page ?? 'index.html'
const urlPage = params['*'] ?? 'index.html'
const urlHash = location.hash.split('?')[0] ?? ''
const urlHideUi =
searchParams.get('hide-ui') === 'true' ||
Expand Down
22 changes: 0 additions & 22 deletions web/src/pages/EscapeSlashForDocsPath.tsx

This file was deleted.

29 changes: 0 additions & 29 deletions web/src/repositories/ProjectRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,6 @@ import { type Project } from '../models/ProjectsResponse'

const RESOURCE = 'doc'

/**
* Escapes all slashes in a url to the docs page from the point between the version and the path.
* This is necessary because react-router thinks that the slashes are path separators.
* The slashes are escaped to %2F and reverted back to slashes by react-router.
* Example:
* /doc/project/1.0.0/path/to/page -> /doc/project/1.0.0/path%2Fto%2Fpage
* @param pathname useLocation().pathname
* @param search useLocation().search
* @param hash useLocation().hash
* @returns a url with escaped slashes
*/
function escapeSlashesInUrl(
pathname: string,
search: string,
hash: string
): string {
const url = pathname + hash + search
const projectAndVersion = url.split('/', 3).join('/')
let path = url.substring(projectAndVersion.length + 1)
path = path.replaceAll('/', '%2F')

if (path.length === 0) {
return projectAndVersion
}

return projectAndVersion + '/' + path
}

function filterHiddenVersions(allProjects: Project[]): Project[] {
// create deep-copy first
const projects = JSON.parse(JSON.stringify(allProjects)) as Project[]
Expand Down Expand Up @@ -266,7 +238,6 @@ function setFavorite(projectName: string, shouldBeFavorite: boolean): void {
}

const exp = {
escapeSlashesInUrl,
getVersions,
getLatestVersion,
filterHiddenVersions,
Expand Down
51 changes: 0 additions & 51 deletions web/src/tests/repositories/ProjectRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,54 +459,3 @@ describe('getLatestVersion', () => {
expect(latestVersion).toStrictEqual(versions[0])
})
})

describe('escapeSlashesInUrl', () => {
test('should ignore version and project name', () => {
const url = '/project/1.0.0'

expect(ProjectRepository.escapeSlashesInUrl(url, '', '')).toBe(url)
})

test('should ignore trailing slash', () => {
const given = '/project/1.0.0/'
const expected = '/project/1.0.0'

expect(ProjectRepository.escapeSlashesInUrl(given, '', '')).toBe(expected)
})

test('should escape slashes in path', () => {
const given = '/project/1.0.0/path/with/slashes'
const expected = '/project/1.0.0/path%2Fwith%2Fslashes'

expect(ProjectRepository.escapeSlashesInUrl(given, '', '')).toBe(expected)
})

test('should work with query parameters', () => {
const given = '/project/1.0.0/path/with/slashes'
const query = '?param=value'
const expected = '/project/1.0.0/path%2Fwith%2Fslashes?param=value'

expect(ProjectRepository.escapeSlashesInUrl(given, query, '')).toBe(
expected
)
})

test('should work with hash', () => {
const given = '/project/1.0.0/path/with/slashes'
const hash = '#hash'
const expected = '/project/1.0.0/path%2Fwith%2Fslashes#hash'

expect(ProjectRepository.escapeSlashesInUrl(given, '', hash)).toBe(expected)
})

test('should work with query parameters and hash', () => {
const given = '/project/1.0.0/path/with/slashes'
const query = '?param=value'
const hash = '#hash'
const expected = '/project/1.0.0/path%2Fwith%2Fslashes#hash?param=value'

expect(ProjectRepository.escapeSlashesInUrl(given, query, hash)).toBe(
expected
)
})
})

0 comments on commit be07a8d

Please sign in to comment.