efront 4.19.7 → 4.20.1

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.
Files changed (50) hide show
  1. package/apps/kugou/singer/keywords.less +5 -1
  2. package/apps/kugou/song/list.jsp +14 -0
  3. package/apps/kugou/song//347/233/227/345/260/206/350/241/214 - /350/212/261/347/262/245,/351/251/254/351/233/250/351/230/263.krc +0 -0
  4. package/coms/basic/Table.js +4 -3
  5. package/coms/basic/data.js +19 -7
  6. package/coms/basic/isSubpath.js +33 -0
  7. package/coms/basic/mark.js +47 -14
  8. package/coms/basic/mark_test.js +8 -0
  9. package/coms/basic/spaces.js +8 -0
  10. package/coms/compile/Html.js +28 -1
  11. package/coms/compile/Html_test.js +3 -1
  12. package/coms/compile/common.js +8 -3
  13. package/coms/compile/downLevel_test.js +2 -2
  14. package/coms/compile/unstruct.js +1 -0
  15. package/coms/compile/unstruct_test.js +4 -1
  16. package/coms/explorer/edit.js +1 -1
  17. package/coms/kugou/bg.less +2 -2
  18. package/coms/kugou/dance.js +1 -1
  19. package/coms/kugou/krc.js +61 -34
  20. package/coms/kugou/krc.less +1 -0
  21. package/coms/kugou/krc_parse.js +56 -0
  22. package/coms/kugou/krc_stringify.js +16 -0
  23. package/coms/kugou/musicList.js +1 -1
  24. package/coms/kugou/parseSongsList.js +1 -1
  25. package/coms/kugou/playList.html +3 -2
  26. package/coms/kugou/playList.less +5 -0
  27. package/coms/kugou/player.html +1 -0
  28. package/coms/kugou/player.js +40 -32
  29. package/coms/kugou/player.less +125 -34
  30. package/coms/kugou/song.html +4 -4
  31. package/coms/kugou/song.js +1 -0
  32. package/coms/kugou/song.less +77 -26
  33. package/coms/kugou/titlebar.less +3 -0
  34. package/coms/kugou//346/255/214/350/257/215/347/274/226/350/276/221/345/231/250.xht +153 -0
  35. package/coms/zimoli/button.js +3 -76
  36. package/coms/zimoli/button.less +1 -3
  37. package/coms/zimoli/confirm.js +4 -3
  38. package/coms/zimoli/img.less +1 -0
  39. package/coms/zimoli/menu.less +0 -4
  40. package/coms/zimoli/menuItem.html +1 -1
  41. package/coms/zimoli/patchHover.js +74 -0
  42. package/coms/zimoli/popup.js +16 -0
  43. package/coms/zimoli/prompt.js +8 -2
  44. package/coms/zimoli/textarea.less +1 -0
  45. package/coms/zimoli/touchList.js +1 -0
  46. package/coms/zimoli/view.js +0 -6
  47. package/coms/zimoli/vscroll.js +2 -1
  48. package/coms/zimoli/zimoli.js +11 -10
  49. package/package.json +1 -1
  50. package/public/efront.js +1 -1
@@ -28,7 +28,11 @@
28
28
  @media (max-width:720px) {
29
29
 
30
30
  song .bg {
31
- display: none;
31
+
32
+ &:after,
33
+ &:before {
34
+ background-color: transparent;
35
+ }
32
36
  }
33
37
 
34
38
  song {
@@ -1,6 +1,20 @@
1
1
  <script serverside>
2
2
  var fs = require("fs").promises;
3
3
  var names = await fs.readdir(__dirname);
4
+ var namesMap = Object.create(null);
5
+ names.filter(a => /\.[gkl]rc$/i.test(a)).forEach(a => {
6
+ var k = a.replace(/\.\w+$/, '');
7
+ if (k in namesMap) {
8
+ if (!/^lrc$/i.test(namesMap[k])) return;
9
+ }
10
+ namesMap[k] = a.slice(k.length + 1);
11
+ });
4
12
  names = names.filter(a => /\.(flac|mp3|wav)$/i.test(a));
13
+ names = names.map(n => {
14
+ var k = n.replace(/\.\w+$/i, '');
15
+ var m = namesMap[k];
16
+ if (m) n += '#' + m;
17
+ return n;
18
+ });
5
19
  return JSON.stringify(names);
6
20
  </script>
@@ -1,4 +1,4 @@
1
- Promise.resolve(init("pinyin")).then(py =>mark.setPinyin(py));
1
+ Promise.resolve(init("pinyin")).then(py => mark.setPinyin(py));
2
2
 
3
3
  function minusPower(a, b) {
4
4
  return a.$power - b.$power >= 0;
@@ -122,12 +122,13 @@ class Table extends Array {
122
122
  if (name === searchtext) this.hasFullmatch = true;
123
123
  var [p, m] = mark.power(name, searchtext);
124
124
  if (p > power) power = p;
125
- if (p >= searchtext.length) this.coverCount++;
126
125
  if (!isEmpty(f.key) && !isFunction(f.key)) o[f.key] = m;
127
126
  else o.name = m, o.toString = returnName, o.valueOf = returnName;
128
127
  }
128
+ if (power >= searchtext.length) this.coverCount++;
129
129
  o.$power = power;
130
- if (o.$power > 0) {
130
+ var cp = searchtext.length;
131
+ if (o.$power > cp * .6) {
131
132
  var summary = this.$summaryData;
132
133
  if (!summary.length) saveToOrderedArray(this, o, minusPower);
133
134
  else this.summary(o);
@@ -98,19 +98,31 @@ var seekFromSource = function (obj, base) {
98
98
  }
99
99
  return obj;
100
100
  };
101
+ var getkey = [
102
+ a => a.toUpperCase(),
103
+ a => a.charAt(0).toUpperCase() + a.slice(1),
104
+ a => a,
105
+ ]
101
106
  function getErrorMessage(error = this) {
102
107
  if (!isObject(error)) return String(error);
103
108
  if (error instanceof Error) return String(error);
104
109
  var words = "reason,message,desc,descption,msg,err,error,detail,data".split(',');
105
- while (words.length) {
110
+ w: while (words.length) {
106
111
  var a = words.shift();
107
- if (error[a]) {
108
- return String(error[a]);
112
+ var keys = getkey.slice();
113
+ while (keys.length) {
114
+ a = keys.pop()(a);
115
+ var e = error[a];
116
+ if (typeof e === 'string') {
117
+ return e;
118
+ }
119
+ if (isObject(e)) {
120
+ var s = String(e);
121
+ if (!/^\[object\s/i.test(s)) return s;
122
+ error = e;
123
+ continue w;
124
+ }
109
125
  }
110
- a = a.charAt(0).toUpperCase() + a.slice(1);
111
- if (error[a]) return String(error[a]);
112
- a = a.toUpperCase();
113
- if (error[a]) return String(error[a]);
114
126
  }
115
127
  return Object.keys(error).map(k => `${k}: ${error[k]}`).join(',\r\n');
116
128
  }
@@ -0,0 +1,33 @@
1
+ var normalize = function (url) {
2
+ var normal = [];
3
+ var protocol = /^\w+\:/.exec(url);
4
+ if (protocol) {
5
+ url = url.slice(protocol[0].length).replace(/^[\\\/]+/, '');
6
+ }
7
+ url = url.split(/[\/\\]+/);
8
+ while (url.length) {
9
+ var u = url.pop();
10
+ switch (u) {
11
+ case ".":
12
+ break;
13
+ case "..":
14
+ normal.pop();
15
+ break;
16
+ default:
17
+ normal.push(u);
18
+ }
19
+ }
20
+ if (protocol) {
21
+ normal.unshift(protocol[0].toUpperCase());
22
+ }
23
+ return normal;
24
+ }
25
+ function isSubpath(path, root) {
26
+ path = normalize(path);
27
+ root = normalize(root);
28
+ if (path.length <= root.length) return false;
29
+ for (var cx = 0, dx = root.length; cx < dx; cx++) {
30
+ if (root[cx] !== path[cx]) return false;
31
+ }
32
+ return true;
33
+ }
@@ -28,14 +28,12 @@ var couple = function (source, marker, pinyin) {
28
28
  var begin1 = len1, begin2 = len2;
29
29
  var end1 = begin1;
30
30
  var end2 = begin2;
31
- for (var cx = -len1, dx = len2; cx < dx; cx++) {
32
- var c1 = cx >= 0 ? 0 : -cx;
33
- var c2 = cx >= 0 ? cx : 0;
31
+ var run = function () {
34
32
  var cc = c2;
35
33
  var start = 0, end = 0;
36
- for (var ct = 0, dt = setDt(); ct < dt; ct++) {
37
- var s = source[c1 + ct];
38
- var m = marker[c2 + ct];
34
+ for (ct = 0, dt = setDt(); ct < dt; ct++) {
35
+ s = source[c1 + ct];
36
+ m = marker[c2 + ct];
39
37
  if (s === m || pinyin && isLike()) {
40
38
  end = ct + 1;
41
39
  if (end === dt && c2 + end - cc - start > end2 - begin2) {
@@ -55,7 +53,10 @@ var couple = function (source, marker, pinyin) {
55
53
  start = ct + 1;
56
54
  }
57
55
  }
58
- }
56
+ };
57
+ var s, m, ct, dt;
58
+ for (var c1 = 0, c2 = 0; c1 < len1; c1++) run();
59
+ for (var c1 = 0, c2 = 1; c2 < len2; c2++) run();
59
60
  return [source.slice(begin1, end1), begin1, begin2, end2];
60
61
  };
61
62
  var MARK_PRE1, MARK_PRE2, _PRE1, _PRE2 = _PRE1 = "<b>";
@@ -78,28 +79,60 @@ var pair = function (source, search, t1, t2, t3, t4) {
78
79
  }
79
80
  return power2(source, search);
80
81
  }
82
+ var searchText = '';
81
83
  var power = function (source, search) {
84
+ searchText = search;
85
+ var res = power_(source, search);
86
+ searchText = '';
87
+ return res;
88
+ };
89
+ var power_p = function () { };
90
+ var power_f = function () { };
91
+ var power_ = function (source, search, func, mp) {
82
92
  if (!search || !source) {
83
93
  return [0, source];
84
94
  }
85
95
  var matchers = couple(source, search, _pinyin);
86
96
  var match_text = matchers[0];
87
97
  var match_start = matchers[1];
88
- var match_length = matchers[3] - matchers[2];
98
+ var search_start = matchers[2];
99
+ var search_end = matchers[3];
100
+ var match_length = search_end - search_start;
89
101
  if (match_length >= 1) {
90
102
  var match_text_pre = source.slice(0, match_start);
91
103
  var match_text_aft = source.slice(match_start + match_text.length);
92
104
  var pp = 0, ap = 0;
93
105
  var p = match_length !== match_text.length ? match_length - .1 : match_length;
94
- if (match_start) p += .1 / match_start - .2;
95
- if (match_text_pre.length > 1) {
96
- [pp, match_text_pre] = power(match_text_pre, search);
106
+ if (match_start) p += .1 / (1 + match_start) - .1;
107
+ if (match_text_aft.length) p += .01 / (match_text_aft.length + 1) - .01;
108
+ if (!mp) mp = p;
109
+ var pw = null;
110
+ if (match_text_pre.length > 1 && !(func === power_f && search_start === 0)) {
111
+ pw = power_(match_text_pre, search_start > 0 ? search.slice(0, search_start) : searchText, search_start > 0 ? power_p : null, p);
112
+ pp = pw[0];
113
+ if (search_start !== 0) match_text_pre = pw[1];
114
+ else {
115
+ if (pp >= mp - .6) {
116
+ match_text_pre = pw[1];
117
+ }
118
+ pp = 0;
119
+ }
97
120
  }
98
- if (match_text_aft.length > 1) {
99
- [ap, match_text_aft] = power(match_text_aft, search);
121
+
122
+ var isend = search_end === search.length;
123
+ if (match_text_aft.length > 1 && !(func === power_p && isend)) {
124
+ pw = power_(match_text_aft, isend ? searchText : search.slice(search_end), isend ? null : power_f, p);
125
+ var ap = pw[0];
126
+ if (search_end !== search.length) match_text_aft = pw[1];
127
+ else {
128
+ if (ap >= mp - .6) {
129
+ match_text_aft = pw[1];
130
+ }
131
+ ap = 0;
132
+ }
100
133
  }
101
134
  if (match_length !== search.length) {
102
- p += (pp + ap) / source.length / search.length * .01 - .2;
135
+ p += (pp + ap) * .86;
103
136
  }
104
137
  else if (pp >= p) {
105
138
  p += pp / source.length / search.length * .01 - .2;
@@ -2,8 +2,16 @@ var test = function (t1, t2) {
2
2
  var a = mark.power(t1, t2)
3
3
  console.log(t1, t2, a);
4
4
  }
5
+ test("live", 'lvie');
6
+ test("listenv", 'lvie');
7
+ test("simple", 'il');
8
+ test("build", 'il');
5
9
  test("11234", '1234');
6
10
  test("1234", '1234');
11
+ test('kugou', 'kug');
12
+ test('kuugou', 'kug');
13
+ test('kugoukuugou', 'kug');
14
+ test('kugoukugou', 'kugu');
7
15
  mark.setPinyin(await init('pinyin'));
8
16
  test('我们', 'women');
9
17
  test('我们', 'wm');
@@ -28,6 +28,8 @@ spaceDefined.avoid = function (extra_tokens) {
28
28
  var reg = new RegExp(`(?:[${spaceDefined.join('')}]|${unicode.join('|')})+`);
29
29
  var is_reg = new RegExp(`^${reg.source}$`);
30
30
  var trim_reg = new RegExp(`^${reg.source}|${reg.source}$`, 'g');
31
+ var trim_start_reg = new RegExp(`^${reg.source}`);
32
+ var trim_end_reg = new RegExp(`${reg.source}$`);
31
33
  var format_reg = new RegExp(reg.source, 'g');
32
34
  spaceDefined.reg = reg;
33
35
  spaceDefined.is_reg = is_reg;
@@ -40,6 +42,12 @@ spaceDefined.exec = function (a) {
40
42
  spaceDefined.trim = function (a) {
41
43
  return a.replace(trim_reg, '');
42
44
  };
45
+ spaceDefined.trimStart = function (a) {
46
+ return a.replace(trim_start_reg, '');
47
+ };
48
+ spaceDefined.trimEnd = function (a) {
49
+ return a.replace(trim_end_reg, '');
50
+ };
43
51
  var formatter = function (a) {
44
52
  if (/[ \u2002\u00a0\u3000]/.test(a)) return ' ';
45
53
  return '';
@@ -30,6 +30,33 @@ var parseProperty = function (a) {
30
30
  }
31
31
 
32
32
  var fixElement = function (o) {
33
+ if (o.length) {
34
+ var o0 = o[0];
35
+ if (o0.type & (PIECE | SPACE)) {
36
+ var text = spaces.trimStart(o0.text);
37
+ if (!text) {
38
+ o.shift();
39
+ o0 = o[0];
40
+ o.first = o0;
41
+ if (o0) o0.prev = null;
42
+ }
43
+ else o0.text = text;
44
+ }
45
+ }
46
+ if (o.length) {
47
+ var o1 = o[o.length - 1];
48
+ if (o1.type & (PIECE | SPACE)) {
49
+ var text = spaces.trimEnd(o1.text);
50
+ if (!text) {
51
+ o.pop();
52
+ o1 = o[o.length - 1];
53
+ o.last = o1;
54
+ if (o1) o1.next = null;
55
+ }
56
+ else o1.text = text;
57
+ }
58
+ }
59
+
33
60
  if (!o.attributes) return;
34
61
  var attributes = [];
35
62
  var needValue = false;
@@ -114,7 +141,7 @@ Html.prototype.createScoped = function (code) {
114
141
  case ELEMENT:
115
142
  var v = toCamelCase(c.tag);
116
143
  c.tagName = c.tag.toUpperCase();
117
- if (!/^(script|style|template)$/i.test(c.tagName)) {
144
+ if (!/^(script|style)$/i.test(c.tagName)) {
118
145
  fixElement(c);
119
146
  noTag = false;
120
147
  if (c.attributes) c.attributes.forEach(run);
@@ -15,8 +15,10 @@ var test2 = function (source) {
15
15
  var s = scanner2(source, 'html');
16
16
  assert(s.toString(), source);
17
17
  }
18
- test("<h><a #c>b</a><c b=x>d</c><d/><e>2px</e></h>");
18
+ test("<h><a #c>b</a><c b=x>d</c><d/><e>2px</e></h>", "<h><a #c>b</a><c b=x>d</c><d></d><e>2px</e></h>");
19
19
  test("<a>Let's Encrypt</a>");
20
+ test("<a> </a>", 'scoped.outerHTML', "<a></a>");
21
+ test("<a> Let's Encrypt</a>", 'scoped.outerHTML', "<a>Let's Encrypt</a>");
20
22
  test("<style>{a-b:2}</style>");
21
23
  assert(scanner2("<a>Let's Encrypt</a>", Html).length, 1);
22
24
  test('<a href="${i18n``}">Let\'s Encrypt</a>');
@@ -1403,10 +1403,15 @@ var createString = function (parsed) {
1403
1403
  if (o.length) {
1404
1404
  o.forEach(run);
1405
1405
  }
1406
- result.push(o.tag_entry);
1407
- result.push(o.tag);
1406
+ result.push(o.tag_entry, o.tag, o.leave);
1408
1407
  }
1409
- result.push(o.leave);
1408
+ else if (o.tag && o.leave === '/>') {
1409
+ if (/^(input|img|meta|br|hr|link|area|base|basefont|param|col|frame|embed|keygen)$/i.test(o.tag)) {
1410
+ result.push('/>');
1411
+ }
1412
+ else result.push(`></`, o.tag, '>');
1413
+ }
1414
+ else result.push(o.leave);
1410
1415
  }
1411
1416
  else {
1412
1417
  if (o.tag_leave) result.push(o.tag_leave);
@@ -440,9 +440,9 @@ function () {
440
440
  if (!a) return [1, 0]; return [2, 0]
441
441
  },
442
442
  function () {
443
- _1 = getRequestProtocol(url); _0 = _1 + "//", location = _0 + location; return [1, 0]
443
+ _0 = getRequestProtocol(url), _0 = _0 + "//", location = _0 + location; return [1, 0]
444
444
  })
445
- var _0, _1 }`);
445
+ var _0 }`);
446
446
  assert(downLevel("var{a}=await b"), `return async_(
447
447
  function () {
448
448
  _0 = b; return [_0, 1]
@@ -863,6 +863,7 @@ var ternary = function (body, getname, ret) {
863
863
  var punc = eq.text.slice(0, eq.text.length - 1);
864
864
  var bdtmp = [...ass.map(cloneNode), { type: STAMP, text: punc }, ...asn];
865
865
  relink(bdtmp);
866
+ eqused++;
866
867
  var explist2 = _express(bdtmp, getnextname, true);
867
868
  if (isSimpleAssign) {
868
869
  [asn, an = cloneNode(ass)] = popexp(explist2);
@@ -163,6 +163,9 @@ test("var res = null, krc;", `res = null; krc`)
163
163
  test("res = null, krc;", `res = null; krc`)
164
164
  test(`while (a && b);`, '_ = a; if (!_) return [1, 0]; _ = b;\r\n if (!_) return [1, 0]; return [-1, 0]', true);
165
165
  test(`while (a < b);`, '_ = a < b; if (!_) return [1, 0]; return [0, 0]', true);
166
- unstruct.debug = true; r++;
167
166
  test(`if (a() > a+b);`, '_ = a(), _0 = a + b, _ = _ > _0; if (!_) return [1, 0]; return [1, 0]', true);
168
167
  test(`index > start && result.length < pageSize`, '_ = index > start; if (!_) return [1, 0]; _ = result.length, _ < pageSize', true);
168
+ unstruct.debug = true; r++;
169
+ test(`menus[0][str_name] += [str__v_, version[0], str__v_1][str_join]("")`, `_ = menus[0]; _0 = str__v_; _1 = version[0]; _2 = str__v_1; _0 = [_0, _1, _2]; _0 = _0[str_join](""); _1 = _[str_name], _1 = _1 + _0; _[str_name] = _1`);
170
+ test(`a.b.c += menus[0][str_name] += [str__v_, version[0], str__v_1][str_join]("")`, `_ = menus[0]; _0 = str__v_; _1 = version[0]; _2 = str__v_1; _0 = [_0, _1, _2]; _0 = _0[str_join](""); _1 = _[str_name], _1 = _1 + _0; _[str_name] = _1; _2 = a.b.c, _2 = _2 + _1; a.b.c = _2`);
171
+ test(`menus[0].c += menus[0][str_name] += [str__v_, version[0], str__v_1][str_join]("")`, `_ = menus[0]; _0 = menus[0]; _1 = str__v_; _2 = version[0]; _3 = str__v_1; _1 = [_1, _2, _3]; _1 = _1[str_join](""); _2 = _0[str_name], _2 = _2 + _1; _0[str_name] = _2; _3 = _.c, _3 = _3 + _2; _.c = _3`);
@@ -33,7 +33,7 @@ function main({ path: root, rename, isfolder, add, name, hasName }) {
33
33
  var path = root + "/" + a.$scope.data.name;
34
34
  if (origin) {
35
35
  var to = path;
36
- path = origin;
36
+ path = root + '/' + origin;
37
37
  }
38
38
  if (origin) await rename(path, to);
39
39
  else await add(path)
@@ -1,4 +1,4 @@
1
- :active>& {
1
+ .active>& {
2
2
  &:after {
3
3
  width: 300px;
4
4
  height: 140px;
@@ -42,7 +42,7 @@
42
42
  &:after,
43
43
  &:before {
44
44
  content: "";
45
- background-color: #2873;
45
+ background-color: #9cb1;
46
46
  position: absolute;
47
47
  border-radius: 50%;
48
48
  // backdrop-filter: invert(1);
@@ -1,5 +1,5 @@
1
1
  var activeDevice, ratio = 1;
2
- var strokeColor = '#096';
2
+ var strokeColor = '#acb';
3
3
  function line(buffer, style, lineWidth = window.devicePixelRatio || 1) {
4
4
  var canvas = this;
5
5
  var context = canvas.getContext("2d");
package/coms/kugou/krc.js CHANGED
@@ -2,7 +2,8 @@ var secret = [64, 71, 97, 119, 94, 50, 116, 71, 81, 54, 49, 45, 206, 210, 110, 1
2
2
  var isTrident = /Trident/i.test(navigator.userAgent);
3
3
  function krc(list = div()) {
4
4
  care(list, function (info) {
5
- if (!info.krc) {
5
+ list.info = info;
6
+ if (!info.grc && !info.krc) {
6
7
  remove(list.children);
7
8
  if (info.lrc) {
8
9
  var children = createLRC(info.lrc);
@@ -15,14 +16,61 @@ function krc(list = div()) {
15
16
  }
16
17
  return;
17
18
  }
18
- var content = info.krc.slice(4).map((a, i) => a ^ secret[i % 16]);
19
- var bufff = thirdParty$inflate(content.slice(2));
20
- var krc = decodeUTF8(bufff);
19
+ var krc = info.grc || info.krc_text;
20
+ if (!krc) {
21
+ var content = info.krc.slice(4).map((a, i) => a ^ secret[i % 16]);
22
+ var bufff = thirdParty$inflate(content.slice(2));
23
+ krc = decodeUTF8(bufff);
24
+ info.krc_text = krc;
25
+ }
21
26
  remove(list.children);
22
27
  var children = createKRC(krc);
28
+ list.extra = children.extra;
23
29
  appendChild(list, children);
24
30
  list.process = children.process;
25
- })
31
+ });
32
+ contextmenu(list, [
33
+ {
34
+ name: "编辑歌词",
35
+ hidden: true,
36
+ do() {
37
+ popup('歌词编辑器', list.info, true);
38
+ }
39
+ },
40
+ {
41
+ name: "调整时间",
42
+ async do() {
43
+ var delta = await prompt('输入时间差值(毫秒)以调整整首歌词', a => +a === (a | 0));
44
+ delta = +delta;
45
+ var extra = list.extra;
46
+ if (extra.offset) extra.offset += +delta;
47
+ else extra.offset = +delta;
48
+ }
49
+ },
50
+ {
51
+ name: '保存歌词',
52
+ do() {
53
+ if (!list.info) return;
54
+ var a = document.createElement('a');
55
+ if (!("download" in a)) {
56
+ alert('当前浏览器无法保存', 'warn');
57
+ return;
58
+ }
59
+ var { grc, krc_text = grc, lrc, songname, songName, singername, singerName } = list.info;
60
+ if (krc_text) {
61
+ var kp = krc_parse(krc_text);
62
+ kp.extra.offset = list.extra.offset;
63
+ var grc = krc_stringify(kp);
64
+ }
65
+ if (!grc && !lrc) {
66
+ alert('当前歌曲没有可保存的歌词!', 'warn');
67
+ return;
68
+ }
69
+ a.href = 'data:application/octet-stream;base64,' + toBase64(encodeUTF8(grc || lrc));
70
+ a.download = `${songname || songName}-${singername || singerName}.${krc_text ? 'grc' : 'lrc'}`;
71
+ a.click();
72
+ }
73
+ }])
26
74
  return list;
27
75
  }
28
76
  function createLRC(lrc) {
@@ -78,6 +126,7 @@ function createLRC(lrc) {
78
126
  }
79
127
  }
80
128
  };
129
+ krcList.rows = saved_rows;
81
130
  return krcList;
82
131
  }
83
132
 
@@ -97,39 +146,16 @@ function setClass(krcList, index) {
97
146
  });
98
147
  if (index + 2 < krcList.length) addClass(krcList[index + 1], 'after-active');
99
148
  }
149
+
100
150
  function createKRC(krc) {
101
- var saved_rows = [];
102
- krc.split(/[\r\n]+/).map(function (row) {
103
- var data = /^\s*\[(.*?),(.*?)\](.*?)$/.exec(row);
104
- if (data) {
105
- var [, startTime, schedule, words] = data;
106
- var wordReg = /<(.*?),(.*?),.*?>([^<]*)/g;
107
- var saved_words = [];
108
- do {
109
- var word = wordReg.exec(words);
110
- if (word) {
111
- var [, timeBegin, timeLength, label] = word;
112
- saveToOrderedArray(saved_words, {
113
- value: +timeBegin,
114
- timeBegin: +timeBegin,
115
- timeLength: +timeLength,
116
- label
117
- });
118
- }
119
- } while (word);
120
- saveToOrderedArray(saved_rows, {
121
- value: +startTime,
122
- startTime: +startTime,
123
- schedule: +schedule,
124
- words: saved_words
125
- });
126
- } else {
127
- if (!isProduction) console.info("%c未解析%c", "color:#c28", "color:#333", row, data);
128
- }
129
- });
151
+ var saved_rows = krc_parse(krc);
152
+ var extra = saved_rows.extra;
130
153
  var krcList = saved_rows.map(createRow);
131
154
  krcList.process = function (offset, length) {
132
155
  var offsetMTime = offset * 1000 | 0;
156
+ if (extra.offset) {
157
+ offsetMTime -= extra.offset;
158
+ }
133
159
  var index = getIndexFromOrderedArray(saved_rows, offsetMTime);
134
160
  var current_row = saved_rows[index];
135
161
  if (current_row) {
@@ -170,6 +196,7 @@ function createKRC(krc) {
170
196
  }
171
197
  };
172
198
  var markerLabel = document.createElement("div");
199
+ krcList.extra = extra;
173
200
  return krcList;
174
201
  }
175
202
  function createCell(word) {
@@ -9,6 +9,7 @@
9
9
  display: block;
10
10
  text-align: center;
11
11
  >div {
12
+ pointer-events: none;
12
13
  white-space: nowrap;
13
14
  position: relative;
14
15
  transition: margin-top .2s ease-out;
@@ -0,0 +1,56 @@
1
+ var extra_func = {
2
+ total(a) {
3
+ return +a
4
+ },
5
+ offset(a) {
6
+ return +a
7
+ },
8
+ language(a) {
9
+ a = atob(a);
10
+ a = JSON.parse(a);
11
+ }
12
+ }
13
+ var krc_parse = function (krc_text) {
14
+ var saved_rows = [];
15
+ var extra = {};
16
+ krc_text = krc_text.trim();
17
+ krc_text.split(/[\r\n]+/).map(function (row) {
18
+ var data = /^\s*\[(.*?),(.*?)\](.*?)$/.exec(row);
19
+ if (data) {
20
+ var [, startTime, schedule, words] = data;
21
+ var wordReg = /<(.*?),(.*?)(?:,.*?)?>([^<]*)/g;
22
+ var saved_words = [];
23
+ do {
24
+ var word = wordReg.exec(words);
25
+ if (word) {
26
+ var [, timeBegin, timeLength, label] = word;
27
+ saveToOrderedArray(saved_words, {
28
+ value: +timeBegin,
29
+ timeBegin: +timeBegin,
30
+ timeLength: +timeLength,
31
+ label
32
+ });
33
+ }
34
+ } while (word);
35
+ saveToOrderedArray(saved_rows, {
36
+ value: +startTime,
37
+ startTime: +startTime,
38
+ schedule: +schedule,
39
+ words: saved_words
40
+ });
41
+ } else {
42
+ var data = /^\[([^\]\:,]+)[\:,]([^,\:\]]*)\]$/.exec(row);
43
+ if (data) {
44
+ var [, key, value] = data;
45
+ if (!value) value = null;
46
+ else if (extra_func.hasOwnProperty(key)) {
47
+ value = extra_func[key](value);
48
+ }
49
+ extra[key] = value;
50
+ }
51
+ else if (!isProduction) console.info("%c未解析%c", "color:#c28", "color:#333", row, data);
52
+ }
53
+ });
54
+ saved_rows.extra = extra;
55
+ return saved_rows;
56
+ }
@@ -0,0 +1,16 @@
1
+ function krc_stringify(krc_rows) {
2
+ var extra = krc_rows.extra;
3
+ var e = Object.keys(extra).map(k => {
4
+ if (k === 'id') return;
5
+ if (k === 'hash') return;
6
+ var a = extra[k];
7
+ if (!isHandled(a)) return;
8
+ if (typeof a === 'object') return;
9
+ return `[${k}:${a}]`;
10
+ }).filter(a => !!a).join('\r\n');
11
+ var a = krc_rows.map(r => {
12
+ var w = r.words.map(w => `<${w.timeBegin},${w.timeLength}>${w.label}`).join('');
13
+ return `[${r.startTime},${r.schedule}]${w}`;
14
+ }).join('\r\n');
15
+ return e + "\r\n\r\n" + a;
16
+ }
@@ -13,7 +13,7 @@ var isSameSong = function (m1, m2) {
13
13
  m1.id && m1.id === m2.id || // 网易云 千千静听
14
14
  m1.rid && m1.rid === m2.rid || // 酷我
15
15
  m1.mid && m1.mid === m2.mid ||// 酷我
16
- m1.url && m1.url === m2.url;
16
+ m1.url && String(m1.url).replace(/#[\s\S]*$/, '') === String(m2.url).replace(/#[\s\S]*$/, '');
17
17
  };
18
18
 
19
19
  function addMethod(name, func) {
@@ -6,7 +6,7 @@ await data.from("efront-singer", function (a) {
6
6
  })
7
7
  });
8
8
  var parseFileName = function (b) {
9
- var [name, singer] = String(b).replace(/\.\w+$/, '')
9
+ var [name, singer] = String(b).replace(/\.[\w#]+$/, '')
10
10
  .replace(/^\s*\d+[\s\.,\-]+(\S+)($|\W\s*\-)/, "$1$2")
11
11
  .replace(/^\s*\d+[\.]+\s*([\s\S]+)/, "$1")
12
12
  .replace(/^\s*\d+\s+(\W+)/, "$1")