diff --git a/web/src/typeahead_helper.js b/web/src/typeahead_helper.js
index 4a71004c6a..07788e71b9 100644
--- a/web/src/typeahead_helper.js
+++ b/web/src/typeahead_helper.js
@@ -29,16 +29,24 @@ export function build_highlight_regex(query) {
}
export function highlight_with_escaping_and_regex(regex, item) {
+ // if regex is empty return entire item highlighted and escaped
+ if (regex.source === "()") {
+ return "" + Handlebars.Utils.escapeExpression(item) + "";
+ }
+
// We need to assemble this manually (as opposed to doing 'join') because we need to
// (1) escape all the pieces and (2) the regex is case-insensitive, and we need
// to know the case of the content we're replacing (you can't just use a bolded
// version of 'query')
- const pieces = item.split(regex);
+ const pieces = item.split(regex).filter(Boolean);
let result = "";
- for (const piece of pieces) {
- if (regex.test(piece)) {
+ for (let i = 0; i < pieces.length; i += 1) {
+ const piece = pieces[i];
+ if (regex.test(piece) && (i === 0 || pieces[i - 1].endsWith(" "))) {
+ // only highlight if the matching part is a word prefix, ie
+ // if it is the 1st piece or if there was a space before it
result += "" + Handlebars.Utils.escapeExpression(piece) + "";
} else {
result += Handlebars.Utils.escapeExpression(piece);
diff --git a/web/tests/typeahead_helper.test.js b/web/tests/typeahead_helper.test.js
index b4e10e7a75..4726e303bd 100644
--- a/web/tests/typeahead_helper.test.js
+++ b/web/tests/typeahead_helper.test.js
@@ -671,6 +671,12 @@ test("highlight_with_escaping", () => {
expected = "development help";
result = highlight(query, item);
assert.equal(result, expected);
+
+ item = "Prefix notprefix prefix";
+ query = "pre";
+ expected = "Prefix notprefix prefix";
+ result = highlight(query, item);
+ assert.equal(result, expected);
});
test("render_person when emails hidden", ({mock_template}) => {