mirror of
https://github.com/wassname/talk.git
synced 2026-09-09 11:38:08 +08:00
Implement simple regexp based highlighter
This commit is contained in:
@@ -1,25 +1,56 @@
|
||||
import React from 'react';
|
||||
import Highlighter from 'react-highlight-words';
|
||||
import Linkify from 'react-linkify';
|
||||
const linkify = new Linkify();
|
||||
import {linkRegexp} from '../utils/regexp';
|
||||
|
||||
const wordSeperator = /([.\s'"?!])/;
|
||||
|
||||
function markWords(body, words, index) {
|
||||
const tokens = body.split(wordSeperator);
|
||||
const content = [];
|
||||
let tmp = [];
|
||||
tokens.forEach((token, i) => {
|
||||
if (words.indexOf(token.toLowerCase()) >= 0) {
|
||||
content.push(...tmp);
|
||||
tmp = [];
|
||||
content.push(<mark key={`${index}_${i}`}>{token}</mark>);
|
||||
return;
|
||||
}
|
||||
tmp.push(token);
|
||||
});
|
||||
content.push(...tmp);
|
||||
return content;
|
||||
}
|
||||
|
||||
function markLinks(body) {
|
||||
const tokens = body.split(linkRegexp);
|
||||
const content = [];
|
||||
let tmp = [];
|
||||
tokens
|
||||
.filter((token) => token)
|
||||
.forEach((token, i) => {
|
||||
if (token.match(linkRegexp)) {
|
||||
content.push(...tmp);
|
||||
tmp = [];
|
||||
content.push(<mark key={i}>{token}</mark>);
|
||||
return;
|
||||
}
|
||||
tmp.push(token);
|
||||
});
|
||||
content.push(...tmp);
|
||||
return content;
|
||||
}
|
||||
|
||||
export default ({suspectWords, bannedWords, body, ...rest}) => {
|
||||
|
||||
const links = linkify.getMatches(body);
|
||||
const linkText = links ? links.map((link) => link.raw) : [];
|
||||
|
||||
const searchWords = [
|
||||
...suspectWords,
|
||||
...bannedWords,
|
||||
...linkText
|
||||
];
|
||||
|
||||
const words = [...suspectWords, ...bannedWords].map((word) => word.toLowerCase());
|
||||
const content = markLinks(body)
|
||||
.map((element, index) => {
|
||||
if (typeof element !== 'string') {
|
||||
return element;
|
||||
}
|
||||
return markWords(element, words, index);
|
||||
});
|
||||
return (
|
||||
<Highlighter
|
||||
{...rest}
|
||||
autoEscape={true}
|
||||
searchWords={searchWords}
|
||||
textToHighlight={body}
|
||||
/>
|
||||
<div {...rest}>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import React from 'react';
|
||||
import Linkify from 'react-linkify';
|
||||
const linkify = new Linkify();
|
||||
import {linkRegexp} from '../utils/regexp';
|
||||
|
||||
export default ({text, children}) => {
|
||||
const hasLinks = !!linkify.getMatches(text);
|
||||
const hasLinks = text.match(linkRegexp);
|
||||
|
||||
if (!hasLinks) {
|
||||
return null;
|
||||
|
||||
@@ -127,7 +127,7 @@ class Comment extends React.Component {
|
||||
</div>
|
||||
<CommentAnimatedEdit body={comment.body}>
|
||||
<div className={styles.itemBody}>
|
||||
<p className={styles.body}>
|
||||
<div className={styles.body}>
|
||||
<CommentBodyHighlighter
|
||||
suspectWords={suspectWords}
|
||||
bannedWords={bannedWords}
|
||||
@@ -141,7 +141,7 @@ class Comment extends React.Component {
|
||||
>
|
||||
<Icon name="open_in_new" /> {t('comment.view_context')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<Slot
|
||||
fill="adminCommentContent"
|
||||
data={data}
|
||||
|
||||
@@ -2,3 +2,4 @@ export const isPremod = (mod) => mod === 'PRE';
|
||||
|
||||
export const getModPath = (type = 'all', assetId) =>
|
||||
assetId ? `/admin/moderate/${type}/${assetId}` : `/admin/moderate/${type}`;
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const linkRegexp = /([-a-zA-Z0-9@:%_+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_+.~#?&//=]*)?)/;
|
||||
@@ -154,9 +154,7 @@
|
||||
"react": "^15.4.2",
|
||||
"react-apollo": "^1.4.12",
|
||||
"react-dom": "^15.4.2",
|
||||
"react-highlight-words": "^0.6.0",
|
||||
"react-input-autosize": "^1.1.4",
|
||||
"react-linkify": "^0.1.3",
|
||||
"react-mdl": "^1.7.2",
|
||||
"react-mdl-selectfield": "^0.2.0",
|
||||
"react-recaptcha": "^2.2.6",
|
||||
|
||||
@@ -922,7 +922,7 @@ babel-register@^6.26.0:
|
||||
mkdirp "^0.5.1"
|
||||
source-map-support "^0.4.15"
|
||||
|
||||
babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.6.1:
|
||||
babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.6.1:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||
dependencies:
|
||||
@@ -3396,12 +3396,6 @@ hide-powered-by@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hide-powered-by/-/hide-powered-by-1.0.0.tgz#4a85ad65881f62857fc70af7174a1184dccce32b"
|
||||
|
||||
highlight-words-core@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/highlight-words-core/-/highlight-words-core-1.0.3.tgz#0886d0e757c8ca3928cbc873042bd544f8f6b2e5"
|
||||
dependencies:
|
||||
babel-runtime "^6.11.6"
|
||||
|
||||
history@^3.0.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/history/-/history-3.3.0.tgz#fcedcce8f12975371545d735461033579a6dae9c"
|
||||
@@ -4395,12 +4389,6 @@ license-webpack-plugin@^1.0.0:
|
||||
dependencies:
|
||||
ejs "^2.5.7"
|
||||
|
||||
linkify-it@^1.2.0:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-1.2.4.tgz#0773526c317c8fd13bd534ee1d180ff88abf881a"
|
||||
dependencies:
|
||||
uc.micro "^1.0.1"
|
||||
|
||||
linkify-it@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f"
|
||||
@@ -6379,12 +6367,6 @@ react-dom@^15.3.1, react-dom@^15.4.2:
|
||||
object-assign "^4.1.0"
|
||||
prop-types "~15.5.7"
|
||||
|
||||
react-highlight-words@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/react-highlight-words/-/react-highlight-words-0.6.0.tgz#e12e9fedda4333e410ea408cdedffc77122020aa"
|
||||
dependencies:
|
||||
highlight-words-core "^1.0.2"
|
||||
|
||||
react-input-autosize@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-1.1.4.tgz#cbc45072d4084ddc57806db8e3b34e644b8366ac"
|
||||
@@ -6392,13 +6374,6 @@ react-input-autosize@^1.1.4:
|
||||
create-react-class "^15.5.2"
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-linkify@^0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/react-linkify/-/react-linkify-0.1.3.tgz#6e886180bda6c8fdc5f9f8a7ebe82fc0f48db7ad"
|
||||
dependencies:
|
||||
linkify-it "^1.2.0"
|
||||
tlds "^1.57.0"
|
||||
|
||||
react-mdl-selectfield@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-mdl-selectfield/-/react-mdl-selectfield-0.2.0.tgz#36e1a97233036c057ab2bdb31ec09ad8d9988411"
|
||||
@@ -7456,10 +7431,6 @@ title-case-minors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/title-case-minors/-/title-case-minors-1.0.0.tgz#51f17037c294747a1d1cda424b5004c86d8eb115"
|
||||
|
||||
tlds@^1.57.0:
|
||||
version "1.185.0"
|
||||
resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.185.0.tgz#9d5ddaae379778a98e3edc3a131d46a40cbc3ba4"
|
||||
|
||||
tmp@^0.0.31:
|
||||
version "0.0.31"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7"
|
||||
|
||||
Reference in New Issue
Block a user