From 1f3addcca5bad9ed12ed3e1df7ba75859c650249 Mon Sep 17 00:00:00 2001 From: Alex Shpak Date: Tue, 16 Jul 2019 14:34:02 +0200 Subject: Implement search, loading on demand --- assets/_utils.scss | 4 +++ assets/book.scss | 34 +++++++++++++---------- assets/search-data.js | 24 ++++++++++++++++ assets/search.js | 76 +++++++++++++++++++++++++++++---------------------- 4 files changed, 92 insertions(+), 46 deletions(-) create mode 100644 assets/search-data.js (limited to 'assets') diff --git a/assets/_utils.scss b/assets/_utils.scss index 76ff8ae..31bfaed 100644 --- a/assets/_utils.scss +++ b/assets/_utils.scss @@ -42,6 +42,10 @@ text-align: center; } +.hidden { + display: none; +} + @mixin fixed { position: fixed; top: 0; diff --git a/assets/book.scss b/assets/book.scss index 8a94551..d5f3f87 100644 --- a/assets/book.scss +++ b/assets/book.scss @@ -138,22 +138,28 @@ ul.pagination { } .book-search { - border: 0; - border-bottom: $padding-1 solid $gray-200; - outline: none; - // padding: $padding-4 $padding-8 $padding-4 $padding-16+$padding-4; - padding: $padding-4 $padding-8 $padding-4 0; - margin-bottom: $padding-4; - width: 100%; - - // background: url("svg/search.svg") left center no-repeat; - // background-size: $padding-16; - - &:focus { - border-bottom-color: $body-font-color; + #book-search-input { + border: 0; + border-bottom: $padding-1 solid $gray-200; + outline: none; + padding: $padding-4 $padding-8 $padding-4 $padding-16 + $padding-4; + + width: 85%; + + background: url("svg/search.svg") left center no-repeat; + background-size: $padding-16; + + &:focus { + border-bottom-color: $body-font-color; + } + } + + #book-search-results li:last-child { + margin-bottom: $padding-16 * 2; } } + .book-toc { flex: 0 0 $toc-width; font-size: $font-size-12; @@ -196,7 +202,7 @@ ul.pagination { .book-posts { min-width: $body-min-width; - max-width: $sm-breakpoint; + max-width: $body-min-width * 2; flex-grow: 1; padding: $padding-16; diff --git a/assets/search-data.js b/assets/search-data.js new file mode 100644 index 0000000..5b015e4 --- /dev/null +++ b/assets/search-data.js @@ -0,0 +1,24 @@ +(function() { + const pages = [ + {{ range $index, $page := .Site.Pages }} + {{- if and $index (gt $index 0) -}},{{- end }} + { + "idx": {{ $index }}, + "href": "{{ $page.RelPermalink }}", + "title": "{{ partial "docs/title" $page }}", + "content": {{ $page.Plain | jsonify }} + } + {{- end -}} + ]; + + window.bookSearch = { + pages: pages, + idx: lunr(function() { + this.ref('idx'); + this.field('title'); + this.field('content'); + + pages.forEach(this.add, this); + }), + } +})(); diff --git a/assets/search.js b/assets/search.js index 84e522a..63bb366 100644 --- a/assets/search.js +++ b/assets/search.js @@ -1,41 +1,53 @@ -addEventListener("load", function() { - let input = document.querySelector("#book-search"); - let results = document.querySelector("#book-search-results"); - - Promise.all([ - loadScript("{{ "lunr.min.js" | relURL }}"), - loadScript("{{ "index.json" | relURL }}") - ]).then(enableLunr); - - function enableLunr() { - results.idx = lunr(function() { - this.ref('href') - this.field('title') - this.field('content') - - window.lunrData.forEach(function (page) { - this.add(page) - }, this) +{{- $searchData := resources.Get "search-data.js" | resources.ExecuteAsTemplate "search-data.js" . | resources.Minify | resources.Fingerprint }} + +(function() { + const input = document.querySelector("#book-search-input"); + const results = document.querySelector("#book-search-results"); + const dummy = document.querySelector("#book-search-dummy"); + + input.addEventListener("focus", init); + + function init() { + loadScript("{{ $searchData.RelPermalink }}", function() { + input.disabled = false; + input.addEventListener("keyup", search); + search(); }); - input.addEventListener("keyup", search); + input.removeEventListener("focus", init); } function search() { + while (results.firstChild) { + results.removeChild(results.firstChild); + } + if (input.value) { - var hits = results.idx.search(`${input.value}*`); - results.innerHTML = JSON.stringify(hits); - } else { - results.innerHTML = ''; + const hits = window.bookSearch.idx.search(`${input.value}*`); + hits.slice(0, 10).forEach(function(hit) { + const page = window.bookSearch.pages[hit.ref]; + const li = dummy.querySelector("li").cloneNode(true), + a = li.querySelector("a"); + + a.href = page.href; + a.textContent = page.title; + + results.appendChild(li); + }); } } - function loadScript(src) { - return new Promise(function(resolve, reject) { - let script = document.createElement('script'); - script.src = src; - script.onload = () => resolve(script); - - document.head.append(script); - }); + function newLi(href, title) { + + + return li; + } + + function loadScript(src, callback) { + const script = document.createElement("script"); + script.defer = true; + script.src = src; + script.onload = callback; + + document.head.append(script); } -}); +})(); -- cgit v1.2.3