mirror of
https://github.com/harness/drone.git
synced 2025-05-31 11:43:15 +00:00
feat: [CODE-25]: Handle relative links to repository files inside a README
This commit is contained in:
parent
67048fb2c8
commit
a1818991aa
@ -1,5 +1,5 @@
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import React, { useCallback, useMemo, useState } from 'react'
|
||||
import { Container } from '@harness/uicore'
|
||||
import cx from 'classnames'
|
||||
import MarkdownPreview from '@uiw/react-markdown-preview'
|
||||
@ -19,9 +19,8 @@ export function MarkdownViewer({ source, className, maxHeight }: MarkdownViewerP
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false)
|
||||
const history = useHistory()
|
||||
const [zoomLevel, setZoomLevel] = useState(INITIAL_ZOOM_LEVEL)
|
||||
|
||||
const [imgEvent, setImageEvent] = useState<string[]>([])
|
||||
|
||||
const refRootHref = useMemo(() => document.getElementById('repository-ref-root')?.getAttribute('href'), [])
|
||||
const interceptClickEventOnViewerContainer = useCallback(
|
||||
event => {
|
||||
const { target } = event
|
||||
@ -31,19 +30,26 @@ export function MarkdownViewer({ source, className, maxHeight }: MarkdownViewerP
|
||||
const imageSrc = string.split('![image]')[1]
|
||||
return imageSrc.slice(1, imageSrc.length - 1)
|
||||
})
|
||||
|
||||
setImageEvent(imageStringArray)
|
||||
|
||||
if (target?.tagName?.toLowerCase() === 'a') {
|
||||
const { href } = target
|
||||
const href = target.getAttribute('href')
|
||||
|
||||
// Intercept click event on internal links and navigate to pages to avoid full page reload
|
||||
if (href && !href.startsWith('#')) {
|
||||
if (href) {
|
||||
try {
|
||||
const url = new URL(href)
|
||||
const url = new URL(target.href)
|
||||
|
||||
if (url.origin === window.location.origin) {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
history.push(url.pathname)
|
||||
|
||||
if (href.startsWith('#')) {
|
||||
document.getElementById(href.slice(1))?.scrollIntoView()
|
||||
} else {
|
||||
history.push(url.pathname)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
@ -71,6 +77,43 @@ export function MarkdownViewer({ source, className, maxHeight }: MarkdownViewerP
|
||||
if (parent && /^h(1|2|3|4|5|6)/.test((parent as unknown as HTMLDivElement).tagName)) {
|
||||
parent.children = parent.children.slice(1)
|
||||
}
|
||||
|
||||
// Rewrite a.href to point to the correct location for relative links to files inside repository.
|
||||
// Relative links are defined as links that do not start with /, #, https:, http:, mailto:,
|
||||
// tel:, data:, javascript:, sms:, or http(s):
|
||||
if (refRootHref) {
|
||||
const { properties } = node as unknown as { properties: { href: string } }
|
||||
let href: string = properties.href
|
||||
|
||||
if (
|
||||
href &&
|
||||
!href.startsWith('/') &&
|
||||
!href.startsWith('#') &&
|
||||
!href.startsWith('https:') &&
|
||||
!href.startsWith('http:') &&
|
||||
!href.startsWith('mailto:') &&
|
||||
!href.startsWith('tel:') &&
|
||||
!href.startsWith('data:') &&
|
||||
!href.startsWith('javascript:') &&
|
||||
!href.startsWith('sms:') &&
|
||||
!/^http(s)?:/.test(href)
|
||||
) {
|
||||
try {
|
||||
// Some relative links are prefixed by `./`, normalize them
|
||||
if (href.startsWith('./')) {
|
||||
href = properties.href = properties.href.replace('./', '')
|
||||
}
|
||||
|
||||
// Test if the link is relative to the current page.
|
||||
// If true, rewrite it to point to the correct location
|
||||
if (new URL(window.location.href + '/' + href).origin === window.location.origin) {
|
||||
properties.href = (refRootHref + '/~/' + href).replace(/^\/ng\//, '/')
|
||||
}
|
||||
} catch (_exception) {
|
||||
// eslint-disable-line no-empty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
rehypePlugins={[
|
||||
|
@ -68,7 +68,9 @@ export function ContentHeader({
|
||||
/>
|
||||
<Container>
|
||||
<Layout.Horizontal spacing="small">
|
||||
<Link to={routes.toCODERepository({ repoPath: repoMetadata.path as string, gitRef })}>
|
||||
<Link
|
||||
id="repository-ref-root"
|
||||
to={routes.toCODERepository({ repoPath: repoMetadata.path as string, gitRef })}>
|
||||
<Icon name={CodeIcon.Folder} />
|
||||
</Link>
|
||||
<Text color={Color.GREY_900}>/</Text>
|
||||
|
@ -8,8 +8,6 @@
|
||||
|
||||
.heading {
|
||||
box-shadow: 0px 0px 1px rgba(40, 41, 61, 0.08), 0px 0.5px 2px rgba(96, 97, 112, 0.16);
|
||||
// border-top: 1px solid var(--grey-200);
|
||||
// border-bottom: 1px solid var(--grey-200);
|
||||
align-items: center;
|
||||
padding-left: var(--spacing-large) !important;
|
||||
background-color: var(--grey-100);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import { Container } from '@harness/uicore'
|
||||
import { GitInfoProps, isDir } from 'utils/GitUtils'
|
||||
import { ContentHeader } from './ContentHeader/ContentHeader'
|
||||
@ -12,6 +12,10 @@ export function RepositoryContent({
|
||||
resourcePath,
|
||||
resourceContent
|
||||
}: Pick<GitInfoProps, 'repoMetadata' | 'gitRef' | 'resourcePath' | 'resourceContent'>) {
|
||||
useEffect(() => {
|
||||
window.scroll({ top: 0 })
|
||||
}, [gitRef, resourcePath])
|
||||
|
||||
return (
|
||||
<Container className={css.resourceContent}>
|
||||
<ContentHeader
|
||||
|
Loading…
x
Reference in New Issue
Block a user