doc.silverstripe.org/src/utils/rewriteLink.ts

130 lines
3.2 KiB
TypeScript
Raw Normal View History

2019-11-08 03:40:20 +01:00
import { createElement, ReactElement } from 'react';
import { domToReact, DomElement, HTMLReactParserOptions } from 'html-react-parser';
import { Link } from 'gatsby';
import rewriteAPILink from './rewriteAPILink';
2019-11-14 03:05:03 +01:00
import { getCurrentNode, getCurrentVersion } from '../utils/nodes';
2019-11-08 03:40:20 +01:00
import path from 'path';
import { SilverstripeDocument } from '../types';
2019-11-08 03:40:20 +01:00
interface LinkAttributes {
href?: string;
};
const relativeLink = (currentNode: SilverstripeDocument, href: string): string => {
const slug = path.join(currentNode.isIndex ? currentNode.slug : currentNode.parentSlug, href);
if (!slug.endsWith('/')) {
return `${slug}/`
}
return slug;
};
2019-11-19 04:29:29 +01:00
/**
* Ensure links use the Gatsby <Link /> component. Client-side routing FTW
*
* @param attribs
* @param children
* @param parseOptions
*/
2019-11-08 03:40:20 +01:00
const rewriteLink = (
attribs: LinkAttributes,
children: DomElement[],
parseOptions: HTMLReactParserOptions
): ReactElement|false => {
const { href } = attribs;
if (!href) {
return false;
}
const currentNode = getCurrentNode();
2019-11-14 03:05:03 +01:00
const version = getCurrentVersion();
2019-11-19 23:15:37 +01:00
// shorthand api links
2019-11-08 03:40:20 +01:00
if (href.match(/^api\:/)) {
const newHref = rewriteAPILink(href);
return createElement(
'a',
2019-11-19 04:29:29 +01:00
{
className: 'api-link',
href: newHref,
target: '_blank'
},
2019-11-08 03:40:20 +01:00
domToReact(children, parseOptions)
);
}
2019-11-19 23:15:37 +01:00
// explicit API links
if (href.match(/api\.silverstripe\.org/)) {
return createElement(
'a',
{
className: 'api-link',
href,
target: '_blank',
2019-11-19 23:46:39 +01:00
},
domToReact(children, parseOptions)
2019-11-19 23:15:37 +01:00
)
}
2019-11-08 03:40:20 +01:00
// absolute links
if (href.match(/^https?/)) {
return createElement(
'a',
{ href, target: '_blank' },
domToReact(children, parseOptions)
);
}
// Relative to root
2019-11-14 03:05:03 +01:00
if (href.startsWith('/')) {
2019-11-08 03:40:20 +01:00
return createElement(
Link,
2019-11-14 03:05:03 +01:00
{
2019-11-14 03:25:03 +01:00
to: path.join('/', 'en', version, href),
2019-11-14 03:05:03 +01:00
className: 'gatsby-link'
},
2019-11-08 03:40:20 +01:00
domToReact(children, parseOptions)
)
}
// Relative to page
if (currentNode && currentNode.parentSlug) {
// Relative links to markdown files should be resolved to their pretty urls.
if (href.endsWith('.md')) {
return createElement(
Link,
{
to: relativeLink(currentNode, href.replace(/\.md$/, '')),
className: 'gatsby-link',
},
domToReact(children, parseOptions)
)
}
2019-11-08 03:40:20 +01:00
return createElement(
Link,
{
to: relativeLink(currentNode, href),
2019-11-08 03:40:20 +01:00
className: 'gatsby-link'
},
domToReact(children, parseOptions)
)
}
// All else fails, just return the link as is.
return createElement(
Link,
{
to: path.join('/', href),
className: 'gatsby-link',
},
domToReact(children, parseOptions)
);
}
export default rewriteLink;