hexo-theme-shokax 0.4.3 → 0.4.5
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/layout/_partials/layout.pug +1 -1
- package/package.json +1 -1
- package/scripts/plugin/index.js +3 -1
- package/source/js/_app/components/comments.ts +1 -1
- package/source/js/_app/components/sidebar.ts +23 -23
- package/source/js/_app/components/tcomments.ts +1 -2
- package/source/js/_app/globals/globalVars.ts +10 -10
- package/source/js/_app/globals/handles.ts +9 -8
- package/source/js/_app/globals/themeColor.ts +2 -3
- package/source/js/_app/globals/tools.ts +1 -1
- package/source/js/_app/library/declare.d.ts +0 -3
- package/source/js/_app/library/dom.ts +4 -2
- package/source/js/_app/library/loadFile.ts +7 -0
- package/source/js/_app/library/proto.ts +8 -12
- package/source/js/_app/library/vue.ts +3 -4
- package/source/js/_app/page/common.ts +5 -4
- package/source/js/_app/page/fancybox.ts +2 -1
- package/source/js/_app/page/post.ts +22 -22
- package/source/js/_app/page/search.ts +3 -3
- package/source/js/_app/page/tab.ts +4 -4
- package/source/js/_app/pjax/domInit.ts +10 -10
- package/source/js/_app/pjax/refresh.ts +24 -21
- package/source/js/_app/pjax/siteInit.ts +3 -3
- package/source/js/_app/player.ts +13 -14
@@ -130,7 +130,7 @@ html(lang=page.language?page.language:config.language, style=theme.grayMode ? 'f
|
|
130
130
|
|
131
131
|
!= vendor_js()
|
132
132
|
if theme.polyfill.enable
|
133
|
-
script(src=`https://
|
133
|
+
script(src=`https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?version=4.8.0&features=${theme.polyfill.features}` defer)
|
134
134
|
|
135
135
|
!= _js('siteInit.js')
|
136
136
|
|
package/package.json
CHANGED
package/scripts/plugin/index.js
CHANGED
@@ -47,7 +47,9 @@ hexo.on('generateBefore', () => {
|
|
47
47
|
});
|
48
48
|
hexo.on('generateAfter', () => {
|
49
49
|
// 检查版本更新
|
50
|
-
fetch('https://api.shokax.top/version/hexo'
|
50
|
+
fetch('https://api.shokax.top/version/hexo', { headers: {
|
51
|
+
"User-Agent": "Mozilla/5.0 ShokaX Client (hexo-theme-shokax)"
|
52
|
+
} }).then((res) => {
|
51
53
|
res.json().then((resp) => {
|
52
54
|
try {
|
53
55
|
const latest = resp['version'];
|
@@ -4,7 +4,7 @@ import { CONFIG, Container, diffY, menuToggle, showContents, sideBar } from '../
|
|
4
4
|
import { clipBoard } from '../globals/tools'
|
5
5
|
import { pageScroll, transition } from '../library/anime'
|
6
6
|
import { $dom } from '../library/dom'
|
7
|
-
import initProto, {
|
7
|
+
import initProto, { getHeight, setDisplay } from '../library/proto'
|
8
8
|
|
9
9
|
initProto()
|
10
10
|
export const sideBarToggleHandle = (event:Event, force?:number) => {
|
@@ -33,17 +33,17 @@ export const sideBarToggleHandle = (event:Event, force?:number) => {
|
|
33
33
|
}
|
34
34
|
|
35
35
|
export const sideBarTab = () => {
|
36
|
-
const sideBarInner =
|
36
|
+
const sideBarInner = sideBar.querySelector('.inner')
|
37
37
|
|
38
|
-
if (sideBar.
|
39
|
-
sideBarInner.removeChild(sideBar.
|
38
|
+
if (sideBar.querySelector('.tab')) {
|
39
|
+
sideBarInner.removeChild(sideBar.querySelector('.tab'))
|
40
40
|
}
|
41
41
|
|
42
42
|
const list = document.createElement('ul'); let active = 'active'
|
43
43
|
list.className = 'tab';
|
44
44
|
|
45
45
|
['contents', 'related', 'overview'].forEach((item) => {
|
46
|
-
const element = sideBar.
|
46
|
+
const element = sideBar.querySelector('.panel.' + item)
|
47
47
|
|
48
48
|
if (element.innerHTML.trim().length < 1) {
|
49
49
|
if (item === 'contents') {
|
@@ -81,7 +81,7 @@ export const sideBarTab = () => {
|
|
81
81
|
element.removeClass('active')
|
82
82
|
})
|
83
83
|
|
84
|
-
sideBar.
|
84
|
+
sideBar.querySelector('.panel.' + target.className.replace(' item', '')).addClass('active')
|
85
85
|
|
86
86
|
target.addClass('active')
|
87
87
|
})
|
@@ -91,10 +91,10 @@ export const sideBarTab = () => {
|
|
91
91
|
})
|
92
92
|
|
93
93
|
if (list.childNodes.length > 1) {
|
94
|
-
sideBarInner.insertBefore(list, sideBarInner.childNodes[0])
|
95
|
-
sideBar.
|
94
|
+
sideBarInner.insertBefore(list, sideBarInner.childNodes[0]);
|
95
|
+
(sideBar.querySelector('.panels') as HTMLElement).style.paddingTop = ''
|
96
96
|
} else {
|
97
|
-
sideBar.
|
97
|
+
(sideBar.querySelector('.panels') as HTMLElement).style.paddingTop = '.625rem'
|
98
98
|
}
|
99
99
|
}
|
100
100
|
|
@@ -124,7 +124,7 @@ export const sidebarTOC = () => {
|
|
124
124
|
while (!parent.matches('.contents')) {
|
125
125
|
if (parent.matches('li')) {
|
126
126
|
parent.addClass('active')
|
127
|
-
const t =
|
127
|
+
const t = document.querySelector(parent.querySelector('a.toc-link').getAttribute('href'))
|
128
128
|
if (t) {
|
129
129
|
t.addClass('active')
|
130
130
|
}
|
@@ -133,7 +133,7 @@ export const sidebarTOC = () => {
|
|
133
133
|
}
|
134
134
|
// Scrolling to center active TOC element if TOC content is taller than viewport.
|
135
135
|
if (getComputedStyle(sideBar).display !== 'none' && tocElement.hasClass('active')) {
|
136
|
-
pageScroll(tocElement, target.offsetTop - (tocElement.offsetHeight / 4))
|
136
|
+
pageScroll((tocElement as HTMLElement), target.offsetTop - ((tocElement as HTMLElement).offsetHeight / 4))
|
137
137
|
}
|
138
138
|
}
|
139
139
|
const navItems = $dom.all('.contents li')
|
@@ -142,21 +142,21 @@ export const sidebarTOC = () => {
|
|
142
142
|
return
|
143
143
|
}
|
144
144
|
|
145
|
-
let sections = [...navItems]
|
145
|
+
let sections = [...navItems] as HTMLElement[]
|
146
146
|
let activeLock = null
|
147
147
|
|
148
148
|
sections = sections.map((element, index) => {
|
149
|
-
const link = element.
|
150
|
-
const anchor =
|
149
|
+
const link = element.querySelector('a.toc-link')
|
150
|
+
const anchor = document.querySelector(decodeURI(link.getAttribute('href')))
|
151
151
|
if (!anchor) return null
|
152
|
-
const alink = anchor.
|
152
|
+
const alink = anchor.querySelector('a.anchor')
|
153
153
|
|
154
154
|
const anchorScroll = (event:MouseEvent) => {
|
155
155
|
event.preventDefault()
|
156
|
-
const target =
|
156
|
+
const target = document.querySelector(decodeURI((event.currentTarget as HTMLElement).getAttribute('href')))
|
157
157
|
|
158
158
|
activeLock = index
|
159
|
-
pageScroll(target, null, () => {
|
159
|
+
pageScroll((target as HTMLElement), null, () => {
|
160
160
|
activateNavByIndex(index)
|
161
161
|
activeLock = null
|
162
162
|
})
|
@@ -165,13 +165,13 @@ export const sidebarTOC = () => {
|
|
165
165
|
// TOC item animation navigate.
|
166
166
|
link.addEventListener('click', anchorScroll)
|
167
167
|
alink && alink.addEventListener('click', (event) => {
|
168
|
-
anchorScroll(event)
|
168
|
+
anchorScroll(<MouseEvent>event)
|
169
169
|
clipBoard(CONFIG.hostname + '/' + LOCAL.path + (event.currentTarget as HTMLElement).getAttribute('href'))
|
170
170
|
})
|
171
|
-
return anchor
|
171
|
+
return (anchor as HTMLElement)
|
172
172
|
})
|
173
173
|
|
174
|
-
const tocElement = sideBar.
|
174
|
+
const tocElement = sideBar.querySelector('.contents.panel')
|
175
175
|
|
176
176
|
const findIndex = (entries: IntersectionObserverEntry[]) => {
|
177
177
|
let index = 0
|
@@ -218,19 +218,19 @@ export const goToBottomHandle = () => {
|
|
218
218
|
}
|
219
219
|
|
220
220
|
export const goToCommentHandle = () => {
|
221
|
-
pageScroll(
|
221
|
+
pageScroll(document.getElementById('comments'))
|
222
222
|
}
|
223
223
|
|
224
224
|
export const menuActive = () => {
|
225
225
|
$dom.each('.menu .item:not(.title)', (element) => {
|
226
|
-
const target = <HTMLAnchorElement> element.
|
226
|
+
const target = <HTMLAnchorElement> element.querySelector('a[href]')
|
227
227
|
const parentItem = element.parentNode.parentNode
|
228
228
|
if (!target) return
|
229
229
|
const isSamePath = target.pathname === location.pathname || target.pathname === location.pathname.replace('index.html', '')
|
230
230
|
const isSubPath = !CONFIG.root.startsWith(target.pathname) && location.pathname.startsWith(target.pathname)
|
231
231
|
const active = !target.onclick && target.hostname === location.hostname && (isSamePath || isSubPath)
|
232
232
|
element.toggleClass('active', active)
|
233
|
-
if (element.parentNode.
|
233
|
+
if (element.parentNode.querySelector('.active') && parentItem.hasClass('dropdown')) {
|
234
234
|
parentItem.removeClass('active').addClass('expand')
|
235
235
|
} else {
|
236
236
|
parentItem.removeClass('expand')
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import * as twikoo from 'twikoo'
|
2
2
|
import { CONFIG } from '../globals/globalVars'
|
3
|
-
import { $dom } from '../library/dom'
|
4
3
|
|
5
4
|
export const twikooComment = function () {
|
6
5
|
twikoo.init({
|
@@ -51,5 +50,5 @@ export const twikooRecentComments = async function () {
|
|
51
50
|
newComments.appendChild(commentEl)
|
52
51
|
})
|
53
52
|
|
54
|
-
|
53
|
+
document.getElementById('new-comment').appendChild(newComments)
|
55
54
|
}
|
@@ -10,20 +10,20 @@ export let diffY = 0
|
|
10
10
|
export let originTitle: string, titleTime: NodeJS.Timeout
|
11
11
|
export const BODY = document.getElementsByTagName('body')[0]
|
12
12
|
export const HTML = document.documentElement
|
13
|
-
export const Container =
|
14
|
-
export const loadCat =
|
15
|
-
export const siteNav =
|
16
|
-
export const siteHeader =
|
17
|
-
export const menuToggle = siteNav.
|
18
|
-
export const quickBtn =
|
19
|
-
export const sideBar =
|
20
|
-
export const siteBrand =
|
21
|
-
export let toolBtn =
|
13
|
+
export const Container = document.getElementById('container')
|
14
|
+
export const loadCat = document.getElementById('loading')
|
15
|
+
export const siteNav = document.getElementById('nav')
|
16
|
+
export const siteHeader = document.getElementById('header')
|
17
|
+
export const menuToggle = siteNav.querySelector('.toggle')
|
18
|
+
export const quickBtn = document.getElementById('quick')
|
19
|
+
export const sideBar = document.getElementById('sidebar')
|
20
|
+
export const siteBrand = document.getElementById('brand')
|
21
|
+
export let toolBtn = document.getElementById('tool')
|
22
22
|
export let toolPlayer
|
23
23
|
export let backToTop: HTMLElement
|
24
24
|
export let goToComment
|
25
25
|
export let showContents
|
26
|
-
export let siteSearch =
|
26
|
+
export let siteSearch = document.getElementById('search')
|
27
27
|
export let siteNavHeight: number, headerHightInner: number, headerHight: number
|
28
28
|
export let oWinHeight = window.innerHeight
|
29
29
|
export let oWinWidth = window.innerWidth
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { sideBarToggleHandle } from '../components/sidebar'
|
2
|
-
import { $dom, getDocHeight } from '../library/dom'
|
3
2
|
import {
|
4
3
|
backToTop,
|
5
4
|
diffY,
|
@@ -24,13 +23,15 @@ import { changeMetaTheme } from './themeColor'
|
|
24
23
|
import { Loader } from './thirdparty'
|
25
24
|
import { getHeight, setWidth } from '../library/proto'
|
26
25
|
|
26
|
+
const wavesEle = document.getElementById('waves')
|
27
|
+
|
27
28
|
export const resizeHandle = () => {
|
28
29
|
// 获取 siteNav 的高度
|
29
30
|
setSiteNavHeight(getHeight(siteNav))
|
30
31
|
// 获取 siteHeader 的高度
|
31
32
|
setHeaderHightInner(getHeight(siteHeader))
|
32
33
|
// 获取 #waves 的高度
|
33
|
-
setHeaderHight(headerHightInner + getHeight(
|
34
|
+
setHeaderHight(headerHightInner + getHeight(wavesEle))
|
34
35
|
|
35
36
|
// 判断窗口宽度是否改变
|
36
37
|
if (oWinWidth !== window.innerWidth) {
|
@@ -46,7 +47,7 @@ export const scrollHandle = () => {
|
|
46
47
|
// 获取窗口高度
|
47
48
|
const winHeight = window.innerHeight
|
48
49
|
// 获取文档高度
|
49
|
-
const docHeight =
|
50
|
+
const docHeight = (document.querySelector('main > .inner') as HTMLElement).offsetHeight
|
50
51
|
// 计算可见内容高度
|
51
52
|
const contentVisibilityHeight = docHeight > winHeight ? docHeight - winHeight : document.body.scrollHeight - winHeight
|
52
53
|
// 判断页面是否滚动超过 headerHightInner
|
@@ -86,18 +87,18 @@ export const scrollHandle = () => {
|
|
86
87
|
// 计算滚动百分比
|
87
88
|
const scrollPercent = Math.round(Math.min(100 * window.scrollY / contentVisibilityHeight, 100)) + '%'
|
88
89
|
// 更新回到顶部按钮的文字
|
89
|
-
if (backToTop.
|
90
|
-
backToTop.
|
90
|
+
if (backToTop.querySelector('span').innerText !== scrollPercent) {
|
91
|
+
backToTop.querySelector('span').innerText = scrollPercent
|
91
92
|
}
|
92
93
|
// 更新百分比进度条的宽度
|
93
|
-
if (
|
94
|
-
setWidth(
|
94
|
+
if (document.getElementById('sidebar').hasClass('affix') || document.getElementById('sidebar').hasClass('on')) {
|
95
|
+
setWidth(document.querySelector('.percent'), scrollPercent)
|
95
96
|
}
|
96
97
|
}
|
97
98
|
|
98
99
|
// 可见度监听(离开页面和返回时更改document的title)
|
99
100
|
export const visibilityListener = () => {
|
100
|
-
const iconNode =
|
101
|
+
const iconNode = document.querySelector('[rel="icon"]')
|
101
102
|
document.addEventListener('visibilitychange', () => {
|
102
103
|
switch (document.visibilityState) {
|
103
104
|
case 'hidden':
|
@@ -1,12 +1,11 @@
|
|
1
1
|
import { $storage } from '../library/storage'
|
2
|
-
import { $dom } from '../library/dom'
|
3
2
|
import { CONFIG, HTML } from './globalVars'
|
4
3
|
|
5
4
|
/**
|
6
5
|
* 更改日夜模式
|
7
6
|
*/
|
8
7
|
export const changeTheme = (type?: string) => {
|
9
|
-
const btn =
|
8
|
+
const btn = document.querySelector('.theme .ic')
|
10
9
|
if (type === 'dark') {
|
11
10
|
HTML.setAttribute('data-theme', type)
|
12
11
|
btn.removeClass('i-sun')
|
@@ -40,7 +39,7 @@ export const changeMetaTheme = (color: string): void => {
|
|
40
39
|
color = '#222'
|
41
40
|
}
|
42
41
|
|
43
|
-
|
42
|
+
document.querySelector('meta[name="theme-color"]').setAttribute('content', color)
|
44
43
|
}
|
45
44
|
|
46
45
|
// 记忆日夜模式切换和系统亮暗模式监听
|
@@ -7,8 +7,6 @@ interface AudioItem {
|
|
7
7
|
}
|
8
8
|
|
9
9
|
declare interface EventTarget {
|
10
|
-
createChild(tag: string, obj: Object, positon?: string): HTMLElement;
|
11
|
-
wrapObject(obj: Object): void;
|
12
10
|
changeOrGetHeight(h: number | string): void;
|
13
11
|
changeOrGetHeight(): number;
|
14
12
|
changeOrGetWidth(w: number | string): void;
|
@@ -18,7 +16,6 @@ declare interface EventTarget {
|
|
18
16
|
insertAfter(element: HTMLElement): void;
|
19
17
|
display(d: string): EventTarget;
|
20
18
|
display():string
|
21
|
-
child(selector: string): HTMLElement;
|
22
19
|
find(selector: string): NodeListOf<HTMLElement>;
|
23
20
|
_class(type: string, className: string, display?: boolean): void;
|
24
21
|
addClass(className: string): EventTarget;
|
@@ -1,6 +1,6 @@
|
|
1
|
-
const getDocHeight = () => $dom('main > .inner').offsetHeight
|
2
1
|
/**
|
3
2
|
* 获取一个dom选择器对应的元素
|
3
|
+
* @deprecated Will be removed in the v0.5
|
4
4
|
*/
|
5
5
|
const $dom = (selector: string, element: Document = document): HTMLElement => {
|
6
6
|
// 在测试环境中这能优化0.01-0.02ms左右
|
@@ -12,15 +12,17 @@ const $dom = (selector: string, element: Document = document): HTMLElement => {
|
|
12
12
|
|
13
13
|
/**
|
14
14
|
* 获取具有此选择器的所有dom节点
|
15
|
+
* @deprecated Will be removed in the v0.5
|
15
16
|
*/
|
16
17
|
$dom.all = (selector: string, element: Document = document): NodeListOf<HTMLElement> => {
|
17
18
|
return element.querySelectorAll(selector)
|
18
19
|
}
|
19
20
|
/**
|
20
21
|
* 获取具有此选择器的所有dom节点,并依次执行callback函数
|
22
|
+
* @deprecated Will be removed in the v0.5
|
21
23
|
*/
|
22
24
|
$dom.each = (selector: string, callback: (value: HTMLElement, key: number, parent: NodeListOf<Element>) => void, element?: Document): void => {
|
23
25
|
$dom.all(selector, element).forEach(callback)
|
24
26
|
}
|
25
27
|
|
26
|
-
export { $dom
|
28
|
+
export { $dom }
|
@@ -4,6 +4,7 @@ import { createChild } from './proto'
|
|
4
4
|
|
5
5
|
/**
|
6
6
|
* 用途是根据不同的资源名称和类型生成相应的资源 URL。
|
7
|
+
* @deprecated Use smart bundle and import() instead. Will be removed in the v0.5
|
7
8
|
*/
|
8
9
|
const assetUrl = (asset: string, type: string): string => {
|
9
10
|
const str = CONFIG[asset][type]
|
@@ -19,6 +20,9 @@ const assetUrl = (asset: string, type: string): string => {
|
|
19
20
|
return `/${str}`
|
20
21
|
}
|
21
22
|
|
23
|
+
/**
|
24
|
+
@deprecated Use smart bundle and import() instead. Will be removed in the v0.5
|
25
|
+
*/
|
22
26
|
export const vendorJs = (type: string, callback?: Function, condition?: string) => {
|
23
27
|
if (LOCAL[type]) {
|
24
28
|
getScript(assetUrl('js', type), callback || function () {
|
@@ -27,6 +31,9 @@ export const vendorJs = (type: string, callback?: Function, condition?: string)
|
|
27
31
|
}
|
28
32
|
}
|
29
33
|
|
34
|
+
/**
|
35
|
+
@deprecated Use smart bundle and import() instead. Will be removed in the v0.5
|
36
|
+
*/
|
30
37
|
export const vendorCss = (type: string, condition?: string): void => {
|
31
38
|
if (window['css' + type]) {
|
32
39
|
return
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { $dom } from './dom'
|
2
2
|
|
3
|
-
export const insertAfter = function (el:
|
3
|
+
export const insertAfter = function (el: Element, element: HTMLElement): void {
|
4
4
|
const parent = el.parentNode
|
5
5
|
if (parent.lastChild === el) {
|
6
6
|
parent.appendChild(element)
|
@@ -12,7 +12,7 @@ export const insertAfter = function (el: HTMLElement, element: HTMLElement): voi
|
|
12
12
|
/**
|
13
13
|
* 创建一个子节点并放置
|
14
14
|
*/
|
15
|
-
export const createChild = function (parent:
|
15
|
+
export const createChild = function (parent: Element, tag: string, obj: object, positon?: string): HTMLElement {
|
16
16
|
const child = document.createElement(tag)
|
17
17
|
Object.assign(child, obj)
|
18
18
|
switch (positon) {
|
@@ -71,20 +71,11 @@ export const setDisplay = function (el: HTMLElement, d: string): HTMLElement {
|
|
71
71
|
return el
|
72
72
|
}
|
73
73
|
|
74
|
-
// TODO 未完成迁移
|
75
|
-
export const child = function (el: HTMLElement, selector: string): HTMLElement {
|
76
|
-
return $dom(selector, (el as unknown as Document))
|
77
|
-
}
|
78
74
|
export default function initProto () {
|
79
75
|
Object.assign(HTMLElement.prototype, {
|
80
76
|
/**
|
81
|
-
* 找到此节点第一个符合selector选择器的子节点
|
82
|
-
*/
|
83
|
-
child (selector: string): HTMLElement {
|
84
|
-
return $dom(selector, this)
|
85
|
-
},
|
86
|
-
/**
|
87
77
|
* 找到此节点所有符合selector选择器的子节点
|
78
|
+
* @deprecated Will be removed in the v0.5
|
88
79
|
*/
|
89
80
|
find (selector: string): NodeListOf<HTMLElement> {
|
90
81
|
return $dom.all(selector, this)
|
@@ -95,6 +86,7 @@ export default function initProto () {
|
|
95
86
|
* className 是一个或多个要操作的类名,
|
96
87
|
* display 是一个可选的布尔值,用于在执行切换操作时指定类名是否应显示或隐藏。
|
97
88
|
* 该方法会根据操作类型执行相应的类名操作。
|
89
|
+
* @deprecated Will be removed in the v0.5
|
98
90
|
*/
|
99
91
|
_class (type: string, className: string, display?: boolean): void {
|
100
92
|
const classNames = className.indexOf(' ') ? className.split(' ') : [className]
|
@@ -109,6 +101,7 @@ export default function initProto () {
|
|
109
101
|
/**
|
110
102
|
* 这个方法是对 _class 方法的封装,调用时会将操作类型设为 'add',然后执行添加类名的操作。
|
111
103
|
* 最后,它返回当前的 EventTarget,通常是 DOM 元素本身,以支持链式调用。
|
104
|
+
* @deprecated Will be removed in the v0.5
|
112
105
|
*/
|
113
106
|
addClass (className: string): EventTarget {
|
114
107
|
this._class('add', className)
|
@@ -117,6 +110,7 @@ export default function initProto () {
|
|
117
110
|
/**
|
118
111
|
* 这个方法是对 _class 方法的封装,调用时会将操作类型设为 'remove',然后执行移除类名的操作。
|
119
112
|
* 最后,它返回当前的 EventTarget,通常是 DOM 元素本身,以支持链式调用。
|
113
|
+
* @deprecated Will be removed in the v0.5
|
120
114
|
*/
|
121
115
|
removeClass (className: string): EventTarget {
|
122
116
|
this._class('remove', className)
|
@@ -126,6 +120,7 @@ export default function initProto () {
|
|
126
120
|
* 这个方法是对 _class 方法的封装,调用时会将操作类型设为 'toggle',然后执行切换类名的操作。
|
127
121
|
* 如果提供了 display 参数,它将根据布尔值决定是否显示或隐藏类名。
|
128
122
|
* 最后,它返回当前的 EventTarget,通常是 DOM 元素本身,以支持链式调用。
|
123
|
+
* @deprecated Will be removed in the v0.5
|
129
124
|
*/
|
130
125
|
toggleClass (className: string, display?: boolean): EventTarget {
|
131
126
|
this._class('toggle', className, display)
|
@@ -133,6 +128,7 @@ export default function initProto () {
|
|
133
128
|
},
|
134
129
|
/**
|
135
130
|
* 这个方法返回一个布尔值,表示元素是否包含指定的类名。
|
131
|
+
* @deprecated Will be removed in the v0.5
|
136
132
|
*/
|
137
133
|
hasClass (className: string): boolean {
|
138
134
|
return this.classList.contains(className)
|
@@ -1,13 +1,12 @@
|
|
1
1
|
import { $storage } from './storage'
|
2
2
|
import { transition } from './anime'
|
3
|
-
import { $dom } from './dom'
|
4
3
|
import { BODY } from '../globals/globalVars'
|
5
4
|
import { changeTheme } from '../globals/themeColor'
|
6
|
-
import {
|
5
|
+
import { createChild, setDisplay } from './proto'
|
7
6
|
export function initVue () {
|
8
7
|
function changeThemeByBtn () {
|
9
8
|
let c: { (): void; (): void; (): void }
|
10
|
-
const btn =
|
9
|
+
const btn = document.querySelector('.theme').querySelector('.ic')
|
11
10
|
|
12
11
|
const neko = createChild(BODY, 'div', {
|
13
12
|
id: 'neko',
|
@@ -46,5 +45,5 @@ export function initVue () {
|
|
46
45
|
setDisplay(neko, 'block')
|
47
46
|
})
|
48
47
|
}
|
49
|
-
|
48
|
+
document.getElementById('rightNav').querySelector('.theme .ic').addEventListener('click', changeThemeByBtn)
|
50
49
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { $dom } from '../library/dom'
|
2
2
|
|
3
3
|
export const cardActive = () => {
|
4
|
-
if (
|
4
|
+
if (!document.querySelector('.index.wrap')) { return }
|
5
5
|
const io = new IntersectionObserver((entries) => {
|
6
6
|
entries.forEach((article) => {
|
7
7
|
if (article.target.hasClass('show')) {
|
@@ -22,13 +22,14 @@ export const cardActive = () => {
|
|
22
22
|
io.observe(article)
|
23
23
|
})
|
24
24
|
|
25
|
-
|
25
|
+
document.querySelector('.index.wrap .item:first-child').addClass('show')
|
26
26
|
|
27
27
|
$dom.each('.cards .item', (element) => {
|
28
28
|
['mouseenter', 'touchstart'].forEach((item) => {
|
29
29
|
element.addEventListener(item, () => {
|
30
|
-
|
31
|
-
|
30
|
+
const cardEle = document.querySelector('.cards .item.active')
|
31
|
+
if (cardEle) {
|
32
|
+
cardEle.removeClass('active')
|
32
33
|
}
|
33
34
|
element.addClass('active')
|
34
35
|
}, { passive: true })
|
@@ -2,8 +2,9 @@ import { $dom } from '../library/dom'
|
|
2
2
|
import { vendorCss, vendorJs } from '../library/loadFile'
|
3
3
|
import { insertAfter } from '../library/proto'
|
4
4
|
|
5
|
+
// TODO 使用PhotoSwipe替换Fancybox
|
5
6
|
export const postFancybox = (p:string) => {
|
6
|
-
if (
|
7
|
+
if (document.querySelector(p + ' .md img')) {
|
7
8
|
vendorCss('fancybox')
|
8
9
|
vendorCss('justifiedGallery')
|
9
10
|
vendorJs('fancybox', () => {
|
@@ -7,13 +7,13 @@ import { mediaPlayer } from '../player'
|
|
7
7
|
import { getDisplay, setDisplay, wrapObject } from '../library/proto'
|
8
8
|
|
9
9
|
export const postBeauty = () => {
|
10
|
-
if (
|
10
|
+
if (!document.querySelector('.md')) { return }
|
11
11
|
|
12
12
|
if (__shokax_fancybox__) {
|
13
13
|
postFancybox('.post.block')
|
14
14
|
}
|
15
15
|
|
16
|
-
|
16
|
+
(document.querySelector('.post.block') as HTMLTextAreaElement).oncopy = (event) => {
|
17
17
|
showtip(LOCAL.copyright)
|
18
18
|
|
19
19
|
if (LOCAL.nocopy) {
|
@@ -21,12 +21,12 @@ export const postBeauty = () => {
|
|
21
21
|
return
|
22
22
|
}
|
23
23
|
|
24
|
-
const copyright =
|
24
|
+
const copyright = document.getElementById('copyright')
|
25
25
|
if (window.getSelection().toString().length > 30 && copyright) {
|
26
26
|
event.preventDefault()
|
27
|
-
const author = '# ' + copyright.
|
28
|
-
const link = '# ' + copyright.
|
29
|
-
const license = '# ' + copyright.
|
27
|
+
const author = '# ' + (copyright.querySelector('.author') as HTMLElement).innerText
|
28
|
+
const link = '# ' + (copyright.querySelector('.link') as HTMLElement).innerText
|
29
|
+
const license = '# ' + (copyright.querySelector('.license') as HTMLElement).innerText
|
30
30
|
const htmlData = author + '<br>' + link + '<br>' + license + '<br><br>' + window.getSelection().toString().replace(/\r\n/g, '<br>')
|
31
31
|
|
32
32
|
const textData = author + '\n' + link + '\n' + license + '\n\n' + window.getSelection().toString().replace(/\r\n/g, '\n')
|
@@ -68,12 +68,12 @@ export const postBeauty = () => {
|
|
68
68
|
})
|
69
69
|
|
70
70
|
$dom.each('figure.highlight', (element) => {
|
71
|
-
const code_container = element.
|
72
|
-
const caption = element.
|
71
|
+
const code_container = element.querySelector('.code-container') as HTMLElement
|
72
|
+
const caption = element.querySelector('figcaption')
|
73
73
|
|
74
74
|
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>')
|
75
75
|
|
76
|
-
const copyBtn = element.
|
76
|
+
const copyBtn = element.querySelector('.copy-btn')
|
77
77
|
if (LOCAL.nocopy) {
|
78
78
|
copyBtn.remove()
|
79
79
|
} else {
|
@@ -86,42 +86,42 @@ export const postBeauty = () => {
|
|
86
86
|
})
|
87
87
|
|
88
88
|
clipBoard(code, (result) => {
|
89
|
-
target.
|
89
|
+
target.querySelector('.ic').className = result ? 'ic i-check' : 'ic i-times'
|
90
90
|
target.blur()
|
91
91
|
showtip(LOCAL.copyright)
|
92
92
|
})
|
93
93
|
}, { passive: true })
|
94
94
|
copyBtn.addEventListener('mouseleave', (event) => {
|
95
95
|
setTimeout(() => {
|
96
|
-
event.target.
|
96
|
+
(event.target as HTMLElement).querySelector('.ic').className = 'ic i-clipboard'
|
97
97
|
}, 1000)
|
98
98
|
})
|
99
99
|
}
|
100
100
|
|
101
|
-
const breakBtn = element.
|
101
|
+
const breakBtn = element.querySelector('.breakline-btn')
|
102
102
|
breakBtn.addEventListener('click', (event) => {
|
103
|
-
const target = event.currentTarget
|
103
|
+
const target = event.currentTarget as HTMLElement
|
104
104
|
if (element.hasClass('breakline')) {
|
105
105
|
element.removeClass('breakline')
|
106
|
-
target.
|
106
|
+
target.querySelector('.ic').className = 'ic i-align-left'
|
107
107
|
} else {
|
108
108
|
element.addClass('breakline')
|
109
|
-
target.
|
109
|
+
target.querySelector('.ic').className = 'ic i-align-justify'
|
110
110
|
}
|
111
111
|
})
|
112
112
|
|
113
|
-
const fullscreenBtn = element.
|
113
|
+
const fullscreenBtn = element.querySelector('.fullscreen-btn')
|
114
114
|
const removeFullscreen = () => {
|
115
115
|
element.removeClass('fullscreen')
|
116
116
|
element.scrollTop = 0
|
117
117
|
BODY.removeClass('fullscreen')
|
118
|
-
fullscreenBtn.
|
118
|
+
fullscreenBtn.querySelector('.ic').className = 'ic i-expand'
|
119
119
|
}
|
120
120
|
const fullscreenHandle = () => {
|
121
121
|
if (element.hasClass('fullscreen')) {
|
122
122
|
removeFullscreen()
|
123
123
|
if (code_container && code_container.find('tr').length > 15) {
|
124
|
-
const showBtn = code_container.
|
124
|
+
const showBtn = code_container.querySelector('.show-btn')
|
125
125
|
code_container.style.maxHeight = '300px'
|
126
126
|
showBtn.removeClass('open')
|
127
127
|
}
|
@@ -129,9 +129,9 @@ export const postBeauty = () => {
|
|
129
129
|
} else {
|
130
130
|
element.addClass('fullscreen')
|
131
131
|
BODY.addClass('fullscreen')
|
132
|
-
fullscreenBtn.
|
132
|
+
fullscreenBtn.querySelector('.ic').className = 'ic i-compress'
|
133
133
|
if (code_container && code_container.find('tr').length > 15) {
|
134
|
-
const showBtn = code_container.
|
134
|
+
const showBtn = code_container.querySelector('.show-btn')
|
135
135
|
code_container.style.maxHeight = ''
|
136
136
|
showBtn.addClass('open')
|
137
137
|
}
|
@@ -143,7 +143,7 @@ export const postBeauty = () => {
|
|
143
143
|
if (code_container && code_container.find('tr').length > 15) {
|
144
144
|
code_container.style.maxHeight = '300px'
|
145
145
|
code_container.insertAdjacentHTML('beforeend', '<div class="show-btn"><i class="ic i-angle-down"></i></div>')
|
146
|
-
const showBtn = code_container.
|
146
|
+
const showBtn = code_container.querySelector('.show-btn')
|
147
147
|
|
148
148
|
const hideCode = () => {
|
149
149
|
code_container.style.maxHeight = '300px'
|
@@ -174,7 +174,7 @@ export const postBeauty = () => {
|
|
174
174
|
$dom.each('.reward button', (element) => {
|
175
175
|
element.addEventListener('click', (event) => {
|
176
176
|
event.preventDefault()
|
177
|
-
const qr =
|
177
|
+
const qr = document.getElementById('qr')
|
178
178
|
if (getDisplay(qr) === 'inline-flex') {
|
179
179
|
transition(qr, 0)
|
180
180
|
} else {
|
@@ -12,7 +12,7 @@ export function algoliaSearch (pjax) {
|
|
12
12
|
searchClient: algoliasearch(CONFIG.search.appID, CONFIG.search.apiKey),
|
13
13
|
// TODO 移除弃用函数
|
14
14
|
searchFunction (helper) {
|
15
|
-
const searchInput =
|
15
|
+
const searchInput = document.querySelector('.search-input') as HTMLInputElement
|
16
16
|
if (searchInput.value) {
|
17
17
|
helper.search()
|
18
18
|
}
|
@@ -20,7 +20,7 @@ export function algoliaSearch (pjax) {
|
|
20
20
|
})
|
21
21
|
|
22
22
|
search.on('render', () => {
|
23
|
-
pjax.refresh(
|
23
|
+
pjax.refresh(document.getElementById("search-hits"))
|
24
24
|
})
|
25
25
|
|
26
26
|
// Registering Widgets
|
@@ -105,7 +105,7 @@ export function algoliaSearch (pjax) {
|
|
105
105
|
onPopupClose()
|
106
106
|
}
|
107
107
|
})
|
108
|
-
|
108
|
+
document.querySelector('.close-btn').addEventListener('click', onPopupClose)
|
109
109
|
window.addEventListener('pjax:success', onPopupClose)
|
110
110
|
window.addEventListener('keyup', (event) => {
|
111
111
|
if (event.key === 'Escape') {
|
@@ -10,14 +10,14 @@ export const tabFormat = () => {
|
|
10
10
|
|
11
11
|
const id = element.getAttribute('data-id')
|
12
12
|
const title = element.getAttribute('data-title')
|
13
|
-
let box =
|
13
|
+
let box = document.getElementById(id)
|
14
14
|
if (!box) {
|
15
15
|
box = document.createElement('div')
|
16
16
|
box.className = 'tabs'
|
17
17
|
box.id = id
|
18
18
|
box.innerHTML = '<div class="show-btn"></div>'
|
19
19
|
|
20
|
-
const showBtn = box.
|
20
|
+
const showBtn = box.querySelector('.show-btn')
|
21
21
|
showBtn.addEventListener('click', () => {
|
22
22
|
pageScroll(box)
|
23
23
|
})
|
@@ -28,12 +28,12 @@ export const tabFormat = () => {
|
|
28
28
|
first_tab = false
|
29
29
|
}
|
30
30
|
|
31
|
-
let ul = box.
|
31
|
+
let ul = box.querySelector('.nav ul')
|
32
32
|
if (!ul) {
|
33
33
|
ul = createChild(box, 'div', {
|
34
34
|
className: 'nav',
|
35
35
|
innerHTML: '<ul></ul>'
|
36
|
-
}).
|
36
|
+
}).querySelector('ul')
|
37
37
|
}
|
38
38
|
|
39
39
|
const li = createChild(ul, 'li', {
|
@@ -15,19 +15,19 @@ import {
|
|
15
15
|
import { Loader } from '../globals/thirdparty'
|
16
16
|
import { $dom } from '../library/dom'
|
17
17
|
import { mediaPlayer } from '../player'
|
18
|
-
import {
|
18
|
+
import { createChild } from '../library/proto'
|
19
19
|
|
20
20
|
export default function domInit () {
|
21
21
|
$dom.each('.overview .menu > .item', (el) => {
|
22
|
-
|
22
|
+
siteNav.querySelector('.menu').appendChild(el.cloneNode(true))
|
23
23
|
})
|
24
24
|
|
25
25
|
loadCat.addEventListener('click', Loader.vanish)
|
26
26
|
menuToggle.addEventListener('click', sideBarToggleHandle)
|
27
|
-
|
27
|
+
document.querySelector('.dimmer').addEventListener('click', sideBarToggleHandle)
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
quickBtn.querySelector('.down').addEventListener('click', goToBottomHandle)
|
30
|
+
quickBtn.querySelector('.up').addEventListener('click', backToTopHandle)
|
31
31
|
|
32
32
|
if (!toolBtn) {
|
33
33
|
setToolBtn(createChild(siteHeader, 'div', {
|
@@ -36,10 +36,10 @@ export default function domInit () {
|
|
36
36
|
}))
|
37
37
|
}
|
38
38
|
|
39
|
-
setToolPlayer(toolBtn.
|
40
|
-
setBackToTop(toolBtn.
|
41
|
-
setGoToComment(toolBtn.
|
42
|
-
setShowContents(toolBtn.
|
39
|
+
setToolPlayer(toolBtn.querySelector('.player'))
|
40
|
+
setBackToTop(toolBtn.querySelector('.back-to-top'))
|
41
|
+
setGoToComment(toolBtn.querySelector('.chat'))
|
42
|
+
setShowContents(toolBtn.querySelector('.contents'))
|
43
43
|
|
44
44
|
backToTop.addEventListener('click', backToTopHandle)
|
45
45
|
goToComment.addEventListener('click', goToCommentHandle)
|
@@ -48,7 +48,7 @@ export default function domInit () {
|
|
48
48
|
if (__shokax_player__) {
|
49
49
|
mediaPlayer(toolPlayer)
|
50
50
|
|
51
|
-
|
51
|
+
document.querySelector('main').addEventListener('click', () => {
|
52
52
|
toolPlayer.player.mini()
|
53
53
|
})
|
54
54
|
}
|
@@ -27,7 +27,7 @@ export const pjaxReload = () => {
|
|
27
27
|
menuToggle.removeClass('close')
|
28
28
|
}) // 'transition.slideRightOut'
|
29
29
|
}
|
30
|
-
const mainNode =
|
30
|
+
const mainNode = document.getElementById('main')
|
31
31
|
mainNode.innerHTML = ''
|
32
32
|
mainNode.appendChild(loadCat.lastChild.cloneNode(true))
|
33
33
|
pageScroll(0)
|
@@ -76,29 +76,32 @@ export const siteRefresh = (reload) => {
|
|
76
76
|
postBeauty()
|
77
77
|
})
|
78
78
|
|
79
|
-
const
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
79
|
+
const cpel = document.getElementById('copyright')
|
80
|
+
if (cpel) {
|
81
|
+
const comment = new IntersectionObserver((entries) => {
|
82
|
+
entries.forEach((entry) => {
|
83
|
+
if (entry.isIntersecting) {
|
84
|
+
if (__shokax_waline__) {
|
85
|
+
import('../components/comments').then(({walinePageview, walineComment}) => {
|
86
|
+
walinePageview()
|
87
|
+
walineComment()
|
88
|
+
})
|
89
|
+
}
|
90
|
+
if (__shokax_twikoo__) {
|
91
|
+
import('../components/tcomments').then(({twikooComment}) => {
|
92
|
+
twikooComment()
|
93
|
+
})
|
94
|
+
}
|
95
|
+
comment.disconnect()
|
92
96
|
}
|
93
|
-
|
94
|
-
|
97
|
+
})
|
98
|
+
}, {
|
99
|
+
root: null,
|
100
|
+
threshold: 0.2
|
95
101
|
})
|
96
|
-
}, {
|
97
|
-
root: null,
|
98
|
-
threshold: 0.2
|
99
|
-
})
|
100
102
|
|
101
|
-
|
103
|
+
comment.observe(cpel)
|
104
|
+
}
|
102
105
|
|
103
106
|
lazyLoad()
|
104
107
|
|
@@ -40,7 +40,7 @@ const siteInit = () => {
|
|
40
40
|
themeColorListener()
|
41
41
|
|
42
42
|
if (__shokax_search__) {
|
43
|
-
|
43
|
+
document.querySelector('li.item.search > i').addEventListener('click', () => {
|
44
44
|
if (CONFIG.search === null) { return }
|
45
45
|
|
46
46
|
if (!siteSearch) {
|
@@ -55,12 +55,12 @@ const siteInit = () => {
|
|
55
55
|
})
|
56
56
|
|
57
57
|
// Handle and trigger popup window
|
58
|
-
// search 只有一个,不需要 each
|
58
|
+
// TODO search 只有一个,不需要 each
|
59
59
|
$dom.each('.search', (element) => {
|
60
60
|
element.addEventListener('click', () => {
|
61
61
|
document.body.style.overflow = 'hidden'
|
62
62
|
transition(siteSearch, 'shrinkIn', () => {
|
63
|
-
|
63
|
+
(document.querySelector('.search-input') as HTMLInputElement).focus()
|
64
64
|
}) // transition.shrinkIn
|
65
65
|
})
|
66
66
|
})
|
package/source/js/_app/player.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import { CONFIG, originTitle } from './globals/globalVars'
|
2
2
|
import { showtip } from './globals/tools'
|
3
3
|
import { pageScroll } from './library/anime'
|
4
|
-
import { $dom } from './library/dom'
|
5
4
|
import { $storage } from './library/storage'
|
6
5
|
import { tabFormat } from './page/tab'
|
7
6
|
import { createChild, getLeft, getWidth, setDisplay, setWidth } from './library/proto'
|
@@ -68,7 +67,7 @@ export const mediaPlayer = (t, config?) => {
|
|
68
67
|
that.btns[item] = createChild(that.el, 'div', opt)
|
69
68
|
})
|
70
69
|
|
71
|
-
that.btns.volume.bar = that.btns.volume.
|
70
|
+
that.btns.volume.bar = that.btns.volume.querySelector('.bar')
|
72
71
|
},
|
73
72
|
events: {
|
74
73
|
mode (e) {
|
@@ -217,11 +216,11 @@ export const mediaPlayer = (t, config?) => {
|
|
217
216
|
|
218
217
|
preview.el.innerHTML = '<div class="cover"><div class="disc"><img src="' + (current.cover) + '" class="blur" alt="music cover"/></div></div>' +
|
219
218
|
'<div class="info"><h4 class="title">' + current.name + '</h4><span>' + current.artist + '</span>' +
|
220
|
-
'<div class="lrc"></div></div>'
|
219
|
+
'<div class="lrc"></div></div>';
|
221
220
|
|
222
|
-
preview.el.
|
221
|
+
(preview.el as HTMLElement).querySelector('.cover').addEventListener('click', t.player.options.events['play-pause'])
|
223
222
|
|
224
|
-
lyrics.create(preview.el.
|
223
|
+
lyrics.create((preview.el as HTMLElement).querySelector('.lrc'))
|
225
224
|
}
|
226
225
|
}
|
227
226
|
let source
|
@@ -257,7 +256,7 @@ export const mediaPlayer = (t, config?) => {
|
|
257
256
|
if (item.el) { return null }
|
258
257
|
|
259
258
|
const id = 'list-' + t.player._id + '-' + item.group
|
260
|
-
let tab =
|
259
|
+
let tab = document.getElementById(id)
|
261
260
|
if (!tab) {
|
262
261
|
tab = createChild(el, 'div', {
|
263
262
|
id,
|
@@ -270,7 +269,7 @@ export const mediaPlayer = (t, config?) => {
|
|
270
269
|
}
|
271
270
|
}
|
272
271
|
|
273
|
-
item.el = createChild(tab.
|
272
|
+
item.el = createChild(tab.querySelector('ol'), 'li', {
|
274
273
|
title: item.name + ' - ' + item.artist,
|
275
274
|
innerHTML: '<span class="info"><span>' + item.name + '</span><span>' + item.artist + '</span></span>',
|
276
275
|
onclick (event) {
|
@@ -299,13 +298,13 @@ export const mediaPlayer = (t, config?) => {
|
|
299
298
|
},
|
300
299
|
scroll () {
|
301
300
|
const item = this.current()
|
302
|
-
let li = this.el.
|
301
|
+
let li = this.el.querySelector('li.active')
|
303
302
|
li && li.removeClass('active')
|
304
|
-
let tab = this.el.
|
303
|
+
let tab = this.el.querySelector('.tab.active')
|
305
304
|
tab && tab.removeClass('active')
|
306
|
-
li = this.el.
|
305
|
+
li = this.el.querySelectorAll('.nav li')[item.group]
|
307
306
|
li && li.addClass('active')
|
308
|
-
tab = this.el.
|
307
|
+
tab = this.el.querySelectorAll('.tab')[item.group]
|
309
308
|
tab && tab.addClass('active')
|
310
309
|
|
311
310
|
pageScroll(item.el, item.el.offsetTop)
|
@@ -335,9 +334,9 @@ export const mediaPlayer = (t, config?) => {
|
|
335
334
|
innerHTML: (t.player.options.type === 'audio' ? '<div class="preview"></div>' : '') + '<div class="controller"></div><div class="playlist"></div>'
|
336
335
|
}, 'after')
|
337
336
|
|
338
|
-
preview.el = this.el.
|
339
|
-
playlist.el = this.el.
|
340
|
-
controller.el = this.el.
|
337
|
+
preview.el = this.el.querySelector('.preview')
|
338
|
+
playlist.el = this.el.querySelector('.playlist')
|
339
|
+
controller.el = this.el.querySelector('.controller')
|
341
340
|
},
|
342
341
|
hide () {
|
343
342
|
const el = this.el
|