Use noreferrer in addition to noopener for edge case browsers

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2020-02-23 22:14:29 +00:00
parent d89b8b5148
commit d783ce86c8
33 changed files with 54 additions and 53 deletions

View file

@ -160,7 +160,7 @@ const transformTags = { // custom to matrix
delete attribs.target;
}
}
attribs.rel = 'noopener'; // https://mathiasbynens.github.io/rel-noopener/
attribs.rel = 'noreferrer noopener'; // https://mathiasbynens.github.io/rel-noopener/
return { tagName, attribs };
},
'img': function(tagName, attribs) {

View file

@ -136,7 +136,7 @@ export default class Markdown {
// thus opening in a new tab.
if (externalLinks) {
attrs.push(['target', '_blank']);
attrs.push(['rel', 'noopener']);
attrs.push(['rel', 'noreferrer noopener']);
}
this.tag('a', attrs);
} else {

View file

@ -821,10 +821,10 @@ export default createReactClass({
{_t(
"Want more than a community? <a>Get your own server</a>", {},
{
a: sub => <a href={hostingSignupLink} target="_blank" rel="noopener">{sub}</a>,
a: sub => <a href={hostingSignupLink} target="_blank" rel="noreferrer noopener">{sub}</a>,
},
)}
<a href={hostingSignupLink} target="_blank" rel="noopener">
<a href={hostingSignupLink} target="_blank" rel="noreferrer noopener">
<img src={require("../../../res/img/external-link.svg")} width="11" height="10" alt='' />
</a>
</div>;

View file

@ -481,7 +481,7 @@ export default createReactClass({
"Either use HTTPS or <a>enable unsafe scripts</a>.", {},
{
'a': (sub) => {
return <a target="_blank" rel="noopener"
return <a target="_blank" rel="noreferrer noopener"
href="https://www.google.com/search?&q=enable%20unsafe%20scripts"
>
{ sub }
@ -497,7 +497,7 @@ export default createReactClass({
"is not blocking requests.", {},
{
'a': (sub) => {
return <a target="_blank" rel="noopener" href={this.props.serverConfig.hsUrl}>
return <a target="_blank" rel="noreferrer noopener" href={this.props.serverConfig.hsUrl}>
{ sub }
</a>;
},

View file

@ -26,7 +26,7 @@ export default createReactClass({
render: function() {
return (
<div className="mx_AuthFooter">
<a href="https://matrix.org" target="_blank" rel="noopener">{ _t("powered by Matrix") }</a>
<a href="https://matrix.org" target="_blank" rel="noreferrer noopener">{ _t("powered by Matrix") }</a>
</div>
);
},

View file

@ -331,7 +331,7 @@ export const TermsAuthEntry = createReactClass({
checkboxes.push(
<label key={"policy_checkbox_" + policy.id} className="mx_InteractiveAuthEntryComponents_termsPolicy">
<input type="checkbox" onChange={() => this._togglePolicy(policy.id)} checked={checked} />
<a href={policy.url} target="_blank" rel="noopener">{ policy.name }</a>
<a href={policy.url} target="_blank" rel="noreferrer noopener">{ policy.name }</a>
</label>,
);
}

View file

@ -99,7 +99,7 @@ export default class ModularServerConfig extends ServerConfig {
"Enter the location of your Modular homeserver. It may use your own " +
"domain name or be a subdomain of <a>modular.im</a>.",
{}, {
a: sub => <a href={MODULAR_URL} target="_blank" rel="noopener">
a: sub => <a href={MODULAR_URL} target="_blank" rel="noreferrer noopener">
{sub}
</a>,
},

View file

@ -46,7 +46,7 @@ export const TYPES = {
label: () => _t('Premium'),
logo: () => <img src={require('../../../../res/img/modular-bw-logo.svg')} />,
description: () => _t('Premium hosting for organisations <a>Learn more</a>', {}, {
a: sub => <a href={MODULAR_URL} target="_blank" rel="noopener">
a: sub => <a href={MODULAR_URL} target="_blank" rel="noreferrer noopener">
{sub}
</a>,
}),

View file

@ -420,7 +420,7 @@ export default createReactClass({
onClick={this.onPermalinkClick}
href={permalink}
target="_blank"
rel="noopener"
rel="noreferrer noopener"
>
{ mxEvent.isRedacted() || mxEvent.getType() !== 'm.room.message'
? _t('Share Permalink') : _t('Share Message') }
@ -445,7 +445,7 @@ export default createReactClass({
element="a"
className="mx_MessageContextMenu_field"
target="_blank"
rel="noopener"
rel="noreferrer noopener"
onClick={this.closeMenu}
href={mxEvent.event.content.external_url}
>

View file

@ -68,10 +68,10 @@ export default class TopLeftMenu extends React.Component {
{_t(
"<a>Upgrade</a> to your own domain", {},
{
a: sub => <a href={hostingSignupLink} target="_blank" rel="noopener" tabIndex={-1}>{sub}</a>,
a: sub => <a href={hostingSignupLink} target="_blank" rel="noreferrer noopener" tabIndex={-1}>{sub}</a>,
},
)}
<a href={hostingSignupLink} target="_blank" rel="noopener" role="presentation" aria-hidden={true} tabIndex={-1}>
<a href={hostingSignupLink} target="_blank" rel="noreferrer noopener" role="presentation" aria-hidden={true} tabIndex={-1}>
<img src={require("../../../../res/img/external-link.svg")} width="11" height="10" alt='' />
</a>
</div>;

View file

@ -52,7 +52,7 @@ export default class ChangelogDialog extends React.Component {
_elementsForCommit(commit) {
return (
<li key={commit.sha} className="mx_ChangelogDialog_li">
<a href={commit.html_url} target="_blank" rel="noopener">
<a href={commit.html_url} target="_blank" rel="noreferrer noopener">
{commit.commit.message.split('\n')[0]}
</a>
</li>

View file

@ -1046,7 +1046,7 @@ export default class InviteDialog extends React.PureComponent {
"If you can't find someone, ask them for their username, share your " +
"username (%(userId)s) or <a>profile link</a>.",
{userId},
{a: (sub) => <a href={makeUserPermalink(userId)} rel="noopener" target="_blank">{sub}</a>},
{a: (sub) => <a href={makeUserPermalink(userId)} rel="noreferrer noopener" target="_blank">{sub}</a>},
);
buttonText = _t("Go");
goButtonFn = this._startDm;
@ -1055,7 +1055,7 @@ export default class InviteDialog extends React.PureComponent {
helpText = _t(
"If you can't find someone, ask them for their username (e.g. @user:server.com) or " +
"<a>share this room</a>.", {},
{a: (sub) => <a href={makeRoomPermalink(this.props.roomId)} rel="noopener" target="_blank">{sub}</a>},
{a: (sub) => <a href={makeRoomPermalink(this.props.roomId)} rel="noreferrer noopener" target="_blank">{sub}</a>},
);
buttonText = _t("Invite");
goButtonFn = this._inviteUsers;

View file

@ -218,7 +218,7 @@ export default class ShareDialog extends React.Component {
</div>
<div className="mx_ShareDialog_social_container">
{
socials.map((social) => <a rel="noopener"
socials.map((social) => <a rel="noreferrer noopener"
target="_blank"
key={social.name}
name={social.name}

View file

@ -135,7 +135,7 @@ export default class TermsDialog extends React.PureComponent {
rows.push(<tr key={termDoc[termsLang].url}>
<td className="mx_TermsDialog_service">{serviceName}</td>
<td className="mx_TermsDialog_summary">{summary}</td>
<td>{termDoc[termsLang].name} <a rel="noopener" target="_blank" href={termDoc[termsLang].url}>
<td>{termDoc[termsLang].name} <a rel="noreferrer noopener" target="_blank" href={termDoc[termsLang].url}>
<span className="mx_TermsDialog_link" />
</a></td>
<td><TermsCheckbox

View file

@ -552,7 +552,7 @@ export default class AppTile extends React.Component {
// Using Object.assign workaround as the following opens in a new window instead of a new tab.
// window.open(this._getSafeUrl(), '_blank', 'noopener=yes');
Object.assign(document.createElement('a'),
{ target: '_blank', href: this._getSafeUrl(), rel: 'noopener'}).click();
{ target: '_blank', href: this._getSafeUrl(), rel: 'noreferrer noopener'}).click();
}
_onReloadWidgetClick() {

View file

@ -91,7 +91,7 @@ export default class ImageView extends React.Component {
getName() {
let name = this.props.name;
if (name && this.props.link) {
name = <a href={ this.props.link } target="_blank" rel="noopener">{ name }</a>;
name = <a href={ this.props.link } target="_blank" rel="noreferrer noopener">{ name }</a>;
}
return name;
}

View file

@ -297,7 +297,7 @@ export default createReactClass({
} else if (contentUrl) {
const downloadProps = {
target: "_blank",
rel: "noopener",
rel: "noreferrer noopener",
// We set the href regardless of whether or not we intercept the download
// because we don't really want to convert the file to a blob eagerly, and

View file

@ -219,7 +219,7 @@ export default createReactClass({
if (link) {
span = (
<a href={link} target="_blank" rel="noopener">
<a href={link} target="_blank" rel="noreferrer noopener">
{ span }
</a>
);

View file

@ -136,7 +136,7 @@ export default createReactClass({
<div className="mx_LinkPreviewWidget" >
{ img }
<div className="mx_LinkPreviewWidget_caption">
<div className="mx_LinkPreviewWidget_title"><a href={this.props.link} target="_blank" rel="noopener">{ p["og:title"] }</a></div>
<div className="mx_LinkPreviewWidget_title"><a href={this.props.link} target="_blank" rel="noreferrer noopener">{ p["og:title"] }</a></div>
<div className="mx_LinkPreviewWidget_siteName">{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }</div>
<div className="mx_LinkPreviewWidget_description" ref={this._description}>
{ description }

View file

@ -509,7 +509,7 @@ export default createReactClass({
"<issueLink>submit a bug report</issueLink>.",
{ errcode: this.props.error.errcode },
{ issueLink: label => <a href="https://github.com/vector-im/riot-web/issues/new/choose"
target="_blank" rel="noopener">{ label }</a> },
target="_blank" rel="noreferrer noopener">{ label }</a> },
),
];
break;

View file

@ -119,7 +119,7 @@ export default createReactClass({
'In future this will be improved.',
) }
{' '}
<a href="https://github.com/vector-im/riot-web/issues/2671" target="_blank" rel="noopener">
<a href="https://github.com/vector-im/riot-web/issues/2671" target="_blank" rel="noreferrer noopener">
https://github.com/vector-im/riot-web/issues/2671
</a>
</div>,

View file

@ -172,7 +172,7 @@ export default class EventIndexPanel extends React.Component {
{},
{
'nativeLink': (sub) => <a href={nativeLink} target="_blank"
rel="noopener">{sub}</a>,
rel="noreferrer noopener">{sub}</a>,
},
)
}
@ -188,7 +188,7 @@ export default class EventIndexPanel extends React.Component {
{},
{
'riotLink': (sub) => <a href="https://riot.im/download/desktop"
target="_blank" rel="noopener">{sub}</a>,
target="_blank" rel="noreferrer noopener">{sub}</a>,
},
)
}

View file

@ -132,10 +132,10 @@ export default class ProfileSettings extends React.Component {
{_t(
"<a>Upgrade</a> to your own domain", {},
{
a: sub => <a href={hostingSignupLink} target="_blank" rel="noopener">{sub}</a>,
a: sub => <a href={hostingSignupLink} target="_blank" rel="noreferrer noopener">{sub}</a>,
},
)}
<a href={hostingSignupLink} target="_blank" rel="noopener">
<a href={hostingSignupLink} target="_blank" rel="noreferrer noopener">
<img src={require("../../../../res/img/external-link.svg")} width="11" height="10" alt='' />
</a>
</span>;

View file

@ -68,7 +68,7 @@ export default class BridgeSettingsTab extends React.Component {
{
// TODO: We don't have this link yet: this will prevent the translators
// having to re-translate the string when we do.
a: sub => <a href={BRIDGES_LINK} target="_blank" rel="noopener">{sub}</a>,
a: sub => <a href={BRIDGES_LINK} target="_blank" rel="noreferrer noopener">{sub}</a>,
},
)}</p>
<ul className="mx_RoomSettingsDialog_BridgeList">
@ -82,7 +82,7 @@ export default class BridgeSettingsTab extends React.Component {
{
// TODO: We don't have this link yet: this will prevent the translators
// having to re-translate the string when we do.
a: sub => <a href={BRIDGES_LINK} target="_blank" rel="noopener">{sub}</a>,
a: sub => <a href={BRIDGES_LINK} target="_blank" rel="noreferrer noopener">{sub}</a>,
},
)}</p>;
}

View file

@ -97,7 +97,7 @@ export default class SecurityRoomSettingsTab extends React.Component {
{},
{
'a': (sub) => {
return <a rel='noopener' target='_blank'
return <a rel='noreferrer noopener' target='_blank'
href='https://about.riot.im/help#end-to-end-encryption'>{sub}</a>;
},
},

View file

@ -37,7 +37,7 @@ const ghVersionLabel = function(repo, token='') {
} else {
url = `https://github.com/${repo}/commit/${token.split('-')[0]}`;
}
return <a target="_blank" rel="noopener" href={url}>{ token }</a>;
return <a target="_blank" rel="noreferrer noopener" href={url}>{ token }</a>;
};
export default class HelpUserSettingsTab extends React.Component {
@ -110,7 +110,7 @@ export default class HelpUserSettingsTab extends React.Component {
const legalLinks = [];
for (const tocEntry of SdkConfig.get().terms_and_conditions_links) {
legalLinks.push(<div key={tocEntry.url}>
<a href={tocEntry.url} rel="noopener" target="_blank">{tocEntry.text}</a>
<a href={tocEntry.url} rel="noreferrer noopener" target="_blank">{tocEntry.text}</a>
</div>);
}
@ -132,27 +132,27 @@ export default class HelpUserSettingsTab extends React.Component {
<span className='mx_SettingsTab_subheading'>{_t("Credits")}</span>
<ul>
<li>
The <a href="themes/riot/img/backgrounds/valley.jpg" rel="noopener" target="_blank">
The <a href="themes/riot/img/backgrounds/valley.jpg" rel="noreferrer noopener" target="_blank">
default cover photo</a> is ©&nbsp;
<a href="https://www.flickr.com/golan" rel="noopener" target="_blank">Jesús Roncero</a>{' '}
<a href="https://www.flickr.com/golan" rel="noreferrer noopener" target="_blank">Jesús Roncero</a>{' '}
used under the terms of&nbsp;
<a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="noopener" target="_blank">
<a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="noreferrer noopener" target="_blank">
CC-BY-SA 4.0</a>.
</li>
<li>
The <a href="https://github.com/matrix-org/twemoji-colr" rel="noopener" target="_blank">
The <a href="https://github.com/matrix-org/twemoji-colr" rel="noreferrer noopener" target="_blank">
twemoji-colr</a> font is ©&nbsp;
<a href="https://mozilla.org" rel="noopener" target="_blank">Mozilla Foundation</a>{' '}
<a href="https://mozilla.org" rel="noreferrer noopener" target="_blank">Mozilla Foundation</a>{' '}
used under the terms of&nbsp;
<a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noopener" target="_blank">
<a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noopener" target="_blank">
Apache 2.0</a>.
</li>
<li>
The <a href="https://twemoji.twitter.com/" rel="noopener" target="_blank">
The <a href="https://twemoji.twitter.com/" rel="noreferrer noopener" target="_blank">
Twemoji</a> emoji art is ©&nbsp;
<a href="https://twemoji.twitter.com/" rel="noopener" target="_blank">Twitter, Inc and other
<a href="https://twemoji.twitter.com/" rel="noreferrer noopener" target="_blank">Twitter, Inc and other
contributors</a> used under the terms of&nbsp;
<a href="https://creativecommons.org/licenses/by/4.0/" rel="noopener" target="_blank">
<a href="https://creativecommons.org/licenses/by/4.0/" rel="noreferrer noopener" target="_blank">
CC-BY 4.0</a>.
</li>
</ul>
@ -162,7 +162,8 @@ export default class HelpUserSettingsTab extends React.Component {
render() {
let faqText = _t('For help with using Riot, click <a>here</a>.', {}, {
'a': (sub) => <a href="https://about.riot.im/need-help/" rel='noopener' target='_blank'>{sub}</a>,
'a': (sub) =>
<a href="https://about.riot.im/need-help/" rel='noreferrer noopener' target='_blank'>{sub}</a>,
});
if (SdkConfig.get().welcomeUserId && getCurrentLanguage().startsWith('en')) {
faqText = (
@ -170,7 +171,7 @@ export default class HelpUserSettingsTab extends React.Component {
{
_t('For help with using Riot, click <a>here</a> or start a chat with our ' +
'bot using the button below.', {}, {
'a': (sub) => <a href="https://about.riot.im/need-help/" rel='noopener'
'a': (sub) => <a href="https://about.riot.im/need-help/" rel='noreferrer noopener'
target='_blank'>{sub}</a>,
})
}

View file

@ -55,7 +55,7 @@ export default class LabsUserSettingsTab extends React.Component {
'<a>Learn more</a>.', {}, {
'a': (sub) => {
return <a href="https://github.com/vector-im/riot-web/blob/develop/docs/labs.md"
rel='noopener' target='_blank'>{sub}</a>;
rel='noreferrer noopener' target='_blank'>{sub}</a>;
},
})
}

View file

@ -77,7 +77,7 @@ export default class InlineTermsAgreement extends React.Component {
"Accept <policyLink /> to continue:", {}, {
policyLink: () => {
return (
<a href={policy.url} rel='noopener' target='_blank'>
<a href={policy.url} rel='noreferrer noopener' target='_blank'>
{policy.name}
<span className='mx_InlineTermsAgreement_link' />
</a>

View file

@ -227,7 +227,7 @@ matrixLinkify.options = {
},
linkAttributes: {
rel: 'noopener',
rel: 'noreferrer noopener',
},
target: function(href, type) {

View file

@ -15,7 +15,7 @@ function remoteRender(event) {
const a = document.createElement("a");
a.id = "a";
a.rel = "noopener";
a.rel = "noreferrer noopener";
a.target = "_blank";
a.download = data.download;
a.style = data.style;

View file

@ -78,7 +78,7 @@ export default class AutoDiscoveryUtils {
return <a
href="https://github.com/vector-im/riot-web/blob/master/docs/config.md"
target="_blank"
rel="noopener"
rel="noreferrer noopener"
>{sub}</a>;
},
},

View file

@ -36,7 +36,7 @@ export function messageForResourceLimitError(limitType, adminContact, strings, e
const linkSub = sub => {
if (adminContact) {
return <a href={adminContact} target="_blank" rel="noopener">{sub}</a>;
return <a href={adminContact} target="_blank" rel="noreferrer noopener">{sub}</a>;
} else {
return sub;
}

View file

@ -121,7 +121,7 @@ describe("<TextualBody />", () => {
expect(wrapper.text()).toBe(ev.getContent().body);
const content = wrapper.find(".mx_EventTile_body");
expect(content.html()).toBe('<span class="mx_EventTile_body" dir="auto">' +
'Visit <a href="https://matrix.org/" class="linkified" target="_blank" rel="noopener">' +
'Visit <a href="https://matrix.org/" class="linkified" target="_blank" rel="noreferrer noopener">' +
'https://matrix.org/</a></span>');
});
});