Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 685x 685x 685x 559x 559x 1x 558x 685x 685x 487x 685x 81x 685x | /*
* Part of Pleiar.no - a collection of tools for nurses
*
* Copyright (C) Eskild Hustvedt 2017-2018
* Copyright (C) Fagforbundet 2019
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// @flow
import * as React from 'react';
import featureDetection from '../../helper.feature-detection';
/**
* This is a class that wraps anchor-elements that link to external websites.
*
* The default is to open those in a new tab. This exposes us to security
* risks because of window.opener (see
* https://mathiasbynens.github.io/rel-noopener/). The workaround for this is
* to add rel="noopener" to anchor elements. However, this is not supported in
* all browsers, so we need to add rel="noreferrer" as well, which isn't
* actually what we want to do. Thus this wrapper element will detect if
* noopener is supported, and if it is we will use noopener without noreferrer.
* Otherwise we will use both noopener and noreferrer.
*
* If you don't want to open in a new tab, specify sameWindow={true}, this reverts
* ExternalLink to work just like a regular anchor.
*
* basicStyle makes the generated <a>-element *not* have the class
* "external-link". This is useful when the child is an image, or when you just
* want to style some link like any other. Note that sameWindow={true} implicitly
* enables basicStyle.
*
* In addition to the props it directly supports, namely href, and the internal
* "sameWindow", and child elements, it will also pass on arbitrary props to
* the `a`-element.
*/
class ExternalLink extends React.PureComponent<{href: string, basicStyle?: boolean, sameWindow?: boolean, children: React.Node, className?: string}> // eslint-disable-line flowtype/require-exact-type
{
render (): React.Node // eslint-disable-line require-jsdoc
{
// FIXME: Handle the edge case of rel= being supplied
const { href, children, sameWindow, className, basicStyle, ...otherProps } = this.props;
const externalLinkProps = {};
if (!sameWindow)
{
externalLinkProps.target = '_blank';
// Do feature detection so that we don't have to disable referrer
// for all external links.
if(featureDetection.aSupportsRel('noopener'))
{
externalLinkProps.rel = 'noopener';
}
else
{
externalLinkProps.rel = 'noopener noreferrer';
}
}
const cssClasses = [ ];
if (!sameWindow && basicStyle !== true)
{
cssClasses.push('external-link');
}
if(typeof(className) === "string")
{
cssClasses.push(className);
}
// $FlowIssue[cannot-spread-inexact] Thinks that ...otherProps could include a href conflicting with our href, which is impossible
return <a href={href} className={cssClasses.join(" ")} {...otherProps} {...externalLinkProps}>{children}</a>; // eslint-disable-line react/forbid-elements
}
}
export { ExternalLink };
|