diff --git a/CliClient/tests/StringUtils.js b/CliClient/tests/StringUtils.js
new file mode 100644
index 0000000000..5e1b4b3b5d
--- /dev/null
+++ b/CliClient/tests/StringUtils.js
@@ -0,0 +1,44 @@
+require('app-module-path').addPath(__dirname);
+
+const { time } = require('lib/time-utils.js');
+const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
+const StringUtils = require('lib/string-utils');
+
+process.on('unhandledRejection', (reason, p) => {
+ console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
+});
+
+describe('StringUtils', function() {
+
+ beforeEach(async (done) => {
+ done();
+ });
+
+ it('should surround keywords with strings', async (done) => {
+ const testCases = [
+ [['test'], 'test', 'a', 'b', 'atestb'],
+ [['test'], 'Test', 'a', 'b', 'aTestb'],
+ [['te[]st'], 'Te[]st', 'a', 'b', 'aTe[]stb'],
+ [['test1', 'test2'], 'bla test1 blabla test1 bla test2 not this one - test22', 'a', 'b', 'bla atest1b blabla atest1b bla atest2b not this one - test22'],
+ [['test1', 'test2'], 'bla test1 test1 bla test2', '', '', 'bla test1 test1 bla test2'],
+ [[{ type:'regex', value:'test.*?'}], 'bla test1 test1 bla test2 test tttest', 'a', 'b', 'bla atest1b atest1b bla atest2b atestb tttest'],
+ ];
+
+ for (let i = 0; i < testCases.length; i++) {
+ const t = testCases[i];
+
+ const keywords = t[0];
+ const input = t[1];
+ const prefix = t[2];
+ const suffix = t[3];
+ const expected = t[4];
+
+ const actual = StringUtils.surroundKeywords(keywords, input, prefix, suffix);
+
+ expect(actual).toBe(expected);
+ }
+
+ done();
+ });
+
+});
\ No newline at end of file
diff --git a/ReactNativeClient/lib/MdToHtml.js b/ReactNativeClient/lib/MdToHtml.js
index 6125fefa93..11774ce886 100644
--- a/ReactNativeClient/lib/MdToHtml.js
+++ b/ReactNativeClient/lib/MdToHtml.js
@@ -7,7 +7,7 @@ const { shim } = require('lib/shim.js');
const { _ } = require('lib/locale');
const md5 = require('md5');
const MdToHtml_Katex = require('lib/MdToHtml_Katex');
-const { pregQuote } = require('lib/string-utils.js');
+const StringUtils = require('lib/string-utils.js');
class MdToHtml {
@@ -415,22 +415,7 @@ class MdToHtml {
}
applyHighlightedKeywords_(body, keywords) {
- for (let i = 0; i < keywords.length; i++) {
- const k = keywords[i];
-
- let regexString = '';
-
- if (k.type === 'regex') {
- regexString = k.value;
- } else {
- regexString = pregQuote(k);
- }
-
- const re = new RegExp('(^|\n|\b)(' + regexString + ')(\n|\b|$)', 'gi');
- body = body.replace(re, '$1$2$3');
- }
-
- return body;
+ return StringUtils.surroundKeywords(keywords, body, '', '');
}
render(body, style, options = null) {
diff --git a/ReactNativeClient/lib/services/SearchEngine.js b/ReactNativeClient/lib/services/SearchEngine.js
index ce56e02453..a32d9313f2 100644
--- a/ReactNativeClient/lib/services/SearchEngine.js
+++ b/ReactNativeClient/lib/services/SearchEngine.js
@@ -108,7 +108,8 @@ class SearchEngine {
let regexString = pregQuote(term);
if (regexString[regexString.length - 1] === '*') {
- regexString = regexString.substr(0, regexString.length - 2) + '[^' + pregQuote(' \t\n\r,.,+-*?!={}<>|:"\'()[]') + ']' + '*';
+ // regexString = regexString.substr(0, regexString.length - 2) + '[^' + pregQuote(' \t\n\r,.,+-*?!={}<>|:"\'()[]') + ']' + '*';
+ regexString = regexString.substr(0, regexString.length - 2) + '.*?';
}
return regexString;
diff --git a/ReactNativeClient/lib/string-utils.js b/ReactNativeClient/lib/string-utils.js
index 27b378e300..955e31ff77 100644
--- a/ReactNativeClient/lib/string-utils.js
+++ b/ReactNativeClient/lib/string-utils.js
@@ -224,8 +224,21 @@ function escapeHtml(s) {
.replace(/'/g, "'");
}
-function pregQuote(str, delimiter) {
+function pregQuote(str, delimiter = '') {
return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
}
-module.exports = { removeDiacritics, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase, escapeHtml, pregQuote };
\ No newline at end of file
+function surroundKeywords(keywords, text, prefix, suffix) {
+ let regexString = keywords.map((k) => {
+ if (k.type === 'regex') {
+ return k.value;
+ } else {
+ return pregQuote(k);
+ }
+ }).join('|');
+ regexString = '\\b(' + regexString + ')\\b'
+ const re = new RegExp(regexString, 'gi');
+ return text.replace(re, prefix + '$1' + suffix);
+}
+
+module.exports = { removeDiacritics, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase, escapeHtml, pregQuote, surroundKeywords };
\ No newline at end of file