aboutsummaryrefslogtreecommitdiff
path: root/static/search.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/search.js')
-rw-r--r--static/search.js370
1 files changed, 188 insertions, 182 deletions
diff --git a/static/search.js b/static/search.js
index 544ca07..da46986 100644
--- a/static/search.js
+++ b/static/search.js
@@ -3,6 +3,7 @@ function closeSearchNow() {
const main = document.querySelector("main");
main.innerHTML = window.main
}
+
function goSearchNow() {
const main = document.querySelector("main");
if (!window.main) {
@@ -27,13 +28,6 @@ function goSearchNow() {
document.body.contains(document.closeSearch) && (document.closeSearch.onsubmit = function() { closeSearchNow() })
return false
}
-window.onload = function() {
- document.body.contains(document.goSearch) && (document.goSearch.onsubmit = function() { return goSearchNow() })
-};
-
-// Everything Below this line For Suggestsions as you type in search box
-var suggestions = document.getElementById("suggestions");
-var searchinput = document.getElementById("searchinput");
/* Close search suggestion popup list */
function closeAllLists(elmnt) {
@@ -82,9 +76,6 @@ function inputFocus(e) {
}
-document.addEventListener("keydown", inputFocus);
-document.addEventListener("click", function(event) {suggestions.contains(event.target) || suggestions.classList.add("d-none")});
-
// Get substring by bytes
// If using JavaScript inline substring method, it will return error codes
// Source: https://www.52pojie.cn/thread-1059814-1-1.html
@@ -156,208 +147,223 @@ function getByteByHex(hexCode) {
return getByteByBinary(parseInt(hexCode, 16).toString(2));
}
-/*
-Source:
- - https://github.com/nextapps-de/flexsearch#index-documents-field-search
- - https://raw.githack.com/nextapps-de/flexsearch/master/demo/autocomplete.html
- - http://elasticlunr.com/
- - https://github.com/getzola/zola/blob/master/docs/static/search.js
- - https://github.com/aaranxu/adidoks/blob/main/static/js/search.js
-*/
-(function(){
- var lang = document.documentElement.getAttribute("lang");
- var langOnly = lang.substring(0, 2);
- var baseUrl = document.querySelector("meta[name='base']").getAttribute("content");
- if (baseUrl.slice(-1) == "/") {
- baseUrl = baseUrl.slice(0, -1);
- }
+window.onload = function() {
+ if (document.body.contains(document.goSearch)) {
+ document.goSearch.onsubmit = function() { return goSearchNow() };
+ var suggestions = document.getElementById("suggestions");
+ var searchinput = document.getElementById("searchinput");
+ document.addEventListener("keydown", inputFocus);
+ document.addEventListener("click", function(event) {suggestions.contains(event.target) || suggestions.classList.add("d-none")});
- var index;
- searchinput.addEventListener('input', show_results, true);
- suggestions.addEventListener('click', accept_suggestion, true);
+ /*
+ Source:
+ - https://github.com/nextapps-de/flexsearch#index-documents-field-search
+ - https://raw.githack.com/nextapps-de/flexsearch/master/demo/autocomplete.html
+ - http://elasticlunr.com/
+ - https://github.com/getzola/zola/blob/master/docs/static/search.js
+ - https://github.com/aaranxu/adidoks/blob/main/static/js/search.js
+ */
+ (function(){
+ var lang = document.documentElement.getAttribute("lang");
+ var langOnly = lang.substring(0, 2);
+ var baseUrl = document.querySelector("meta[name='base']").getAttribute("content");
+ if (baseUrl.slice(-1) == "/") {
+ baseUrl = baseUrl.slice(0, -1);
+ }
- async function show_results(){
- var initIndex = async function () {
- if (index === undefined) {
- index = fetch(baseUrl + '/search_index.' + langOnly + '.json')
- .then(
- async function(response) {
- return await elasticlunr.Index.load(await response.json());
+ var index;
+ searchinput.addEventListener('input', show_results, true);
+ suggestions.addEventListener('click', accept_suggestion, true);
+
+ async function show_results(){
+ var initIndex = async function () {
+ if (index === undefined) {
+ index = fetch(baseUrl + '/search_index.' + langOnly + '.json')
+ .then(
+ async function(response) {
+ return await elasticlunr.Index.load(await response.json());
+ }
+ );
+ }
+ let res = await index;
+ return res;
}
- );
- }
- let res = await index;
- return res;
- }
- var value = this.value.trim();
- var options = {
- bool: "OR",
- fields: {
- title: {boost: 2},
- body: {boost: 1},
- }
- };
- //var results = index.search(value, options);
- var results = (await initIndex()).search(value, options);
+ var value = this.value.trim();
+ var options = {
+ bool: "OR",
+ fields: {
+ title: {boost: 2},
+ body: {boost: 1},
+ }
+ };
+ //var results = index.search(value, options);
+ var results = (await initIndex()).search(value, options);
- var entry, childs = suggestions.childNodes;
- var i = 0, len = results.length;
- var items = value.split(/\s+/);
- suggestions.classList.remove('d-none');
+ var entry, childs = suggestions.childNodes;
+ var i = 0, len = results.length;
+ var items = value.split(/\s+/);
+ suggestions.classList.remove('d-none');
- results.forEach(function(page) {
- if (page.doc.body !== '') {
- entry = document.createElement('div');
+ results.forEach(function(page) {
+ if (page.doc.body !== '') {
+ entry = document.createElement('div');
- entry.innerHTML = '<a href><span></span><span></span></a>';
+ entry.innerHTML = '<a href><span></span><span></span></a>';
- a = entry.querySelector('a'),
- t = entry.querySelector('span:first-child'),
- d = entry.querySelector('span:nth-child(2)');
- a.href = page.ref;
- t.textContent = page.doc.title;
- d.innerHTML = makeTeaser(page.doc.body, items);
+ a = entry.querySelector('a'),
+ t = entry.querySelector('span:first-child'),
+ d = entry.querySelector('span:nth-child(2)');
+ a.href = page.ref;
+ t.textContent = page.doc.title;
+ d.innerHTML = makeTeaser(page.doc.body, items);
- suggestions.appendChild(entry);
- }
- });
+ suggestions.appendChild(entry);
+ }
+ });
- while(childs.length > len){
- suggestions.removeChild(childs[i])
- }
+ while(childs.length > len){
+ suggestions.removeChild(childs[i])
+ }
- }
+ }
- function accept_suggestion(){
+ function accept_suggestion(){
- while(suggestions.lastChild){
+ while(suggestions.lastChild){
- suggestions.removeChild(suggestions.lastChild);
- }
+ suggestions.removeChild(suggestions.lastChild);
+ }
- return false;
- }
+ return false;
+ }
- // Taken from mdbook
- // The strategy is as follows:
- // First, assign a value to each word in the document:
- // Words that correspond to search terms (stemmer aware): 40
- // Normal words: 2
- // First word in a sentence: 8
- // Then use a sliding window with a constant number of words and count the
- // sum of the values of the words within the window. Then use the window that got the
- // maximum sum. If there are multiple maximas, then get the last one.
- // Enclose the terms in <b>.
- function makeTeaser(body, terms) {
- var TERM_WEIGHT = 40;
- var NORMAL_WORD_WEIGHT = 2;
- var FIRST_WORD_WEIGHT = 8;
- var TEASER_MAX_WORDS = 30;
+ /* Taken from mdbook
+ // The strategy is as follows:
+ // First, assign a value to each word in the document:
+ // Words that correspond to search terms (stemmer aware): 40
+ // Normal words: 2
+ // First word in a sentence: 8
+ // Then use a sliding window with a constant number of words and count the
+ // sum of the values of the words within the window. Then use the window that got the
+ // maximum sum. If there are multiple maximas, then get the last one.
+ // Enclose the terms in <b>.
+ */
+ function makeTeaser(body, terms) {
+ var TERM_WEIGHT = 40;
+ var NORMAL_WORD_WEIGHT = 2;
+ var FIRST_WORD_WEIGHT = 8;
+ var TEASER_MAX_WORDS = 30;
- var stemmedTerms = terms.map(function (w) {
- return elasticlunr.stemmer(w.toLowerCase());
- });
- var termFound = false;
- var index = 0;
- var weighted = []; // contains elements of ["word", weight, index_in_document]
+ var stemmedTerms = terms.map(function (w) {
+ return elasticlunr.stemmer(w.toLowerCase());
+ });
+ var termFound = false;
+ var index = 0;
+ var weighted = []; // contains elements of ["word", weight, index_in_document]
- // split in sentences, then words
- var sentences = body.toLowerCase().split(". ");
- for (var i in sentences) {
- var words = sentences[i].split(/[\s\n]/);
- var value = FIRST_WORD_WEIGHT;
- for (var j in words) {
+ // split in sentences, then words
+ var sentences = body.toLowerCase().split(". ");
+ for (var i in sentences) {
+ var words = sentences[i].split(/[\s\n]/);
+ var value = FIRST_WORD_WEIGHT;
+ for (var j in words) {
- var word = words[j];
+ var word = words[j];
- if (word.length > 0) {
- for (var k in stemmedTerms) {
- if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) {
- value = TERM_WEIGHT;
- termFound = true;
+ if (word.length > 0) {
+ for (var k in stemmedTerms) {
+ if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) {
+ value = TERM_WEIGHT;
+ termFound = true;
+ }
+ }
+ weighted.push([word, value, index]);
+ value = NORMAL_WORD_WEIGHT;
+ }
+
+ index += word.length;
+ index += 1; // ' ' or '.' if last word in sentence
}
+
+ index += 1; // because we split at a two-char boundary '. '
}
- weighted.push([word, value, index]);
- value = NORMAL_WORD_WEIGHT;
- }
- index += word.length;
- index += 1; // ' ' or '.' if last word in sentence
- }
+ if (weighted.length === 0) {
+ if (body.length !== undefined && body.length > TEASER_MAX_WORDS * 10) {
+ return body.substring(0, TEASER_MAX_WORDS * 10) + '...';
+ } else {
+ return body;
+ }
+ }
- index += 1; // because we split at a two-char boundary '. '
- }
+ var windowWeights = [];
+ var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS);
+ // We add a window with all the weights first
+ var curSum = 0;
+ for (var i = 0; i < windowSize; i++) {
+ curSum += weighted[i][1];
+ }
+ windowWeights.push(curSum);
- if (weighted.length === 0) {
- if (body.length !== undefined && body.length > TEASER_MAX_WORDS * 10) {
- return body.substring(0, TEASER_MAX_WORDS * 10) + '...';
- } else {
- return body;
- }
- }
+ for (var i = 0; i < weighted.length - windowSize; i++) {
+ curSum -= weighted[i][1];
+ curSum += weighted[i + windowSize][1];
+ windowWeights.push(curSum);
+ }
- var windowWeights = [];
- var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS);
- // We add a window with all the weights first
- var curSum = 0;
- for (var i = 0; i < windowSize; i++) {
- curSum += weighted[i][1];
- }
- windowWeights.push(curSum);
+ // If we didn't find the term, just pick the first window
+ var maxSumIndex = 0;
+ if (termFound) {
+ var maxFound = 0;
+ // backwards
+ for (var i = windowWeights.length - 1; i >= 0; i--) {
+ if (windowWeights[i] > maxFound) {
+ maxFound = windowWeights[i];
+ maxSumIndex = i;
+ }
+ }
+ }
- for (var i = 0; i < weighted.length - windowSize; i++) {
- curSum -= weighted[i][1];
- curSum += weighted[i + windowSize][1];
- windowWeights.push(curSum);
- }
+ var teaser = [];
+ var startIndex = weighted[maxSumIndex][2];
+ for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) {
+ var word = weighted[i];
+ if (startIndex < word[2]) {
+ // missing text from index to start of `word`
+ teaser.push(body.substring(startIndex, word[2]));
+ startIndex = word[2];
+ }
- // If we didn't find the term, just pick the first window
- var maxSumIndex = 0;
- if (termFound) {
- var maxFound = 0;
- // backwards
- for (var i = windowWeights.length - 1; i >= 0; i--) {
- if (windowWeights[i] > maxFound) {
- maxFound = windowWeights[i];
- maxSumIndex = i;
+ // add <em/> around search terms
+ if (word[1] === TERM_WEIGHT) {
+ teaser.push("<b>");
+ }
+
+ startIndex = word[2] + word[0].length;
+ // Check the string is ascii characters or not
+ var re = /^[\x00-\xff]+$/
+ if (word[1] !== TERM_WEIGHT && word[0].length >= 12 && !re.test(word[0])) {
+ // If the string's length is too long, it maybe a Chinese/Japance/Korean article
+ // if using substring method directly, it may occur error codes on emoji chars
+ var strBefor = body.substring(word[2], startIndex);
+ var strAfter = substringByByte(strBefor, 12);
+ teaser.push(strAfter);
+ } else {
+ teaser.push(body.substring(word[2], startIndex));
+ }
+
+ if (word[1] === TERM_WEIGHT) {
+ teaser.push("</b>");
+ }
+ }
+ teaser.push("…");
+ return teaser.join("");
}
- }
+ document.goSearch.onsubmit = function() { return goSearchNow() };
+ }());
}
+};
- var teaser = [];
- var startIndex = weighted[maxSumIndex][2];
- for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) {
- var word = weighted[i];
- if (startIndex < word[2]) {
- // missing text from index to start of `word`
- teaser.push(body.substring(startIndex, word[2]));
- startIndex = word[2];
- }
- // add <em/> around search terms
- if (word[1] === TERM_WEIGHT) {
- teaser.push("<b>");
- }
- startIndex = word[2] + word[0].length;
- // Check the string is ascii characters or not
- var re = /^[\x00-\xff]+$/
- if (word[1] !== TERM_WEIGHT && word[0].length >= 12 && !re.test(word[0])) {
- // If the string's length is too long, it maybe a Chinese/Japance/Korean article
- // if using substring method directly, it may occur error codes on emoji chars
- var strBefor = body.substring(word[2], startIndex);
- var strAfter = substringByByte(strBefor, 12);
- teaser.push(strAfter);
- } else {
- teaser.push(body.substring(word[2], startIndex));
- }
- if (word[1] === TERM_WEIGHT) {
- teaser.push("</b>");
- }
- }
- teaser.push("…");
- return teaser.join("");
- }
-document.body.contains(document.goSearch) && (document.goSearch.onsubmit = function() { return goSearchNow() })
-}());