aboutsummaryrefslogtreecommitdiffstats
path: root/packages/react-shared/src/components/markdown_link_block.tsx
blob: 8f58622498d004f2af40726b28c50772cdd93138 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import * as _ from 'lodash';
import * as React from 'react';

import { constants } from '../utils/constants';
import { utils } from '../utils/utils';

export interface MarkdownLinkBlockProps {
    href: string;
}

export interface MarkdownLinkBlockState {}

export class MarkdownLinkBlock extends React.Component<MarkdownLinkBlockProps, MarkdownLinkBlockState> {
    // Re-rendering a linkBlock causes it to remain unclickable.
    // We therefore noop re-renders on this component if it's props haven't changed.
    public shouldComponentUpdate(nextProps: MarkdownLinkBlockProps, nextState: MarkdownLinkBlockState) {
        return nextProps.href !== this.props.href;
    }
    public render() {
        const href = this.props.href;
        const isLinkToSection = _.startsWith(href, '#');
        // If protocol is http or https, we can open in a new tab, otherwise don't for security reasons
        if (_.startsWith(href, 'http') || _.startsWith(href, 'https')) {
            return (
                <a href={href} target="_blank" rel="nofollow noreferrer noopener">
                    {this.props.children}
                </a>
            );
        } else if (isLinkToSection) {
            return (
                <a
                    style={{ cursor: 'pointer', textDecoration: 'underline' }}
                    onClick={this._onHashUrlClick.bind(this, href)}
                >
                    {this.props.children}
                </a>
            );
        } else {
            return <a href={href}>{this.props.children}</a>;
        }
    }
    private _onHashUrlClick(href: string) {
        const hash = href.split('#')[1];
        utils.scrollToHash(hash, constants.SCROLL_CONTAINER_ID);
        utils.setUrlHash(hash);
    }
}