diff --git a/assets/search.js b/assets/search.js index e98674df..18acb2f7 100644 --- a/assets/search.js +++ b/assets/search.js @@ -2,27 +2,9 @@ {{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }} {{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify | resources.Fingerprint }} -{{ $searchConfig := i18n "bookSearchConfig" | default "{}" }} (function () { const searchDataURL = '{{ $searchData.RelPermalink }}'; - const indexConfig = Object.assign({{ $searchConfig }}, { - includeScore: true, - useExtendedSearch: true, - fieldNormWeight: 1.5, - threshold: 0.2, - ignoreLocation: true, - keys: [ - { - name: 'title', - weight: 0.7 - }, - { - name: 'content', - weight: 0.3 - } - ] - }); const input = document.querySelector('#book-search-input'); const results = document.querySelector('#book-search-results'); @@ -31,6 +13,8 @@ return } + const worker = new Worker('/searchWorker.js'); + input.addEventListener('focus', init); input.addEventListener('input', search); @@ -72,9 +56,7 @@ fetch(searchDataURL) .then(pages => pages.json()) - .then(pages => { - window.bookSearchIndex = new Fuse(pages, indexConfig); - }) + .then(pages => worker.postMessage(pages)) .then(() => input.required = false) .then(search); } @@ -86,25 +68,28 @@ } function runSearch() { - while (results.firstChild) { - results.removeChild(results.firstChild); - } - if (!input.value) { return; } - const searchHits = window.bookSearchIndex.search(input.value).slice(0,10); - searchHits.forEach(function (page) { - const li = element('
  • '); - const a = li.querySelector('a'), small = li.querySelector('small'); + worker.onmessage = (ev) => { + while (results.firstChild) { + results.removeChild(results.firstChild); + } + + const searchHits = ev.data; + searchHits.forEach(function (page) { + const li = element('
  • '); + const a = li.querySelector('a'), small = li.querySelector('small'); - a.href = page.item.href; - a.textContent = page.item.title; - small.textContent = page.item.section; + a.href = page.item.href; + a.textContent = page.item.title; + small.textContent = page.item.section; - results.appendChild(li); - }); + results.appendChild(li); + }); + }; + worker.postMessage(input.value); } /** diff --git a/assets/searchWorker.js b/assets/searchWorker.js new file mode 100644 index 00000000..0cefd848 --- /dev/null +++ b/assets/searchWorker.js @@ -0,0 +1,32 @@ +importScripts("fuse.min.js") + +{{ $searchConfig := i18n "bookSearchConfig" | default "{}" }} +const indexConfig = Object.assign({{ $searchConfig }}, { + includeScore: true, + useExtendedSearch: true, + fieldNormWeight: 1.5, + threshold: 0.2, + ignoreLocation: true, + keys: [ + { + name: 'title', + weight: 0.7 + }, + { + name: 'content', + weight: 0.3 + } + ] +}); + +let index; +self.onmessage = (ev) => { + if (!index) { + let pages = ev.data; + index = new Fuse(pages, indexConfig); + return; + } + + const searchHits = index.search(ev.data).slice(0,10); + self.postMessage(searchHits); +}; diff --git a/layouts/partials/docs/inject/head.html b/layouts/partials/docs/inject/head.html new file mode 100644 index 00000000..096554d2 --- /dev/null +++ b/layouts/partials/docs/inject/head.html @@ -0,0 +1,4 @@ +{{- if default true .Site.Params.BookSearch -}} + {{- $searchWorkerJS := resources.Get "searchWorker.js" | resources.ExecuteAsTemplate "searchWorker.js" . }} + +{{ end -}}