diff options
author | Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org> | 2021-09-24 12:26:18 +0300 |
---|---|---|
committer | Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org> | 2021-09-26 08:29:43 +0200 |
commit | 833a936a4416be31136729594329311cabb24f7f (patch) | |
tree | 8ca46d806d400a731c76958ba7808aac1fa7d744 /help3xsl/help.js | |
parent | 39f3c4dc011dd2cffbbd9b6eb9cea655e1e09772 (diff) |
Switch from Fuzzysort to FlexSearch
FlexSearch has the best performance of JS search libs at the moment.
It doesn't have fuzzy search yet, but maybe our users don't even
want the feature. RFE is https://github.com/nextapps-de/flexsearch/issues/118
flexsearch.debug.js is used because it is the only unminified version and
we can't use minified files in the source code as they are equivalent to
binary files (close source). There doesn't seem to be anything that would
make it a bad idea to use the debug version in production, only a couple
of edge case checks that print warnings to console.
This commit also makes automatic filtering work when the input field already
has a string upon page load (functions were called in the wrong order).
Change-Id: I5055f7f7f99cad92dfa3a544e5314eb85a1faced
Reviewed-on: https://gerrit.libreoffice.org/c/help/+/122566
Tested-by: Jenkins
Tested-by: Olivier Hallot <olivier.hallot@libreoffice.org>
Reviewed-by: Rafael Lima <rafael.palma.lima@gmail.com>
Reviewed-by: Olivier Hallot <olivier.hallot@libreoffice.org>
Diffstat (limited to 'help3xsl/help.js')
-rw-r--r-- | help3xsl/help.js | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/help3xsl/help.js b/help3xsl/help.js index 17d4909058..1f767a9c12 100644 --- a/help3xsl/help.js +++ b/help3xsl/help.js @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// Pagination and fuzzy search +// Pagination and bookmark search var url = window.location.pathname; var moduleRegex = new RegExp('text\\/(\\w+)\\/'); var regexArray = moduleRegex.exec(url); @@ -16,6 +16,19 @@ var indexEl = document.getElementsByClassName("index")[0]; var fullLinks = fullLinkify(indexEl, bookmarks, modules, currentModule()); var search = document.getElementById('search-bar'); search.addEventListener('keyup', debounce(filter, 100, indexEl)); +var flexIndex = new FlexSearch.Document({ document: { + // Only the text content gets indexed, the others get stored as-is + index: [{ + field: 'text', + tokenize: 'full' + }], + store: ['url','app','text'] + } +}); +// Populate FlexSearch index +loadSearch(); +// Render the unfiltered index list on page load +fillIndex(indexEl, fullLinks, modules); // Preserve search input value during the session search.value = sessionStorage.getItem('searchsave'); if (search.value !== undefined) { @@ -24,8 +37,6 @@ if (search.value !== undefined) { window.addEventListener('unload', function(event) { sessionStorage.setItem('searchsave', search.value); }); -// render the unfiltered index list on page load -fillIndex(indexEl, fullLinks, modules); function currentModule() { var module = ''; @@ -55,6 +66,11 @@ function fullLinkify(indexEl, bookmarks, modules, currentModule) { }); return fullLinkified; } +function loadSearch() { + bookmarks.forEach((el, i) => { + flexIndex.add(i, el); + }); +} function fillIndex(indexEl, content, modules) { indexEl.innerHTML = content; var indexKids = indexEl.children; @@ -72,23 +88,23 @@ function fillIndex(indexEl, content, modules) { } // filter the index list based on search field input function filter(indexList) { - var results = null; - var group = []; - var target = search.value.trim(); - var filtered = ''; + let group = []; + let target = search.value.trim(); + let filtered = ''; if (target.length < 1) { fillIndex(indexEl, fullLinks, modules); return; } - - results = fuzzysort.go(target, bookmarks, {threshold: -15000, key:'text'}); + // Regex for highlighting the match + let regex = new RegExp(target.split(/\s+/).filter((i) => i?.length).join("|"), 'gi'); + let results = flexIndex.search(target, { pluck: "text", enrich: true, limit: 1000 }); // tdf#123506 - Group the filtered list into module groups, keeping the ordering modules.forEach(function(module) { group[module] = ''; }); results.forEach(function(result) { - group[result.obj['app']] += '<a href="' + result.obj['url'] + '" class="' + result.obj['app'] + '">' + fuzzysort.highlight(result) + '</a>'; + group[result.doc.app] += '<a href="' + result.doc.url + '" class="' + result.doc.app + '">' + result.doc.text.replace(regex, (match) => `<strong>${match}</strong>`) + '</a>'; }); modules.forEach(function(module) { if (group[module].length > 0) { @@ -97,7 +113,6 @@ function filter(indexList) { }); fillIndex(indexList, filtered, modules); - }; // delay the rendering of the filtered results while user is typing function debounce(fn, wait, indexList) { |