Skip to content

Commit

Permalink
source code
Browse files Browse the repository at this point in the history
  • Loading branch information
Wu-jiyan authored Oct 25, 2022
1 parent 6ebc86f commit 2b89acc
Show file tree
Hide file tree
Showing 31 changed files with 3,224 additions and 0 deletions.
1,003 changes: 1,003 additions & 0 deletions bitcron-pro-plus/assets/media/css/katex.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions bitcron-pro-plus/assets/media/gridea-search/ejs.min.js

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions bitcron-pro-plus/assets/media/gridea-search/fuse.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

229 changes: 229 additions & 0 deletions bitcron-pro-plus/assets/media/gridea-search/gridea-search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
//获取url参数
function getParam(url, param) {
if (url.indexOf('?') > -1) {
var urlSearch = url.split('?');
var paramList = urlSearch[1].split('&');
for (var i = paramList.length - 1; i >= 0; i--) {
var tep = paramList[i].split('=');
if (tep[0] == param) {
return tep[1];
}
}
}
};

//原生js Ajax 异步GET请求
function ajax(obj) {
var xhr = new XMLHttpRequest();
xhr.open('get', obj.url, true);
xhr.send(null);
xhr.onreadystatechange = function () {
//异步请求:响应状态为4,数据加载完毕
if (xhr.readyState == 4)
callback();
}
function callback() {
if (xhr.status == 200) {
obj.success(xhr.responseText);
} else {
obj.error(xhr.status);
}
}
}

//模糊搜索 https://github.com/krisk/fuse
function fuzzySearch(data, phrase) {
var phrase_len = phrase.length;
var min_len = 4;
var max_len = 32;
//根据搜索的词数决定匹配大小,最小匹配词数不能大于词数,最大匹配词数不能小于词数
if(phrase_len<4){
min_len = phrase_len;
}
if(phrase_len<=0){
min_len = 99999999;
max_len = 99999999;
}
if(phrase_len>32){
max_len = phrase_len;
}

var options = {
shouldSort: true,
includeMatches: true,
threshold: 0.5,// 匹配算法阈值。阈值为0.0需要完全匹配(字母和位置),阈值为1.0将匹配任何内容。
location: 0,// 确定文本中预期找到的模式的大致位置。
distance: 1000,
maxPatternLength: max_len, // 模式的最大长度
minMatchCharLength: min_len, // 模式的最小字符长度
// 搜索标题与内容
keys: [
'title',
'content',
'tags.name'
]
};
var fuse = new Fuse(data, options);
var fuzzyResult = fuse.search(phrase);
return fuzzyResult;
}

//检查缓存是否最新
function checkCache() {
var infosCache = JSON.parse(localStorage.getItem('InfosCache'));
var contentsCache = JSON.parse(localStorage.getItem('ContentsCache'));
if (infosCache && contentsCache) {
var cachedTime = infosCache.utils.now.toString();
var updateTime = document.getElementById('gridea-search-form').getAttribute('data-update');
if (cachedTime === updateTime) {
return true;
}
}
localStorage.removeItem('InfosCache');
localStorage.removeItem('ContentsCache');
return false;
}

//获取博客全文api
function getContents(callback) {
if (checkCache()) {
var contentsCache = JSON.parse(localStorage.getItem('ContentsCache'));
callback(contentsCache);
}
else {
ajax({
url: '/api-content/index.html',
success: function (data) {
callback(JSON.parse(data));
localStorage.setItem('ContentsCache', data);
}
});
}
}

//获取博客信息api
function getInfos(callback) {
if (checkCache()) {
var infosCache = JSON.parse(localStorage.getItem('InfosCache'));
callback(infosCache);
}
else {
ajax({
url: '/api-info/index.html',
success: function (data) {
callback(JSON.parse(data));
localStorage.setItem('InfosCache', data);
}
});
}
}

//根据一段文本调用模糊搜索
function searchBy(phrase, callback) {
var result = '';
var getFuzzyResult = function (data) {
result = fuzzySearch(data.posts, phrase);
callback(result);
}
//根据全文内容获取搜索结果
getContents(getFuzzyResult);
}

//显示无搜索结果
function showNoResult() {
var resultDIV = document.getElementById('gridea-search-result');
var noResult = resultDIV.getElementsByClassName('no-result')[0];
noResult.style.display = 'block';
resultDIV.innerHTML = noResult.outerHTML;
}

//根据URL参数执行搜索
function searchByParam(resultHandler) {
var phrase = getParam(window.location.href, 'q');
if (phrase === '' || typeof (phrase) === 'undefined') {
showNoResult();
} else {
searchBy(decodeURI(phrase), resultHandler);
}
}

//获取搜索结果列表模板的URL
function getTemplateURL() {
var scripts = document.getElementsByTagName('script');
var templateURL = '';
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].type === 'text/ejs') {
templateURL = scripts[i].src;
return templateURL;
}
}
}

//渲染搜索结果列表
function renderResult(searchedInfos) {
if (searchedInfos.posts.length > 0) {
ajax({
url: getTemplateURL(),
success: function (data) {
var resultDIV = document.getElementById('gridea-search-result');
resultDIV.innerHTML = ejs.compile(data)(searchedInfos);
}
});
} else {
showNoResult();
}
}

//搜索结果关键字高亮
function keywordsHighlight(searchedContent) {
var searchedPostContent = searchedContent.item.content;//搜索结果内容预览
var preview = '';
for (var i = 0; i < searchedContent.matches.length; i++) {
if (searchedContent.matches[i].key === 'content') {//如果匹配到文章内容,截取关键字
var indices = searchedContent.matches[i].indices[0];
var beforeKeyword = searchedPostContent.substring(indices[0] - 10, indices[0]);//关键字前20字
var keyword = searchedPostContent.substring(indices[0], indices[1] + 1);//关键字
var afterKeyword = searchedPostContent.substring(indices[1] + 1, indices[1] + 70);//关键字后80字
preview = beforeKeyword + '<span class="searched-keyword">'
+ keyword + '</span>' + afterKeyword;
} else {//没有匹配到文章内容,则是标题
preview = searchedPostContent.substring(0, 80);
}
}
return preview + '...';
}

//循环匹配搜索到的内容与展示信息
function getResult(infos, searchedContents) {
var searchedInfos = JSON.parse(JSON.stringify(infos));//对象深拷贝
searchedInfos.posts = [];
for (var i = 0; i < infos.posts.length; i++) {
for (var j = 0; j < searchedContents.length; j++) {
if (searchedContents[j].item.link === infos.posts[i].link) {
infos.posts[i].searchedPreview = keywordsHighlight(searchedContents[j]);//预览关键字高亮
infos.posts[i].content = searchedContents[j].item.content;//content注入
searchedInfos.posts.push(infos.posts[i]);//push到所需结果中
}
}
}
return searchedInfos;
}

//主方法
function grideaSearch() {
//搜索结果回调
var resultHandler = function (searchedContents) {
getInfos(function (infos) {
//console.log(infos);
//console.log(searchedContents);
var searchedInfos = getResult(infos, searchedContents);
renderResult(searchedInfos);
});
}
searchByParam(resultHandler);
}

//页面加载完执行
window.onload = function () {
grideaSearch();
}
22 changes: 22 additions & 0 deletions bitcron-pro-plus/assets/media/gridea-search/result-template.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<div class="post-container">
<% posts.forEach(function(post,seq) { %>
<article class="post">
<a href="<%= post.link %>">
<h2 class="post-title"><%= post.title %></h2>
</a>
<div class="post-info">
<time class="post-time">
· <%= post.dateFormat %> ·
</time>
<% post.tags.forEach(function(tag) { %>
<a href="<%= tag.link %>" class="post-tag">
# <%= tag.name %>
</a>
<% }); %>
</div>
<div class="post-abstract" style="word-break: break-all">
<%- post.searchedPreview %>
</div>
</article>
<% }); %>
</div>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added bitcron-pro-plus/assets/media/images/scroll.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2b89acc

Please sign in to comment.