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

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