Replaces smileys and the logic of replacing links/emails. (#3560)

* Replaces smileys and the logic of replacing links/emails.

Now using react-emoji-render and react-linkify.

* Fixes heart emoji.

It is known that current implementation doesn't work with ascii emojis that contain < or >, like >:( >:-( </3 <\3 <3. Making those work may bring some xss issues.

* Adds '_blank' and 'noopener noreferrer' to the replaced links.

* Fixes package-lock links (http vs https).

* Fixes comments.
This commit is contained in:
Дамян Минков
2018-12-03 18:01:40 +00:00
committed by GitHub
parent 34f2ff9b85
commit f11b6cbb1e
30 changed files with 124 additions and 1876 deletions

View File

@@ -1,11 +1,12 @@
// @flow
import React, { PureComponent } from 'react';
import { toArray } from 'react-emoji-render';
import Linkify from 'react-linkify';
import { translate } from '../../base/i18n';
import { processReplacements } from '../replacement';
/**
* The type of the React {@code Component} props of {@link Chat}.
*/
@@ -37,7 +38,7 @@ class ChatMessage extends PureComponent<Props> {
render() {
const { message } = this.props;
let messageTypeClassname = '';
let messagetoDisplay = message.message;
let messageToDisplay = message.message;
switch (message.messageType) {
case 'local':
@@ -46,9 +47,9 @@ class ChatMessage extends PureComponent<Props> {
break;
case 'error':
messageTypeClassname = 'error';
messagetoDisplay = this.props.t('chat.error', {
messageToDisplay = this.props.t('chat.error', {
error: message.error,
originalText: messagetoDisplay
originalText: messageToDisplay
});
break;
default:
@@ -58,10 +59,27 @@ class ChatMessage extends PureComponent<Props> {
// replace links and smileys
// Strophe already escapes special symbols on sending,
// so we escape here only tags to avoid double &amp;
const escMessage = messagetoDisplay.replace(/</g, '&lt;')
const escMessage = messageToDisplay.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\n/g, '<br/>');
const messageWithHTML = processReplacements(escMessage);
const processedMessage = [];
// content is an array of text and emoji components
const content = toArray(escMessage, { className: 'smiley' });
content.forEach(i => {
if (typeof i === 'string') {
processedMessage.push(
<Linkify
key = { i }
properties = {{
rel: 'noopener noreferrer',
target: '_blank'
}}>{ i }</Linkify>);
} else {
processedMessage.push(i);
}
});
return (
<div className = { `chatmessage ${messageTypeClassname}` }>
@@ -74,10 +92,9 @@ class ChatMessage extends PureComponent<Props> {
<div className = { 'timestamp' }>
{ ChatMessage.formatTimestamp(message.timestamp) }
</div>
<div
className = 'usermessage'
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML = {{ __html: messageWithHTML }} />
<div className = 'usermessage'>
{ processedMessage }
</div>
</div>
);
}