summaryrefslogtreecommitdiff
path: root/help3xsl/help.js
diff options
context:
space:
mode:
authorIlmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>2021-09-24 12:26:18 +0300
committerIlmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>2021-09-26 08:29:43 +0200
commit833a936a4416be31136729594329311cabb24f7f (patch)
tree8ca46d806d400a731c76958ba7808aac1fa7d744 /help3xsl/help.js
parent39f3c4dc011dd2cffbbd9b6eb9cea655e1e09772 (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.js37
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) {