hexo-theme-shokax 0.3.14 → 0.3.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/scripts/filters/locals.js +52 -0
  3. package/scripts/filters/post.js +5 -0
  4. package/scripts/generaters/archive.js +133 -0
  5. package/scripts/generaters/config.js +48 -0
  6. package/scripts/generaters/images.js +23 -0
  7. package/scripts/generaters/index.js +107 -0
  8. package/scripts/generaters/pages.js +15 -0
  9. package/scripts/generaters/script.js +118 -0
  10. package/scripts/helpers/asset.js +147 -0
  11. package/scripts/helpers/engine.js +153 -0
  12. package/scripts/helpers/list_categories.js +84 -0
  13. package/scripts/helpers/summary_ai.js +107 -0
  14. package/scripts/helpers/symbols_count_time.js +69 -0
  15. package/scripts/plugin/check.js +32 -0
  16. package/scripts/plugin/index.js +78 -0
  17. package/scripts/plugin/lib/injects-point.js +20 -0
  18. package/scripts/plugin/lib/injects.js +89 -0
  19. package/scripts/tags/links.js +44 -0
  20. package/scripts/tags/media.js +19 -0
  21. package/scripts/utils.js +14 -0
  22. package/source/js/_app/components/sidebar.js +209 -0
  23. package/source/js/_app/fireworks.js +10 -0
  24. package/source/js/_app/globals/globalVars.js +80 -0
  25. package/source/js/_app/globals/handles.js +98 -0
  26. package/source/js/_app/globals/themeColor.js +62 -0
  27. package/source/js/_app/globals/thirdparty.js +62 -0
  28. package/source/js/_app/globals/tools.js +66 -0
  29. package/source/js/_app/library/anime.js +106 -0
  30. package/source/js/_app/library/dom.js +34 -0
  31. package/source/js/_app/library/loadFile.js +36 -0
  32. package/source/js/_app/library/proto.js +163 -0
  33. package/source/js/_app/library/scriptPjax.js +70 -0
  34. package/source/js/_app/library/storage.js +12 -0
  35. package/source/js/_app/library/vue.js +53 -0
  36. package/source/js/_app/page/comment.js +23 -0
  37. package/source/js/_app/page/common.js +41 -0
  38. package/source/js/_app/page/fancybox.js +65 -0
  39. package/source/js/_app/page/post.js +244 -0
  40. package/source/js/_app/page/search.js +118 -0
  41. package/source/js/_app/page/tab.js +53 -0
  42. package/source/js/_app/pjax/domInit.js +76 -0
  43. package/source/js/_app/pjax/refresh.js +52 -0
  44. package/source/js/_app/pjax/siteInit.js +51 -0
  45. package/source/js/_app/player.js +771 -0
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* global hexo */
7
+ const js_yaml_1 = __importDefault(require("js-yaml"));
8
+ function postMedia(args, content) {
9
+ if (!args[0] || !content) {
10
+ return;
11
+ }
12
+ const list = js_yaml_1.default.load(content);
13
+ switch (args[0]) {
14
+ case 'video':
15
+ case 'audio':
16
+ return `<div class="media-container"><div class="player" data-type="${args[0]}" data-src='${JSON.stringify(list)}'></div></div>`;
17
+ }
18
+ }
19
+ hexo.extend.tag.register('media', postMedia, { ends: true });
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVendorLink = void 0;
4
+ function getVendorLink(hexo, source) {
5
+ const VendorsCfg = hexo.theme.config.vendors;
6
+ const tagIdx = source.indexOf('|');
7
+ if (tagIdx !== -1) {
8
+ return `${VendorsCfg.cdns[source.substring(0, tagIdx)]}/${source.substring(tagIdx + 1)}`;
9
+ }
10
+ else {
11
+ return source;
12
+ }
13
+ }
14
+ exports.getVendorLink = getVendorLink;
@@ -0,0 +1,209 @@
1
+ /* 边栏分区 */
2
+ import { Container, diffY, menuToggle, showContents, sideBar } from '../globals/globalVars';
3
+ import { clipBoard } from '../globals/tools';
4
+ import { pageScroll, transition } from '../library/anime';
5
+ import { $dom } from '../library/dom';
6
+ export const sideBarToggleHandle = (event, force) => {
7
+ if (sideBar.hasClass('on')) {
8
+ sideBar.removeClass('on');
9
+ menuToggle.removeClass('close');
10
+ if (force) {
11
+ // @ts-ignore
12
+ // noinspection JSConstantReassignment
13
+ sideBar.style = '';
14
+ }
15
+ else {
16
+ transition(sideBar, 'slideRightOut');
17
+ }
18
+ }
19
+ else {
20
+ if (force) {
21
+ // @ts-ignore
22
+ // noinspection JSConstantReassignment
23
+ sideBar.style = '';
24
+ }
25
+ else {
26
+ transition(sideBar, 'slideRightIn', () => {
27
+ sideBar.addClass('on');
28
+ menuToggle.addClass('close');
29
+ });
30
+ }
31
+ }
32
+ };
33
+ export const sideBarTab = () => {
34
+ const sideBarInner = sideBar.child('.inner');
35
+ if (sideBar.child('.tab')) {
36
+ sideBarInner.removeChild(sideBar.child('.tab'));
37
+ }
38
+ const list = document.createElement('ul');
39
+ let active = 'active';
40
+ list.className = 'tab';
41
+ ['contents', 'related', 'overview'].forEach((item) => {
42
+ const element = sideBar.child('.panel.' + item);
43
+ if (element.innerHTML.trim().length < 1) {
44
+ if (item === 'contents') {
45
+ showContents.display('none');
46
+ }
47
+ return;
48
+ }
49
+ if (item === 'contents') {
50
+ showContents.display('');
51
+ }
52
+ const tab = document.createElement('li');
53
+ const span = document.createElement('span');
54
+ const text = document.createTextNode(element.attr('data-title'));
55
+ span.appendChild(text);
56
+ tab.appendChild(span);
57
+ tab.addClass(item + ' item');
58
+ if (active) {
59
+ element.addClass(active);
60
+ tab.addClass(active);
61
+ }
62
+ else {
63
+ element.removeClass('active');
64
+ }
65
+ tab.addEventListener('click', (event) => {
66
+ const target = event.currentTarget;
67
+ if (target.hasClass('active'))
68
+ return;
69
+ sideBar.find('.tab .item').forEach((element) => {
70
+ element.removeClass('active');
71
+ });
72
+ sideBar.find('.panel').forEach((element) => {
73
+ element.removeClass('active');
74
+ });
75
+ sideBar.child('.panel.' + target.className.replace(' item', '')).addClass('active');
76
+ target.addClass('active');
77
+ });
78
+ list.appendChild(tab);
79
+ active = '';
80
+ });
81
+ if (list.childNodes.length > 1) {
82
+ sideBarInner.insertBefore(list, sideBarInner.childNodes[0]);
83
+ sideBar.child('.panels').style.paddingTop = '';
84
+ }
85
+ else {
86
+ sideBar.child('.panels').style.paddingTop = '.625rem';
87
+ }
88
+ };
89
+ export const sidebarTOC = () => {
90
+ const activateNavByIndex = (index) => {
91
+ const target = navItems[index];
92
+ if (!target)
93
+ return;
94
+ if (target.hasClass('current')) {
95
+ return;
96
+ }
97
+ $dom.each('.toc .active', (element) => {
98
+ element && element.removeClass('active current');
99
+ });
100
+ sections.forEach((element) => {
101
+ element && element.removeClass('active');
102
+ });
103
+ target.addClass('active current');
104
+ sections[index] && sections[index].addClass('active');
105
+ let parent = target.parentNode;
106
+ while (!parent.matches('.contents')) {
107
+ if (parent.matches('li')) {
108
+ parent.addClass('active');
109
+ const t = $dom(parent.child('a.toc-link').attr('href'));
110
+ if (t) {
111
+ t.addClass('active');
112
+ }
113
+ }
114
+ parent = parent.parentNode;
115
+ }
116
+ // Scrolling to center active TOC element if TOC content is taller than viewport.
117
+ if (getComputedStyle(sideBar).display !== 'none' && tocElement.hasClass('active')) {
118
+ pageScroll(tocElement, target.offsetTop - (tocElement.offsetHeight / 4));
119
+ }
120
+ };
121
+ const navItems = $dom.all('.contents li');
122
+ if (navItems.length < 1) {
123
+ return;
124
+ }
125
+ let sections = [...navItems];
126
+ let activeLock = null;
127
+ sections = sections.map((element, index) => {
128
+ const link = element.child('a.toc-link');
129
+ const anchor = $dom(decodeURI(link.attr('href')));
130
+ if (!anchor)
131
+ return null;
132
+ const alink = anchor.child('a.anchor');
133
+ const anchorScroll = (event) => {
134
+ event.preventDefault();
135
+ const target = $dom(decodeURI(event.currentTarget.attr('href')));
136
+ activeLock = index;
137
+ pageScroll(target, null, () => {
138
+ activateNavByIndex(index);
139
+ activeLock = null;
140
+ });
141
+ };
142
+ // TOC item animation navigate.
143
+ link.addEventListener('click', anchorScroll);
144
+ alink && alink.addEventListener('click', (event) => {
145
+ anchorScroll(event);
146
+ clipBoard(CONFIG.hostname + '/' + LOCAL.path + event.currentTarget.attr('href'));
147
+ });
148
+ return anchor;
149
+ });
150
+ const tocElement = sideBar.child('.contents.panel');
151
+ const findIndex = (entries) => {
152
+ let index = 0;
153
+ let entry = entries[index];
154
+ if (entry.boundingClientRect.top > 0) {
155
+ index = sections.indexOf(entry.target);
156
+ return index === 0 ? 0 : index - 1;
157
+ }
158
+ for (; index < entries.length; index++) {
159
+ if (entries[index].boundingClientRect.top <= 0) {
160
+ entry = entries[index];
161
+ }
162
+ else {
163
+ return sections.indexOf(entry.target);
164
+ }
165
+ }
166
+ return sections.indexOf(entry.target);
167
+ };
168
+ const createIntersectionObserver = () => {
169
+ const observer = new IntersectionObserver((entries) => {
170
+ const index = findIndex(entries) + (diffY < 0 ? 1 : 0);
171
+ if (activeLock === null) {
172
+ activateNavByIndex(index);
173
+ }
174
+ }, {
175
+ rootMargin: '0px 0px -100% 0px', threshold: 0
176
+ });
177
+ sections.forEach((element) => {
178
+ element && observer.observe(element);
179
+ });
180
+ };
181
+ createIntersectionObserver();
182
+ };
183
+ export const backToTopHandle = () => {
184
+ pageScroll(0);
185
+ };
186
+ export const goToBottomHandle = () => {
187
+ pageScroll(parseInt(String(Container.changeOrGetHeight())));
188
+ };
189
+ export const goToCommentHandle = () => {
190
+ pageScroll($dom('#comments'));
191
+ };
192
+ export const menuActive = () => {
193
+ $dom.each('.menu .item:not(.title)', (element) => {
194
+ const target = element.child('a[href]');
195
+ const parentItem = element.parentNode.parentNode;
196
+ if (!target)
197
+ return;
198
+ const isSamePath = target.pathname === location.pathname || target.pathname === location.pathname.replace('index.html', '');
199
+ const isSubPath = !CONFIG.root.startsWith(target.pathname) && location.pathname.startsWith(target.pathname);
200
+ const active = target.hostname === location.hostname && (isSamePath || isSubPath);
201
+ element.toggleClass('active', active);
202
+ if (element.parentNode.child('.active') && parentItem.hasClass('dropdown')) {
203
+ parentItem.removeClass('active').addClass('expand');
204
+ }
205
+ else {
206
+ parentItem.removeClass('expand');
207
+ }
208
+ });
209
+ };
@@ -0,0 +1,10 @@
1
+ import firework from 'mouse-firework';
2
+ /*
3
+ * 烟花分区
4
+ */
5
+ export function initFireworks() {
6
+ if (typeof CONFIG.fireworks === 'undefined') {
7
+ return;
8
+ }
9
+ firework(CONFIG.fireworks);
10
+ }
@@ -0,0 +1,80 @@
1
+ import { $dom } from '../library/dom';
2
+ import initProto from '../library/proto';
3
+ initProto();
4
+ export const statics = CONFIG.statics.indexOf('//') > 0 ? CONFIG.statics : CONFIG.root;
5
+ export const scrollAction = { x: 0, y: 0 };
6
+ export let diffY = 0;
7
+ export let originTitle, titleTime;
8
+ export const BODY = document.getElementsByTagName('body')[0];
9
+ export const HTML = document.documentElement;
10
+ export const Container = $dom('#container');
11
+ export const loadCat = $dom('#loading');
12
+ export const siteNav = $dom('#nav');
13
+ export const siteHeader = $dom('#header');
14
+ export const menuToggle = siteNav.child('.toggle');
15
+ export const quickBtn = $dom('#quick');
16
+ export const sideBar = $dom('#sidebar');
17
+ export const siteBrand = $dom('#brand');
18
+ export let toolBtn = $dom('#tool');
19
+ export let toolPlayer;
20
+ export let backToTop;
21
+ export let goToComment;
22
+ export let showContents;
23
+ export let siteSearch = $dom('#search');
24
+ export let siteNavHeight, headerHightInner, headerHight;
25
+ export let oWinHeight = window.innerHeight;
26
+ export let oWinWidth = window.innerWidth;
27
+ export let LOCAL_HASH = 0;
28
+ export let LOCAL_URL = window.location.href;
29
+ export let pjax;
30
+ export function setSiteNavHeight(value) {
31
+ siteNavHeight = value;
32
+ }
33
+ export function setHeaderHightInner(value) {
34
+ headerHightInner = value;
35
+ }
36
+ export function setHeaderHight(value) {
37
+ headerHight = value;
38
+ }
39
+ export function setOWinHeight(value) {
40
+ oWinHeight = value;
41
+ }
42
+ export function setOWinWidth(value) {
43
+ oWinWidth = value;
44
+ }
45
+ export function setDiffY(value) {
46
+ diffY = value;
47
+ }
48
+ export function setTitleTime(value) {
49
+ titleTime = value;
50
+ }
51
+ export function setLocalHash(value) {
52
+ LOCAL_HASH = value;
53
+ }
54
+ export function setLocalUrl(value) {
55
+ LOCAL_URL = value;
56
+ }
57
+ export function setPjax(value) {
58
+ pjax = value;
59
+ }
60
+ export function setOriginTitle(value) {
61
+ originTitle = value;
62
+ }
63
+ export function setToolPlayer(value) {
64
+ toolPlayer = value;
65
+ }
66
+ export function setBackToTop(value) {
67
+ backToTop = value;
68
+ }
69
+ export function setGoToComment(value) {
70
+ goToComment = value;
71
+ }
72
+ export function setShowContents(value) {
73
+ showContents = value;
74
+ }
75
+ export function setToolBtn(value) {
76
+ toolBtn = value;
77
+ }
78
+ export function setSiteSearch(value) {
79
+ siteSearch = value;
80
+ }
@@ -0,0 +1,98 @@
1
+ import { sideBarToggleHandle } from '../components/sidebar';
2
+ import { $dom, getDocHeight } from '../library/dom';
3
+ import { backToTop, diffY, headerHight, headerHightInner, oWinWidth, originTitle, scrollAction, sideBar, siteBrand, siteHeader, siteNav, statics, titleTime, toolBtn, setSiteNavHeight, setHeaderHightInner, setHeaderHight, setOWinHeight, setOWinWidth, setDiffY, setTitleTime } from './globalVars';
4
+ import { changeMetaTheme } from './themeColor';
5
+ import { Loader } from './thirdparty';
6
+ export const resizeHandle = () => {
7
+ // 获取 siteNav 的高度
8
+ setSiteNavHeight(siteNav.changeOrGetHeight());
9
+ // 获取 siteHeader 的高度
10
+ setHeaderHightInner(siteHeader.changeOrGetHeight());
11
+ // 获取 #waves 的高度
12
+ setHeaderHight(headerHightInner + $dom('#waves').changeOrGetHeight());
13
+ // 判断窗口宽度是否改变
14
+ if (oWinWidth !== window.innerWidth) {
15
+ sideBarToggleHandle(null, 1);
16
+ }
17
+ // 记录窗口高度和宽度
18
+ setOWinHeight(window.innerHeight);
19
+ setOWinWidth(window.innerWidth);
20
+ };
21
+ export const scrollHandle = () => {
22
+ // 获取窗口高度
23
+ const winHeight = window.innerHeight;
24
+ // 获取文档高度
25
+ const docHeight = getDocHeight();
26
+ // 计算可见内容高度
27
+ const contentVisibilityHeight = docHeight > winHeight ? docHeight - winHeight : document.body.scrollHeight - winHeight;
28
+ // 判断页面是否滚动超过 headerHightInner
29
+ const SHOW = window.scrollY > headerHightInner;
30
+ // 判断页面是否开始滚动
31
+ const startScroll = window.scrollY > 0;
32
+ // 根据条件修改 meta theme
33
+ if (SHOW) {
34
+ changeMetaTheme('#FFF');
35
+ }
36
+ else {
37
+ changeMetaTheme('#222');
38
+ }
39
+ // 控制导航栏的显示隐藏
40
+ siteNav.toggleClass('show', SHOW);
41
+ // 控制网站 logo 的显示隐藏
42
+ toolBtn.toggleClass('affix', startScroll);
43
+ // 控制侧边栏的显示隐藏,当滚动高度大于 headerHight 且窗口宽度大于 991px 时显示
44
+ siteBrand.toggleClass('affix', startScroll);
45
+ sideBar.toggleClass('affix', window.scrollY > headerHight && document.body.offsetWidth > 991);
46
+ // 初始化滚动时导航栏的显示方向
47
+ if (typeof scrollAction.y === 'undefined') {
48
+ scrollAction.y = window.scrollY;
49
+ }
50
+ setDiffY(scrollAction.y - window.scrollY);
51
+ // 控制滑动时导航栏显示
52
+ if (diffY < 0) {
53
+ siteNav.removeClass('up');
54
+ siteNav.toggleClass('down', SHOW);
55
+ }
56
+ else if (diffY > 0) {
57
+ siteNav.removeClass('down');
58
+ siteNav.toggleClass('up', SHOW);
59
+ }
60
+ else { /* empty */ }
61
+ scrollAction.y = window.scrollY;
62
+ // 计算滚动百分比
63
+ const scrollPercent = Math.round(Math.min(100 * window.scrollY / contentVisibilityHeight, 100)) + '%';
64
+ // 更新回到顶部按钮的文字
65
+ if (backToTop.child('span').innerText !== scrollPercent) {
66
+ backToTop.child('span').innerText = scrollPercent;
67
+ }
68
+ // 更新百分比进度条的宽度
69
+ if ($dom('#sidebar').hasClass('affix') || $dom('#sidebar').hasClass('on')) {
70
+ $dom('.percent').changeOrGetWidth(scrollPercent);
71
+ }
72
+ };
73
+ // 可见度监听(离开页面和返回时更改document的title)
74
+ export const visibilityListener = () => {
75
+ const iconNode = $dom('[rel="icon"]');
76
+ document.addEventListener('visibilitychange', () => {
77
+ switch (document.visibilityState) {
78
+ case 'hidden':
79
+ iconNode.attr('href', statics + CONFIG.favicon.hidden);
80
+ document.title = LOCAL.favicon.hide;
81
+ if (CONFIG.loader.switch) {
82
+ Loader.show();
83
+ }
84
+ clearTimeout(titleTime);
85
+ break;
86
+ case 'visible':
87
+ iconNode.attr('href', statics + CONFIG.favicon.normal);
88
+ document.title = LOCAL.favicon.show;
89
+ if (CONFIG.loader.switch) {
90
+ Loader.hide(1000);
91
+ }
92
+ setTitleTime(setTimeout(() => {
93
+ document.title = originTitle;
94
+ }, 2000));
95
+ break;
96
+ }
97
+ });
98
+ };
@@ -0,0 +1,62 @@
1
+ import { $storage } from '../library/storage';
2
+ import { $dom } from '../library/dom';
3
+ import { HTML } from './globalVars';
4
+ /**
5
+ * 更改日夜模式
6
+ */
7
+ export const changeTheme = (type) => {
8
+ const btn = $dom('.theme .ic');
9
+ if (type === 'dark') {
10
+ HTML.attr('data-theme', type);
11
+ btn.removeClass('i-sun');
12
+ btn.addClass('i-moon');
13
+ }
14
+ else {
15
+ HTML.attr('data-theme', null);
16
+ btn.removeClass('i-moon');
17
+ btn.addClass('i-sun');
18
+ }
19
+ };
20
+ /**
21
+ * 自动调整黑夜白天
22
+ * 优先级: 手动选择>时间>跟随系统
23
+ */
24
+ export const autoDarkmode = () => {
25
+ if (CONFIG.auto_dark.enable) {
26
+ if (new Date().getHours() >= CONFIG.auto_dark.start || new Date().getHours() <= CONFIG.auto_dark.end) {
27
+ changeTheme('dark');
28
+ }
29
+ else {
30
+ changeTheme();
31
+ }
32
+ }
33
+ };
34
+ /**
35
+ * 更改主题的meta
36
+ */
37
+ export const changeMetaTheme = (color) => {
38
+ if (HTML.attr('data-theme') === 'dark') {
39
+ color = '#222';
40
+ }
41
+ $dom('meta[name="theme-color"]').attr('content', color);
42
+ };
43
+ // 记忆日夜模式切换和系统亮暗模式监听
44
+ export const themeColorListener = () => {
45
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (mediaQueryList) => {
46
+ if (mediaQueryList.matches) {
47
+ changeTheme('dark');
48
+ }
49
+ else {
50
+ changeTheme();
51
+ }
52
+ });
53
+ const t = $storage.get('theme');
54
+ if (t) {
55
+ changeTheme(t);
56
+ }
57
+ else {
58
+ if (CONFIG.darkmode) {
59
+ changeTheme('dark');
60
+ }
61
+ }
62
+ };
@@ -0,0 +1,62 @@
1
+ // 与第三方js的交互或第三方嵌入js
2
+ import { loadCat } from './globalVars';
3
+ import { transition } from '../library/anime';
4
+ // 加载动画
5
+ export const Loader = {
6
+ timer: undefined,
7
+ lock: false,
8
+ show() {
9
+ clearTimeout(this.timer);
10
+ document.body.removeClass('loaded');
11
+ loadCat.attr('style', 'display:block');
12
+ Loader.lock = false;
13
+ },
14
+ hide(sec) {
15
+ if (!CONFIG.loader.start) {
16
+ sec = -1;
17
+ }
18
+ this.timer = setTimeout(this.vanish, sec || 3000);
19
+ },
20
+ vanish() {
21
+ if (Loader.lock) {
22
+ return;
23
+ }
24
+ if (CONFIG.loader.start) {
25
+ transition(loadCat, 0);
26
+ }
27
+ document.body.addClass('loaded');
28
+ Loader.lock = true;
29
+ }
30
+ };
31
+ export const isOutime = () => {
32
+ let updateTime;
33
+ if (CONFIG.outime.enable && LOCAL.outime) {
34
+ const times = document.getElementsByTagName('time');
35
+ if (times.length === 0) {
36
+ return;
37
+ }
38
+ const posts = document.getElementsByClassName('body md');
39
+ if (posts.length === 0) {
40
+ return;
41
+ }
42
+ const now = Date.now(); // 当前时间戳
43
+ const pubTime = new Date(times[0].dateTime); // 文章发布时间戳
44
+ if (times.length === 1) {
45
+ updateTime = pubTime; // 文章发布时间亦是最后更新时间
46
+ }
47
+ else {
48
+ updateTime = new Date(times[1].dateTime); // 文章最后更新时间戳
49
+ }
50
+ // @ts-ignore
51
+ const interval = parseInt(String(now - updateTime)); // 时间差
52
+ const days = parseInt(String(CONFIG.outime.days)) || 30; // 设置时效,默认硬编码 30 天
53
+ // 最后一次更新时间超过 days 天(毫秒)
54
+ if (interval > (days * 86400000)) {
55
+ // @ts-ignore
56
+ const publish = parseInt(String((now - pubTime) / 86400000));
57
+ const updated = parseInt(String(interval / 86400000));
58
+ const template = LOCAL.template.replace('{{publish}}', String(publish)).replace('{{updated}}', String(updated));
59
+ posts[0].insertAdjacentHTML('afterbegin', template);
60
+ }
61
+ }
62
+ };
@@ -0,0 +1,66 @@
1
+ import { pageScroll } from '../library/anime';
2
+ import { $dom } from '../library/dom';
3
+ import { $storage } from '../library/storage';
4
+ import { BODY, LOCAL_HASH, LOCAL_URL, scrollAction, setLocalHash } from './globalVars';
5
+ // 显示提示(现阶段用于版权及复制结果提示)
6
+ export const showtip = (msg) => {
7
+ if (!msg) {
8
+ return;
9
+ }
10
+ const tipbox = BODY.createChild('div', {
11
+ innerHTML: msg,
12
+ className: 'tip'
13
+ });
14
+ setTimeout(() => {
15
+ tipbox.addClass('hide');
16
+ setTimeout(() => {
17
+ BODY.removeChild(tipbox);
18
+ }, 300);
19
+ }, 3000);
20
+ };
21
+ export const pagePosition = () => {
22
+ // 判断配置项是否开启了自动记录滚动位置
23
+ if (CONFIG.auto_scroll) {
24
+ // 将当前页面的滚动位置存入本地缓存
25
+ $storage.set(LOCAL_URL, String(scrollAction.y));
26
+ }
27
+ };
28
+ export const positionInit = (comment) => {
29
+ // 获取页面锚点
30
+ const anchor = window.location.hash;
31
+ let target = null;
32
+ if (LOCAL_HASH) {
33
+ $storage.del(LOCAL_URL);
34
+ return;
35
+ }
36
+ if (anchor) {
37
+ target = $dom(decodeURI(anchor));
38
+ }
39
+ else {
40
+ target = CONFIG.auto_scroll ? parseInt($storage.get(LOCAL_URL)) : 0;
41
+ }
42
+ if (target) {
43
+ pageScroll(target);
44
+ setLocalHash(1);
45
+ }
46
+ if (comment && anchor && !LOCAL_HASH) {
47
+ pageScroll(target);
48
+ setLocalHash(1);
49
+ }
50
+ };
51
+ /*
52
+ 基于clipboard API的复制功能,仅在https环境下有效
53
+ */
54
+ export const clipBoard = (str, callback) => {
55
+ if (navigator.clipboard && window.isSecureContext) {
56
+ navigator.clipboard.writeText(str).then(() => {
57
+ callback && callback(true);
58
+ }, () => {
59
+ callback && callback(false);
60
+ });
61
+ }
62
+ else {
63
+ console.error('Too old browser, clipborad API not supported.');
64
+ callback && callback(false);
65
+ }
66
+ };