diff --git a/_config.yml b/_config.yml
index d82d07a..fc00c1a 100644
--- a/_config.yml
+++ b/_config.yml
@@ -1,10 +1,16 @@
# theme basic info
theme_info:
name: ILS
- version: 1.0.2
+ version: 1.1.0
author: XPoet
repository: https://github.com/XPoet/hexo-theme-ils
+# favicon
+favicon: images/favicon.png
+
+# avatar
+avatar: images/avatar.png
+
# navigation menu
menu:
Home: /
@@ -17,84 +23,78 @@ menu:
rss:
enable: true
-# favicon
-favicon: images/favicon.png
-
# comment plugin
comments:
- # Valine.
- # more info please open https://github.com/xCss/Valine
+ # Valine https://github.com/xCss/Valine
valine:
- enable: false # true or false
- appid: # your leancloud application appid
- appkey: # your leancloud application appkey
- meta: # type: Array, default: ['nick','mail','link']
- placeholder: Please share your thoughts with us in the comments below! #your placeholder
+ enable: false
+ appid: # your leancloud application appid
+ appkey: # your leancloud application appkey
+ meta: # comment input meta, type: Array, values: ['nick','mail','link']
+ placeholder: # your placeholder
- # Gitalk
- # For more information: https://gitalk.github.io, https://github.com/gitalk/gitalk
+ # Gitalk https://github.com/gitalk/gitalk
gitalk:
enable: false
- github_id: # GitHub repo owner
- repository: # Repository name to store issues
- client_id: # GitHub Application Client ID
- client_secret: # GitHub Application Client Secret
+ github_id: # GitHub repo owner
+ repository: # Repository name to store issues
+ client_id: # GitHub Application Client ID
+ client_secret: # GitHub Application Client Secret
distraction_free_mode: false # Facebook-like distraction free mode
-# Show PV/UV of the website/page with busuanzi.
-# Get more information on http://ibruce.info/2015/04/04/busuanzi/
-busuanzi_count:
- # count values only if the other configs are false
- enable: false
- # custom uv span for the whole site
- site_uv: false
- # custom pv span for the whole site
- site_pv: false
- # custom pv span for one page only
- page_pv: false
+# website count
+website_count:
+ # busuanzi http://ibruce.info/2015/04/04/busuanzi/
+ busuanzi_count:
+ enable: false
+ site_uv: false
+ site_pv: false
+ page_pv: false
# Local Search
# Dependencies: https://github.com/theme-next/hexo-generator-searchdb
local_search:
- enable: false
+ enable: true
+
# If auto, trigger search by changing input.
# If manual, trigger search by pressing enter key or search button.
- trigger: auto
- # Show top n results per article, show all results by setting to -1
- top_n_per_article: 1
+ trigger: auto # values: auto | manual
+
# Unescape html strings to the readable one.
unescape: false
+
# Preload the search data when the page loads.
preload: false
-# Code Block
-codeblock:
- style: flat # Available values: default | flat | mac
- copy_button:
- enable: true
-
-# Table of Contents in the Sidebar
-toc:
+# Code Copy
+code_copy:
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 style
-magic:
- enable: true
- sidebar:
- enable: true
- fixed: true
- position: right
+ style: flat # values: default | flat | mac
# sidebar tools
-side-tools:
+side_tools:
enable: true
- position: right
+ position: right # values: left | right
# back to top
back2top:
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
\ No newline at end of file
diff --git a/layout/_partial/article-meta-info.ejs b/layout/_partial/article-meta-info.ejs
index b276aeb..512a914 100644
--- a/layout/_partial/article-meta-info.ejs
+++ b/layout/_partial/article-meta-info.ejs
@@ -26,7 +26,7 @@
<% } %>
- <% 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()) { %>
diff --git a/layout/_partial/footer.ejs b/layout/_partial/footer.ejs
index 8380c54..d233478 100644
--- a/layout/_partial/footer.ejs
+++ b/layout/_partial/footer.ejs
@@ -7,15 +7,15 @@
<%- __('powered_by', 'Hexo') %> | <%- __('theme') %> <%= theme.theme_info.name %> v<%= theme.theme_info.version %>
- <% if (theme.busuanzi_count.enable) { %>
+ <% if (theme.website_count.busuanzi_count.enable) { %>
- <% if (theme.busuanzi_count.site_uv) { %>
+ <% if (theme.website_count.busuanzi_count.site_uv) { %>
<%- __('site_uv') %>
<% } %>
- <% if (theme.busuanzi_count.site_pv) { %>
+ <% if (theme.website_count.busuanzi_count.site_pv) { %>
<%- __('site_pv') %>
diff --git a/layout/_partial/scripts.ejs b/layout/_partial/scripts.ejs
index 3b32705..a99ea71 100644
--- a/layout/_partial/scripts.ejs
+++ b/layout/_partial/scripts.ejs
@@ -10,7 +10,7 @@
<% if (is_post()) { %>
- <% if (theme.codeblock.copy_button.enable) { %>
+ <% if (theme.code_copy.enable) { %>
<%- js('js/code-copy.js') %>
<% } %>
diff --git a/source/css/layout/article-content.styl b/source/css/layout/article-content.styl
index 1ffd6bd..e450e6c 100644
--- a/source/css/layout/article-content.styl
+++ b/source/css/layout/article-content.styl
@@ -59,7 +59,7 @@ if ((hexo-config('magic.enable') && !hexo-config('magic.sidebar.enable') && hexo
position: fixed;
top: $header-height + $component-interspace;
- if (hexo-config('side-tools.position') == left) {
+ if (hexo-config('side_tools.position') == left) {
right: 30px;
} else {
left: 30px;
diff --git a/source/css/layout/common/codeblock/copy-code.styl b/source/css/layout/common/codeblock/copy-code.styl
index 8f94d4e..01a0a60 100644
--- a/source/css/layout/common/codeblock/copy-code.styl
+++ b/source/css/layout/common/codeblock/copy-code.styl
@@ -28,13 +28,13 @@ disable-user-select() {
disable-user-select();
the-transition();
- if (hexo-config('codeblock.style') == 'flat') {
+ if (hexo-config('code_copy.style') == 'flat') {
background: white;
border: 0;
font-size: 0.8em;
right: 0;
top: 0;
- } else if (hexo-config('codeblock.style') == 'mac') {
+ } else if (hexo-config('code_copy.style') == 'mac') {
color: white;
font-size: 1em;
right: 2px;
@@ -51,7 +51,7 @@ disable-user-select() {
}
-if (hexo-config('codeblock.style') == 'mac') {
+if (hexo-config('code_copy.style') == 'mac') {
.highlight-container {
background: #21252b;
border-radius: 5px;
diff --git a/source/css/layout/common/variables.styl b/source/css/layout/common/variables.styl
index 35dbc74..e8dd6ee 100644
--- a/source/css/layout/common/variables.styl
+++ b/source/css/layout/common/variables.styl
@@ -1,10 +1,10 @@
-// ==================================
-// THEME VARIABLE
-// ==================================
+// ===================================
+// THEME VARIABLE //
+// ===================================
-// ===============================
+// ===================================
// layout
-// ===============================
+// ===================================
if (hexo-config('magic.enable')) {
$header-height = 80px; // 头部默认高度
} else {
@@ -22,15 +22,15 @@ $header-shrink-height = 60px; // 头部收缩高度
$tool-button-width = 36px; // 方形工具按钮宽度
$component-interspace = 30px; // 组件/模块的间隔值(px)
-// ===============================
+// ===================================
// 媒体查询
-// ===============================
+// ===================================
$media-max-width = 760px; // 媒体查询最大宽度
-// ===============================
+// ===================================
// z-index
-// ===============================
+// ===================================
$z-index-1 = 1001;
$z-index-2 = 1002;
$z-index-3 = 1003;
@@ -39,16 +39,16 @@ $z-index-5 = 1005;
$z-index-6 = 1006;
-// ===============================
+// ===================================
// color
-// ===============================
+// ===================================
// normal mode color
-$primary-color = #1b65ea; // 主题颜色
+$primary-color = #225eea; // 主题颜色
$background-color = #fff; // 背景颜色
$magic-background-color = #f5f5f5; // MAGIC 主题背景颜色
-$normal-text-color = #3c3944; // 通用文本颜色(默认字体颜色)
-$first-text-color = darken($normal-text-color, 10%); // 第一文本颜色
-$second-text-color = darken($normal-text-color, 5%); // 第二文本颜色
+$normal-text-color = #43404d; // 通用文本颜色(默认字体颜色)
+$first-text-color = darken($normal-text-color, 8%); // 第一文本颜色
+$second-text-color = darken($normal-text-color, 4%); // 第二文本颜色
$third-text-color = lighten($normal-text-color, 40%); // 第三文本颜色
$fourth-text-color = #eee; // 第四文本颜色
$border-color = darken($background-color, 30%); // 边框颜色
@@ -67,9 +67,9 @@ $dark-border-color = lighten($dark-background-color, 20%);
$dark-selection-color = $selection-color;
-// ===============================
+// ===================================
// font
-// ===============================
+// ===================================
//$default-font-family = 'PingHei', 'PingFang SC', 'Microsoft YaHei';
//$default-font-family = 'PingFang SC', 'Hiragino Sans GB', 'STHeiti Light';
//$default-font-family = 'Microsoft YaHei', 'SimHei', 'WenQuanYi Micro Hei', sans-serif;
diff --git a/source/css/layout/page.styl b/source/css/layout/page.styl
index 9699f0d..efb1a89 100644
--- a/source/css/layout/page.styl
+++ b/source/css/layout/page.styl
@@ -68,7 +68,7 @@
.sidebar-tools {
position: fixed;
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);
} else {
right: ((100% - $main-content-width) / 4);
@@ -140,7 +140,7 @@
}
.sidebar-tools {
- if (hexo-config('side-tools.position') == left) {
+ if (hexo-config('side_tools.position') == left) {
left: 2% !important;
transform-origin: left top;
} else {
diff --git a/source/js/local-search.js b/source/js/local-search.js
index 86755c9..9a1d230 100644
--- a/source/js/local-search.js
+++ b/source/js/local-search.js
@@ -1,297 +1,297 @@
/* global CONFIG */
window.addEventListener('DOMContentLoaded', () => {
- // Popup Window
- let isfetched = false;
- let datas;
- let isXml = true;
- // Search DB path
- let searchPath = CONFIG.path;
- if (searchPath.length === 0) {
- searchPath = 'search.xml';
- } else if (searchPath.endsWith('json')) {
- 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(/"/g, '"')
- .replace(/'/g, '\'')
- .replace(/:/g, ':')
- // Replace all the other chars
- .replace(/(\d+);/g, (m, p) => {
- return String.fromCharCode(p);
- })
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/&/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();
+ // Popup Window
+ let isfetched = false;
+ let datas;
+ let isXml = true;
+ // Search DB path
+ let searchPath = CONFIG.path;
+ if (searchPath.length === 0) {
+ searchPath = 'search.xml';
+ } else if (searchPath.endsWith('json')) {
+ isXml = false;
}
- while ((position = text.indexOf(word, startPosition)) > -1) {
- index.push({ position, word });
- startPosition = position + wordLen;
- }
- return index;
- };
+ const input = document.querySelector('.search-input');
+ const resultContent = document.getElementById('search-result');
- // Merge hits into slices
- const mergeIntoSlice = (start, end, index, searchText) => {
- let item = index[index.length - 1];
- let { position, word } = item;
- let hits = [];
- let searchTextCountInSlice = 0;
- while (position + word.length <= end && index.length !== 0) {
- if (word === searchText) {
- searchTextCountInSlice++;
- }
- hits.push({
- position,
- length: word.length
- });
- 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
+ // Ref: https://github.com/ForbesLindesay/unescape-html
+ const unescapeHtml = html => {
+ return String(html)
+ .replace(/"/g, '"')
+ .replace(/'/g, '\'')
+ .replace(/:/g, ':')
+ // Replace all the other chars
+ .replace(/(\d+);/g, (m, p) => {
+ return String.fromCharCode(p);
+ })
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/&/g, '&');
};
- };
- // Highlight title and content
- const highlightKeyword = (text, slice) => {
- let result = '';
- let prevEnd = slice.start;
- slice.hits.forEach(hit => {
- result += text.substring(prevEnd, hit.position);
- let end = hit.position + hit.length;
- result += `
${text.substring(hit.position, end)}`;
- prevEnd = end;
- });
- result += text.substring(prevEnd, slice.end);
- return result;
- };
+ 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) {
+ index.push({position, word});
+ startPosition = position + wordLen;
+ }
+ return index;
+ };
- const inputEventFunction = () => {
- 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));
- });
-
- // 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;
+ // Merge hits into slices
+ const mergeIntoSlice = (start, end, index, searchText) => {
+ let item = index[index.length - 1];
+ let {position, word} = item;
+ let hits = [];
+ let searchTextCountInSlice = 0;
+ while (position + word.length <= end && index.length !== 0) {
+ if (word === searchText) {
+ searchTextCountInSlice++;
+ }
+ hits.push({
+ position,
+ length: word.length
});
- });
+ let wordEnd = position + 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;
+ // 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;
+ }
}
- 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 += `
${highlightKeyword(title, slicesOfTitle[0])}`;
- } else {
- resultItem += `${title}`;
- }
-
- slicesOfContent.forEach(slice => {
- resultItem += `${highlightKeyword(content, slice)}...
`;
- });
-
- resultItem += '';
- resultItems.push({
- item: resultItem,
- id : resultItems.length,
- hitCount,
- searchTextCount
- });
}
- });
- }
- if (keywords.length === 1 && keywords[0] === '') {
- resultContent.innerHTML = '
';
- } else if (resultItems.length === 0) {
- resultContent.innerHTML = '
';
- } 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 = '
';
- resultItems.forEach(result => {
- searchResultList += result.item;
- });
- searchResultList += '
';
- resultContent.innerHTML = searchResultList;
- window.pjax && window.pjax.refresh(resultContent);
- }
- };
+ return {
+ hits,
+ start,
+ end,
+ searchTextCount: searchTextCountInSlice
+ };
+ };
- 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;
+ // Highlight title and content
+ const highlightKeyword = (text, slice) => {
+ let result = '';
+ let prevEnd = slice.start;
+ slice.hits.forEach(hit => {
+ result += text.substring(prevEnd, hit.position);
+ let end = hit.position + hit.length;
+ result += `
${text.substring(hit.position, end)}`;
+ prevEnd = end;
});
- // Remove loading animation
- document.getElementById('no-result').innerHTML = '
';
- });
- };
+ result += text.substring(prevEnd, slice.end);
+ return result;
+ };
- if (CONFIG.localsearch.preload) {
- fetchData();
- }
+ const inputEventFunction = () => {
+ 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') {
- if (input) {
- input.addEventListener('input', inputEventFunction);
+ // 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 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 += `
${highlightKeyword(title, slicesOfTitle[0])}`;
+ } else {
+ resultItem += `${title}`;
+ }
+
+ slicesOfContent.forEach(slice => {
+ resultItem += `${highlightKeyword(content, slice)}...
`;
+ });
+
+ resultItem += '';
+ resultItems.push({
+ item: resultItem,
+ id: resultItems.length,
+ hitCount,
+ searchTextCount
+ });
+ }
+ });
+ }
+ if (keywords.length === 1 && keywords[0] === '') {
+ resultContent.innerHTML = '
';
+ } else if (resultItems.length === 0) {
+ resultContent.innerHTML = '
';
+ } 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 = '
';
+ resultItems.forEach(result => {
+ searchResultList += result.item;
+ });
+ searchResultList += '
';
+ 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 = '
';
+ });
+ };
+
+ if (CONFIG.localsearch.preload) {
+ fetchData();
}
- } else {
- document.querySelector('.search-icon').addEventListener('click', inputEventFunction);
- input.addEventListener('keypress', event => {
- if (event.key === 'Enter') {
- inputEventFunction();
- }
+ if (CONFIG.localsearch.trigger === 'auto') {
+ if (input) {
+ input.addEventListener('input', 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
- 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();
+ // 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();
+ }
});
- });
-
- // 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();
- }
- });
});