From c76f408d19c8b0d7929c1a66823c447c392e08cd Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Mon, 28 Jan 2019 14:01:21 -0200 Subject: [PATCH] Make autolinker avoid message tokens --- .../rocketchat-autolinker/client/client.js | 106 ++++++++---------- 1 file changed, 49 insertions(+), 57 deletions(-) diff --git a/packages/rocketchat-autolinker/client/client.js b/packages/rocketchat-autolinker/client/client.js index 2afe8f89f7c00..d76baeff2195b 100644 --- a/packages/rocketchat-autolinker/client/client.js +++ b/packages/rocketchat-autolinker/client/client.js @@ -1,75 +1,67 @@ import { Meteor } from 'meteor/meteor'; import s from 'underscore.string'; import { RocketChat } from 'meteor/rocketchat:lib'; +import Autolinker from 'autolinker'; -// -// AutoLinker is a named function that will replace links on messages -// @param {Object} message - The message object -// +const createAutolinker = () => { + const regUrls = new RegExp(RocketChat.settings.get('AutoLinker_UrlsRegExp')); -import Autolinker from 'autolinker'; + const replaceAutolinkerMatch = (match) => { + if (match.getType() !== 'url') { + return null; + } -function AutoLinker(message) { - if (RocketChat.settings.get('AutoLinker') !== true) { - return message; - } + if (!regUrls.test(match.matchedText)) { + return null; + } - if (s.trim(message.html)) { - const regUrls = new RegExp(RocketChat.settings.get('AutoLinker_UrlsRegExp')); + if (match.matchedText.indexOf(Meteor.absoluteUrl()) === 0) { + const tag = match.buildTag(); + tag.setAttr('target', ''); + return tag; + } - const autolinker = new Autolinker({ - stripPrefix: RocketChat.settings.get('AutoLinker_StripPrefix'), - urls: { - schemeMatches: RocketChat.settings.get('AutoLinker_Urls_Scheme'), - wwwMatches: RocketChat.settings.get('AutoLinker_Urls_www'), - tldMatches: RocketChat.settings.get('AutoLinker_Urls_TLD'), - }, - email: RocketChat.settings.get('AutoLinker_Email'), - phone: RocketChat.settings.get('AutoLinker_Phone'), - twitter: false, - stripTrailingSlash: false, - replaceFn(match) { - if (match.getType() === 'url') { - if (regUrls.test(match.matchedText)) { - if (match.matchedText.indexOf(Meteor.absoluteUrl()) === 0) { - // returns an `Autolinker.HtmlTag` instance for an tag - const tag = match.buildTag(); - // sets target to empty, instead of _blank - tag.setAttr('target', ''); - return tag; - } + return true; + }; - return true; - } - } + return new Autolinker({ + stripPrefix: RocketChat.settings.get('AutoLinker_StripPrefix'), + urls: { + schemeMatches: RocketChat.settings.get('AutoLinker_Urls_Scheme'), + wwwMatches: RocketChat.settings.get('AutoLinker_Urls_www'), + tldMatches: RocketChat.settings.get('AutoLinker_Urls_TLD'), + }, + email: RocketChat.settings.get('AutoLinker_Email'), + phone: RocketChat.settings.get('AutoLinker_Phone'), + twitter: false, + stripTrailingSlash: false, + replaceFn: replaceAutolinkerMatch, + }); +}; - return null; - }, - }); +const renderMessage = (message) => { + if (RocketChat.settings.get('AutoLinker') !== true) { + return message; + } - let regNonAutoLink = /(```\w*[\n ]?[\s\S]*?```+?)|(`(?:[^`]+)`)/; - if (RocketChat.settings.get('Katex_Enabled')) { - regNonAutoLink = /(```\w*[\n ]?[\s\S]*?```+?)|(`(?:[^`]+)`)|(\\\(\w*[\n ]?[\s\S]*?\\\)+?)/; - } + if (!s.trim(message.html)) { + return message; + } - // Separate text in code blocks and non code blocks - const msgParts = message.html.split(regNonAutoLink); + const regexTokens = new RegExp(`(${ (message.tokens || []).map(({ token }) => RegExp.escape(token)) })`, 'g'); - msgParts.forEach((part, index) => { - if (part && part.length > 0) { - // Verify if this part is code - const codeMatch = part.match(regNonAutoLink); - if (!codeMatch) { - msgParts[index] = autolinker.link(part); - } + const autolinker = createAutolinker(); + message.html = message.html.split(regexTokens) + .map((msgPart) => { + if (regexTokens.test(msgPart)) { + return msgPart; } - }); - // Re-mount message - message.html = msgParts.join(''); - } + return autolinker.link(msgPart); + }) + .join(''); return message; -} +}; -RocketChat.callbacks.add('renderMessage', AutoLinker, RocketChat.callbacks.priority.LOW, 'autolinker'); +RocketChat.callbacks.add('renderMessage', renderMessage, RocketChat.callbacks.priority.LOW, 'autolinker');