Template
1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo synced 2024-11-29 05:06:11 +01:00

Modernize docs/assets/js/search.js (#10621)

- reformated file with eslint's --fix
- did some minor rule adjustments
- removed unneccesary console debug
- fixed a typo
This commit is contained in:
silverwind 2020-03-09 01:41:52 +01:00 committed by GitHub
parent 11f7fc5621
commit d6657644a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 137 additions and 137 deletions

View file

@ -36,6 +36,8 @@ rules:
max-len: [0] max-len: [0]
newline-per-chained-call: [0] newline-per-chained-call: [0]
no-alert: [0] no-alert: [0]
no-cond-assign: [2, except-parens]
no-console: [1, {allow: [info, warn, error]}]
no-continue: [0] no-continue: [0]
no-mixed-operators: [0] no-mixed-operators: [0]
no-multi-assign: [0] no-multi-assign: [0]

View file

@ -1,166 +1,164 @@
/* global Fuse, Mark */
function ready(fn) { function ready(fn) {
if (document.readyState != 'loading') { if (document.readyState !== 'loading') {
fn(); fn();
} else { } else {
document.addEventListener('DOMContentLoaded', fn); document.addEventListener('DOMContentLoaded', fn);
} }
} }
ready(doSearch); ready(doSearch);
const summaryInclude = 60; const summaryInclude = 60;
const fuseOptions = { const fuseOptions = {
shouldSort: true, shouldSort: true,
includeMatches: true, includeMatches: true,
matchAllTokens: true, matchAllTokens: true,
threshold: 0.0, // for parsing diacritics threshold: 0.0, // for parsing diacritics
tokenize: true, tokenize: true,
location: 0, location: 0,
distance: 100, distance: 100,
maxPatternLength: 32, maxPatternLength: 32,
minMatchCharLength: 1, minMatchCharLength: 1,
keys: [{ keys: [{
name: "title", name: 'title',
weight: 0.8 weight: 0.8
}, },
{ {
name: "contents", name: 'contents',
weight: 0.5 weight: 0.5
}, },
{ {
name: "tags", name: 'tags',
weight: 0.3 weight: 0.3
}, },
{ {
name: "categories", name: 'categories',
weight: 0.3 weight: 0.3
} }
] ]
}; };
function param(name) { function param(name) {
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' '); return decodeURIComponent((window.location.search.split(`${name}=`)[1] || '').split('&')[0]).replace(/\+/g, ' ');
} }
let searchQuery = param("s"); const searchQuery = param('s');
function doSearch() { function doSearch() {
if (searchQuery) { if (searchQuery) {
document.getElementById("search-query").value = searchQuery; document.getElementById('search-query').value = searchQuery;
executeSearch(searchQuery); executeSearch(searchQuery);
} else { } else {
const para = document.createElement("P"); const para = document.createElement('P');
para.innerText = "Please enter a word or phrase above"; para.innerText = 'Please enter a word or phrase above';
document.getElementById("search-results").appendChild(para); document.getElementById('search-results').appendChild(para);
} }
} }
function getJSON(url, fn) { function getJSON(url, fn) {
const request = new XMLHttpRequest(); const request = new XMLHttpRequest();
request.open('GET', url, true); request.open('GET', url, true);
request.onload = function () { request.onload = function () {
if (request.status >= 200 && request.status < 400) { if (request.status >= 200 && request.status < 400) {
const data = JSON.parse(request.responseText); const data = JSON.parse(request.responseText);
fn(data); fn(data);
} else { } else {
console.log("Target reached on " + url + " with error " + request.status); console.error(`Target reached on ${url} with error ${request.status}`);
} }
}; };
request.onerror = function () { request.onerror = function () {
console.log("Connection error " + request.status); console.error(`Connection error ${request.status}`);
}; };
request.send(); request.send();
} }
function executeSearch(searchQuery) { function executeSearch(searchQuery) {
getJSON("/" + document.LANG + "/index.json", function (data) { getJSON(`/${document.LANG}/index.json`, (data) => {
const pages = data; const pages = data;
const fuse = new Fuse(pages, fuseOptions); const fuse = new Fuse(pages, fuseOptions);
const result = fuse.search(searchQuery); const result = fuse.search(searchQuery);
console.log({ document.getElementById('search-results').innerHTML = '';
"matches": result if (result.length > 0) {
}); populateResults(result);
document.getElementById("search-results").innerHTML = ""; } else {
if (result.length > 0) { const para = document.createElement('P');
populateResults(result); para.innerText = 'No matches found';
} else { document.getElementById('search-results').appendChild(para);
const para = document.createElement("P"); }
para.innerText = "No matches found"; });
document.getElementById("search-results").appendChild(para);
}
});
} }
function populateResults(result) { function populateResults(result) {
result.forEach(function (value, key) { result.forEach((value, key) => {
const content = value.item.contents; const content = value.item.contents;
let snippet = ""; let snippet = '';
const snippetHighlights = []; const snippetHighlights = [];
if (fuseOptions.tokenize) { if (fuseOptions.tokenize) {
snippetHighlights.push(searchQuery); snippetHighlights.push(searchQuery);
value.matches.forEach(function (mvalue) { value.matches.forEach((mvalue) => {
if (mvalue.key === "tags" || mvalue.key === "categories") { if (mvalue.key === 'tags' || mvalue.key === 'categories') {
snippetHighlights.push(mvalue.value); snippetHighlights.push(mvalue.value);
} else if (mvalue.key === "contents") { } else if (mvalue.key === 'contents') {
const ind = content.toLowerCase().indexOf(searchQuery.toLowerCase()); const ind = content.toLowerCase().indexOf(searchQuery.toLowerCase());
const start = ind - summaryInclude > 0 ? ind - summaryInclude : 0; const start = ind - summaryInclude > 0 ? ind - summaryInclude : 0;
const end = ind + searchQuery.length + summaryInclude < content.length ? ind + searchQuery.length + summaryInclude : content.length; const end = ind + searchQuery.length + summaryInclude < content.length ? ind + searchQuery.length + summaryInclude : content.length;
snippet += content.substring(start, end); snippet += content.substring(start, end);
if (ind > -1) { if (ind > -1) {
snippetHighlights.push(content.substring(ind, ind + searchQuery.length)) snippetHighlights.push(content.substring(ind, ind + searchQuery.length));
} else { } else {
snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1)); snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1));
} }
}
});
} }
});
}
if (snippet.length < 1) { if (snippet.length < 1) {
snippet += content.substring(0, summaryInclude * 2); snippet += content.substring(0, summaryInclude * 2);
} }
//pull template from hugo templarte definition // pull template from hugo template definition
const templateDefinition = document.getElementById("search-result-template").innerHTML; const templateDefinition = document.getElementById('search-result-template').innerHTML;
//replace values // replace values
const output = render(templateDefinition, { const output = render(templateDefinition, {
key: key, key,
title: value.item.title, title: value.item.title,
link: value.item.permalink, link: value.item.permalink,
tags: value.item.tags, tags: value.item.tags,
categories: value.item.categories, categories: value.item.categories,
snippet: snippet snippet
});
document.getElementById("search-results").appendChild(htmlToElement(output));
snippetHighlights.forEach(function (snipvalue) {
new Mark(document.getElementById("summary-" + key)).mark(snipvalue);
});
}); });
document.getElementById('search-results').appendChild(htmlToElement(output));
snippetHighlights.forEach((snipvalue) => {
new Mark(document.getElementById(`summary-${key}`)).mark(snipvalue);
});
});
} }
function render(templateString, data) { function render(templateString, data) {
let conditionalMatches, copy; let conditionalMatches, copy;
const conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g; const conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g;
//since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop // since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
copy = templateString; copy = templateString;
while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) { while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) {
if (data[conditionalMatches[1]]) { if (data[conditionalMatches[1]]) {
//valid key, remove conditionals, leave content. // valid key, remove conditionals, leave content.
copy = copy.replace(conditionalMatches[0], conditionalMatches[2]); copy = copy.replace(conditionalMatches[0], conditionalMatches[2]);
} else { } else {
//not valid, remove entire section // not valid, remove entire section
copy = copy.replace(conditionalMatches[0], ''); copy = copy.replace(conditionalMatches[0], '');
}
} }
templateString = copy; }
//now any conditionals removed we can do simple substitution templateString = copy;
let key, find, re; // now any conditionals removed we can do simple substitution
for (key in data) { let key, find, re;
find = '\\$\\{\\s*' + key + '\\s*\\}'; for (key of Object.keys(data)) {
re = new RegExp(find, 'g'); find = `\\$\\{\\s*${key}\\s*\\}`;
templateString = templateString.replace(re, data[key]); re = new RegExp(find, 'g');
} templateString = templateString.replace(re, data[key]);
return templateString; }
return templateString;
} }
/** /**
@ -169,8 +167,8 @@ function render(templateString, data) {
* @return {Element} * @return {Element}
*/ */
function htmlToElement(html) { function htmlToElement(html) {
const template = document.createElement('template'); const template = document.createElement('template');
html = html.trim(); // Never return a text node of whitespace as the result html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = html; template.innerHTML = html;
return template.content.firstChild; return template.content.firstChild;
} }