hexo-theme-shokax 0.3.13 → 0.4.0-alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. package/_config.yml +11 -5
  2. package/layout/_mixin/comment.pug +4 -4
  3. package/package.json +4 -4
  4. package/scripts/filters/locals.d.ts +1 -0
  5. package/scripts/filters/locals.ts +59 -0
  6. package/scripts/filters/post.d.ts +0 -0
  7. package/scripts/filters/post.ts +6 -0
  8. package/scripts/generaters/archive.d.ts +1 -0
  9. package/scripts/generaters/archive.ts +144 -0
  10. package/scripts/generaters/config.d.ts +1 -0
  11. package/scripts/generaters/config.ts +52 -0
  12. package/scripts/generaters/images.d.ts +1 -0
  13. package/scripts/generaters/images.ts +26 -0
  14. package/scripts/generaters/index.d.ts +1 -0
  15. package/scripts/generaters/index.ts +110 -0
  16. package/scripts/generaters/pages.d.ts +0 -0
  17. package/scripts/generaters/pages.ts +16 -0
  18. package/scripts/generaters/script.d.ts +1 -0
  19. package/scripts/generaters/script.js +22 -6
  20. package/scripts/generaters/script.ts +110 -0
  21. package/scripts/helpers/asset.d.ts +1 -0
  22. package/scripts/helpers/asset.ts +158 -0
  23. package/scripts/helpers/engine.d.ts +1 -0
  24. package/scripts/helpers/engine.ts +171 -0
  25. package/scripts/helpers/list_categories.d.ts +1 -0
  26. package/scripts/helpers/list_categories.ts +104 -0
  27. package/scripts/helpers/summary_ai.d.ts +1 -0
  28. package/scripts/helpers/summary_ai.ts +100 -0
  29. package/scripts/helpers/symbols_count_time.d.ts +1 -0
  30. package/scripts/helpers/symbols_count_time.ts +76 -0
  31. package/scripts/plugin/check.d.ts +1 -0
  32. package/scripts/plugin/check.ts +35 -0
  33. package/scripts/plugin/index.d.ts +6 -0
  34. package/scripts/plugin/index.ts +52 -0
  35. package/scripts/plugin/lib/injects-point.d.ts +5 -0
  36. package/scripts/plugin/lib/injects-point.ts +20 -0
  37. package/scripts/plugin/lib/injects.d.ts +2 -0
  38. package/scripts/plugin/lib/injects.ts +101 -0
  39. package/scripts/tags/links.d.ts +1 -0
  40. package/scripts/tags/links.ts +75 -0
  41. package/scripts/tags/media.d.ts +1 -0
  42. package/scripts/tags/media.ts +19 -0
  43. package/source/js/_app/components/sidebar.ts +237 -0
  44. package/source/js/_app/globals/globalVars.ts +98 -0
  45. package/source/js/_app/globals/handles.ts +122 -0
  46. package/source/js/_app/globals/themeColor.ts +64 -0
  47. package/source/js/_app/globals/thirdparty.ts +63 -0
  48. package/source/js/_app/globals/tools.ts +74 -0
  49. package/source/js/_app/library/anime.ts +109 -0
  50. package/source/js/_app/library/declare.d.ts +117 -0
  51. package/source/js/_app/library/dom.ts +26 -0
  52. package/source/js/_app/library/libtype.d.ts +4 -0
  53. package/source/js/_app/library/loadFile.ts +41 -0
  54. package/source/js/_app/library/proto.ts +143 -0
  55. package/source/js/_app/library/scriptPjax.ts +72 -0
  56. package/source/js/_app/library/storage.ts +12 -0
  57. package/source/js/_app/library/vue.ts +60 -0
  58. package/source/js/_app/page/common.ts +42 -0
  59. package/source/js/_app/page/fancybox.ts +70 -0
  60. package/source/js/_app/page/post.ts +265 -0
  61. package/source/js/_app/page/search.ts +129 -0
  62. package/source/js/_app/page/tab.ts +59 -0
  63. package/source/js/_app/pjax/domInit.ts +95 -0
  64. package/source/js/_app/pjax/refresh.ts +75 -0
  65. package/source/js/_app/pjax/siteInit.ts +67 -0
  66. package/source/js/_app/player.ts +798 -0
  67. package/source/js/_app/components/sidebar.js +0 -209
  68. package/source/js/_app/fireworks.js +0 -10
  69. package/source/js/_app/globals/globalVars.js +0 -80
  70. package/source/js/_app/globals/handles.js +0 -98
  71. package/source/js/_app/globals/themeColor.js +0 -62
  72. package/source/js/_app/globals/thirdparty.js +0 -62
  73. package/source/js/_app/globals/tools.js +0 -66
  74. package/source/js/_app/library/anime.js +0 -106
  75. package/source/js/_app/library/dom.js +0 -34
  76. package/source/js/_app/library/loadFile.js +0 -36
  77. package/source/js/_app/library/proto.js +0 -163
  78. package/source/js/_app/library/scriptPjax.js +0 -70
  79. package/source/js/_app/library/storage.js +0 -12
  80. package/source/js/_app/library/vue.js +0 -53
  81. package/source/js/_app/page/comment.js +0 -23
  82. package/source/js/_app/page/common.js +0 -41
  83. package/source/js/_app/page/fancybox.js +0 -65
  84. package/source/js/_app/page/post.js +0 -244
  85. package/source/js/_app/page/search.js +0 -118
  86. package/source/js/_app/page/tab.js +0 -53
  87. package/source/js/_app/pjax/domInit.js +0 -76
  88. package/source/js/_app/pjax/refresh.js +0 -52
  89. package/source/js/_app/pjax/siteInit.js +0 -51
  90. package/source/js/_app/player.js +0 -771
@@ -0,0 +1,265 @@
1
+ import { $dom } from '../library/dom'
2
+ import { postFancybox } from './fancybox'
3
+ import { clipBoard, showtip } from '../globals/tools'
4
+ import { BODY } from '../globals/globalVars'
5
+ import { pageScroll, transition } from '../library/anime'
6
+ import { mediaPlayer } from '../player'
7
+
8
+ export const postBeauty = () => {
9
+ if (!$dom('.md')) { return }
10
+
11
+ if (__shokax_fancybox__) {
12
+ postFancybox('.post.block')
13
+ }
14
+
15
+ $dom('.post.block').oncopy = (event) => {
16
+ showtip(LOCAL.copyright)
17
+
18
+ if (LOCAL.nocopy) {
19
+ event.preventDefault()
20
+ return
21
+ }
22
+
23
+ const copyright = $dom('#copyright')
24
+ if (window.getSelection().toString().length > 30 && copyright) {
25
+ event.preventDefault()
26
+ const author = '# ' + copyright.child('.author').innerText
27
+ const link = '# ' + copyright.child('.link').innerText
28
+ const license = '# ' + copyright.child('.license').innerText
29
+ const htmlData = author + '<br>' + link + '<br>' + license + '<br><br>' + window.getSelection().toString().replace(/\r\n/g, '<br>')
30
+
31
+ const textData = author + '\n' + link + '\n' + license + '\n\n' + window.getSelection().toString().replace(/\r\n/g, '\n')
32
+ if (event.clipboardData) {
33
+ event.clipboardData.setData('text/html', htmlData)
34
+ event.clipboardData.setData('text/plain', textData)
35
+ } else {
36
+ // @ts-ignore
37
+ if (window.clipboardData) {
38
+ // @ts-ignore
39
+ return window.clipboardData.setData('text', textData)
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ $dom.each('li ruby', (element) => {
46
+ let parent = element.parentNode
47
+ // @ts-ignore
48
+ if (element.parentNode.tagName !== 'LI') {
49
+ parent = element.parentNode.parentNode
50
+ }
51
+ parent.addClass('ruby')
52
+ })
53
+
54
+ $dom.each('ol[start]', (element) => {
55
+ // @ts-ignore
56
+ element.style.counterReset = 'counter ' + parseInt(element.getAttribute('start') - 1)
57
+ })
58
+
59
+ $dom.each('.md table', (element) => {
60
+ element.wrapObject({
61
+ className: 'table-container'
62
+ })
63
+ })
64
+
65
+ $dom.each('.highlight > .table-container', (element) => {
66
+ element.className = 'code-container'
67
+ })
68
+
69
+ $dom.each('figure.highlight', (element) => {
70
+ const code_container = element.child('.code-container')
71
+ const caption = element.child('figcaption')
72
+
73
+ element.insertAdjacentHTML('beforeend', '<div class="operation"><span class="breakline-btn"><i class="ic i-align-left"></i></span><span class="copy-btn"><i class="ic i-clipboard"></i></span><span class="fullscreen-btn"><i class="ic i-expand"></i></span></div>')
74
+
75
+ const copyBtn = element.child('.copy-btn')
76
+ if (LOCAL.nocopy) {
77
+ copyBtn.remove()
78
+ } else {
79
+ copyBtn.addEventListener('click', (event) => {
80
+ const target = <HTMLElement>event.currentTarget
81
+ let comma = ''; let code = ''
82
+ code_container.find('pre').forEach((line) => {
83
+ code += comma + line.innerText
84
+ comma = '\n'
85
+ })
86
+
87
+ clipBoard(code, (result) => {
88
+ target.child('.ic').className = result ? 'ic i-check' : 'ic i-times'
89
+ target.blur()
90
+ showtip(LOCAL.copyright)
91
+ })
92
+ }, { passive: true })
93
+ copyBtn.addEventListener('mouseleave', (event) => {
94
+ setTimeout(() => {
95
+ event.target.child('.ic').className = 'ic i-clipboard'
96
+ }, 1000)
97
+ })
98
+ }
99
+
100
+ const breakBtn = element.child('.breakline-btn')
101
+ breakBtn.addEventListener('click', (event) => {
102
+ const target = event.currentTarget
103
+ if (element.hasClass('breakline')) {
104
+ element.removeClass('breakline')
105
+ target.child('.ic').className = 'ic i-align-left'
106
+ } else {
107
+ element.addClass('breakline')
108
+ target.child('.ic').className = 'ic i-align-justify'
109
+ }
110
+ })
111
+
112
+ const fullscreenBtn = element.child('.fullscreen-btn')
113
+ const removeFullscreen = () => {
114
+ element.removeClass('fullscreen')
115
+ element.scrollTop = 0
116
+ BODY.removeClass('fullscreen')
117
+ fullscreenBtn.child('.ic').className = 'ic i-expand'
118
+ }
119
+ const fullscreenHandle = () => {
120
+ if (element.hasClass('fullscreen')) {
121
+ removeFullscreen()
122
+ if (code_container && code_container.find('tr').length > 15) {
123
+ const showBtn = code_container.child('.show-btn')
124
+ code_container.style.maxHeight = '300px'
125
+ showBtn.removeClass('open')
126
+ }
127
+ pageScroll(element)
128
+ } else {
129
+ element.addClass('fullscreen')
130
+ BODY.addClass('fullscreen')
131
+ fullscreenBtn.child('.ic').className = 'ic i-compress'
132
+ if (code_container && code_container.find('tr').length > 15) {
133
+ const showBtn = code_container.child('.show-btn')
134
+ code_container.style.maxHeight = ''
135
+ showBtn.addClass('open')
136
+ }
137
+ }
138
+ }
139
+ fullscreenBtn.addEventListener('click', fullscreenHandle)
140
+ caption && caption.addEventListener('click', fullscreenHandle)
141
+
142
+ if (code_container && code_container.find('tr').length > 15) {
143
+ code_container.style.maxHeight = '300px'
144
+ code_container.insertAdjacentHTML('beforeend', '<div class="show-btn"><i class="ic i-angle-down"></i></div>')
145
+ const showBtn = code_container.child('.show-btn')
146
+
147
+ const hideCode = () => {
148
+ code_container.style.maxHeight = '300px'
149
+ showBtn.removeClass('open')
150
+ }
151
+ const showCode = () => {
152
+ code_container.style.maxHeight = ''
153
+ showBtn.addClass('open')
154
+ }
155
+
156
+ showBtn.addEventListener('click', () => {
157
+ if (showBtn.hasClass('open')) {
158
+ removeFullscreen()
159
+ hideCode()
160
+ pageScroll(code_container)
161
+ } else {
162
+ showCode()
163
+ }
164
+ })
165
+ }
166
+ })
167
+
168
+ $dom.each('pre.mermaid > svg', (element) => {
169
+ const temp = <SVGAElement><unknown>element
170
+ temp.style.maxWidth = ''
171
+ })
172
+
173
+ $dom.each('.reward button', (element) => {
174
+ element.addEventListener('click', (event) => {
175
+ event.preventDefault()
176
+ const qr = $dom('#qr')
177
+ if (qr.display() === 'inline-flex') {
178
+ transition(qr, 0)
179
+ } else {
180
+ transition(qr, 1, () => {
181
+ qr.display('inline-flex')
182
+ }) // slideUpBigIn
183
+ }
184
+ })
185
+ })
186
+
187
+ // quiz
188
+ if (__shokax_quiz__) {
189
+ $dom.each('.quiz > ul.options li', (element) => {
190
+ element.addEventListener('click', () => {
191
+ if (element.hasClass('correct')) {
192
+ element.toggleClass('right')
193
+ element.parentNode.parentNode.addClass('show')
194
+ } else {
195
+ element.toggleClass('wrong')
196
+ }
197
+ })
198
+ })
199
+
200
+ $dom.each('.quiz > p', (element) => {
201
+ element.addEventListener('click', () => {
202
+ element.parentNode.toggleClass('show')
203
+ })
204
+ })
205
+
206
+ $dom.each('.quiz > p:first-child', (element) => {
207
+ const quiz = element.parentNode
208
+ let type = 'choice'
209
+ if (quiz.hasClass('true') || quiz.hasClass('false')) {
210
+ type = 'true_false'
211
+ }
212
+ if (quiz.hasClass('multi')) {
213
+ type = 'multiple'
214
+ }
215
+ if (quiz.hasClass('fill')) {
216
+ type = 'gap_fill'
217
+ }
218
+ if (quiz.hasClass('essay')) {
219
+ type = 'essay'
220
+ }
221
+ element.setAttribute('data-type', LOCAL.quiz[type])
222
+ })
223
+
224
+ $dom.each('.quiz .mistake', (element) => {
225
+ element.setAttribute('data-type', LOCAL.quiz.mistake)
226
+ })
227
+ }
228
+
229
+ $dom.each('div.tags a', (element) => {
230
+ element.className = ['primary', 'success', 'info', 'warning', 'danger'][Math.floor(Math.random() * 5)]
231
+ })
232
+
233
+ if (__shokax_player__) {
234
+ $dom.each('.md div.player', (element) => {
235
+ mediaPlayer(element, {
236
+ type: element.getAttribute('data-type'),
237
+ mode: 'order',
238
+ btns: []
239
+ }).player.load(JSON.parse(element.getAttribute('data-src'))).fetch()
240
+ })
241
+ }
242
+
243
+ const angleDown = document.querySelectorAll('.show-btn .i-angle-down')
244
+ if (angleDown.length) {
245
+ const io = new IntersectionObserver((entries) => {
246
+ entries.forEach(entry => {
247
+ if (entry.isIntersecting) {
248
+ angleDown.forEach(i => {
249
+ i.classList.remove('stop-animation')
250
+ })
251
+ } else {
252
+ angleDown.forEach(i => {
253
+ i.classList.add('stop-animation')
254
+ })
255
+ }
256
+ })
257
+ }, {
258
+ root: null,
259
+ threshold: 0.5
260
+ })
261
+ angleDown.forEach(i => {
262
+ io.observe(i)
263
+ })
264
+ }
265
+ }
@@ -0,0 +1,129 @@
1
+ import { BODY, setSiteSearch, siteSearch } from '../globals/globalVars'
2
+ import { transition } from '../library/anime'
3
+ import { $dom } from '../library/dom'
4
+
5
+ export function algoliaSearch (pjax) {
6
+ if (CONFIG.search === null) { return }
7
+
8
+ if (!siteSearch) {
9
+ setSiteSearch(BODY.createChild('div', {
10
+ id: 'search',
11
+ innerHTML: '<div class="inner"><div class="header"><span class="icon"><i class="ic i-search"></i></span><div class="search-input-container"></div><span class="close-btn"><i class="ic i-times-circle"></i></span></div><div class="results"><div class="inner"><div id="search-stats"></div><div id="search-hits"></div><div id="search-pagination"></div></div></div></div>'
12
+ }))
13
+ }
14
+
15
+ const search = instantsearch({
16
+ indexName: CONFIG.search.indexName,
17
+ searchClient: algoliasearch(CONFIG.search.appID, CONFIG.search.apiKey),
18
+ searchFunction (helper) {
19
+ const searchInput = <HTMLInputElement><unknown>$dom('.search-input')
20
+ if (searchInput.value) {
21
+ helper.search()
22
+ }
23
+ }
24
+ })
25
+
26
+ search.on('render', () => {
27
+ pjax.refresh($dom('#search-hits'))
28
+ })
29
+
30
+ // Registering Widgets
31
+ search.addWidgets([
32
+ instantsearch.widgets.configure({
33
+ hitsPerPage: CONFIG.search.hits.per_page || 10
34
+ }),
35
+
36
+ instantsearch.widgets.searchBox({
37
+ container: '.search-input-container',
38
+ placeholder: LOCAL.search.placeholder,
39
+ // Hide default icons of algolia search
40
+ showReset: false,
41
+ showSubmit: false,
42
+ showLoadingIndicator: false,
43
+ cssClasses: {
44
+ input: 'search-input'
45
+ }
46
+ }),
47
+
48
+ instantsearch.widgets.stats({
49
+ container: '#search-stats',
50
+ templates: {
51
+ text (data) {
52
+ const stats = LOCAL.search.stats
53
+ .replace(/\$\{hits}/, data.nbHits)
54
+ .replace(/\$\{time}/, data.processingTimeMS)
55
+ return stats + '<span class="algolia-powered"></span><hr>'
56
+ }
57
+ }
58
+ }),
59
+
60
+ instantsearch.widgets.hits({
61
+ container: '#search-hits',
62
+ templates: {
63
+ item (data) {
64
+ const cats = data.categories ? '<span>' + data.categories.join('<i class="ic i-angle-right"></i>') + '</span>' : ''
65
+ return '<a href="' + CONFIG.root + data.path + '">' + cats + data._highlightResult.title.value + '</a>'
66
+ },
67
+ empty (data) {
68
+ return '<div id="hits-empty">' +
69
+ LOCAL.search.empty.replace(/\$\{query}/, data.query) +
70
+ '</div>'
71
+ }
72
+ },
73
+ cssClasses: {
74
+ item: 'item'
75
+ }
76
+ }),
77
+
78
+ instantsearch.widgets.pagination({
79
+ container: '#search-pagination',
80
+ scrollTo: false,
81
+ showFirst: false,
82
+ showLast: false,
83
+ templates: {
84
+ first: '<i class="ic i-angle-double-left"></i>',
85
+ last: '<i class="ic i-angle-double-right"></i>',
86
+ previous: '<i class="ic i-angle-left"></i>',
87
+ next: '<i class="ic i-angle-right"></i>'
88
+ },
89
+ cssClasses: {
90
+ root: 'pagination',
91
+ item: 'pagination-item',
92
+ link: 'page-number',
93
+ selectedItem: 'current',
94
+ disabledItem: 'disabled-item'
95
+ }
96
+ })
97
+ ])
98
+
99
+ search.start()
100
+
101
+ // Handle and trigger popup window
102
+ $dom.each('.search', (element) => {
103
+ element.addEventListener('click', () => {
104
+ document.body.style.overflow = 'hidden'
105
+ transition(siteSearch, 'shrinkIn', () => {
106
+ $dom('.search-input').focus()
107
+ }) // transition.shrinkIn
108
+ })
109
+ })
110
+
111
+ // Monitor main search box
112
+ const onPopupClose = () => {
113
+ document.body.style.overflow = ''
114
+ transition(siteSearch, 0) // "transition.shrinkOut"
115
+ }
116
+
117
+ siteSearch.addEventListener('click', (event) => {
118
+ if (event.target === siteSearch) {
119
+ onPopupClose()
120
+ }
121
+ })
122
+ $dom('.close-btn').addEventListener('click', onPopupClose)
123
+ window.addEventListener('pjax:success', onPopupClose)
124
+ window.addEventListener('keyup', (event) => {
125
+ if (event.key === 'Escape') {
126
+ onPopupClose()
127
+ }
128
+ })
129
+ }
@@ -0,0 +1,59 @@
1
+ import { pageScroll } from '../library/anime'
2
+ import { $dom } from '../library/dom'
3
+
4
+ export const tabFormat = () => {
5
+ // tab
6
+ let first_tab:boolean
7
+ $dom.each('div.tab', (element) => {
8
+ if (element.getAttribute('data-ready')) { return }
9
+
10
+ const id = element.getAttribute('data-id')
11
+ const title = element.getAttribute('data-title')
12
+ let box = $dom('#' + id)
13
+ if (!box) {
14
+ box = document.createElement('div')
15
+ box.className = 'tabs'
16
+ box.id = id
17
+ box.innerHTML = '<div class="show-btn"></div>'
18
+
19
+ const showBtn = box.child('.show-btn')
20
+ showBtn.addEventListener('click', () => {
21
+ pageScroll(box)
22
+ })
23
+
24
+ element.parentNode.insertBefore(box, element)
25
+ first_tab = true
26
+ } else {
27
+ first_tab = false
28
+ }
29
+
30
+ let ul = box.child('.nav ul')
31
+ if (!ul) {
32
+ ul = box.createChild('div', {
33
+ className: 'nav',
34
+ innerHTML: '<ul></ul>'
35
+ }).child('ul')
36
+ }
37
+
38
+ const li = ul.createChild('li', {
39
+ innerHTML: title
40
+ })
41
+
42
+ if (first_tab) {
43
+ li.addClass('active')
44
+ element.addClass('active')
45
+ }
46
+
47
+ li.addEventListener('click', (event) => {
48
+ const target = event.currentTarget
49
+ box.find('.active').forEach((el) => {
50
+ el.removeClass('active')
51
+ })
52
+ element.addClass('active')
53
+ target.addClass('active')
54
+ })
55
+
56
+ box.appendChild(element)
57
+ element.setAttribute('data-ready', String(true))
58
+ })
59
+ }
@@ -0,0 +1,95 @@
1
+ import { backToTopHandle, goToBottomHandle, goToCommentHandle, sideBarToggleHandle } from '../components/sidebar'
2
+ import {
3
+ backToTop,
4
+ goToComment,
5
+ loadCat,
6
+ menuToggle,
7
+ quickBtn, setBackToTop, setGoToComment, setShowContents, setToolBtn,
8
+ setToolPlayer,
9
+ showContents,
10
+ siteHeader,
11
+ siteNav,
12
+ toolBtn,
13
+ toolPlayer
14
+ } from '../globals/globalVars'
15
+ import { Loader } from '../globals/thirdparty'
16
+ import { $dom } from '../library/dom'
17
+ import { mediaPlayer } from '../player'
18
+
19
+ export default function domInit () {
20
+ $dom.each('.overview .menu > .item', (el) => {
21
+ siteNav.child('.menu').appendChild(el.cloneNode(true))
22
+ })
23
+
24
+ loadCat.addEventListener('click', Loader.vanish)
25
+ menuToggle.addEventListener('click', sideBarToggleHandle)
26
+ $dom('.dimmer').addEventListener('click', sideBarToggleHandle)
27
+
28
+ quickBtn.child('.down').addEventListener('click', goToBottomHandle)
29
+ quickBtn.child('.up').addEventListener('click', backToTopHandle)
30
+
31
+ if (!toolBtn) {
32
+ setToolBtn(siteHeader.createChild('div', {
33
+ id: 'tool',
34
+ innerHTML: '<div class="item player"></div><div class="item contents"><i class="ic i-list-ol"></i></div><div class="item chat"><i class="ic i-comments"></i></div><div class="item back-to-top"><i class="ic i-arrow-up"></i><span>0%</span></div>'
35
+ }))
36
+ }
37
+
38
+ setToolPlayer(toolBtn.child('.player'))
39
+ setBackToTop(toolBtn.child('.back-to-top'))
40
+ setGoToComment(toolBtn.child('.chat'))
41
+ setShowContents(toolBtn.child('.contents'))
42
+
43
+ backToTop.addEventListener('click', backToTopHandle)
44
+ goToComment.addEventListener('click', goToCommentHandle)
45
+ showContents.addEventListener('click', sideBarToggleHandle)
46
+
47
+ if (__shokax_player__) {
48
+ mediaPlayer(toolPlayer)
49
+
50
+ $dom('main').addEventListener('click', () => {
51
+ toolPlayer.player.mini()
52
+ })
53
+ }
54
+
55
+ const createIntersectionObserver = () => {
56
+ // waves在视口外时停止动画
57
+ new IntersectionObserver(([entry]) => {
58
+ if (entry.isIntersecting) {
59
+ document.querySelectorAll('.parallax>use').forEach(i => {
60
+ i.classList.remove('stop-animation')
61
+ })
62
+ document.querySelectorAll('#imgs .item').forEach(i => {
63
+ i.classList.remove('stop-animation')
64
+ })
65
+ } else {
66
+ document.querySelectorAll('.parallax>use').forEach(i => {
67
+ i.classList.add('stop-animation')
68
+ })
69
+ // waves不可见时imgs也应该不可见了
70
+ document.querySelectorAll('#imgs .item').forEach(i => {
71
+ i.classList.add('stop-animation')
72
+ })
73
+ }
74
+ }, {
75
+ root: null,
76
+ threshold: 0.2
77
+ }).observe(document.getElementById('waves'))
78
+ // sakura在视口外时停止动画
79
+ new IntersectionObserver(([entry]) => {
80
+ if (entry.isIntersecting) {
81
+ document.querySelectorAll('.with-love>i').forEach(i => {
82
+ i.classList.remove('stop-animation')
83
+ })
84
+ } else {
85
+ document.querySelectorAll('.with-love>i').forEach(i => {
86
+ i.classList.add('stop-animation')
87
+ })
88
+ }
89
+ }, {
90
+ root: null,
91
+ threshold: 0.2
92
+ }).observe(document.querySelector('.with-love'))
93
+ }
94
+ createIntersectionObserver()
95
+ }
@@ -0,0 +1,75 @@
1
+ import { $dom } from '../library/dom'
2
+ import { cardActive } from '../page/common'
3
+ import { postBeauty } from '../page/post'
4
+ import { pageScroll, transition } from '../library/anime'
5
+ import { vendorCss, vendorJs } from '../library/loadFile'
6
+ import { pjaxScript } from '../library/scriptPjax'
7
+ import { resizeHandle } from '../globals/handles'
8
+ import {
9
+ loadCat,
10
+ menuToggle,
11
+ setLocalHash, setLocalUrl, setOriginTitle,
12
+ sideBar,
13
+ toolPlayer
14
+ } from '../globals/globalVars'
15
+ import { pagePosition, positionInit } from '../globals/tools'
16
+ import { menuActive, sideBarTab, sidebarTOC } from '../components/sidebar'
17
+ import { Loader, isOutime } from '../globals/thirdparty'
18
+ import { tabFormat } from '../page/tab'
19
+
20
+ export const pjaxReload = () => {
21
+ pagePosition()
22
+
23
+ if (sideBar.hasClass('on')) {
24
+ transition(sideBar, 0, () => {
25
+ sideBar.removeClass('on')
26
+ menuToggle.removeClass('close')
27
+ }) // 'transition.slideRightOut'
28
+ }
29
+ const mainNode = $dom('#main')
30
+ mainNode.innerHTML = ''
31
+ mainNode.appendChild(loadCat.lastChild.cloneNode(true))
32
+ pageScroll(0)
33
+ }
34
+
35
+ export const siteRefresh = (reload) => {
36
+ setLocalHash(0)
37
+ setLocalUrl(window.location.href)
38
+
39
+ vendorCss('katex')
40
+ vendorJs('copy_tex')
41
+ vendorCss('mermaid')
42
+
43
+ if (reload !== 1) {
44
+ $dom.each('script[data-pjax]', pjaxScript)
45
+ }
46
+
47
+ setOriginTitle(document.title)
48
+
49
+ resizeHandle()
50
+
51
+ menuActive()
52
+
53
+ sideBarTab()
54
+ sidebarTOC()
55
+
56
+ postBeauty()
57
+ if (__shokax_tabs__) {
58
+ tabFormat()
59
+ }
60
+
61
+ if (__shokax_player__) {
62
+ toolPlayer.player.load(LOCAL.audio || CONFIG.audio || {})
63
+ }
64
+ Loader.hide()
65
+
66
+ setTimeout(() => {
67
+ positionInit()
68
+ }, 500)
69
+
70
+ cardActive()
71
+
72
+ if (__shokax_outime__) {
73
+ isOutime()
74
+ }
75
+ }
@@ -0,0 +1,67 @@
1
+ import domInit from './domInit'
2
+ import { pjaxReload, siteRefresh } from './refresh'
3
+ import { cloudflareInit } from '../library/scriptPjax'
4
+ import { algoliaSearch } from '../page/search'
5
+ import { pjax, setPjax } from '../globals/globalVars'
6
+ import { autoDarkmode, themeColorListener } from '../globals/themeColor'
7
+ import { resizeHandle, scrollHandle, visibilityListener } from '../globals/handles'
8
+ import { pagePosition } from '../globals/tools'
9
+ import Pjax from 'theme-shokax-pjax'
10
+ import { initVue } from '../library/vue'
11
+ import { lazyLoad } from 'unlazy'
12
+ import firework from 'mouse-firework'
13
+
14
+ const siteInit = () => {
15
+ domInit()
16
+ initVue()
17
+
18
+ setPjax(new Pjax({
19
+ selectors: [
20
+ 'head title',
21
+ '.languages',
22
+ '.twikoo',
23
+ '.pjax',
24
+ '.leancloud-recent-comment',
25
+ 'script[data-config]'
26
+ ],
27
+ cacheBust: false
28
+ }))
29
+
30
+ CONFIG.quicklink.ignores = LOCAL.ignores
31
+ quicklink.listen(CONFIG.quicklink)
32
+ autoDarkmode()
33
+
34
+ if (__shokax_VL__) {
35
+ visibilityListener()
36
+ }
37
+ themeColorListener()
38
+ if (__shokax_search__) {
39
+ algoliaSearch(pjax)
40
+ }
41
+
42
+ if (__shokax_fireworks__) {
43
+ firework(CONFIG.fireworks)
44
+ }
45
+ lazyLoad()
46
+
47
+ window.addEventListener('scroll', scrollHandle)
48
+
49
+ window.addEventListener('resize', resizeHandle)
50
+
51
+ window.addEventListener('pjax:send', pjaxReload)
52
+
53
+ window.addEventListener('pjax:success', siteRefresh) // 默认会传入一个event参数
54
+
55
+ window.addEventListener('beforeunload', () => {
56
+ pagePosition()
57
+ })
58
+ siteRefresh(1)
59
+ }
60
+
61
+ cloudflareInit()
62
+
63
+ window.addEventListener('DOMContentLoaded', siteInit, {
64
+ passive: true
65
+ })
66
+
67
+ console.log('%c Theme.ShokaX v' + CONFIG.version + ' %c https://github.com/theme-shoka-x/hexo-theme-shokaX ', 'color: white; background: #e9546b; padding:5px 0;', 'padding:4px;border:1px solid #e9546b;')