From 0fdfaf2cf9c81f01902d33eceb7fdc23afc4317d Mon Sep 17 00:00:00 2001 From: Rafael Specht Date: Fri, 21 Sep 2018 16:56:22 -0300 Subject: [PATCH] Issue #11248: Avoiding links with highlighted words --- .../client/client.js | 9 +--- .../client/helper.js | 42 +++++++++++++++++++ .../tests/helper.test.js | 36 ++++++++++++++++ 3 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 packages/rocketchat-highlight-words/client/helper.js create mode 100644 packages/rocketchat-highlight-words/tests/helper.test.js diff --git a/packages/rocketchat-highlight-words/client/client.js b/packages/rocketchat-highlight-words/client/client.js index f2174eb38ca5..1c9141d5779c 100644 --- a/packages/rocketchat-highlight-words/client/client.js +++ b/packages/rocketchat-highlight-words/client/client.js @@ -4,6 +4,7 @@ */ import _ from 'underscore'; import s from 'underscore.string'; +import { highlightWords } from './helper'; function HighlightWordsClient(message) { let msg = message; @@ -16,13 +17,7 @@ function HighlightWordsClient(message) { } const to_highlight = RocketChat.getUserPreference(Meteor.user(), 'highlights'); - if (Array.isArray(to_highlight)) { - to_highlight.forEach((highlight) => { - if (!s.isBlank(highlight)) { - return msg = msg.replace(new RegExp(`(^|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(${ s.escapeRegExp(highlight) })($|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(?![^<]*>|[^<>]*<\\/)`, 'gmi'), '$1$2$3'); - } - }); - } + msg = highlightWords(msg, to_highlight); message.html = msg; return message; diff --git a/packages/rocketchat-highlight-words/client/helper.js b/packages/rocketchat-highlight-words/client/helper.js new file mode 100644 index 000000000000..3f7ef9edd3fa --- /dev/null +++ b/packages/rocketchat-highlight-words/client/helper.js @@ -0,0 +1,42 @@ +import s from 'underscore.string'; + +export const checkHighlightedWordsInUrls = (msg, highlight) => { + const urlRegex = new RegExp(`https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)(${ s.escapeRegExp(highlight) })\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)`, 'gmi'); + const urlMatches = msg.match(urlRegex); + + return urlMatches; +}; + +export const removeHighlightedUrls = (msg, highlight, urlMatches) => { + + urlMatches.forEach((match) => { + const highlightRegex = new RegExp(highlight, 'gmi'); + const withTemplate = match.replace(highlightRegex, `${ highlight }`); + const regexWithTemplate = new RegExp(withTemplate, 'i'); + + msg = msg.replace(regexWithTemplate, match); + }); + + return msg; +}; + +export const highlightWords = (msg, to_highlight) => { + const highlightTemplate = '$1$2$3'; + + if (Array.isArray(to_highlight)) { + to_highlight.forEach((highlight) => { + if (!s.isBlank(highlight)) { + const regex = new RegExp(`(^|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(${ s.escapeRegExp(highlight) })($|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(?![^<]*>|[^<>]*<\\/)`, 'gmi'); + const urlMatches = checkHighlightedWordsInUrls(msg, highlight); + + msg = msg.replace(regex, highlightTemplate); + + if (urlMatches) { + msg = removeHighlightedUrls(msg, highlight, urlMatches); + } + } + }); + } + + return msg; +}; diff --git a/packages/rocketchat-highlight-words/tests/helper.test.js b/packages/rocketchat-highlight-words/tests/helper.test.js new file mode 100644 index 000000000000..033b18dcde03 --- /dev/null +++ b/packages/rocketchat-highlight-words/tests/helper.test.js @@ -0,0 +1,36 @@ +/* eslint-env mocha */ + +import 'babel-polyfill'; +import assert from 'assert'; +import { highlightWords } from '../client/helper'; + +describe('helper', () => { + describe('highlightWords', () => { + it('highlights the correct words', () => { + const res = highlightWords('here is some word', ['word']); + + assert.equal(res, 'here is some word'); + }); + + describe('handles links', () => { + it('not highlighting one link', () => { + const res = highlightWords('here we go https://somedomain.com/here-some.word/pulls more words after', ['word']); + + assert.equal(res, 'here we go https://somedomain.com/here-some.word/pulls more words after'); + }); + + it('not highlighting two links', () => { + const msg = 'here https://somedomain.com/here-some-foo/pulls more words after http://www.domain.com/some.foo/bar words after'; + const res = highlightWords(msg, ['foo']); + + assert.equal(res, msg); + }); + + it('not highlighting link but keep words on message highlighted', () => { + const res = highlightWords('here we go https://somedomain.com/here-some.foo/pulls more foo after', ['foo']); + + assert.equal(res, 'here we go https://somedomain.com/here-some.foo/pulls more foo after'); + }); + }); + }); +});