diff --git a/lib/features/search/search.js b/lib/features/search/search.js index 3b9964eb2..8def8ee5d 100644 --- a/lib/features/search/search.js +++ b/lib/features/search/search.js @@ -175,10 +175,16 @@ function scoreToken(token) { } return token.start - ? 1.37 - : token.wordStart - ? 1.13 - : 1; + ? ( + token.end + ? 131.9 + : 7.87 + ) + : ( + token.wordStart + ? 2.19 + : 1 + ); } /** @@ -217,7 +223,12 @@ function matchString(string, words) { const tokens = []; const matchedWords = {}; - const regexpString = words.map(escapeRegexp).flatMap(str => [ '(?\\b' + str + ')', str ]).join('|'); + const wordsEscaped = words.map(escapeRegexp); + + const regexpString = [ + `(?${wordsEscaped.join('\\s+')})`, + ...wordsEscaped + ].join('|'); const regexp = new RegExp(regexpString, 'ig'); @@ -228,6 +239,17 @@ function matchString(string, words) { const [ value ] = match; + const startIndex = match.index; + const endIndex = match.index + value.length; + + const start = startIndex === 0; + const end = endIndex === string.length; + + const all = !!match.groups.all; + + const wordStart = start || /\s/.test(string.charAt(startIndex - 1)); + const wordEnd = end || /\s/.test(string.charAt(endIndex + 1)); + if (match.index > lastIndex) { // add previous token (NO match) @@ -242,11 +264,18 @@ function matchString(string, words) { value, index: match.index, match: true, - wordStart: !!match.groups.wordStart, - start: match.index === 0 + wordStart, + wordEnd, + start, + end, + all }); - matchedWords[value.toLowerCase()] = true; + const newMatchedWords = all ? words : [ value ]; + + for (const word of newMatchedWords) { + matchedWords[word.toLowerCase()] = true; + } lastIndex = match.index + value.length; } diff --git a/test/spec/features/search/searchSpec.js b/test/spec/features/search/searchSpec.js index 166581455..ffa9f57c1 100644 --- a/test/spec/features/search/searchSpec.js +++ b/test/spec/features/search/searchSpec.js @@ -189,16 +189,13 @@ describe('features/search', function() { // given const items = [ { - title: 'bar baz foo', - description: 'bar' + title: 'foobar' }, { - title: 'foo', - description: 'bar' + title: 'bar baz ofoo foo -+ofoo woofoo foo' }, { - title: 'baz foo', - description: 'bar' + title: 'baz foo' } ]; @@ -212,8 +209,8 @@ describe('features/search', function() { // then expect(results).to.have.length(3); - expect(results[0].item).to.eql(items[1]); - expect(results[1].item).to.eql(items[0]); + expect(results[0].item).to.eql(items[0]); + expect(results[1].item).to.eql(items[1]); expect(results[2].item).to.eql(items[2]); })); @@ -223,13 +220,19 @@ describe('features/search', function() { // given const items = [ { - title: 'baz foo bar' + title: 'foo bar' + }, + { + title: 'foo baz and very long additional text\nalso foo bar' + }, + { + title: 'baz and very long foo bar bar bar\nalso foo bar' }, { title: 'foo bar baz' }, { - title: 'foo bar' + title: 'baz foo bar' } ]; @@ -241,10 +244,12 @@ describe('features/search', function() { }); // then - expect(results).to.have.length(3); - expect(results[0].item).to.eql(items[2]); + expect(results).to.have.length(5); + expect(results[0].item).to.eql(items[0]); expect(results[1].item).to.eql(items[1]); - expect(results[2].item).to.eql(items[0]); + expect(results[2].item).to.eql(items[2]); + expect(results[3].item).to.eql(items[3]); + expect(results[4].item).to.eql(items[4]); })); @@ -253,10 +258,13 @@ describe('features/search', function() { // given const items = [ { - title: 'yes barfoo' + title: 'yes foowoo' }, { - title: 'yes foowoo' + title: 'yesfoo woofoo' + }, + { + title: 'yes barfoo' } ]; @@ -268,9 +276,10 @@ describe('features/search', function() { }); // then - expect(results).to.have.length(2); - expect(results[0].item).to.eql(items[1]); - expect(results[1].item).to.eql(items[0]); + expect(results).to.have.length(3); + expect(results[0].item).to.eql(items[0]); + expect(results[1].item).to.eql(items[1]); + expect(results[2].item).to.eql(items[2]); })); @@ -398,14 +407,14 @@ describe('features/search', function() { // given const items = [ - { - title: 'Kafka amess', - description: 'Nope' - }, { title: 'mess', description: 'kafka' }, + { + title: 'Kafka amess', + description: 'Nope' + }, { title: 'mess' } @@ -460,7 +469,7 @@ describe('features/search', function() { // given const items = [ { - title: 'bar foo bar' + title: 'bar foo bar' } ];