diff options
author | Asaad Mahmood <Unknowngi@live.com> | 2015-10-27 20:15:33 +0500 |
---|---|---|
committer | Asaad Mahmood <Unknowngi@live.com> | 2015-10-27 20:15:33 +0500 |
commit | 179c4ea684af8d2a021cc6f0042bc4408f39b0bb (patch) | |
tree | 7789805249e5c962f1175f301beb74272dee30c0 /web/react/utils/text_formatting.jsx | |
parent | 68b02ffb9eeb7a414feae8ed89b4011ccecf96bc (diff) | |
parent | 50eb3d9fe46d6364b6f12201edfe0a401be3ccdd (diff) | |
download | chat-179c4ea684af8d2a021cc6f0042bc4408f39b0bb.tar.gz chat-179c4ea684af8d2a021cc6f0042bc4408f39b0bb.tar.bz2 chat-179c4ea684af8d2a021cc6f0042bc4408f39b0bb.zip |
Merge branch 'master' of https://github.com/mattermost/platform into ui-improvements
Diffstat (limited to 'web/react/utils/text_formatting.jsx')
-rw-r--r-- | web/react/utils/text_formatting.jsx | 74 |
1 files changed, 58 insertions, 16 deletions
diff --git a/web/react/utils/text_formatting.jsx b/web/react/utils/text_formatting.jsx index 5c2e68f1e..9f1a5a53f 100644 --- a/web/react/utils/text_formatting.jsx +++ b/web/react/utils/text_formatting.jsx @@ -47,8 +47,8 @@ export function doFormatText(text, options) { const tokens = new Map(); // replace important words and phrases with tokens - output = autolinkUrls(output, tokens); output = autolinkAtMentions(output, tokens); + output = autolinkUrls(output, tokens); output = autolinkHashtags(output, tokens); if (!('emoticons' in options) || options.emoticon) { @@ -78,6 +78,13 @@ export function doFormatEmoticons(text) { return output; } +export function doFormatMentions(text) { + const tokens = new Map(); + let output = autolinkAtMentions(text, tokens); + output = replaceTokens(output, tokens); + return output; +} + export function sanitizeHtml(text) { let output = text; @@ -91,6 +98,7 @@ export function sanitizeHtml(text) { return output; } +// Convert URLs into tokens function autolinkUrls(text, tokens) { function replaceUrlWithToken(autolinker, match) { const linkText = match.getMatchedText(); @@ -132,26 +140,61 @@ function autolinkUrls(text, tokens) { } function autolinkAtMentions(text, tokens) { - let output = text; + // Return true if provided character is punctuation + function isPunctuation(character) { + const re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g; + return re.test(character); + } + + // Test if provided text needs to be highlighted, special mention or current user + function mentionExists(u) { + return (Constants.SPECIAL_MENTIONS.indexOf(u) !== -1 || UserStore.getProfileByUsername(u)); + } + + function addToken(username, mention, extraText) { + const index = tokens.size; + const alias = `MM_ATMENTION${index}`; + + tokens.set(alias, { + value: `<a class='mention-link' href='#' data-mention='${username}'>${mention}</a>`, + originalText: mention, + extraText + }); + return alias; + } function replaceAtMentionWithToken(fullMatch, prefix, mention, username) { - const usernameLower = username.toLowerCase(); - if (Constants.SPECIAL_MENTIONS.indexOf(usernameLower) !== -1 || UserStore.getProfileByUsername(usernameLower)) { - const index = tokens.size; - const alias = `MM_ATMENTION${index}`; - - tokens.set(alias, { - value: `<a class='mention-link' href='#' data-mention='${usernameLower}'>${mention}</a>`, - originalText: mention - }); + let usernameLower = username.toLowerCase(); + if (mentionExists(usernameLower)) { + // Exact match + const alias = addToken(usernameLower, mention, ''); return prefix + alias; } + // Not an exact match, attempt to truncate any punctuation to see if we can find a user + const originalUsername = usernameLower; + + for (let c = usernameLower.length; c > 0; c--) { + if (isPunctuation(usernameLower[c - 1])) { + usernameLower = usernameLower.substring(0, c - 1); + + if (mentionExists(usernameLower)) { + const extraText = originalUsername.substr(c - 1); + const alias = addToken(usernameLower, '@' + usernameLower, extraText); + return prefix + alias; + } + } else { + // If the last character is not punctuation, no point in going any further + break; + } + } + return fullMatch; } - output = output.replace(/(^|\s)(@([a-z0-9.\-_]*[a-z0-9]))/gi, replaceAtMentionWithToken); + let output = text; + output = output.replace(/(^|\s)(@([a-z0-9.\-_]*))/gi, replaceAtMentionWithToken); return output; } @@ -169,10 +212,9 @@ function highlightCurrentMentions(text, tokens) { const newAlias = `MM_SELFMENTION${index}`; newTokens.set(newAlias, { - value: `<span class='mention-highlight'>${alias}</span>`, + value: `<span class='mention-highlight'>${alias}</span>` + token.extraText, originalText: token.originalText }); - output = output.replace(alias, newAlias); } } @@ -246,7 +288,7 @@ function highlightSearchTerm(text, tokens, searchTerm) { var newTokens = new Map(); for (const [alias, token] of tokens) { - if (token.originalText === searchTerm) { + if (token.originalText.indexOf(searchTerm.replace(/\*$/, '')) > -1) { const index = tokens.size + newTokens.size; const newAlias = `MM_SEARCHTERM${index}`; @@ -276,7 +318,7 @@ function highlightSearchTerm(text, tokens, searchTerm) { return prefix + alias; } - return output.replace(new RegExp(`(^|\\W)(${searchTerm})\\b`, 'gi'), replaceSearchTermWithToken); + return output.replace(new RegExp(`()(${searchTerm})`, 'gi'), replaceSearchTermWithToken); } function replaceTokens(text, tokens) { |