hexo-theme-stellar 1.17.0 → 1.17.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  ######## Stellar info ########
2
2
  stellar:
3
- version: '1.17.0'
3
+ version: '1.17.2'
4
4
  homepage: 'https://xaoxuu.com/wiki/stellar/'
5
5
  repo: 'https://github.com/xaoxuu/hexo-theme-stellar'
6
6
  cdn_css: # Use cdn links instead of /css/main.css
@@ -25,10 +25,22 @@ sidebar:
25
25
  # about: '[关于](/about/)'
26
26
  # Sidebar widgets
27
27
  widgets:
28
- index: welcome, recent, search, timeline # for home/wiki/categories/tags/archives/404 pages
29
- page: welcome, toc # for pages using 'layout:page'
28
+ #### 自动生成的页面 ####
29
+ # 主页
30
+ home: search, welcome, recent, timeline # for home
31
+ # 博客索引页
32
+ blog_index: search_blog, recent, timeline # for categories/tags/archives
33
+ # 文档索引页
34
+ wiki_index: search_docs, recent, timeline # for wiki
35
+ # 其它(404)
36
+ others: search, welcome, recent, timeline # for 404 and ...
37
+ #### 手动创建的页面 ####
38
+ # 文章内页
30
39
  post: toc, ghrepo, search, ghissues # for pages using 'layout:post'
40
+ # 文档内页
31
41
  wiki: search, ghrepo, toc, ghissues, related # for pages using 'layout:wiki'
42
+ # 其它 layout:page 的页面
43
+ page: welcome, toc, search # for custom pages using 'layout:page'
32
44
 
33
45
  ######## Index ########
34
46
  post-index: # 近期发布 分类 标签 归档 and ...
@@ -62,8 +74,12 @@ article:
62
74
 
63
75
 
64
76
  search:
65
- service: local_search # hexo, todo...
66
- local_search: # npm i hexo-generator-search
77
+ service: local_search # local_search, todo...
78
+ local_search: # front-matter 中设置 indexing:false 来避免被搜索索引
79
+ field: all # post, page, all
80
+ path: /search.json # 搜索文件存放位置
81
+ content: true # 是否搜索内容
82
+ codeblock: true # 是否搜索代码块(需要content: true)
67
83
 
68
84
 
69
85
  ######## Comments ########
package/_data/widgets.yml CHANGED
@@ -5,6 +5,17 @@
5
5
  search:
6
6
  layout: search
7
7
  filter: auto # auto or 'path'
8
+
9
+
10
+ search_blog:
11
+ layout: search
12
+ filter: /blog/ # auto or 'path'
13
+ placeholder: 文章搜索
14
+
15
+ search_docs:
16
+ layout: search
17
+ filter: /wiki/ # auto or 'path'
18
+ placeholder: 文档搜索
8
19
 
9
20
  ghrepo:
10
21
  layout: ghrepo
@@ -70,9 +70,9 @@ function layoutDiv() {
70
70
  } else if (item == 'weibo') {
71
71
  el += ' href="https://service.weibo.com/share/share.php?url=' + page.permalink;
72
72
  el += '&title=' + (page.seo_title || (page.title + ' - ' + config.title));
73
- if (page.latyout == 'post' && page.cover) {
73
+ if (page.layout == 'post' && page.cover) {
74
74
  el += '&pics=' + page.cover;
75
- } else if (page.latyout == 'wiki' && page.logo && page.logo.src) {
75
+ } else if (page.layout == 'wiki' && page.logo && page.logo.src) {
76
76
  el += '&pics=' + page.logo.src;
77
77
  }
78
78
  el += '&summary=' + truncate(page.description || strip_html(page.excerpt || page.content), {length: 120});
@@ -111,7 +111,7 @@
111
111
  stellar.search = {};
112
112
  stellar.search.service = '<%- theme.search.service %>';
113
113
  if (stellar.search.service == 'local_search') {
114
- let service_obj = Object.assign({}, <%- JSON.stringify(config.search) %>);
114
+ let service_obj = Object.assign({}, <%- JSON.stringify(theme.search.local_search) %>);
115
115
  stellar.search[stellar.search.service] = service_obj;
116
116
  }
117
117
  }
@@ -14,8 +14,14 @@ if (page.sidebar == undefined) {
14
14
  } else {
15
15
  page.sidebar = theme.sidebar.widgets.wiki;
16
16
  }
17
- } else if (is_home() || ['categories', 'tags', 'archives', 'index', '404', undefined].includes(page.layout)) {
18
- page.sidebar = theme.sidebar.widgets.index;
17
+ } else if (is_home()) {
18
+ page.sidebar = theme.sidebar.widgets.home;
19
+ } else if (is_category() || is_tag() || is_archive() || ['categories', 'tags', 'archives'].includes(page.layout)) {
20
+ page.sidebar = theme.sidebar.widgets.blog_index;
21
+ } else if (['wiki_index'].includes(page.layout)) {
22
+ page.sidebar = theme.sidebar.widgets.wiki_index;
23
+ } else if (['404', undefined].includes(page.layout)) {
24
+ page.sidebar = theme.sidebar.widgets.others;
19
25
  } else if (page.layout == 'page') {
20
26
  page.sidebar = theme.sidebar.widgets.page;
21
27
  } else {
@@ -83,7 +89,7 @@ function layoutWidgets() {
83
89
  if (name in theme.data.widgets) {
84
90
  Object.assign(widget, theme.data.widgets[name])
85
91
  }
86
- if (typeof w == 'object' && w.override) {
92
+ if (typeof w == 'object' && (w.override || w.layout)) {
87
93
  Object.assign(widget, w)
88
94
  }
89
95
  if (widget && widget.layout) {
@@ -5,15 +5,23 @@ function layoutDiv() {
5
5
  el += '<div class="search-wrapper" id="search">'
6
6
  el += '<form class="search-form">'
7
7
  var filter = ''
8
- if (item.filter == 'auto' && page.layout == 'wiki') {
9
- let matches = page.path.match(/(.*?)\/(.*?)\//i)
10
- if (matches?.length > 0) {
11
- filter = matches[0]
8
+ if (item.filter == 'auto') {
9
+ if (page.layout == 'wiki') {
10
+ let matches = page.path.match(/(.*?)\/(.*?)\//i)
11
+ if (matches?.length > 0) {
12
+ filter = matches[0]
13
+ }
14
+ }
15
+ } else {
16
+ if (item.filter?.length > 0) {
17
+ filter = item.filter
12
18
  }
13
19
  }
14
20
  el += '<input type="text" class="search-input" id="search-input"'
15
21
  if (filter.length > 0) {
16
- filter = '/' + filter
22
+ if (!filter.startsWith('/')) {
23
+ filter = '/' + filter
24
+ }
17
25
  el += ' data-filter="' + filter + '"'
18
26
  el += ' placeholder="' + (item.placeholder || __('search.search_in', filter)) + '">'
19
27
  } else {
package/layout/index.ejs CHANGED
@@ -1,6 +1,6 @@
1
1
  <%
2
2
  if (page.menu_id == undefined) {
3
- if (page.layout === 'index' && page.wiki) {
3
+ if (page.layout === 'wiki_index' && page.wiki) {
4
4
  page.menu_id = 'wiki';
5
5
  } else {
6
6
  page.menu_id = 'post';
package/layout/wiki.ejs CHANGED
@@ -3,7 +3,7 @@ if (page.menu_id == undefined) {
3
3
  page.menu_id = 'wiki';
4
4
  }
5
5
  if (page.layout == undefined) {
6
- page.layout = 'index';
6
+ page.layout = 'wiki_index';
7
7
  }
8
8
  if (page.title == undefined) {
9
9
  if (page.tagName) {
@@ -21,7 +21,7 @@ function layoutTitle() {
21
21
  }
22
22
  }
23
23
  %>
24
- <% if (page.layout === 'index') { %>
24
+ <% if (page.layout === 'wiki_index') { %>
25
25
  <%- partial('index') %>
26
26
  <% } else { %>
27
27
  <%
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-stellar",
3
- "version": "1.17.0",
3
+ "version": "1.17.2",
4
4
  "description": "Elegant and powerful theme for Hexo.",
5
5
  "main": "package.json",
6
6
  "scripts": {
@@ -0,0 +1,107 @@
1
+ /**
2
+ * https://github.com/wzpan/hexo-generator-search
3
+ */
4
+
5
+ hexo.extend.generator.register('search_json_generator', function (locals) {
6
+ if (this.theme.config.search.service != 'local_search') { return {} }
7
+ const { root } = this.config
8
+ const { local_search: cfg } = this.theme.config.search
9
+ cfg.sort = '-date'
10
+ cfg.field = cfg.field?.trim()
11
+
12
+ var posts, pages
13
+ if (cfg.field == 'post') {
14
+ posts = locals.posts?.filter(p => p.content?.length > 0).sort(cfg.sort)
15
+ } else if (cfg.field == 'page') {
16
+ pages = locals.pages?.filter(p => p.content?.length > 0)
17
+ } else {
18
+ posts = locals.posts?.filter(p => p.content?.length > 0).sort(cfg.sort)
19
+ pages = locals.pages?.filter(p => p.content?.length > 0)
20
+ }
21
+
22
+ var res = new Array()
23
+
24
+ function generateJson(post) {
25
+ var temp_post = new Object()
26
+ if (post.title) {
27
+ temp_post.title = post.title.trim()
28
+ }
29
+ if (post.path) {
30
+ temp_post.path = root + post.path
31
+ }
32
+ if (cfg.content != false && post._content) {
33
+ var content = post._content.trim()
34
+ // 过滤掉标签和注释
35
+ if (content.includes('{%')) {
36
+ // 需要保留内容的的标签
37
+ content = content.replace(/{%\s*mark\s*(.*?)\s*%}/g, '$1')
38
+ content = content.replace(/{%\s*folding\s*(.*?)\s*%}/g, '$1')
39
+ content = content.replace(/{%\s*copy\s*(.*?)\s*%}/g, '$1')
40
+ content = content.replace(/{%\s*note\s*(.*?)\s*%}/g, '$1')
41
+ content = content.replace(/{%\s*kbd\s*(.*?)\s*%}/g, '$1')
42
+ content = content.replace(/{%\s*emp\s*(.*?)\s*%}/g, '$1')
43
+ content = content.replace(/{%\s*wavy\s*(.*?)\s*%}/g, '$1')
44
+ content = content.replace(/{%\s*sub\s*(.*?)\s*%}/g, '$1')
45
+ content = content.replace(/{%\s*sup\s*(.*?)\s*%}/g, '$1')
46
+ content = content.replace(/<!--\s*folder(.*?)\s*-->/g, '$1')
47
+ content = content.replace(/<!--\s*tab(.*?)\s*-->/g, '$1')
48
+ content = content.replace(/<!--\s*node(.*?)\s*-->/g, '$1')
49
+ // 不保留内容的标签
50
+ content = content.replace(/{%\s*(.*?)\s*%}/g, '')
51
+ // 注释
52
+ content = content.replace(/<!--\s*(.*?)\s*-->/g, '')
53
+ // ## 标题
54
+ content = content.replace(/[#]{2,} /g, '')
55
+ // 部分HTML标签
56
+ content = content.replace(/<iframe[\s|\S]+iframe>/g, '')
57
+ // 图片
58
+ content = content.replace(/\!\[(.*?)\]\((.*?)\)/g, '')
59
+ // 链接
60
+ content = content.replace(/\[(.*?)\]\((.*?)\)/g, '$1')
61
+ // 过滤代码块
62
+ if (cfg.codeblock == false) {
63
+ content = content.replace(/```([^`]+)```/g, '')
64
+ }
65
+ // 多个连续空格换成单个空格
66
+ content = content.replace(/[\s]{2,} /g, ' ')
67
+ // 特殊字符
68
+ content = content.replace(/[\r|\n]+/g, '')
69
+ }
70
+ temp_post.content = content.trim()
71
+ }
72
+ if (post.tags && post.tags.length > 0) {
73
+ var tags = []
74
+ post.tags.forEach(function (tag) {
75
+ tags.push(tag.name)
76
+ })
77
+ temp_post.tags = tags
78
+ }
79
+ if (post.categories && post.categories.length > 0) {
80
+ var categories = []
81
+ post.categories.forEach(function (cate) {
82
+ categories.push(cate.name)
83
+ })
84
+ temp_post.categories = categories
85
+ }
86
+ return temp_post
87
+ }
88
+
89
+ if (posts) {
90
+ posts.each(function(post) {
91
+ if (post.indexing == false) return
92
+ let temp_post = generateJson(post)
93
+ res.push(temp_post)
94
+ })
95
+ }
96
+ if (pages) {
97
+ pages.each(function(page) {
98
+ if (page.indexing == false) return
99
+ let temp_post = generateJson(page)
100
+ res.push(temp_post)
101
+ })
102
+ }
103
+ return {
104
+ path: cfg.path,
105
+ data: JSON.stringify(res)
106
+ }
107
+ })
@@ -9,7 +9,7 @@
9
9
  border-radius: $border-card
10
10
  overflow: hidden
11
11
  box-shadow: 0 2px 8px 0px rgba(0, 0, 0, 0.03)
12
- a.page-number
12
+ .page-number
13
13
  padding: 4px 8px
14
14
  border-radius: 8px
15
15
  background: var(--block)
@@ -17,7 +17,7 @@
17
17
  width: 1rem
18
18
  height: 1rem
19
19
  .about-header
20
- display flex
20
+ display: flex
21
21
  justify-content: center
22
22
  flex-wrap: wrap
23
23
  margin: 1.5rem 0
@@ -44,10 +44,8 @@
44
44
  .search-result-title
45
45
  color: $color-hover
46
46
  .search-result-title
47
- background-image: none
48
47
  color: var(--text-p1)
49
- text-transform: capitalize
50
- font-weight: bold
48
+ font-weight: 700
51
49
  line-height: 1.2
52
50
 
53
51
  .search-result-content
package/source/js/main.js CHANGED
@@ -209,7 +209,7 @@ if (stellar.plugins.lazyload) {
209
209
  false
210
210
  );
211
211
  document.addEventListener('DOMContentLoaded', function () {
212
- lazyLoadInstance.update();
212
+ window.lazyLoadInstance?.update();
213
213
  });
214
214
  }
215
215
 
@@ -309,7 +309,7 @@ if (stellar.search.service) {
309
309
  var $inputArea = $("input#search-input");
310
310
  var $resultArea = document.querySelector("div#search-result");
311
311
  $inputArea.focus(function() {
312
- var path = stellar.search[stellar.search.service]?.path || '/search.xml';
312
+ var path = stellar.search[stellar.search.service]?.path || '/search.json';
313
313
  if (!path.startsWith('/')) {
314
314
  path = '/' + path;
315
315
  }
@@ -24,20 +24,6 @@
24
24
  /*exported searchFunc*/
25
25
  var searchFunc = function(path, filter, searchId, contentId) {
26
26
 
27
- function stripHtml(html) {
28
- html = html.replace(/<style([\s\S]*?)<\/style>/gi, "");
29
- html = html.replace(/<script([\s\S]*?)<\/script>/gi, "");
30
- html = html.replace(/<figure([\s\S]*?)<\/figure>/gi, "");
31
- html = html.replace(/<\/div>/ig, "\n");
32
- html = html.replace(/<\/li>/ig, "\n");
33
- html = html.replace(/<li>/ig, " * ");
34
- html = html.replace(/<\/ul>/ig, "\n");
35
- html = html.replace(/<\/p>/ig, "\n");
36
- html = html.replace(/<br\s*[\/]?>/gi, "\n");
37
- html = html.replace(/<[^>]+>/ig, "");
38
- return html;
39
- }
40
-
41
27
  function getAllCombinations(keywords) {
42
28
  var i, j, result = [];
43
29
 
@@ -51,17 +37,9 @@ var searchFunc = function(path, filter, searchId, contentId) {
51
37
 
52
38
  $.ajax({
53
39
  url: path,
54
- dataType: "xml",
55
- success: function(xmlResponse) {
56
- // get the contents from search data
57
- var datas = $("entry", xmlResponse).map(function() {
58
- return {
59
- title: $("title", this).text(),
60
- content: $("content", this).text(),
61
- url: $("link", this).attr("href")
62
- };
63
- }).get();
64
-
40
+ dataType: "json",
41
+ success: function(jsonResponse) {
42
+ var datas = jsonResponse;
65
43
  var $input = document.getElementById(searchId);
66
44
  if (!$input) { return; }
67
45
  var $resultContent = document.getElementById(contentId);
@@ -76,18 +54,17 @@ var searchFunc = function(path, filter, searchId, contentId) {
76
54
  }
77
55
  // perform local searching
78
56
  datas.forEach(function(data) {
57
+ if (!data.title?.trim().length) { return }
58
+ if (!data.content?.trim().length) { return }
79
59
  var matches = 0;
80
- if (!data.title || data.title.trim() === "") {
81
- return;
82
- }
83
- if (filter && !data.url.includes(filter)) {
60
+ if (filter && !data.path.includes(filter)) {
84
61
  return;
85
62
  }
86
- var dataTitle = data.title.trim().toLowerCase();
63
+ var dataTitle = data.title.trim();
87
64
  var dataTitleLowerCase = dataTitle.toLowerCase();
88
- var dataContent = stripHtml(data.content.trim());
65
+ var dataContent = data.content;
89
66
  var dataContentLowerCase = dataContent.toLowerCase();
90
- var dataUrl = data.url;
67
+ var dataUrl = data.path;
91
68
  var indexTitle = -1;
92
69
  var indexContent = -1;
93
70
  var firstOccur = -1;