pref: optimize theme config

This commit is contained in:
XPoet 2020-04-30 12:24:57 +08:00
parent f23ac2d795
commit 73ee16edce
9 changed files with 359 additions and 359 deletions

View File

@ -1,10 +1,16 @@
# theme basic info # theme basic info
theme_info: theme_info:
name: ILS name: ILS
version: 1.0.2 version: 1.1.0
author: XPoet author: XPoet
repository: https://github.com/XPoet/hexo-theme-ils repository: https://github.com/XPoet/hexo-theme-ils
# favicon
favicon: images/favicon.png
# avatar
avatar: images/avatar.png
# navigation menu # navigation menu
menu: menu:
Home: / Home: /
@ -17,84 +23,78 @@ menu:
rss: rss:
enable: true enable: true
# favicon
favicon: images/favicon.png
# comment plugin # comment plugin
comments: comments:
# Valine. # Valine https://github.com/xCss/Valine
# more info please open https://github.com/xCss/Valine
valine: valine:
enable: false # true or false enable: false
appid: # your leancloud application appid appid: # your leancloud application appid
appkey: # your leancloud application appkey appkey: # your leancloud application appkey
meta: # type: Array, default: ['nick','mail','link'] meta: # comment input meta, type: Array, values: ['nick','mail','link']
placeholder: Please share your thoughts with us in the comments below! #your placeholder placeholder: # your placeholder
# Gitalk # Gitalk https://github.com/gitalk/gitalk
# For more information: https://gitalk.github.io, https://github.com/gitalk/gitalk
gitalk: gitalk:
enable: false enable: false
github_id: # GitHub repo owner github_id: # GitHub repo owner
repository: # Repository name to store issues repository: # Repository name to store issues
client_id: # GitHub Application Client ID client_id: # GitHub Application Client ID
client_secret: # GitHub Application Client Secret client_secret: # GitHub Application Client Secret
distraction_free_mode: false # Facebook-like distraction free mode distraction_free_mode: false # Facebook-like distraction free mode
# Show PV/UV of the website/page with busuanzi. # website count
# Get more information on http://ibruce.info/2015/04/04/busuanzi/ website_count:
busuanzi_count: # busuanzi http://ibruce.info/2015/04/04/busuanzi/
# count values only if the other configs are false busuanzi_count:
enable: false enable: false
# custom uv span for the whole site site_uv: false
site_uv: false site_pv: false
# custom pv span for the whole site page_pv: false
site_pv: false
# custom pv span for one page only
page_pv: false
# Local Search # Local Search
# Dependencies: https://github.com/theme-next/hexo-generator-searchdb # Dependencies: https://github.com/theme-next/hexo-generator-searchdb
local_search: local_search:
enable: false enable: true
# If auto, trigger search by changing input. # If auto, trigger search by changing input.
# If manual, trigger search by pressing enter key or search button. # If manual, trigger search by pressing enter key or search button.
trigger: auto trigger: auto # values: auto | manual
# Show top n results per article, show all results by setting to -1
top_n_per_article: 1
# Unescape html strings to the readable one. # Unescape html strings to the readable one.
unescape: false unescape: false
# Preload the search data when the page loads. # Preload the search data when the page loads.
preload: false preload: false
# Code Block # Code Copy
codeblock: code_copy:
style: flat # Available values: default | flat | mac
copy_button:
enable: true
# Table of Contents in the Sidebar
toc:
enable: true enable: true
# Automatically add list number to toc. style: flat # values: default | flat | mac
number: true
# If true, all level of TOC in a post will be displayed, rather than the activated part of it.
expand_all: true
# magic theme style
magic:
enable: true
sidebar:
enable: true
fixed: true
position: right
# sidebar tools # sidebar tools
side-tools: side_tools:
enable: true enable: true
position: right position: right # values: left | right
# back to top # back to top
back2top: back2top:
enable: true enable: true
position: right position: right # values: left | right
# Table of Contents in the Sidebar
toc:
enable: true
# Automatically add list number to toc.
number: true
# If true, all level of TOC in a post will be displayed, rather than the activated part of it.
expand_all: true
# magic theme
magic:
enable: true
sidebar:
enable: false
fixed: true
position: right # values: left | right

View File

@ -26,7 +26,7 @@
</ul> </ul>
</span> </span>
<% } %> <% } %>
<% if (theme.busuanzi_count.enable && theme.busuanzi_count.page_pv && is_post()) { %> <% if (theme.website_count.busuanzi_count.enable && theme.website_count.busuanzi_count.page_pv && is_post()) { %>
<span class="article-pv article-meta-item"> <span class="article-pv article-meta-item">
<i class="fa fa-eye"></i> <span id="busuanzi_value_page_pv"></span> <i class="fa fa-eye"></i> <span id="busuanzi_value_page_pv"></span>
</span> </span>

View File

@ -7,15 +7,15 @@
<%- __('powered_by', '<a target="_blank" href="https://hexo.io">Hexo</a>') %> | <%- __('theme') %> <a <%- __('powered_by', '<a target="_blank" href="https://hexo.io">Hexo</a>') %> | <%- __('theme') %> <a
href="https://github.com/XPoet/hexo-theme-ils" target="_blank"><%= theme.theme_info.name %> v<%= theme.theme_info.version %></a> href="https://github.com/XPoet/hexo-theme-ils" target="_blank"><%= theme.theme_info.name %> v<%= theme.theme_info.version %></a>
</div> </div>
<% if (theme.busuanzi_count.enable) { %> <% if (theme.website_count.busuanzi_count.enable) { %>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script> <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<div class="website-count info-item"> <div class="website-count info-item">
<% if (theme.busuanzi_count.site_uv) { %> <% if (theme.website_count.busuanzi_count.site_uv) { %>
<span id="busuanzi_container_site_uv" style="display: none"> <span id="busuanzi_container_site_uv" style="display: none">
<%- __('site_uv') %><span id="busuanzi_value_site_uv"></span> <%- __('site_uv') %><span id="busuanzi_value_site_uv"></span>
</span> </span>
<% } %> <% } %>
<% if (theme.busuanzi_count.site_pv) { %> <% if (theme.website_count.busuanzi_count.site_pv) { %>
<span id="busuanzi_container_site_pv" style="display: none"> <span id="busuanzi_container_site_pv" style="display: none">
<%- __('site_pv') %><span id="busuanzi_value_site_pv"></span> <%- __('site_pv') %><span id="busuanzi_value_site_pv"></span>
</span> </span>

View File

@ -10,7 +10,7 @@
<% if (is_post()) { %> <% if (is_post()) { %>
<% if (theme.codeblock.copy_button.enable) { %> <% if (theme.code_copy.enable) { %>
<%- js('js/code-copy.js') %> <%- js('js/code-copy.js') %>
<% } %> <% } %>

View File

@ -59,7 +59,7 @@ if ((hexo-config('magic.enable') && !hexo-config('magic.sidebar.enable') && hexo
position: fixed; position: fixed;
top: $header-height + $component-interspace; top: $header-height + $component-interspace;
if (hexo-config('side-tools.position') == left) { if (hexo-config('side_tools.position') == left) {
right: 30px; right: 30px;
} else { } else {
left: 30px; left: 30px;

View File

@ -28,13 +28,13 @@ disable-user-select() {
disable-user-select(); disable-user-select();
the-transition(); the-transition();
if (hexo-config('codeblock.style') == 'flat') { if (hexo-config('code_copy.style') == 'flat') {
background: white; background: white;
border: 0; border: 0;
font-size: 0.8em; font-size: 0.8em;
right: 0; right: 0;
top: 0; top: 0;
} else if (hexo-config('codeblock.style') == 'mac') { } else if (hexo-config('code_copy.style') == 'mac') {
color: white; color: white;
font-size: 1em; font-size: 1em;
right: 2px; right: 2px;
@ -51,7 +51,7 @@ disable-user-select() {
} }
if (hexo-config('codeblock.style') == 'mac') { if (hexo-config('code_copy.style') == 'mac') {
.highlight-container { .highlight-container {
background: #21252b; background: #21252b;
border-radius: 5px; border-radius: 5px;

View File

@ -1,10 +1,10 @@
// ================================== // ===================================
// THEME VARIABLE // THEME VARIABLE //
// ================================== // ===================================
// =============================== // ===================================
// layout // layout
// =============================== // ===================================
if (hexo-config('magic.enable')) { if (hexo-config('magic.enable')) {
$header-height = 80px; // $header-height = 80px; //
} else { } else {
@ -22,15 +22,15 @@ $header-shrink-height = 60px; // 头部收缩高度
$tool-button-width = 36px; // $tool-button-width = 36px; //
$component-interspace = 30px; // /px $component-interspace = 30px; // /px
// =============================== // ===================================
// //
// =============================== // ===================================
$media-max-width = 760px; // $media-max-width = 760px; //
// =============================== // ===================================
// z-index // z-index
// =============================== // ===================================
$z-index-1 = 1001; $z-index-1 = 1001;
$z-index-2 = 1002; $z-index-2 = 1002;
$z-index-3 = 1003; $z-index-3 = 1003;
@ -39,16 +39,16 @@ $z-index-5 = 1005;
$z-index-6 = 1006; $z-index-6 = 1006;
// =============================== // ===================================
// color // color
// =============================== // ===================================
// normal mode color // normal mode color
$primary-color = #1b65ea; // $primary-color = #225eea; //
$background-color = #fff; // $background-color = #fff; //
$magic-background-color = #f5f5f5; // MAGIC $magic-background-color = #f5f5f5; // MAGIC
$normal-text-color = #3c3944; // $normal-text-color = #43404d; //
$first-text-color = darken($normal-text-color, 10%); // $first-text-color = darken($normal-text-color, 8%); //
$second-text-color = darken($normal-text-color, 5%); // $second-text-color = darken($normal-text-color, 4%); //
$third-text-color = lighten($normal-text-color, 40%); // $third-text-color = lighten($normal-text-color, 40%); //
$fourth-text-color = #eee; // $fourth-text-color = #eee; //
$border-color = darken($background-color, 30%); // $border-color = darken($background-color, 30%); //
@ -67,9 +67,9 @@ $dark-border-color = lighten($dark-background-color, 20%);
$dark-selection-color = $selection-color; $dark-selection-color = $selection-color;
// =============================== // ===================================
// font // font
// =============================== // ===================================
//$default-font-family = 'PingHei', 'PingFang SC', 'Microsoft YaHei'; //$default-font-family = 'PingHei', 'PingFang SC', 'Microsoft YaHei';
//$default-font-family = 'PingFang SC', 'Hiragino Sans GB', 'STHeiti Light'; //$default-font-family = 'PingFang SC', 'Hiragino Sans GB', 'STHeiti Light';
//$default-font-family = 'Microsoft YaHei', 'SimHei', 'WenQuanYi Micro Hei', sans-serif; //$default-font-family = 'Microsoft YaHei', 'SimHei', 'WenQuanYi Micro Hei', sans-serif;

View File

@ -68,7 +68,7 @@
.sidebar-tools { .sidebar-tools {
position: fixed; position: fixed;
top: $header-height + $component-interspace; top: $header-height + $component-interspace;
if (hexo-config('side-tools.position') == left) { if (hexo-config('side_tools.position') == left) {
left: ((100% - $main-content-width) / 4); left: ((100% - $main-content-width) / 4);
} else { } else {
right: ((100% - $main-content-width) / 4); right: ((100% - $main-content-width) / 4);
@ -140,7 +140,7 @@
} }
.sidebar-tools { .sidebar-tools {
if (hexo-config('side-tools.position') == left) { if (hexo-config('side_tools.position') == left) {
left: 2% !important; left: 2% !important;
transform-origin: left top; transform-origin: left top;
} else { } else {

View File

@ -1,297 +1,297 @@
/* global CONFIG */ /* global CONFIG */
window.addEventListener('DOMContentLoaded', () => { window.addEventListener('DOMContentLoaded', () => {
// Popup Window // Popup Window
let isfetched = false; let isfetched = false;
let datas; let datas;
let isXml = true; let isXml = true;
// Search DB path // Search DB path
let searchPath = CONFIG.path; let searchPath = CONFIG.path;
if (searchPath.length === 0) { if (searchPath.length === 0) {
searchPath = 'search.xml'; searchPath = 'search.xml';
} else if (searchPath.endsWith('json')) { } else if (searchPath.endsWith('json')) {
isXml = false; isXml = false;
}
const input = document.querySelector('.search-input');
const resultContent = document.getElementById('search-result');
// Ref: https://github.com/ForbesLindesay/unescape-html
const unescapeHtml = html => {
return String(html)
.replace(/&quot;/g, '"')
.replace(/&#39;/g, '\'')
.replace(/&#x3A;/g, ':')
// Replace all the other &#x; chars
.replace(/&#(\d+);/g, (m, p) => {
return String.fromCharCode(p);
})
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&');
};
const getIndexByWord = (word, text, caseSensitive) => {
let wordLen = word.length;
if (wordLen === 0) return [];
let startPosition = 0;
let position = [];
let index = [];
if (!caseSensitive) {
text = text.toLowerCase();
word = word.toLowerCase();
} }
while ((position = text.indexOf(word, startPosition)) > -1) { const input = document.querySelector('.search-input');
index.push({ position, word }); const resultContent = document.getElementById('search-result');
startPosition = position + wordLen;
}
return index;
};
// Merge hits into slices // Ref: https://github.com/ForbesLindesay/unescape-html
const mergeIntoSlice = (start, end, index, searchText) => { const unescapeHtml = html => {
let item = index[index.length - 1]; return String(html)
let { position, word } = item; .replace(/&quot;/g, '"')
let hits = []; .replace(/&#39;/g, '\'')
let searchTextCountInSlice = 0; .replace(/&#x3A;/g, ':')
while (position + word.length <= end && index.length !== 0) { // Replace all the other &#x; chars
if (word === searchText) { .replace(/&#(\d+);/g, (m, p) => {
searchTextCountInSlice++; return String.fromCharCode(p);
} })
hits.push({ .replace(/&lt;/g, '<')
position, .replace(/&gt;/g, '>')
length: word.length .replace(/&amp;/g, '&');
});
let wordEnd = position + word.length;
// Move to next position of hit
index.pop();
while (index.length !== 0) {
item = index[index.length - 1];
position = item.position;
word = item.word;
if (wordEnd > position) {
index.pop();
} else {
break;
}
}
}
return {
hits,
start,
end,
searchTextCount: searchTextCountInSlice
}; };
};
// Highlight title and content const getIndexByWord = (word, text, caseSensitive) => {
const highlightKeyword = (text, slice) => { let wordLen = word.length;
let result = ''; if (wordLen === 0) return [];
let prevEnd = slice.start; let startPosition = 0;
slice.hits.forEach(hit => { let position = [];
result += text.substring(prevEnd, hit.position); let index = [];
let end = hit.position + hit.length; if (!caseSensitive) {
result += `<b class="search-keyword">${text.substring(hit.position, end)}</b>`; text = text.toLowerCase();
prevEnd = end; word = word.toLowerCase();
}); }
result += text.substring(prevEnd, slice.end); while ((position = text.indexOf(word, startPosition)) > -1) {
return result; index.push({position, word});
}; startPosition = position + wordLen;
}
return index;
};
const inputEventFunction = () => { // Merge hits into slices
if (!isfetched) return; const mergeIntoSlice = (start, end, index, searchText) => {
let searchText = input.value.trim().toLowerCase(); let item = index[index.length - 1];
let keywords = searchText.split(/[-\s]+/); let {position, word} = item;
if (keywords.length > 1) { let hits = [];
keywords.push(searchText); let searchTextCountInSlice = 0;
} while (position + word.length <= end && index.length !== 0) {
let resultItems = []; if (word === searchText) {
if (searchText.length > 0) { searchTextCountInSlice++;
// Perform local searching }
datas.forEach(({ title, content, url }) => { hits.push({
let titleInLowerCase = title.toLowerCase(); position,
let contentInLowerCase = content.toLowerCase(); length: word.length
let indexOfTitle = [];
let indexOfContent = [];
let searchTextCount = 0;
keywords.forEach(keyword => {
indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
});
// Show search results
if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
let hitCount = indexOfTitle.length + indexOfContent.length;
// Sort index by position of keyword
[indexOfTitle, indexOfContent].forEach(index => {
index.sort((itemLeft, itemRight) => {
if (itemRight.position !== itemLeft.position) {
return itemRight.position - itemLeft.position;
}
return itemLeft.word.length - itemRight.word.length;
}); });
}); let wordEnd = position + word.length;
let slicesOfTitle = []; // Move to next position of hit
if (indexOfTitle.length !== 0) { index.pop();
let tmp = mergeIntoSlice(0, title.length, indexOfTitle, searchText); while (index.length !== 0) {
searchTextCount += tmp.searchTextCountInSlice; item = index[index.length - 1];
slicesOfTitle.push(tmp); position = item.position;
} word = item.word;
if (wordEnd > position) {
let slicesOfContent = []; index.pop();
while (indexOfContent.length !== 0) { } else {
let item = indexOfContent[indexOfContent.length - 1]; break;
let { position, word } = item; }
// Cut out 100 characters
let start = position - 20;
let end = position + 80;
if (start < 0) {
start = 0;
} }
if (end < position + word.length) {
end = position + word.length;
}
if (end > content.length) {
end = content.length;
}
let tmp = mergeIntoSlice(start, end, indexOfContent, searchText);
searchTextCount += tmp.searchTextCountInSlice;
slicesOfContent.push(tmp);
}
// Sort slices in content by search text's count and hits' count
slicesOfContent.sort((sliceLeft, sliceRight) => {
if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
return sliceRight.searchTextCount - sliceLeft.searchTextCount;
} else if (sliceLeft.hits.length !== sliceRight.hits.length) {
return sliceRight.hits.length - sliceLeft.hits.length;
}
return sliceLeft.start - sliceRight.start;
});
// Select top N slices in content
let upperBound = parseInt(CONFIG.localsearch.top_n_per_article, 10);
if (upperBound >= 0) {
slicesOfContent = slicesOfContent.slice(0, upperBound);
}
let resultItem = '';
if (slicesOfTitle.length !== 0) {
resultItem += `<li><a href="${url}" class="search-result-title">${highlightKeyword(title, slicesOfTitle[0])}</a>`;
} else {
resultItem += `<li><a href="${url}" class="search-result-title">${title}</a>`;
}
slicesOfContent.forEach(slice => {
resultItem += `<a href="${url}"><p class="search-result">${highlightKeyword(content, slice)}...</p></a>`;
});
resultItem += '</li>';
resultItems.push({
item: resultItem,
id : resultItems.length,
hitCount,
searchTextCount
});
} }
}); return {
} hits,
if (keywords.length === 1 && keywords[0] === '') { start,
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x"></i></div>'; end,
} else if (resultItems.length === 0) { searchTextCount: searchTextCountInSlice
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x"></i></div>'; };
} else { };
resultItems.sort((resultLeft, resultRight) => {
if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
return resultRight.searchTextCount - resultLeft.searchTextCount;
} else if (resultLeft.hitCount !== resultRight.hitCount) {
return resultRight.hitCount - resultLeft.hitCount;
}
return resultRight.id - resultLeft.id;
});
let searchResultList = '<ul class="search-result-list">';
resultItems.forEach(result => {
searchResultList += result.item;
});
searchResultList += '</ul>';
resultContent.innerHTML = searchResultList;
window.pjax && window.pjax.refresh(resultContent);
}
};
const fetchData = () => { // Highlight title and content
fetch(CONFIG.root + searchPath) const highlightKeyword = (text, slice) => {
.then(response => response.text()) let result = '';
.then(res => { let prevEnd = slice.start;
// Get the contents from search data slice.hits.forEach(hit => {
isfetched = true; result += text.substring(prevEnd, hit.position);
datas = isXml ? [...new DOMParser().parseFromString(res, 'text/xml').querySelectorAll('entry')].map(element => { let end = hit.position + hit.length;
return { result += `<b class="search-keyword">${text.substring(hit.position, end)}</b>`;
title : element.querySelector('title').textContent, prevEnd = end;
content: element.querySelector('content').textContent,
url : element.querySelector('url').textContent
};
}) : JSON.parse(res);
// Only match articles with not empty titles
datas = datas.filter(data => data.title).map(data => {
data.title = data.title.trim();
data.content = data.content ? data.content.trim().replace(/<[^>]+>/g, '') : '';
if (CONFIG.localsearch.unescape) {
data.content = unescapeHtml(data.content);
}
data.url = decodeURIComponent(data.url).replace(/\/{2,}/g, '/');
return data;
}); });
// Remove loading animation result += text.substring(prevEnd, slice.end);
document.getElementById('no-result').innerHTML = '<i class="fa fa-search fa-5x"></i>'; return result;
}); };
};
if (CONFIG.localsearch.preload) { const inputEventFunction = () => {
fetchData(); if (!isfetched) return;
} let searchText = input.value.trim().toLowerCase();
let keywords = searchText.split(/[-\s]+/);
if (keywords.length > 1) {
keywords.push(searchText);
}
let resultItems = [];
if (searchText.length > 0) {
// Perform local searching
datas.forEach(({title, content, url}) => {
let titleInLowerCase = title.toLowerCase();
let contentInLowerCase = content.toLowerCase();
let indexOfTitle = [];
let indexOfContent = [];
let searchTextCount = 0;
keywords.forEach(keyword => {
indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
});
if (CONFIG.localsearch.trigger === 'auto') { // Show search results
if (input) { if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
input.addEventListener('input', inputEventFunction); let hitCount = indexOfTitle.length + indexOfContent.length;
// Sort index by position of keyword
[indexOfTitle, indexOfContent].forEach(index => {
index.sort((itemLeft, itemRight) => {
if (itemRight.position !== itemLeft.position) {
return itemRight.position - itemLeft.position;
}
return itemLeft.word.length - itemRight.word.length;
});
});
let slicesOfTitle = [];
if (indexOfTitle.length !== 0) {
let tmp = mergeIntoSlice(0, title.length, indexOfTitle, searchText);
searchTextCount += tmp.searchTextCountInSlice;
slicesOfTitle.push(tmp);
}
let slicesOfContent = [];
while (indexOfContent.length !== 0) {
let item = indexOfContent[indexOfContent.length - 1];
let {position, word} = item;
// Cut out 100 characters
let start = position - 20;
let end = position + 80;
if (start < 0) {
start = 0;
}
if (end < position + word.length) {
end = position + word.length;
}
if (end > content.length) {
end = content.length;
}
let tmp = mergeIntoSlice(start, end, indexOfContent, searchText);
searchTextCount += tmp.searchTextCountInSlice;
slicesOfContent.push(tmp);
}
// Sort slices in content by search text's count and hits' count
slicesOfContent.sort((sliceLeft, sliceRight) => {
if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
return sliceRight.searchTextCount - sliceLeft.searchTextCount;
} else if (sliceLeft.hits.length !== sliceRight.hits.length) {
return sliceRight.hits.length - sliceLeft.hits.length;
}
return sliceLeft.start - sliceRight.start;
});
// Select top N slices in content
let upperBound = parseInt(CONFIG.localsearch.top_n_per_article ? CONFIG.localsearch.top_n_per_article : 1, 10);
if (upperBound >= 0) {
slicesOfContent = slicesOfContent.slice(0, upperBound);
}
let resultItem = '';
if (slicesOfTitle.length !== 0) {
resultItem += `<li><a href="${url}" class="search-result-title">${highlightKeyword(title, slicesOfTitle[0])}</a>`;
} else {
resultItem += `<li><a href="${url}" class="search-result-title">${title}</a>`;
}
slicesOfContent.forEach(slice => {
resultItem += `<a href="${url}"><p class="search-result">${highlightKeyword(content, slice)}...</p></a>`;
});
resultItem += '</li>';
resultItems.push({
item: resultItem,
id: resultItems.length,
hitCount,
searchTextCount
});
}
});
}
if (keywords.length === 1 && keywords[0] === '') {
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x"></i></div>';
} else if (resultItems.length === 0) {
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x"></i></div>';
} else {
resultItems.sort((resultLeft, resultRight) => {
if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
return resultRight.searchTextCount - resultLeft.searchTextCount;
} else if (resultLeft.hitCount !== resultRight.hitCount) {
return resultRight.hitCount - resultLeft.hitCount;
}
return resultRight.id - resultLeft.id;
});
let searchResultList = '<ul class="search-result-list">';
resultItems.forEach(result => {
searchResultList += result.item;
});
searchResultList += '</ul>';
resultContent.innerHTML = searchResultList;
window.pjax && window.pjax.refresh(resultContent);
}
};
const fetchData = () => {
fetch(CONFIG.root + searchPath)
.then(response => response.text())
.then(res => {
// Get the contents from search data
isfetched = true;
datas = isXml ? [...new DOMParser().parseFromString(res, 'text/xml').querySelectorAll('entry')].map(element => {
return {
title: element.querySelector('title').textContent,
content: element.querySelector('content').textContent,
url: element.querySelector('url').textContent
};
}) : JSON.parse(res);
// Only match articles with not empty titles
datas = datas.filter(data => data.title).map(data => {
data.title = data.title.trim();
data.content = data.content ? data.content.trim().replace(/<[^>]+>/g, '') : '';
if (CONFIG.localsearch.unescape) {
data.content = unescapeHtml(data.content);
}
data.url = decodeURIComponent(data.url).replace(/\/{2,}/g, '/');
return data;
});
// Remove loading animation
document.getElementById('no-result').innerHTML = '<i class="fa fa-search fa-5x"></i>';
});
};
if (CONFIG.localsearch.preload) {
fetchData();
} }
} else { if (CONFIG.localsearch.trigger === 'auto') {
document.querySelector('.search-icon').addEventListener('click', inputEventFunction); if (input) {
input.addEventListener('keypress', event => { input.addEventListener('input', inputEventFunction);
if (event.key === 'Enter') { }
inputEventFunction();
} } else {
document.querySelector('.search-icon').addEventListener('click', inputEventFunction);
input.addEventListener('keypress', event => {
if (event.key === 'Enter') {
inputEventFunction();
}
});
}
// Handle and trigger popup window
document.querySelectorAll('.popup-trigger').forEach(element => {
element.addEventListener('click', () => {
document.body.style.overflow = 'hidden';
document.querySelector('.search-pop-overlay').style.display = 'block';
input.focus();
if (!isfetched) fetchData();
});
}); });
}
// Handle and trigger popup window // Monitor main search box
document.querySelectorAll('.popup-trigger').forEach(element => { const onPopupClose = () => {
element.addEventListener('click', () => { document.body.style.overflow = '';
document.body.style.overflow = 'hidden'; document.querySelector('.search-pop-overlay').style.display = '';
document.querySelector('.search-pop-overlay').style.display = 'block'; };
input.focus();
if (!isfetched) fetchData(); 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);
window.addEventListener('pjax:success', onPopupClose);
window.addEventListener('keyup', event => {
if (event.key === 'Escape') {
onPopupClose();
}
}); });
});
// Monitor main search box
const onPopupClose = () => {
document.body.style.overflow = '';
document.querySelector('.search-pop-overlay').style.display = '';
};
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);
window.addEventListener('pjax:success', onPopupClose);
window.addEventListener('keyup', event => {
if (event.key === 'Escape') {
onPopupClose();
}
});
}); });