100 lines
3.5 KiB
JavaScript
100 lines
3.5 KiB
JavaScript
|
/* global CONFIG, pjax, LocalSearch */
|
||
|
|
||
|
document.addEventListener('DOMContentLoaded', () => {
|
||
|
if (!CONFIG.path) {
|
||
|
// Search DB path
|
||
|
console.warn('`hexo-generator-searchdb` plugin is not installed!');
|
||
|
return;
|
||
|
}
|
||
|
const localSearch = new LocalSearch({
|
||
|
path : CONFIG.path,
|
||
|
top_n_per_article: CONFIG.localsearch.top_n_per_article,
|
||
|
unescape : CONFIG.localsearch.unescape
|
||
|
});
|
||
|
|
||
|
const input = document.querySelector('.search-input');
|
||
|
|
||
|
const inputEventFunction = () => {
|
||
|
if (!localSearch.isfetched) return;
|
||
|
const searchText = input.value.trim().toLowerCase();
|
||
|
const keywords = searchText.split(/[-\s]+/);
|
||
|
const container = document.querySelector('.search-result-container');
|
||
|
let resultItems = [];
|
||
|
if (searchText.length > 0) {
|
||
|
// Perform local searching
|
||
|
resultItems = localSearch.getResultItems(keywords);
|
||
|
}
|
||
|
if (keywords.length === 1 && keywords[0] === '') {
|
||
|
container.classList.add('no-result');
|
||
|
container.innerHTML = '<div class="search-result-icon"><i class="fa fa-search fa-5x"></i></div>';
|
||
|
} else if (resultItems.length === 0) {
|
||
|
container.classList.add('no-result');
|
||
|
container.innerHTML = '<div class="search-result-icon"><i class="far fa-frown fa-5x"></i></div>';
|
||
|
} else {
|
||
|
resultItems.sort((left, right) => {
|
||
|
if (left.includedCount !== right.includedCount) {
|
||
|
return right.includedCount - left.includedCount;
|
||
|
} else if (left.hitCount !== right.hitCount) {
|
||
|
return right.hitCount - left.hitCount;
|
||
|
}
|
||
|
return right.id - left.id;
|
||
|
});
|
||
|
const stats = CONFIG.i18n.hits.replace('${hits}', resultItems.length);
|
||
|
|
||
|
container.classList.remove('no-result');
|
||
|
container.innerHTML = `<div class="search-stats">${stats}</div>
|
||
|
<hr>
|
||
|
<ul class="search-result-list">${resultItems.map(result => result.item).join('')}</ul>`;
|
||
|
if (typeof pjax === 'object') pjax.refresh(container);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
localSearch.highlightSearchWords(document.querySelector('.post-body'));
|
||
|
if (CONFIG.localsearch.preload) {
|
||
|
localSearch.fetchData();
|
||
|
}
|
||
|
|
||
|
if (CONFIG.localsearch.trigger === 'auto') {
|
||
|
input.addEventListener('input', inputEventFunction);
|
||
|
} else {
|
||
|
document.querySelector('.search-icon').addEventListener('click', inputEventFunction);
|
||
|
input.addEventListener('keypress', event => {
|
||
|
if (event.key === 'Enter') {
|
||
|
inputEventFunction();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
window.addEventListener('search:loaded', inputEventFunction);
|
||
|
|
||
|
// Handle and trigger popup window
|
||
|
document.querySelectorAll('.popup-trigger').forEach(element => {
|
||
|
element.addEventListener('click', () => {
|
||
|
document.body.classList.add('search-active');
|
||
|
// Wait for search-popup animation to complete
|
||
|
setTimeout(() => input.focus(), 500);
|
||
|
if (!localSearch.isfetched) localSearch.fetchData();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// Monitor main search box
|
||
|
const onPopupClose = () => {
|
||
|
document.body.classList.remove('search-active');
|
||
|
};
|
||
|
|
||
|
document.querySelector('.search-pop-overlay').addEventListener('click', event => {
|
||
|
if (event.target === document.querySelector('.search-pop-overlay')) {
|
||
|
onPopupClose();
|
||
|
}
|
||
|
});
|
||
|
document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose);
|
||
|
document.addEventListener('pjax:success', () => {
|
||
|
localSearch.highlightSearchWords(document.querySelector('.post-body'));
|
||
|
onPopupClose();
|
||
|
});
|
||
|
window.addEventListener('keyup', event => {
|
||
|
if (event.key === 'Escape') {
|
||
|
onPopupClose();
|
||
|
}
|
||
|
});
|
||
|
});
|