hexo-theme-stellar 1.31.0 → 1.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_config.yml +15 -13
- package/_data/icons.yml +3 -3
- package/layout/_partial/comments/artalk/script.ejs +1 -2
- package/layout/_partial/comments/layout.ejs +1 -1
- package/layout/_partial/head.ejs +15 -3
- package/layout/_partial/scripts/theme.ejs +3 -3
- package/layout/_partial/sidebar/index_leftbar.ejs +9 -9
- package/layout/index.ejs +3 -1
- package/layout/layout.ejs +3 -2
- package/package.json +4 -2
- package/scripts/events/index.js +39 -2
- package/scripts/events/lib/fix_image_tags.js +44 -0
- package/scripts/events/lib/get_image_ratios.js +110 -0
- package/scripts/events/lib/version-check.js +2 -0
- package/scripts/helpers/json_ld.js +5 -1
- package/scripts/tags/index.js +1 -1
- package/scripts/tags/lib/{quote.js → blockquote.js} +5 -5
- package/scripts/tags/lib/image.js +16 -6
- package/scripts/tags/lib/navbar.js +2 -2
- package/scripts/tags/lib/timeline.js +1 -1
- package/scripts/tags/lib/video.js +2 -2
- package/source/css/_common/base.styl +16 -6
- package/source/css/_common/canonical.styl +1 -1
- package/source/css/_common/highlight.styl +5 -2
- package/source/css/_components/layout.styl +11 -10
- package/source/css/_components/list.styl +3 -0
- package/source/css/_components/main.styl +1 -1
- package/source/css/_components/md.styl +4 -2
- package/source/css/_components/pages/archives.styl +2 -2
- package/source/css/_components/pages/article-story.styl +40 -32
- package/source/css/_components/pages/article-tech.styl +1 -1
- package/source/css/_components/pages/notebook.styl +1 -1
- package/source/css/_components/partial/article-banner.styl +4 -1
- package/source/css/_components/partial/footer.styl +1 -1
- package/source/css/_components/partial/navbar.styl +2 -1
- package/source/css/_components/sidebar/nav-area.styl +1 -1
- package/source/css/_components/sidebar/search.styl +44 -21
- package/source/css/_components/sidebar/sidebar.styl +9 -5
- package/source/css/_components/tag-plugins/banner.styl +1 -1
- package/source/css/_components/tag-plugins/button.styl +3 -4
- package/source/css/_components/tag-plugins/copy.styl +12 -8
- package/source/css/_components/tag-plugins/friends.styl +1 -1
- package/source/css/_components/tag-plugins/gallery.styl +6 -0
- package/source/css/_components/tag-plugins/image.styl +10 -0
- package/source/css/_components/tag-plugins/navbar.styl +18 -8
- package/source/css/_components/tag-plugins/note.styl +0 -3
- package/source/css/_components/tag-plugins/override.styl +0 -5
- package/source/css/_components/tag-plugins/quot.styl +2 -2
- package/source/css/_components/tag-plugins/quote.styl +1 -1
- package/source/css/_components/tag-plugins/tabs.styl +4 -3
- package/source/css/_components/tag-plugins/timeline.styl +2 -2
- package/source/css/_components/tag-plugins/toc.styl +1 -1
- package/source/css/_components/widgets/list.styl +1 -1
- package/source/css/_components/widgets/markdown.styl +0 -7
- package/source/css/_components/widgets/toc.styl +7 -5
- package/source/css/_components/widgets/widgets.styl +0 -5
- package/source/css/_custom.styl +5 -7
- package/source/css/_defines/const.styl +1 -1
- package/source/css/_defines/func.styl +9 -5
- package/source/css/_defines/theme.styl +4 -15
- package/source/css/_plugins/comments/artalk.styl +114 -2
- package/source/css/_plugins/comments/twikoo.styl +3 -3
- package/source/css/_plugins/index.styl +5 -5
- package/source/css/_plugins/lazyload.styl +49 -2
- package/source/js/search/local-search.js +163 -151
- package/source/js/services/artalk_latest_comment.js +1 -1
- package/layout/_partial/widgets/search.ejs +0 -0
|
@@ -1,170 +1,182 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// Joseph Pan <http://github.com/wzpan>
|
|
5
|
-
// Shuhao Mao <http://github.com/maoshuhao>
|
|
6
|
-
// This library is free software; you can redistribute it and/or modify
|
|
7
|
-
// it under the terms of the GNU Lesser General Public License as
|
|
8
|
-
// published by the Free Software Foundation; either version 2.1 of the
|
|
9
|
-
// License, or (at your option) any later version.
|
|
10
|
-
//
|
|
11
|
-
// This library is distributed in the hope that it will be useful, but
|
|
12
|
-
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14
|
-
// Lesser General Public License for more details.
|
|
15
|
-
//
|
|
16
|
-
// You should have received a copy of the GNU Lesser General Public
|
|
17
|
-
// License along with this library; if not, write to the Free Software
|
|
18
|
-
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
19
|
-
// 02110-1301 USA
|
|
20
|
-
//
|
|
21
|
-
// Modified by:
|
|
22
|
-
// Pieter Robberechts <http://github.com/probberechts>
|
|
23
|
-
|
|
24
|
-
/*exported searchFunc*/
|
|
1
|
+
var searchCache = null;
|
|
2
|
+
var searchCacheKey = 'search_cache_v1';
|
|
3
|
+
|
|
25
4
|
var searchFunc = function(path, filter, wrapperId, searchId, contentId) {
|
|
26
5
|
|
|
27
6
|
function getAllCombinations(keywords) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
for (i = 0; i < keywords.length; i++) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
7
|
+
const result = [];
|
|
8
|
+
const maxLen = 3; // 组合最大长度
|
|
9
|
+
for (let i = 0; i < keywords.length; i++) {
|
|
10
|
+
for (let j = i + 1; j <= Math.min(i + maxLen, keywords.length); j++) {
|
|
11
|
+
result.push(keywords.slice(i, j).join(" "));
|
|
12
|
+
}
|
|
34
13
|
}
|
|
35
14
|
return result;
|
|
36
15
|
}
|
|
37
16
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
$wrapper.setAttribute('searching', '
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
// show search results
|
|
89
|
-
if (matches > 0) {
|
|
90
|
-
var searchResult = {};
|
|
91
|
-
searchResult.rank = matches;
|
|
92
|
-
searchResult.str = "<li><a href='"+ dataUrl +"'><span class='search-result-title'>"+ dataTitle +"</span>";
|
|
93
|
-
if (firstOccur >= 0) {
|
|
94
|
-
// cut out 100 characters
|
|
95
|
-
var start = firstOccur - 20;
|
|
96
|
-
var end = firstOccur + 80;
|
|
97
|
-
|
|
98
|
-
if(start < 0){
|
|
99
|
-
start = 0;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if(start == 0){
|
|
103
|
-
end = 100;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if(end > dataContent.length){
|
|
107
|
-
end = dataContent.length;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
var matchContent = dataContent.substring(start, end);
|
|
111
|
-
|
|
112
|
-
// highlight all keywords
|
|
113
|
-
var regS = new RegExp(keywords.join("|"), "gi");
|
|
114
|
-
matchContent = matchContent.replace(regS, function(keyword) {
|
|
115
|
-
return "<span class=\"search-keyword\">"+keyword+"</span>";
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
searchResult.str += "<p class=\"search-result-content\">" + matchContent +"...</p>";
|
|
119
|
-
}
|
|
120
|
-
searchResult.str += "</a></li>";
|
|
121
|
-
resultList.push(searchResult);
|
|
17
|
+
function escapeRegExp(string) {
|
|
18
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function initSearch(datas) {
|
|
22
|
+
var $input = document.getElementById(searchId);
|
|
23
|
+
if (!$input) { return; }
|
|
24
|
+
if ($input._searchInitialized) return; // 防止重复绑定
|
|
25
|
+
$input._searchInitialized = true;
|
|
26
|
+
|
|
27
|
+
var $resultContent = document.getElementById(contentId);
|
|
28
|
+
var $wrapper = document.getElementById(wrapperId);
|
|
29
|
+
|
|
30
|
+
$input.addEventListener("input", function() {
|
|
31
|
+
var resultList = [];
|
|
32
|
+
var keywords = getAllCombinations(this.value.trim().toLowerCase().split(" "))
|
|
33
|
+
.sort(function(a,b) { return b.split(" ").length - a.split(" ").length; });
|
|
34
|
+
$resultContent.innerHTML = "";
|
|
35
|
+
if (this.value.trim().length <= 0) {
|
|
36
|
+
$wrapper.setAttribute('searching', 'false');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
$wrapper.setAttribute('searching', 'true');
|
|
40
|
+
|
|
41
|
+
datas.forEach(function(data) {
|
|
42
|
+
if (!data.content?.trim().length) return;
|
|
43
|
+
if (filter && !data.path.includes(filter)) return;
|
|
44
|
+
|
|
45
|
+
var matches = 0;
|
|
46
|
+
var dataTitle = data.title?.trim() || 'Untitled';
|
|
47
|
+
var dataTitleLowerCase = dataTitle.toLowerCase();
|
|
48
|
+
var dataContent = data.content;
|
|
49
|
+
var dataContentLowerCase = dataContent.toLowerCase();
|
|
50
|
+
var dataUrl = data.path.startsWith('//') ? data.path.slice(1) : data.path;
|
|
51
|
+
|
|
52
|
+
var indexTitle = -1;
|
|
53
|
+
var indexContent = -1;
|
|
54
|
+
var firstOccur = -1;
|
|
55
|
+
|
|
56
|
+
keywords.forEach(function(keyword) {
|
|
57
|
+
indexTitle = dataTitleLowerCase.indexOf(keyword);
|
|
58
|
+
indexContent = dataContentLowerCase.indexOf(keyword);
|
|
59
|
+
if (indexTitle >= 0 || indexContent >= 0) {
|
|
60
|
+
matches += 1;
|
|
61
|
+
if (indexContent < 0) indexContent = 0;
|
|
62
|
+
if (firstOccur < 0) firstOccur = indexContent;
|
|
122
63
|
}
|
|
123
64
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
65
|
+
|
|
66
|
+
if (matches > 0) {
|
|
67
|
+
const li = document.createElement('li');
|
|
68
|
+
const a = document.createElement('a');
|
|
69
|
+
a.href = dataUrl;
|
|
70
|
+
|
|
71
|
+
const titleSpan = document.createElement('span');
|
|
72
|
+
titleSpan.className = 'search-result-title';
|
|
73
|
+
titleSpan.textContent = dataTitle;
|
|
74
|
+
a.appendChild(titleSpan);
|
|
75
|
+
|
|
76
|
+
if (firstOccur >= 0) {
|
|
77
|
+
var start = Math.max(0, firstOccur - 20);
|
|
78
|
+
var end = Math.min(dataContent.length, firstOccur + 80);
|
|
79
|
+
if (start === 0) end = 100;
|
|
80
|
+
var matchContent = dataContent.substring(start, end);
|
|
81
|
+
|
|
82
|
+
var regS = new RegExp(keywords.map(escapeRegExp).join("|"), "gi");
|
|
83
|
+
matchContent = matchContent.replace(regS, function(keyword) {
|
|
84
|
+
return "<span class=\"search-keyword\">" + keyword + "</span>";
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const para = document.createElement('p');
|
|
88
|
+
para.className = 'search-result-content';
|
|
89
|
+
para.innerHTML = matchContent + '...';
|
|
90
|
+
a.appendChild(para);
|
|
131
91
|
}
|
|
132
|
-
|
|
133
|
-
|
|
92
|
+
|
|
93
|
+
li.appendChild(a);
|
|
94
|
+
resultList.push({ rank: matches, element: li });
|
|
134
95
|
}
|
|
135
96
|
});
|
|
136
|
-
|
|
137
|
-
|
|
97
|
+
|
|
98
|
+
if (resultList.length) {
|
|
99
|
+
resultList.sort(function(a, b) {
|
|
100
|
+
return b.rank - a.rank;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const ul = document.createElement('ul');
|
|
104
|
+
ul.className = 'search-result-list';
|
|
105
|
+
resultList.forEach(function(item) {
|
|
106
|
+
ul.appendChild(item.element);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
$resultContent.innerHTML = '';
|
|
110
|
+
$resultContent.appendChild(ul);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!searchCache) {
|
|
116
|
+
// 数据还没准备好,延迟初始化
|
|
117
|
+
const timer = setInterval(() => {
|
|
118
|
+
if (searchCache) {
|
|
119
|
+
clearInterval(timer);
|
|
120
|
+
initSearch(searchCache);
|
|
121
|
+
}
|
|
122
|
+
}, 100);
|
|
123
|
+
} else {
|
|
124
|
+
initSearch(searchCache);
|
|
125
|
+
}
|
|
138
126
|
};
|
|
139
127
|
|
|
140
128
|
utils.jq(() => {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
129
|
+
(function preloadSearchData() {
|
|
130
|
+
var path = ctx.search.path;
|
|
131
|
+
if (path.startsWith('/')) {
|
|
132
|
+
path = path.substring(1);
|
|
144
133
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
path = ctx.root + path;
|
|
152
|
-
const filter = $inputArea.attr('data-filter') || '';
|
|
153
|
-
searchFunc(path, filter, 'search-wrapper', 'search-input', 'search-result');
|
|
154
|
-
});
|
|
155
|
-
$inputArea.keydown(function(e) {
|
|
156
|
-
if (e.which == 13) {
|
|
157
|
-
e.preventDefault();
|
|
134
|
+
path = ctx.root + path;
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
var cached = localStorage.getItem(searchCacheKey);
|
|
138
|
+
if (cached) {
|
|
139
|
+
searchCache = JSON.parse(cached);
|
|
158
140
|
}
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
141
|
+
} catch (e) {
|
|
142
|
+
console.warn('搜索缓存解析失败', e);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fetch(path)
|
|
146
|
+
.then(res => res.json())
|
|
147
|
+
.then(json => {
|
|
148
|
+
searchCache = json;
|
|
149
|
+
try {
|
|
150
|
+
localStorage.setItem(searchCacheKey, JSON.stringify(json));
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.warn('搜索缓存写入失败', e);
|
|
166
153
|
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
154
|
+
});
|
|
155
|
+
})();
|
|
156
|
+
|
|
157
|
+
var $inputArea = $("input#search-input");
|
|
158
|
+
if ($inputArea.length == 0) return;
|
|
159
|
+
var $resultArea = document.querySelector("div#search-result");
|
|
160
|
+
|
|
161
|
+
$inputArea.focus(function() {
|
|
162
|
+
var path = ctx.search.path;
|
|
163
|
+
if (path.startsWith('/')) {
|
|
164
|
+
path = path.substring(1);
|
|
165
|
+
}
|
|
166
|
+
path = ctx.root + path;
|
|
167
|
+
const filter = $inputArea.attr('data-filter') || '';
|
|
168
|
+
searchFunc(path, filter, 'search-wrapper', 'search-input', 'search-result');
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
$inputArea.keydown(function(e) {
|
|
172
|
+
if (e.which == 13) {
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const observer = new MutationObserver(function(mutationsList) {
|
|
178
|
+
const hasResults = $resultArea.querySelector(".search-result-list li");
|
|
179
|
+
$('.search-wrapper').toggleClass('noresult', !hasResults);
|
|
170
180
|
});
|
|
181
|
+
observer.observe($resultArea, { childList: true, subtree: true });
|
|
182
|
+
});
|
|
@@ -10,7 +10,7 @@ utils.jq(() => {
|
|
|
10
10
|
continue;
|
|
11
11
|
}
|
|
12
12
|
utils.request(el, api, async resp => {
|
|
13
|
-
|
|
13
|
+
var data = await resp.json();
|
|
14
14
|
data = data.data || [];
|
|
15
15
|
data.forEach((item, i) => {
|
|
16
16
|
var cell = '<div class="timenode" index="' + i + '">';
|
|
File without changes
|