PageSourceSearch

https://submariner.io/js/search.js?1785606295

js submariner.io collected 2026-10-02 10:05:18 UTC 4,177 bytes, 104 lines download raw bytes

1var lunrIndex, pagesIndex;
2
3// Initialize lunrjs using our generated index file
4function initLunr() {
5    // First retrieve the index file
6    $.getJSON(index_url)
7        .done(function(index) {
8            pagesIndex = index;
9            // Set up lunrjs by declaring the fields we use
10            // Also provide their boost level for the ranking
11            lunrIndex = lunr(function() {
12                this.ref('index');
13                this.field('title', {
14                    boost: 15
15                });
16                this.field('tags', {
17                    boost: 10
18                });
19                this.field('content', {
20                    boost: 5
21                });
22
23                this.pipeline.remove(lunr.stemmer);
24                this.searchPipeline.remove(lunr.stemmer);
25
26                // Feed lunr with each file and let lunr actually index them
27                pagesIndex.forEach(function(page, idx) {
28                    page.index = idx;
29                    this.add(page);
30                }, this);
31            })
32        })
33        .fail(function(jqxhr, textStatus, error) {
34            var err = textStatus + ', ' + error;
35            console.error('Error getting Hugo index file:', err);
36        });
37}
38
39/**
40 * Trigger a search in lunr and transform the result
41 *
42 * @param  {String} term
43 * @return {Array}  results
44 */
45function search(term) {
46    // Find the item in our index corresponding to the lunr one to have more info
47    // Remove Lunr special search characters: https://lunrjs.com/guides/searching.html
48    var searchTerm = lunr.tokenizer(term.replace(/[*:^~+-]/, ' ')).reduce( function(a,token){return a.concat(searchPatterns(token.str))}, []).join(' ');
49    return !searchTerm ? [] : lunrIndex.search(searchTerm).map(function(result) {
50        return { index: result.ref, matches: Object.keys(result.matchData.metadata) }
51    });
52}
53
54function searchPatterns(word) {
55    return [
56        word + '^100',
57        word + '*^10',
58        '*' + word + '^10',
59        word + '~' + Math.floor(word.length / 4) + '^1' // allow 1 in 4 letters to have a typo
60    ];
61}
62
63// Let's get started
64initLunr();
65$(function() {
66    var searchList = new autoComplete({
67        /* selector for the search box element */
68        selector: $('#search-by').get(0),
69        /* source is the callback to perform the search */
70        source: function(term, response) {
71            response(search(term));
72        },
73        /* renderItem displays individual search results */
74        renderItem: function(item, term) {
75            var page = pagesIndex[item.index];
76            var numContextWords = 2;
77            var contextPattern = '(?:\\S+ +){0,' + numContextWords + '}\\S*\\b(?:' +
78                item.matches.map( function(match){return match.replace(/\W/g, '\\$&')} ).join('|') +
79                ')\\b\\S*(?: +\\S+){0,' + numContextWords + '}';
80            var context = page.content.match(new RegExp(contextPattern, 'i'));
81            var divcontext = document.createElement('div');
82            divcontext.className = 'context';
83            divcontext.innerText = (context || '');
84            var divsuggestion = document.createElement('div');
85            divsuggestion.className = 'autocomplete-suggestion';
86            divsuggestion.setAttribute('data-term', term);
87            divsuggestion.setAttribute('data-title', page.title);
88            divsuggestion.setAttribute('data-uri', baseUri + page.uri);
89            divsuggestion.setAttribute('data-context', context);
90            divsuggestion.innerText = '» ' + page.title;
91            divsuggestion.appendChild(divcontext);
92            return divsuggestion.outerHTML;
93        },
94        /* onSelect callback fires when a search suggestion is chosen */
95        onSelect: function(e, term, item) {
96            location.href = item.getAttribute('data-uri');
97        }
98    });
99
100    // JavaScript-autoComplete only registers the focus event when minChars is 0 which doesn't make sense, let's do it ourselves
101    // https://github.com/Pixabay/JavaScript-autoComplete/blob/master/auto-complete.js#L191
102    var selector = $('#search-by').get(0);
103    $(selector).focus(selector.focusHandler);
104});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.