efront 3.26.8 → 3.26.15

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 (67) hide show
  1. package/LICENSE +2 -0
  2. package/apps/index.jsp +2 -2
  3. package/apps/pivot/dht/list.js +53 -0
  4. package/apps/pivot/index.html +3 -1
  5. package/apps/pivot/main.js +1 -0
  6. package/apps/pivot/main.less +3 -0
  7. package/apps/pivot/wow/root.js +138 -104
  8. package/apps/pivot/wow/root.less +1 -62
  9. package/coms/basic/Task.js +51 -0
  10. package/coms/basic/cross_.js +8 -0
  11. package/coms/basic/keys.js +3 -4
  12. package/coms/basic/loader.js +42 -17
  13. package/coms/basic/submit_.js +6 -3
  14. package/coms/explorer/Explorer.js +85 -0
  15. package/coms/explorer/context.js +205 -0
  16. package/coms/explorer/deepcp.js +48 -0
  17. package/{apps/pivot/wow → coms/explorer}/edit.html +1 -1
  18. package/{apps/pivot/wow → coms/explorer}/edit.js +17 -9
  19. package/coms/explorer/fileitem.html +8 -0
  20. package/coms/explorer/fileitem.js +34 -0
  21. package/coms/explorer/fileitem.less +65 -0
  22. package/coms/explorer/filetip.js +10 -0
  23. package/coms/explorer/filetip.less +5 -0
  24. package/coms/explorer/main.html +8 -0
  25. package/coms/explorer/main.js +215 -0
  26. package/coms/explorer/main.less +78 -0
  27. package/coms/frame/route.js +1 -1
  28. package/coms/shapes/file.html +9 -0
  29. package/coms/shapes/folder.html +7 -0
  30. package/coms/zimoli/Cleanup.js +9 -8
  31. package/coms/zimoli/arriswise.js +5 -4
  32. package/coms/zimoli/attr.js +2 -0
  33. package/coms/zimoli/bindGlobalkey.js +37 -0
  34. package/coms/zimoli/confirm.js +8 -8
  35. package/coms/zimoli/confirm.less +6 -80
  36. package/coms/zimoli/container.js +19 -6
  37. package/coms/zimoli/contextmenu.js +35 -15
  38. package/coms/zimoli/drag.js +7 -3
  39. package/coms/zimoli/field.html +1 -1
  40. package/coms/zimoli/field.js +8 -2
  41. package/coms/zimoli/field.less +0 -1
  42. package/coms/zimoli/getChanges.js +1 -0
  43. package/coms/zimoli/list.js +44 -33
  44. package/coms/zimoli/menu.js +1 -24
  45. package/coms/zimoli/menuItem.html +4 -1
  46. package/coms/zimoli/menuList.js +54 -104
  47. package/coms/zimoli/menuList.less +1 -0
  48. package/coms/zimoli/moveupon.js +2 -2
  49. package/coms/zimoli/overpos.js +7 -0
  50. package/coms/zimoli/popup.js +22 -27
  51. package/coms/zimoli/prompt.js +43 -5
  52. package/coms/zimoli/prompt.less +23 -0
  53. package/coms/zimoli/render.js +153 -109
  54. package/coms/zimoli/resize.js +17 -7
  55. package/coms/zimoli/rootElements.js +15 -1
  56. package/coms/zimoli/view.js +33 -0
  57. package/coms/zimoli/view.less +8 -8
  58. package/coms/zimoli/yousure.js +53 -0
  59. package/coms/zimoli/yousure.less +4 -0
  60. package/coms/zimoli/zimoli.js +10 -6
  61. package/package.json +1 -1
  62. package/public/efront.js +1 -1
  63. package/apps/pivot/wow/root.html +0 -10
  64. package/coms/zimoli/explorer.html +0 -5
  65. package/coms/zimoli/explorer.js +0 -8
  66. package/coms/zimoli/explorer.less +0 -18
  67. package/coms/zimoli/explorer_test.js +0 -4
package/LICENSE CHANGED
@@ -18,3 +18,5 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
18
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
19
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
20
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ 共产党与狗不得使用
package/apps/index.jsp CHANGED
@@ -115,11 +115,11 @@
115
115
  })
116
116
  });
117
117
 
118
- rows.push(`<a href="${n}?${stats.mtime.toLocaleDateString()}" target=_blank ><b name>${n}</b><span time>${stats.mtime.toLocaleDateString()}</span></a>`);
118
+ rows.push(`<a href="${n}?${stats.mtime.toLocaleDateString()}" ><b name>${n}</b><span time>${stats.mtime.toLocaleDateString()}</span></a>`);
119
119
  }
120
120
  return rows.join('')
121
121
  </script>
122
- <a href="https://www.npmjs.com/package/efront">
122
+ <a href="https://www.npmjs.com/package/efront" target="_blank">
123
123
  <b name>efront</b>
124
124
  <span time>&nbsp;</span>
125
125
  </a>
@@ -0,0 +1,53 @@
1
+ function hash(a) {
2
+ var r = [];
3
+ for (var cx = 0, dx = a.length; cx < dx; cx += 20) {
4
+ r.push(a.slice(cx, cx + 20).split("").map(a => a.charCodeAt().toString(16)).join(""));
5
+ }
6
+ return r;
7
+ }
8
+ var fields = refilm`名称/name
9
+ 服务器/host
10
+ 端口/port
11
+ `;
12
+ return plist.bind({
13
+ fields,
14
+ type: 'nodes',
15
+ title: "DHT服务器管理",
16
+ buttons: [{
17
+ name: "从文件读取", async do() {
18
+ var FileReader = window.FileReader;
19
+ if (!FileReader) return alert('当前浏览器无法读取文件', 'warn')
20
+ var f = await chooseFile(".torrent",true);
21
+ var pg = await popup("/dht/rent");
22
+ pg.$scope.pending = true;
23
+ for (var f of f) await new Promise(function (ok, oh) {
24
+ var r = new FileReader;
25
+ r.onload = function () {
26
+ try {
27
+ var t = bdecode2(r.result);
28
+ } catch (e) {
29
+ return;
30
+ }
31
+ pg.$scope.load(t);
32
+ pg.$scope.pending = false;
33
+ ok();
34
+ };
35
+ r.onerror = function () {
36
+ alert("读取文件失败!", 'error');
37
+ oh();
38
+ };
39
+ r.readAsArrayBuffer(f);
40
+ });
41
+ console.log(pg.$scope.pending)
42
+ }
43
+ }]
44
+ })
45
+ // function main() {
46
+ // var page = document.createElement('div');
47
+ // page.innerHTML = template;
48
+ // return renderWithDefaults(page, {
49
+ // torrents: [],
50
+ // async rent() {
51
+ // }
52
+ // })
53
+ // }
@@ -36,6 +36,8 @@
36
36
  </style>
37
37
  </head>
38
38
 
39
- <body scroll=no menu="menu.yml"></body>
39
+ <body scroll=no menu="menu.yml">
40
+ 雪下的那么深,下的那么认真..
41
+ </body>
40
42
 
41
43
  </html>
@@ -82,6 +82,7 @@ on("dragover")(document, function (event) {
82
82
  on("drop")(document, function (event) {
83
83
  event.preventDefault();
84
84
  });
85
+ remove(document.body.childNodes);
85
86
  function main() {
86
87
  return layer;
87
88
  }
@@ -2,4 +2,7 @@
2
2
  padding: 50px 10px 0;
3
3
  min-height: 100%;
4
4
  display: block;
5
+ }
6
+ &{
7
+ user-select: none;
5
8
  }
@@ -2,128 +2,162 @@ var fields = refilm`
2
2
  文件
3
3
  `;
4
4
  var passport = encode62.timeencode(encode62.decode62(user._passport, user.session));
5
- async function upload(f, base) {
6
- var api = await data.getApi('upload');
7
- var authorization = await data.getSource(api.base);
8
- var xhr = cross(api.method, api.base + base + f.name, { authorization: authorization });
9
- xhr.setRequestHeader('range', 'bytes=1-' + f.size);
10
- return xhr.send(f);
11
- }
12
- function main() {
13
- async function uploadAll(files) {
14
- await queue.call(files, function (f) {
15
- return upload(f, page.$scope.pathlist.join("/"));
5
+ var pending = [];
6
+ async function upload(f, dist, token) {
7
+ var api = await data.getApi("upload");
8
+ var p = {};
9
+ if (token) {
10
+ var { base, authorization } = token;
11
+ var start = f.start || 0;
12
+ var end = start + f.size - 1;
13
+ var xhr = cross(api.method, base + dist, { authorization });
14
+ xhr.setRequestHeader('range', `bytes=${start}-${end}`);
15
+ xhr.send(f.data);
16
+ var p = { url: base + dist, percent: f.start / f.total, abort: xhr.abort.bind(xhr) };
17
+ pending.push(p);
18
+ xhr.error(function (e) {
19
+ alert.error(e);
20
+ });
21
+ render.refresh();
22
+ await xhr;
23
+ removeFromList(pending, p);
24
+ }
25
+ else {
26
+ var authorization = data.getSource(api.base);
27
+ /**
28
+ * @type {XMLHttpRequest}
29
+ */
30
+ var xhr = cross(api.method, dist + f.name, { authorization });
31
+ var p = { percent: 0, pending: true, name: f.name, folder: dist, abort: xhr.abort.bind(xhr) };
32
+ dist = dist.replace(/^\/+|\/+$/g, '');
33
+ if (dist) p.url = api.base + dist + "/" + f.name;
34
+ else p.url = api.base + f.name;
35
+ this.data.push(p);
36
+ pending.push(p);
37
+ xhr.upload.onprogress = function ({ loaded, total }) {
38
+ p.percent = loaded / total;
39
+ render.refresh();
40
+ };
41
+ xhr.send(f);
42
+ xhr.error((e) => {
43
+ alert.error(e);
44
+ removeFromList(this.data, p);
45
+ removeFromList(pending, p);
16
46
  });
17
- page.$scope.open();
47
+ await xhr;
48
+ removeFromList(this.data, p);
49
+ removeFromList(pending, p);
50
+ }
51
+ return xhr;
52
+ }
53
+ var copyed = null;
54
+ class File {
55
+ constructor(f) {
56
+ var isfolder = /\/$/.test(f);
57
+ this.name = f.replace(/\/+$/, '');
58
+ this.isfolder = isfolder;
59
+ this.type = isfolder ? 'folder' : 'file';
60
+ }
61
+ get pending() {
62
+ for (var p of pending) {
63
+ if (p.url.indexOf(this.url) === 0) {
64
+ this.percent = p.percent;
65
+ return p;
66
+ }
67
+ }
68
+ return false;
69
+ }
70
+ abort() {
71
+ var p = this.pending;
72
+ if (!p) return;
73
+ p.abort();
18
74
  }
19
- var page = div();
20
- page.innerHTML = root;
75
+ }
76
+ function main() {
77
+ var page = explorer$main();
78
+ var backtime = 0;
21
79
  page.onback = function () {
22
80
  var $scope = this.$scope;
23
81
  if (!$scope.pathlist.length) {
24
- return;
82
+ if (Date.now() - backtime < 2022) alert("已是根目录!");
83
+ backtime = Date.now();
84
+ return false;
85
+ }
86
+ if ($scope.pathlist) {
87
+ var name = $scope.pathlist.pop();
88
+ var base = data.getInstance("base").base;
89
+ var p = $scope.pathlist.join("/").replace(/^\/+|\/+$/g, '');
90
+ var bp = p ? base + p + '/' : base;
91
+ p = p + '/';
92
+ data.setInstance("pathlist", $scope.pathlist);
93
+ name = name.replace(/^\/+|\/+$/g, '');
94
+ $scope.selected = [{
95
+ name,
96
+ isfolder: true,
97
+ where: p,
98
+ host: base,
99
+ url: bp + name + "/",
100
+ fullpath: p + name + "/",
101
+ type: 'folder'
102
+ }];
25
103
  }
26
- data.setInstance("pathlist", $scope.pathlist.slice(0, -1));
27
104
  $scope.open();
28
105
  return false;
29
106
  }
30
- page.setAttribute('on-contextmenu', 'setActive')
31
- bind('drop')(page, async function (event) {
32
- event.preventDefault();
33
- var files = event.dataTransfer.files;
34
- uploadAll(files);
35
- });
36
107
 
37
- renderWithDefaults(page, {
38
- lattice,
108
+ extend(page.$scope, {
39
109
  pathlist: data.getInstance("pathlist"),
40
- active: null,
41
- open(p) {
42
- if (p && !/\/$/.test(p.name)) {
43
- // window.open("/" + this.pathlist.concat(p.name).join('/'))
44
- return;
45
- }
46
- if (p) p = String(p.name || '').replace(/\/$/, '');
47
- if (p) data.setInstance("pathlist", this.pathlist.concat(p));
48
- this.data = data.from("folder", { opt: 'list', path: encode62.timeencode("/" + this.pathlist.join('/')) }, files => {
49
- if (files) return sortname(files).map(f => {
50
- return {
51
- name: f,
52
- type: /\/$/.test(f) ? 'folder' : 'file'
53
- }
110
+ read(from, start, size) {
111
+ var authorization = data.getSource(data.getInstance("base").base);
112
+ var xhr = cross("get", from.url, { authorization: authorization });
113
+ var end = start + size - 1;
114
+ xhr.setRequestHeader('range', `bytes=${start}-${end}`);
115
+ xhr.send();
116
+ return xhr;
117
+ },
118
+ load(p) {
119
+ data.setInstance("pathlist", this.pathlist);
120
+ var base = data.getInstance("base").base;
121
+ var p = p.replace(/^\/+|\/+$/g, '');
122
+ var bp = p ? base + p + "/" : base;
123
+ p = p + '/';
124
+ return data.from("folder", { opt: 'list', path: encode62.timeencode(p) }, files => {
125
+ if (files) return files.map(f => {
126
+ var file = new File(f);
127
+ file.host = base;
128
+ file.where = p;
129
+ file.url = bp + f;
130
+ file.fullpath = p + f;
131
+ return file;
54
132
  });
55
133
  });
56
134
  },
57
- setActive(e) {
58
- this.active = getActive(e);
135
+ async getToken() {
136
+ var api = await data.getApi('upload');
137
+ var authorization = await data.getSource(api.base);
138
+ return { authorization, base: api.base };
59
139
  },
60
- data: [],
61
- });
62
- page.$scope.open();
63
- var getActive = e => {
64
- var p = page.querySelector('lattice');
65
- var t = getTargetIn(e => e.parentNode && e.parentNode.parentNode === p, e.target);
66
- return t;
67
- };
68
- var when = e => !!getActive(e);
69
- var popupEdit = function (e) {
70
- zimoli.prepare('/wow/edit', function () {
71
- var p = popup("#/wow/edit", {
72
- path: page.$scope.pathlist,
73
- name: e || ''
74
- });
75
- on('submited')(p, function () {
76
- page.$scope.open();
77
- remove(p);
78
- });
79
- })
80
-
81
- };
82
- contextmenu(page, [
83
- {
84
- name: "新建文件夹",
85
- when: e => !getActive(e),
86
- do() {
87
- popupEdit();
88
- }
140
+ upload,
141
+ async delete(path) {
142
+ return data.from("folder", { opt: 'del', path: encode62.timeencode(path) })
89
143
  },
90
- {
91
- name: "添加文件",
92
- when: e => !getActive(e),
93
- do() {
94
- return chooseFile().then(uploadAll);
95
- }
144
+ async rename(from, to) {
145
+ from = encode62.timeencode(from);
146
+ to = encode62.timeencode(to);
147
+ await data.from("folder", { opt: 'mov', path: from, to }).loading_promise;
96
148
  },
97
- {
98
- name: '重命名',
99
- when,
100
- do(e) {
101
- popupEdit(e.$scope.d.name);
102
- }
149
+ async add(name) {
150
+ name = encode62.timeencode(name);
151
+ await data.from("folder", { opt: 'add', path: name }).loading_promise;
103
152
  },
104
- {
105
- get name() {
106
- return this.confirm ? "确认删除" : "删除";
107
- },
108
- confirm: false,
109
- when(e) {
110
- this.confirm = false;
111
- return when(e);
112
- },
113
- type: "danger",
114
- async do(e) {
115
- if (!this.confirm) {
116
- this.confirm = true;
117
- setTimeout(_ => {
118
- this.confirm = false;
119
- render.refresh();
120
- }, 2000);
121
- return false;
122
- }
123
- await data.from("folder", { opt: 'del', path: encode62.timeencode("/" + page.$scope.pathlist.concat(e.$scope.d.name).join("/")) }).loading_promise;
124
- page.$scope.open();
125
- }
153
+ async mov(from, distpath) {
154
+ var currentHost = data.getInstance("base").base;
155
+ if (from.host !== currentHost) return alert("暂不支持跨服务器操作!");
156
+ from = encode62.timeencode(from.fullpath);
157
+ distpath = encode62.timeencode(distpath);
158
+ await data.from("folder", { opt: 'mov', path: from, to: distpath }).loading_promise;
126
159
  }
127
- ]);
160
+ });
161
+ page.$scope.open();
128
162
  return page;
129
163
  }
@@ -1,63 +1,2 @@
1
- & {
2
- height: 100%;
3
- }
4
-
5
- @height: 44px;
6
-
7
- >lattice {
8
- box-sizing: content-box;
9
- margin-top: -@height;
10
- padding-top: @height + 6px;
11
-
12
- a {
13
- vertical-align: top;
14
- }
15
- }
16
-
17
- padding {
18
- border-right-width: 60px;
19
- }
20
-
21
- >.address {
22
- position: relative;
23
- z-index: 3;
24
- margin-left: 140px;
25
- margin-top: -@height - 6px;
26
- height: @height;
27
- padding: 0 6px;
28
- line-height: @height;
29
-
30
- input {
31
- width: 100%;
32
- }
33
- }
34
-
35
- item {
36
- border: 1px solid #0002;
37
- position: relative;
38
- display: block;
39
- padding: 10px 20px;
40
-
41
- &:hover {
42
- outline: 2px solid #2cf;
43
- }
44
-
45
- &:active {
46
- color: #28c;
47
- outline: 2px solid;
48
- }
49
-
50
- &.focus {
51
- color: #28c;
52
- outline: 2px solid;
53
- }
54
-
55
- >a {
56
- vertical-align: top;
57
- }
58
-
59
- >[op] {
60
- left: 6px;
61
- margin-left: 6px;
62
- }
1
+ &{
63
2
  }
@@ -0,0 +1,51 @@
1
+ var alltasks = Object.create(null);
2
+
3
+ class Task {
4
+ static get alltasks() { return alltasks; };
5
+ rest = [];
6
+ percent = 0;
7
+ aborted = false;
8
+ complete = true;
9
+ open(type, load) {
10
+ this.type = type;
11
+ this.load = load;
12
+ }
13
+ async loop() {
14
+ if (typeof this.load === "function") while (!this.aborted && this.rest.length) {
15
+ this.percent = 0;
16
+ await this.load(this.rest.pop());
17
+ }
18
+ this.percent = 100;
19
+ }
20
+ async send(data) {
21
+ this.rest.push(data);
22
+ if (!this.complete) return;
23
+ this.mount();
24
+ try {
25
+ this.complete = false;
26
+ await Promise.resolve().then(() => this.loop());
27
+ this.complete = true;
28
+ if (typeof this.onload === 'function') this.onload();
29
+ }
30
+ catch (e) {
31
+ if (typeof this.onerror === 'function') this.onerror(e);
32
+ }
33
+ this.unmount();
34
+ }
35
+ mount() {
36
+ var type = this.type;
37
+ if (!alltasks[type]) alltasks[type] = [];
38
+ alltasks[type].push(this);
39
+ }
40
+ unmount() {
41
+ if (!alltasks[this.type]) return;
42
+ removeFromList(alltasks[this.type], this);
43
+ if (!alltasks[this.type].length) delete alltasks[this.type];
44
+ }
45
+ abort() {
46
+ this.aborted = true;
47
+ this.unmount();
48
+ }
49
+ }
50
+
51
+ module.exports = Task;
@@ -308,6 +308,14 @@ function cross_(jsonp, digest = noop, method, url, headers) {
308
308
  cachedata.push({ [data]: value });
309
309
  }
310
310
  else if (!isEmpty(data)) {
311
+ if (!cachedata.length) {
312
+ if (File && data instanceof File || typeof data === 'string') {
313
+ datas = data;
314
+ }
315
+ }
316
+ else {
317
+ datas = '';
318
+ }
311
319
  cachedata.push(data);
312
320
  }
313
321
  return xhr;
@@ -1,6 +1,5 @@
1
1
  function keysFrom() {
2
- var args = [].slice.call(arguments, 0, arguments.length);
2
+ var args = Array.prototype.slice.call(arguments, 0, arguments.length);
3
3
  args.unshift(Object.create(null));
4
- return Object.keys(extend.apply(null, args));
5
- }
6
- var main = keysFrom;
4
+ return Object.keys(extendIfNeeded.apply(null, args));
5
+ }
@@ -75,7 +75,7 @@ var flushTree = function (tree, key, res) {
75
75
  for (var cx = 0, dx = response.length; cx < dx; cx++) {
76
76
  var call = response[cx];
77
77
  if (call instanceof Function) {
78
- call(response.error);
78
+ call(response.error ? key : null);
79
79
  }
80
80
  }
81
81
  }
@@ -84,13 +84,13 @@ var readingCount = 0;
84
84
  var readFile = function (names, then) {
85
85
  if (names instanceof Array) {
86
86
  names = names.slice(0);
87
- var loaded = 0, errored = 0;
87
+ var loaded = 0, errored = [];
88
88
  var callback = function (e) {
89
89
  if (e) {
90
- errored++;
90
+ errored.push(name);
91
91
  }
92
92
  if (++loaded === names.length) {
93
- then(errored);
93
+ then(errored.length ? errored : null);
94
94
  }
95
95
  };
96
96
  if (!names.length) return then();
@@ -150,7 +150,7 @@ var readFile = function (names, then) {
150
150
  }
151
151
  }
152
152
  loadingTree[key].error = e;
153
- loadingTree[key].forEach(a => a(1));
153
+ loadingTree[key].forEach(a => a(e));
154
154
  };
155
155
  var tryload = function () {
156
156
  request(url, ok, oh, version);
@@ -169,8 +169,9 @@ var killCircle = function () {
169
169
  for (var k in loadedModules) {
170
170
  if (k.slice(0, keyprefix.length) === keyprefix && loadedModules[k] instanceof Array) {
171
171
  var key = k.slice(keyprefix.length);
172
- var args = loadedModules[k].args;
173
172
  if (!(loadedModules[k] instanceof Array)) continue;
173
+ var args = loadedModules[k].args;
174
+ if (!(args instanceof Array)) continue;
174
175
  args.forEach(arg => {
175
176
  if (!penddings[arg]) {
176
177
  penddings[arg] = [];
@@ -292,20 +293,16 @@ var loadModule = function (name, then, prebuilds = {}) {
292
293
  mod.required = required;
293
294
  mod.file = name;
294
295
  args = args.concat(required);
295
- var _errored = 0;
296
+ var _errored = [];
296
297
  var response = function (error) {
297
298
  loadingCount++;
298
299
  if (error) {
299
- if (!errored[error]) {
300
- errored[error] = [];
301
- }
300
+ if (!errored[error]) errored[error] = [];
302
301
  errored[error].push(key);
303
- _errored++;
302
+ _errored.push(error);
304
303
  }
305
304
  if (loadingCount === args.length) {
306
- if (_errored.length) {
307
- loadedModules[key].error = true;
308
- }
305
+ if (_errored.length) loadedModules[key].error = _errored;
309
306
  flushTree(loadedModules, key, mod);
310
307
  }
311
308
  };
@@ -602,8 +599,35 @@ var init = function (name, then, prebuilds) {
602
599
  res.errored = true;
603
600
  res.error = error;
604
601
  res.fire();
605
- console.error(`加载${name}失败,${ed && ed.length ? `${ed.join(', ')} 等${ed.length}个模块` : "没有其他模块"}受到影响`);
606
- if (window.document) throw error;
602
+ var rest = [name];
603
+ var track = [];
604
+ var length = 0;
605
+ var deep = 0;
606
+ // <!--
607
+ var map = Object.create(null);
608
+ map[name] = true;
609
+ do {
610
+ deep++;
611
+ var rest2 = Object.create(null);
612
+ while (rest.length) {
613
+ var n = rest.pop();
614
+ var e = loadedModules[n] && loadedModules[n].error;
615
+ if (e instanceof Array) {
616
+ track.push([deep, n, e]);
617
+ if (n.length + deep > length) length = n.length + deep;
618
+ for (var e of e) if (!map[e]) rest2[e] = true, map[e] = true;
619
+ }
620
+ else {
621
+ if (n.length + deep > length) length = n.length + deep;
622
+ track.push([deep, n, [e]]);
623
+ }
624
+
625
+ }
626
+ rest = Object.keys(rest2);
627
+ } while (rest.length);
628
+ track = track.map(([d, a, e]) => ` ${new Array(d + 1).join("•")} ${new Array(2 + length - a.length - d).join("-")} ${a} 溃于: ${e.reverse().join(", ")}`)
629
+ // -->
630
+ console.error(`加载 ${name} 失败,${ed && ed.length ? `${ed.join(', ')} 等 ${ed.length} 个模块` : "没有其他模块"}受到影响。\r\n${track.join("\r\n")}`);
607
631
  };
608
632
  loadModule(name, function (error) {
609
633
  if (hasOwnProperty.call(modules, name)) {
@@ -841,6 +865,7 @@ var modules = {
841
865
  MOVELOCK_DELTA: 3 * renderPixelRatio,
842
866
  SAFE_CIRCLE_DEPTH: 300,
843
867
  init,
868
+ efrontPath,
844
869
  versionTree,
845
870
  responseTree,
846
871
  loadingTree,
@@ -885,7 +910,7 @@ var initIfNotDefined = function (defined, path, onload) {
885
910
  else hook(--requires_count);
886
911
  };
887
912
 
888
- if(document) loadResponseTreeFromStorage();
913
+ if (document) loadResponseTreeFromStorage();
889
914
  initIfNotDefined([].map, "[]map", map => map);
890
915
  initIfNotDefined(Promise, "Promise", promise => Promise = promise);
891
916
  if (!isProduction) window.modules = modules;
@@ -4,6 +4,9 @@ function submit(fields, data) {
4
4
  var select = [];
5
5
  var checks = [];
6
6
  var id = 0;
7
+ var trimname = function (a) {
8
+ return a.name.replace(/^请?(输入|选择|填写)/, '')
9
+ };
7
10
  for (var f of fields) {
8
11
  var error = valid(f, data);
9
12
  if (error === "empty") {
@@ -46,13 +49,13 @@ function submit(fields, data) {
46
49
  }
47
50
  if (checks.length + select.length + inputs.length) {
48
51
  var errors = [];
49
- if (inputs.length) errors.push("请输入" + inputs.map(f => f.name).join("、"));
50
- if (select.length) errors.push("请选择" + select.map(f => f.name).join("、"));
52
+ if (inputs.length) errors.push("请输入" + inputs.map(trimname).join("、"));
53
+ if (select.length) errors.push("请选择" + select.map(trimname).join("、"));
51
54
  if (select.id < inputs.id) {
52
55
  errors = errors.reverse();
53
56
  }
54
57
  if (checks.length) {
55
- errors.push(checks.map(f => f.name).join("、") + "格式错误");
58
+ errors.push("您输入的" + checks.map(trimname).join("、") + "有误");
56
59
  }
57
60
  errors = errors.join(",") + "!";
58
61
  throw errors;