diff --git a/assets/js/offline-search.js b/assets/js/offline-search.js index 548a86a761..58c407f80c 100644 --- a/assets/js/offline-search.js +++ b/assets/js/offline-search.js @@ -1,200 +1,183 @@ // Adapted from code by Matt Walters https://www.mattwalters.net/posts/2018-03-28-hugo-and-lunr/ (function ($) { - 'use strict'; + 'use strict'; - $(document).ready(function () { - const $searchInput = $('.td-search input'); + $(document).ready(function () { + const $searchInput = $('.td-search input'); - // - // Register handler - // + // + // Register handler + // - $searchInput.on('change', (event) => { - render($(event.target)); + $searchInput.on('change', (event) => { + render($(event.target)); - // Hide keyboard on mobile browser - $searchInput.blur(); - }); + // Hide keyboard on mobile browser + $searchInput.blur(); + }); + + // Prevent reloading page by enter key on sidebar search. + $searchInput.closest('form').on('submit', () => { + return false; + }); - // Prevent reloading page by enter key on sidebar search. - $searchInput.closest('form').on('submit', () => { - return false; + // + // Lunr + // + + let idx = null; // Lunr index + const resultDetails = new Map(); // Will hold the data for the search results (titles and summaries) + + // Set up for an Ajax call to request the JSON data file that is created by Hugo's build process + $.ajax($searchInput.data('offline-search-index-json-src')).then((data) => { + idx = lunr(function () { + this.ref('ref'); + + // If you added more searchable fields to the search index, list them here. + // Here you can specify searchable fields to the search index - e.g. individual toxonomies for you project + // With "boost" you can add weighting for specific (default weighting without boost: 1) + this.field('title', { boost: 5 }); + this.field('categories', { boost: 3 }); + this.field('tags', { boost: 3 }); + // this.field('projects', { boost: 3 }); // example for an individual toxonomy called projects + this.field('description', { boost: 2 }); + this.field('body'); + + data.forEach((doc) => { + this.add(doc); + + resultDetails.set(doc.ref, { + title: doc.title, + excerpt: doc.excerpt, + }); }); + }); - // - // Lunr - // - - let idx = null; // Lunr index - const resultDetails = new Map(); // Will hold the data for the search results (titles and summaries) - - // Set up for an Ajax call to request the JSON data file that is created by Hugo's build process - $.ajax($searchInput.data('offline-search-index-json-src')).then( - (data) => { - idx = lunr(function () { - this.ref('ref'); - - // If you added more searchable fields to the search index, list them here. - // Here you can specify searchable fields to the search index - e.g. individual toxonomies for you project - // With "boost" you can add weighting for specific (default weighting without boost: 1) - this.field('title', { boost: 5 }); - this.field('categories', { boost: 3 }); - this.field('tags', { boost: 3 }); - // this.field('projects', { boost: 3 }); // example for an individual toxonomy called projects - this.field('description', { boost: 2 }); - this.field('body'); - - data.forEach((doc) => { - this.add(doc); - - resultDetails.set(doc.ref, { - title: doc.title, - excerpt: doc.excerpt, - }); - }); - }); - - $searchInput.trigger('change'); - } - ); + $searchInput.trigger('change'); + }); - const render = ($targetSearchInput) => { - // - // Dispose existing popover - // - - { - let popover = bootstrap.Popover.getInstance( - $targetSearchInput[0] - ); - if (popover !== null) { - popover.dispose(); - } - } - - // - // Search - // - - if (idx === null) { - return; - } - - const searchQuery = $targetSearchInput.val(); - if (searchQuery === '') { - return; - } - - const results = idx - .query((q) => { - const tokens = lunr.tokenizer(searchQuery.toLowerCase()); - tokens.forEach((token) => { - const queryString = token.toString(); - q.term(queryString, { - boost: 100, - }); - q.term(queryString, { - wildcard: - lunr.Query.wildcard.LEADING | - lunr.Query.wildcard.TRAILING, - boost: 10, - }); - q.term(queryString, { - editDistance: 2, - }); - }); - }) - .slice( - 0, - $targetSearchInput.data('offline-search-max-results') - ); - - // - // Make result html - // - - const $html = $('
'); - - $html.append( - $('
') - .css({ - display: 'flex', - justifyContent: 'space-between', - marginBottom: '1em', - }) - .append( - $('') - .text('Search results') - .css({ fontWeight: 'bold' }) - ) - .append( - $('').addClass( - 'td-offline-search-results__close-button' - ) - ) - ); - - const $searchResultBody = $('
').css({ - maxHeight: `calc(100vh - ${ - $targetSearchInput.offset().top - - $(window).scrollTop() + - 180 - }px)`, - overflowY: 'auto', + const render = ($targetSearchInput) => { + // + // Dispose existing popover + // + + { + let popover = bootstrap.Popover.getInstance($targetSearchInput[0]); + if (popover !== null) { + popover.dispose(); + } + } + + // + // Search + // + + if (idx === null) { + return; + } + + const searchQuery = $targetSearchInput.val(); + if (searchQuery === '') { + return; + } + + const results = idx + .query((q) => { + const tokens = lunr.tokenizer(searchQuery.toLowerCase()); + tokens.forEach((token) => { + const queryString = token.toString(); + q.term(queryString, { + boost: 100, }); - $html.append($searchResultBody); - - if (results.length === 0) { - $searchResultBody.append( - $('

').text(`No results found for query "${searchQuery}"`) - ); - } else { - results.forEach((r) => { - const doc = resultDetails.get(r.ref); - const href = - $searchInput.data('offline-search-base-href') + - r.ref.replace(/^\//, ''); - - const $entry = $('

').addClass('mt-4'); - - $entry.append( - $('').addClass('d-block text-muted').text(r.ref) - ); - - $entry.append( - $('') - .addClass('d-block') - .css({ - fontSize: '1.2rem', - }) - .attr('href', href) - .text(doc.title) - ); - - $entry.append($('

').text(doc.excerpt)); - - $searchResultBody.append($entry); - }); - } - - $targetSearchInput.one('shown.bs.popover', () => { - $('.td-offline-search-results__close-button').on( - 'click', - () => { - $targetSearchInput.val(''); - $targetSearchInput.trigger('change'); - } - ); + q.term(queryString, { + wildcard: + lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING, + boost: 10, }); - - const popover = new bootstrap.Popover($targetSearchInput, { - content: $html[0], - html: true, - customClass: 'td-offline-search-results', - placement: 'bottom', + q.term(queryString, { + editDistance: 2, }); - popover.show(); - }; - }); + }); + }) + .slice(0, $targetSearchInput.data('offline-search-max-results')); + + // + // Make result html + // + + const $html = $('

'); + + $html.append( + $('
') + .css({ + display: 'flex', + justifyContent: 'space-between', + marginBottom: '1em', + }) + .append( + $('').text('Search results').css({ fontWeight: 'bold' }) + ) + .append( + $('').addClass('td-offline-search-results__close-button') + ) + ); + + const $searchResultBody = $('
').css({ + maxHeight: `calc(100vh - ${ + $targetSearchInput.offset().top - $(window).scrollTop() + 180 + }px)`, + overflowY: 'auto', + }); + $html.append($searchResultBody); + + if (results.length === 0) { + $searchResultBody.append( + $('

').text(`No results found for query "${searchQuery}"`) + ); + } else { + results.forEach((r) => { + const doc = resultDetails.get(r.ref); + const href = + $searchInput.data('offline-search-base-href') + + r.ref.replace(/^\//, ''); + + const $entry = $('

').addClass('mt-4'); + + $entry.append( + $('').addClass('d-block text-muted').text(r.ref) + ); + + $entry.append( + $('') + .addClass('d-block') + .css({ + fontSize: '1.2rem', + }) + .attr('href', href) + .text(doc.title) + ); + + $entry.append($('

').text(doc.excerpt)); + + $searchResultBody.append($entry); + }); + } + + $targetSearchInput.one('shown.bs.popover', () => { + $('.td-offline-search-results__close-button').on('click', () => { + $targetSearchInput.val(''); + $targetSearchInput.trigger('change'); + }); + }); + + const popover = new bootstrap.Popover($targetSearchInput, { + content: $html[0], + html: true, + customClass: 'td-offline-search-results', + placement: 'bottom', + }); + popover.show(); + }; + }); })(jQuery); diff --git a/assets/js/search.js b/assets/js/search.js index 2ae687c791..f2767b4f12 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -14,30 +14,26 @@ See the License for the specific language governing permissions and limitations under the License. */ -(function($) { - - 'use strict'; - - var Search = { - init: function() { - $(document).ready(function() { - $(document).on('keypress', '.td-search input', function(e) { - if (e.keyCode !== 13) { - return - } - - var query = $(this).val(); - var searchPage = "{{ "search/" | absURL }}?q=" + query; - document.location = searchPage; - - return false; - }); - - }); - }, - }; - - Search.init(); - - -}(jQuery)); +(function ($) { + 'use strict'; + + var Search = { + init: function () { + $(document).ready(function () { + $(document).on('keypress', '.td-search input', function (e) { + if (e.keyCode !== 13) { + return; + } + + var query = $(this).val(); + var searchPage = '{{ "search/" | absURL }}?q=' + query; + document.location = searchPage; + + return false; + }); + }); + }, + }; + + Search.init(); +})(jQuery); diff --git a/assets/scss/_search.scss b/assets/scss/_search.scss index 6b91373838..9951056b75 100644 --- a/assets/scss/_search.scss +++ b/assets/scss/_search.scss @@ -3,7 +3,7 @@ .td-search { background: transparent; position: relative; - width: 90%; + width: 100%; // Search icon &__icon {