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
@@ -1,771 +0,0 @@
1
- import { originTitle } from './globals/globalVars';
2
- import { showtip } from './globals/tools';
3
- import { pageScroll } from './library/anime';
4
- import { $dom } from './library/dom';
5
- import { $storage } from './library/storage';
6
- import { tabFormat } from './page/tab';
7
- let NOWPLAYING = null;
8
- const isMobile = /mobile/i.test(window.navigator.userAgent);
9
- export const mediaPlayer = /* @__PURE__ */ (t, config) => {
10
- const buttons = {
11
- el: {},
12
- create() {
13
- if (!t.player.options.btns) {
14
- return;
15
- }
16
- t.player.options.btns.forEach((item) => {
17
- if (buttons.el[item]) {
18
- return;
19
- }
20
- buttons.el[item] = t.createChild('div', {
21
- className: item + ' btn',
22
- onclick(event) {
23
- t.player.fetch().then(() => {
24
- t.player.options.events[item](event);
25
- });
26
- }
27
- });
28
- });
29
- }
30
- };
31
- const controller = {
32
- el: null,
33
- btns: {
34
- mode: undefined,
35
- volume: undefined
36
- },
37
- step: 'next',
38
- create: () => {
39
- if (!t.player.options.controls) {
40
- return;
41
- }
42
- const that = controller;
43
- t.player.options.controls.forEach((item) => {
44
- if (that.btns[item]) {
45
- return;
46
- }
47
- const opt = {
48
- onclick(event) {
49
- that.events[item] ? that.events[item](event) : t.player.options.events[item](event);
50
- }
51
- };
52
- switch (item) {
53
- case 'volume':
54
- opt.className = ' ' + (source.muted ? 'off' : 'on');
55
- opt.innerHTML = '<div class="bar"></div>';
56
- opt['on' + utils.nameMap.dragStart] = that.events.volume;
57
- opt.onclick = null;
58
- break;
59
- case 'mode':
60
- opt.className = ' ' + t.player.options.mode;
61
- break;
62
- default:
63
- opt.className = '';
64
- break;
65
- }
66
- opt.className = item + opt.className + ' btn';
67
- that.btns[item] = that.el.createChild('div', opt);
68
- });
69
- that.btns.volume.bar = that.btns.volume.child('.bar');
70
- },
71
- events: {
72
- mode(e) {
73
- switch (t.player.options.mode) {
74
- case 'loop':
75
- t.player.options.mode = 'random';
76
- break;
77
- case 'random':
78
- t.player.options.mode = 'order';
79
- break;
80
- default:
81
- t.player.options.mode = 'loop';
82
- }
83
- controller.btns.mode.className = 'mode ' + t.player.options.mode + ' btn';
84
- $storage.set('_PlayerMode', t.player.options.mode);
85
- },
86
- volume(e) {
87
- e.preventDefault();
88
- const current = e.currentTarget;
89
- let drag = false;
90
- const thumbMove = (e) => {
91
- e.preventDefault();
92
- t.player.volume(controller.percent(e, current));
93
- drag = true;
94
- };
95
- const thumbUp = (e) => {
96
- e.preventDefault();
97
- current.removeEventListener(utils.nameMap.dragEnd, thumbUp);
98
- current.removeEventListener(utils.nameMap.dragMove, thumbMove);
99
- if (drag) {
100
- t.player.muted();
101
- t.player.volume(controller.percent(e, current));
102
- }
103
- else {
104
- if (source.muted) {
105
- t.player.muted();
106
- t.player.volume(source.volume);
107
- }
108
- else {
109
- t.player.muted('muted');
110
- controller.update(0);
111
- }
112
- }
113
- };
114
- current.addEventListener(utils.nameMap.dragMove, thumbMove);
115
- current.addEventListener(utils.nameMap.dragEnd, thumbUp);
116
- },
117
- backward(e) {
118
- controller.step = 'prev';
119
- t.player.mode();
120
- },
121
- forward(e) {
122
- controller.step = 'next';
123
- t.player.mode();
124
- }
125
- },
126
- update(percent) {
127
- controller.btns.volume.className = 'volume ' + (!source.muted && percent > 0 ? 'on' : 'off') + ' btn';
128
- controller.btns.volume.bar.changeOrGetWidth(Math.floor(percent * 100) + '%');
129
- },
130
- percent(e, el) {
131
- let percentage = ((e.clientX || e.changedTouches[0].clientX) - el.left()) / el.changeOrGetWidth();
132
- percentage = Math.max(percentage, 0);
133
- return Math.min(percentage, 1);
134
- }
135
- };
136
- const progress = {
137
- el: null,
138
- bar: null,
139
- create() {
140
- const current = playlist.current().el;
141
- if (current) {
142
- if (progress.el) {
143
- progress.el.parentNode.removeClass('current')
144
- .removeEventListener(utils.nameMap.dragStart, progress.drag);
145
- progress.el.remove();
146
- }
147
- progress.el = current.createChild('div', {
148
- className: 'progress'
149
- });
150
- progress.el.attr('data-dtime', utils.secondToTime(0));
151
- progress.bar = progress.el.createChild('div', {
152
- className: 'bar'
153
- });
154
- current.addClass('current');
155
- current.addEventListener(utils.nameMap.dragStart, progress.drag);
156
- playlist.scroll();
157
- }
158
- },
159
- update(percent) {
160
- progress.bar.changeOrGetWidth(Math.floor(percent * 100) + '%');
161
- progress.el.attr('data-ptime', utils.secondToTime(percent * source.duration));
162
- },
163
- seeking(type) {
164
- if (type) {
165
- progress.el.addClass('seeking');
166
- }
167
- else {
168
- progress.el.removeClass('seeking');
169
- }
170
- },
171
- percent(e, el) {
172
- let percentage = ((e.clientX || e.changedTouches[0].clientX) - el.left()) / el.changeOrGetWidth();
173
- percentage = Math.max(percentage, 0);
174
- return Math.min(percentage, 1);
175
- },
176
- drag(e) {
177
- e.preventDefault();
178
- const current = playlist.current().el;
179
- const thumbMove = (e) => {
180
- e.preventDefault();
181
- const percentage = progress.percent(e, current);
182
- progress.update(percentage);
183
- lyrics.update(percentage * source.duration);
184
- };
185
- const thumbUp = (e) => {
186
- e.preventDefault();
187
- current.removeEventListener(utils.nameMap.dragEnd, thumbUp);
188
- current.removeEventListener(utils.nameMap.dragMove, thumbMove);
189
- const percentage = progress.percent(e, current);
190
- progress.update(percentage);
191
- t.player.seek(percentage * source.duration);
192
- source.disableTimeupdate = false;
193
- progress.seeking(false);
194
- };
195
- source.disableTimeupdate = true;
196
- progress.seeking(true);
197
- current.addEventListener(utils.nameMap.dragMove, thumbMove);
198
- current.addEventListener(utils.nameMap.dragEnd, thumbUp);
199
- }
200
- };
201
- const preview = {
202
- el: null,
203
- create() {
204
- const current = playlist.current();
205
- preview.el.innerHTML = '<div class="cover"><div class="disc"><img src="' + (current.cover) + '" class="blur" alt="music cover"/></div></div>' +
206
- '<div class="info"><h4 class="title">' + current.name + '</h4><span>' + current.artist + '</span>' +
207
- '<div class="lrc"></div></div>';
208
- preview.el.child('.cover').addEventListener('click', t.player.options.events['play-pause']);
209
- lyrics.create(preview.el.child('.lrc'));
210
- }
211
- };
212
- let source;
213
- const playlist = {
214
- el: null,
215
- data: [],
216
- index: -1,
217
- errnum: 0,
218
- add: (group, list) => {
219
- list.forEach((item) => {
220
- item.group = group;
221
- item.name = item.name || item.title || 'Meida name';
222
- item.artist = item.artist || item.author || 'Anonymous';
223
- item.cover = item.cover || item.pic;
224
- item.type = item.type || 'normal';
225
- playlist.data.push(item);
226
- });
227
- },
228
- clear() {
229
- playlist.data = [];
230
- playlist.el.innerHTML = '';
231
- if (playlist.index !== -1) {
232
- playlist.index = -1;
233
- t.player.fetch();
234
- }
235
- },
236
- create() {
237
- const el = playlist.el;
238
- playlist.data.map((item, index) => {
239
- if (item.el) {
240
- return null;
241
- }
242
- const id = 'list-' + t.player._id + '-' + item.group;
243
- let tab = $dom('#' + id);
244
- if (!tab) {
245
- tab = el.createChild('div', {
246
- id,
247
- className: t.player.group ? 'tab' : '',
248
- innerHTML: '<ol></ol>'
249
- });
250
- if (t.player.group) {
251
- tab.attr('data-title', t.player.options.rawList[item.group].title)
252
- // @ts-ignore
253
- .attr('data-id', t.player._id);
254
- }
255
- }
256
- item.el = tab.child('ol').createChild('li', {
257
- title: item.name + ' - ' + item.artist,
258
- innerHTML: '<span class="info"><span>' + item.name + '</span><span>' + item.artist + '</span></span>',
259
- onclick(event) {
260
- const current = event.currentTarget;
261
- if (playlist.index === index && progress.el) {
262
- if (source.paused) {
263
- t.player.play();
264
- }
265
- else {
266
- t.player.seek(source.duration * progress.percent(event, current));
267
- }
268
- return;
269
- }
270
- t.player.switch(index);
271
- t.player.play();
272
- }
273
- });
274
- return item;
275
- });
276
- tabFormat();
277
- },
278
- current() {
279
- return this.data[this.index];
280
- },
281
- scroll() {
282
- const item = this.current();
283
- let li = this.el.child('li.active');
284
- li && li.removeClass('active');
285
- let tab = this.el.child('.tab.active');
286
- tab && tab.removeClass('active');
287
- li = this.el.find('.nav li')[item.group];
288
- li && li.addClass('active');
289
- tab = this.el.find('.tab')[item.group];
290
- tab && tab.addClass('active');
291
- pageScroll(item.el, item.el.offsetTop);
292
- return this;
293
- },
294
- title() {
295
- if (source.paused) {
296
- return;
297
- }
298
- const current = this.current();
299
- document.title = 'Now Playing...' + current.name + ' - ' + current.artist + ' | ' + originTitle;
300
- },
301
- error() {
302
- const current = this.current();
303
- current.el.removeClass('current').addClass('error');
304
- current.error = true;
305
- this.errnum++;
306
- }
307
- };
308
- const info = {
309
- el: null,
310
- create() {
311
- if (this.el) {
312
- return;
313
- }
314
- this.el = t.createChild('div', {
315
- className: 'player-info',
316
- innerHTML: (t.player.options.type === 'audio' ? '<div class="preview"></div>' : '') + '<div class="controller"></div><div class="playlist"></div>'
317
- }, 'after');
318
- preview.el = this.el.child('.preview');
319
- playlist.el = this.el.child('.playlist');
320
- controller.el = this.el.child('.controller');
321
- },
322
- hide() {
323
- const el = this.el;
324
- el.addClass('hide');
325
- window.setTimeout(() => {
326
- el.removeClass('show hide');
327
- }, 300);
328
- }
329
- };
330
- const option = {
331
- type: 'audio',
332
- mode: 'random',
333
- btns: ['play-pause', 'music'],
334
- controls: ['mode', 'backward', 'play-pause', 'forward', 'volume'],
335
- events: {
336
- 'play-pause'(event) {
337
- if (source.paused) {
338
- t.player.play();
339
- }
340
- else {
341
- t.player.pause();
342
- }
343
- },
344
- music(event) {
345
- if (info.el.hasClass('show')) {
346
- info.hide();
347
- }
348
- else {
349
- info.el.addClass('show');
350
- playlist.scroll().title();
351
- }
352
- }
353
- }
354
- };
355
- const utils = {
356
- random(len) {
357
- return Math.floor((Math.random() * len));
358
- },
359
- parse(link) {
360
- let result = [];
361
- [
362
- ['music.163.com.*song.*id=(\\d+)', 'netease', 'song'],
363
- ['music.163.com.*album.*id=(\\d+)', 'netease', 'album'],
364
- ['music.163.com.*artist.*id=(\\d+)', 'netease', 'artist'],
365
- ['music.163.com.*playlist.*id=(\\d+)', 'netease', 'playlist'],
366
- ['music.163.com.*discover/toplist.*id=(\\d+)', 'netease', 'playlist'],
367
- ['y.qq.com.*song/(\\w+)(.html)?', 'tencent', 'song'],
368
- ['y.qq.com.*album/(\\w+)(.html)?', 'tencent', 'album'],
369
- ['y.qq.com.*singer/(\\w+)(.html)?', 'tencent', 'artist'],
370
- ['y.qq.com.*playsquare/(\\w+)(.html)?', 'tencent', 'playlist'],
371
- ['y.qq.com.*playlist/(\\w+)(.html)?', 'tencent', 'playlist'],
372
- ['xiami.com.*song/(\\w+)', 'xiami', 'song'],
373
- ['xiami.com.*album/(\\w+)', 'xiami', 'album'],
374
- ['xiami.com.*artist/(\\w+)', 'xiami', 'artist'],
375
- ['xiami.com.*collect/(\\w+)', 'xiami', 'playlist']
376
- ].forEach((rule) => {
377
- const patt = new RegExp(rule[0]);
378
- const res = patt.exec(link);
379
- if (res !== null) {
380
- result = [rule[1], rule[2], res[1]];
381
- }
382
- });
383
- return result;
384
- },
385
- fetch(source) {
386
- const list = [];
387
- return new Promise((resolve, reject) => {
388
- source.forEach((raw) => {
389
- const meta = utils.parse(raw);
390
- if (meta[0]) {
391
- const skey = JSON.stringify(meta);
392
- const playlist = $storage.get(skey);
393
- if (playlist) {
394
- // list.push.apply(list, JSON.parse(playlist))
395
- list.push(...JSON.parse(playlist));
396
- resolve(list);
397
- }
398
- else {
399
- fetch(`${CONFIG.playerAPI}/meting/?server=` + meta[0] + '&type=' + meta[1] + '&id=' + meta[2] + '&r=' + Math.random())
400
- .then((response) => {
401
- return response.json();
402
- }).then((json) => {
403
- $storage.set(skey, JSON.stringify(json));
404
- // list.push.apply(list, json)
405
- list.push(...json);
406
- resolve(list);
407
- }).catch((ex) => {
408
- // (不)处理catch的异常
409
- });
410
- }
411
- }
412
- else {
413
- list.push(raw);
414
- resolve(list);
415
- }
416
- });
417
- });
418
- },
419
- secondToTime(second) {
420
- const add0 = (num) => {
421
- return isNaN(num) ? '00' : (num < 10 ? '0' + num : '' + num);
422
- };
423
- const hour = Math.floor(second / 3600);
424
- const min = Math.floor((second - hour * 3600) / 60);
425
- const sec = Math.floor(second - hour * 3600 - min * 60);
426
- return (hour > 0 ? [hour, min, sec] : [min, sec]).map(add0).join(':');
427
- },
428
- nameMap: {
429
- dragStart: isMobile ? 'touchstart' : 'mousedown',
430
- dragMove: isMobile ? 'touchmove' : 'mousemove',
431
- dragEnd: isMobile ? 'touchend' : 'mouseup'
432
- }
433
- };
434
- source = null;
435
- t.player = {
436
- _id: utils.random(999999),
437
- group: true,
438
- // 加载播放列表
439
- load(newList) {
440
- let d = '';
441
- if (newList && newList.length > 0) {
442
- if (this.options.rawList !== newList) {
443
- this.options.rawList = newList;
444
- playlist.clear();
445
- // 获取新列表
446
- this.fetch();
447
- }
448
- }
449
- else {
450
- // 没有列表时,隐藏按钮
451
- d = 'none';
452
- this.pause();
453
- }
454
- for (const el in buttons.el) {
455
- buttons.el[el].display(d);
456
- }
457
- return this;
458
- },
459
- fetch() {
460
- return new Promise((resolve, reject) => {
461
- if (playlist.data.length > 0) {
462
- resolve(true);
463
- }
464
- else {
465
- if (this.options.rawList) {
466
- const promises = [];
467
- this.options.rawList.forEach((raw, index) => {
468
- promises.push(new Promise((resolve, reject) => {
469
- let group = index;
470
- let source;
471
- if (!raw.list) {
472
- group = 0;
473
- this.group = false;
474
- source = [raw];
475
- }
476
- else {
477
- this.group = true;
478
- source = raw.list;
479
- }
480
- utils.fetch(source).then((list) => {
481
- playlist.add(group, list);
482
- resolve(0);
483
- });
484
- }));
485
- });
486
- Promise.all(promises).then(() => {
487
- resolve(true);
488
- });
489
- }
490
- }
491
- }).then((c) => {
492
- if (c) {
493
- playlist.create();
494
- controller.create();
495
- this.mode();
496
- }
497
- });
498
- },
499
- // 根据模式切换当前曲目index
500
- mode() {
501
- const total = playlist.data.length;
502
- if (!total || playlist.errnum === total) {
503
- return;
504
- }
505
- const step = controller.step === 'next' ? 1 : -1;
506
- const next = () => {
507
- let index = playlist.index + step;
508
- if (index > total || index < 0) {
509
- index = controller.step === 'next' ? 0 : total - 1;
510
- }
511
- playlist.index = index;
512
- };
513
- const random = () => {
514
- const p = utils.random(total);
515
- if (playlist.index !== p) {
516
- playlist.index = p;
517
- }
518
- else {
519
- next();
520
- }
521
- };
522
- switch (this.options.mode) {
523
- case 'random':
524
- random();
525
- break;
526
- case 'order':
527
- next();
528
- break;
529
- case 'loop':
530
- if (controller.step) {
531
- next();
532
- }
533
- if (playlist.index === -1) {
534
- random();
535
- }
536
- break;
537
- }
538
- this.init();
539
- },
540
- // 直接设置当前曲目index
541
- switch(index) {
542
- if (typeof index === 'number' &&
543
- index !== playlist.index &&
544
- playlist.current() &&
545
- !playlist.current().error) {
546
- playlist.index = index;
547
- this.init();
548
- }
549
- },
550
- // 更新source为当前曲目index
551
- init() {
552
- const item = playlist.current();
553
- if (!item || item.error) {
554
- this.mode();
555
- return;
556
- }
557
- let playing = false;
558
- if (!source.paused) {
559
- playing = true;
560
- this.stop();
561
- }
562
- source.attr('src', item.url);
563
- source.attr('title', item.name + ' - ' + item.artist);
564
- this.volume($storage.get('_PlayerVolume') || '0.7');
565
- this.muted($storage.get('_PlayerMuted'));
566
- progress.create();
567
- if (this.options.type === 'audio') {
568
- preview.create();
569
- }
570
- if (playing === true) {
571
- this.play();
572
- }
573
- },
574
- play() {
575
- NOWPLAYING && NOWPLAYING.player.pause();
576
- if (playlist.current().error) {
577
- this.mode();
578
- return;
579
- }
580
- source.play().then(() => {
581
- playlist.scroll();
582
- }).catch((e) => {
583
- // 不处理错误
584
- });
585
- },
586
- pause() {
587
- source.pause();
588
- document.title = originTitle;
589
- },
590
- stop() {
591
- source.pause();
592
- source.currentTime = 0;
593
- document.title = originTitle;
594
- },
595
- seek(time) {
596
- time = Math.max(time, 0);
597
- time = Math.min(time, source.duration);
598
- source.currentTime = time;
599
- progress.update(time / source.duration);
600
- },
601
- muted(status) {
602
- if (status === 'muted') {
603
- source.muted = status;
604
- $storage.set('_PlayerMuted', status);
605
- controller.update(0);
606
- }
607
- else {
608
- $storage.del('_PlayerMuted');
609
- source.muted = false;
610
- controller.update(source.volume);
611
- }
612
- },
613
- volume(percentage) {
614
- if (!isNaN(percentage)) {
615
- controller.update(percentage);
616
- $storage.set('_PlayerVolume', percentage);
617
- source.volume = percentage;
618
- }
619
- },
620
- mini() {
621
- info.hide();
622
- }
623
- };
624
- const lyrics = {
625
- el: null,
626
- data: null,
627
- index: 0,
628
- create(box) {
629
- const current = playlist.index;
630
- // const that = this
631
- const raw = playlist.current().lrc;
632
- const callback = (body) => {
633
- if (current !== playlist.index) {
634
- return;
635
- }
636
- this.data = this.parse(body);
637
- let lrc = '';
638
- this.data.forEach((line, index) => {
639
- lrc += '<p' + (index === 0 ? ' class="current"' : '') + '>' + line[1] + '</p>';
640
- });
641
- this.el = box.createChild('div', {
642
- className: 'inner',
643
- innerHTML: lrc
644
- }, 'replace');
645
- this.index = 0;
646
- };
647
- if (raw.startsWith('http')) {
648
- this.fetch(raw, callback);
649
- }
650
- else {
651
- callback(raw);
652
- }
653
- },
654
- update(currentTime) {
655
- if (!this.data) {
656
- return;
657
- }
658
- if (this.index > this.data.length - 1 || currentTime < this.data[this.index][0] || (!this.data[this.index + 1] || currentTime >= this.data[this.index + 1][0])) {
659
- for (let i = 0; i < this.data.length; i++) {
660
- if (currentTime >= this.data[i][0] && (!this.data[i + 1] || currentTime < this.data[i + 1][0])) {
661
- this.index = i;
662
- const y = -(this.index - 1);
663
- this.el.style.transform = 'translateY(' + y + 'rem)';
664
- // this.el.style.webkitTransform = 'translateY(' + y + 'rem)';
665
- this.el.getElementsByClassName('current')[0].removeClass('current');
666
- this.el.getElementsByTagName('p')[i].addClass('current');
667
- }
668
- }
669
- }
670
- },
671
- parse(lrc_s) {
672
- if (lrc_s) {
673
- lrc_s = lrc_s.replace(/([^\]^\n])\[/g, (match, p1) => {
674
- return p1 + '\n[';
675
- });
676
- const lyric = lrc_s.split('\n');
677
- let lrc = [];
678
- const lyricLen = lyric.length;
679
- for (let i = 0; i < lyricLen; i++) {
680
- // match lrc time
681
- const lrcTimes = lyric[i].match(/\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g);
682
- // match lrc text
683
- const lrcText = lyric[i]
684
- .replace(/.*\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/g, '')
685
- .replace(/<(\d{2}):(\d{2})(\.(\d{2,3}))?>/g, '')
686
- .trim();
687
- if (lrcTimes) {
688
- // handle multiple time tag
689
- const timeLen = lrcTimes.length;
690
- for (let j = 0; j < timeLen; j++) {
691
- const oneTime = /\[(\d{2}):(\d{2})(\.(\d{2,3}))?]/.exec(lrcTimes[j]);
692
- const min2sec = oneTime[1] * 60;
693
- const sec2sec = parseInt(oneTime[2]);
694
- const msec2sec = oneTime[4] ? parseInt(oneTime[4]) / ((oneTime[4] + '').length === 2 ? 100 : 1000) : 0;
695
- const lrcTime = min2sec + sec2sec + msec2sec;
696
- lrc.push([lrcTime, lrcText]);
697
- }
698
- }
699
- }
700
- // sort by time
701
- lrc = lrc.filter((item) => item[1]);
702
- lrc.sort((a, b) => a[0] - b[0]);
703
- return lrc;
704
- }
705
- else {
706
- return [];
707
- }
708
- },
709
- fetch(url, callback) {
710
- fetch(url)
711
- .then((response) => {
712
- return response.text();
713
- }).then((body) => {
714
- callback(body);
715
- }).catch((ex) => {
716
- // 不处理错误
717
- });
718
- }
719
- };
720
- const events = {
721
- onerror() {
722
- playlist.error();
723
- t.player.mode();
724
- },
725
- ondurationchange() {
726
- if (source.duration !== 1) {
727
- progress.el.attr('data-dtime', utils.secondToTime(source.duration));
728
- }
729
- },
730
- onloadedmetadata() {
731
- t.player.seek(0);
732
- progress.el.attr('data-dtime', utils.secondToTime(source.duration));
733
- },
734
- onplay() {
735
- t.parentNode.addClass('playing');
736
- showtip(this.attr('title'));
737
- NOWPLAYING = t;
738
- },
739
- onpause() {
740
- t.parentNode.removeClass('playing');
741
- NOWPLAYING = null;
742
- },
743
- ontimeupdate() {
744
- if (!this.disableTimeupdate) {
745
- progress.update(this.currentTime / this.duration);
746
- lyrics.update(this.currentTime);
747
- }
748
- },
749
- onended(argument) {
750
- t.player.mode();
751
- t.player.play();
752
- }
753
- };
754
- const init = (config) => {
755
- if (t.player.created) {
756
- return;
757
- }
758
- t.player.options = Object.assign(option, config);
759
- t.player.options.mode = $storage.get('_PlayerMode') || t.player.options.mode;
760
- // 初始化button、controls以及click事件
761
- buttons.create();
762
- // 初始化audio or video
763
- source = t.createChild(t.player.options.type, events);
764
- // 初始化播放列表、预览、控件按钮等
765
- info.create();
766
- t.parentNode.addClass(t.player.options.type);
767
- t.player.created = true;
768
- };
769
- init(config);
770
- return t;
771
- };