clickgo 3.1.2-dev11 → 3.1.4-dev13
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.
- package/README.md +1 -1
- package/dist/app/demo/app.js +0 -73
- package/dist/app/demo/config.json +113 -0
- package/dist/app/demo/form/control/button/button.js +12 -11
- package/dist/app/demo/form/control/button/button.xml +6 -6
- package/dist/app/demo/form/control/check/check.js +14 -10
- package/dist/app/demo/form/control/file/file.js +15 -13
- package/dist/app/demo/form/control/{overflow/overflow.css → flow/flow.css} +0 -0
- package/dist/app/demo/form/control/flow/flow.js +64 -0
- package/dist/app/demo/form/control/{overflow/overflow.scss → flow/flow.scss} +0 -0
- package/dist/app/demo/form/control/flow/flow.xml +101 -0
- package/dist/app/demo/form/control/form/form.js +1 -1
- package/dist/app/demo/form/control/form/form.xml +3 -3
- package/dist/app/demo/form/control/img/img.xml +2 -2
- package/dist/app/demo/form/control/list/list.js +95 -75
- package/dist/app/demo/form/control/list/list.xml +15 -11
- package/dist/app/demo/form/control/marquee/marquee.js +12 -10
- package/dist/app/demo/form/control/menu/menu.js +10 -6
- package/dist/app/demo/form/control/monaco/monaco.js +50 -60
- package/dist/app/demo/form/control/monaco/monaco.xml +6 -5
- package/dist/app/demo/form/control/property/property.js +131 -127
- package/dist/app/demo/form/control/radio/radio.js +9 -5
- package/dist/app/demo/form/control/scroll/scroll.js +16 -12
- package/dist/app/demo/form/control/scroll/scroll.xml +10 -10
- package/dist/app/demo/form/control/select/select.js +132 -71
- package/dist/app/demo/form/control/select/select.xml +69 -67
- package/dist/app/demo/form/control/tab/tab.js +21 -20
- package/dist/app/demo/form/control/tab/tab.xml +2 -2
- package/dist/app/demo/form/control/text/text.js +53 -45
- package/dist/app/demo/form/control/text/text.xml +3 -3
- package/dist/app/demo/form/control/{greatview/greatview.css → vflow/vflow.css} +0 -0
- package/dist/app/demo/form/control/vflow/vflow.js +79 -0
- package/dist/app/demo/form/control/{greatview/greatview.scss → vflow/vflow.scss} +0 -0
- package/dist/app/demo/form/control/{greatview/greatview.xml → vflow/vflow.xml} +25 -25
- package/dist/app/demo/form/event/form/form.js +58 -56
- package/dist/app/demo/form/event/form/form.xml +3 -3
- package/dist/app/demo/form/event/other/other.js +29 -0
- package/dist/app/demo/form/event/other/other.xml +5 -0
- package/dist/app/demo/form/event/screen/screen.js +30 -28
- package/dist/app/demo/form/event/screen/screen.xml +2 -2
- package/dist/app/demo/form/event/task/task.js +31 -31
- package/dist/app/demo/form/event/task/task.xml +3 -3
- package/dist/app/demo/form/main.js +166 -5
- package/dist/app/demo/form/main.xml +37 -35
- package/dist/app/demo/form/method/aform/aform.js +2 -1
- package/dist/app/demo/form/method/aform/aform.xml +3 -2
- package/dist/app/demo/form/method/aform/sd.js +28 -0
- package/dist/app/demo/form/method/aform/sd.xml +7 -0
- package/dist/app/demo/form/method/aform/test.xml +4 -5
- package/dist/app/demo/form/method/core/core.js +23 -8
- package/dist/app/demo/form/method/core/core.xml +6 -1
- package/dist/app/demo/form/method/dom/dom.js +91 -99
- package/dist/app/demo/form/method/dom/dom.xml +6 -7
- package/dist/app/demo/form/method/form/form.js +8 -8
- package/dist/app/demo/form/method/form/form.xml +4 -4
- package/dist/app/demo/form/method/fs/fs.js +34 -33
- package/dist/app/demo/form/method/fs/fs.xml +1 -1
- package/dist/app/demo/form/method/fs/text.js +12 -12
- package/dist/app/demo/form/method/native/native.js +50 -0
- package/dist/app/demo/form/method/native/native.xml +12 -0
- package/dist/app/demo/form/method/system/system.js +50 -0
- package/dist/app/demo/form/method/system/system.xml +11 -0
- package/dist/app/demo/form/method/task/task.js +68 -62
- package/dist/app/demo/form/method/task/task.xml +5 -6
- package/dist/app/demo/form/method/theme/theme.js +14 -14
- package/dist/app/demo/form/method/tool/tool.js +29 -28
- package/dist/app/demo/form/method/tool/tool.xml +3 -3
- package/dist/app/demo/form/method/zip/zip.js +46 -41
- package/dist/app/demo/form/method/zip/zip.xml +1 -1
- package/dist/app/task/app.js +0 -25
- package/dist/app/task/config.json +29 -0
- package/dist/app/task/form/bar/bar.js +1 -1
- package/dist/app/task/form/bar/bar.xml +1 -1
- package/dist/clickgo.js +1 -1
- package/dist/clickgo.ts +1 -1
- package/dist/control/common.cgc +0 -0
- package/dist/control/form.cgc +0 -0
- package/dist/control/monaco.cgc +0 -0
- package/dist/control/property.cgc +0 -0
- package/dist/control/task.cgc +0 -0
- package/dist/global.css +1 -1
- package/dist/index.js +6 -3
- package/dist/index.ts +9 -3
- package/dist/lib/control.js +70 -104
- package/dist/lib/control.ts +97 -123
- package/dist/lib/core.js +163 -253
- package/dist/lib/core.ts +185 -268
- package/dist/lib/dom.js +565 -484
- package/dist/lib/dom.ts +704 -547
- package/dist/lib/form.js +211 -159
- package/dist/lib/form.ts +196 -121
- package/dist/lib/fs.js +107 -12
- package/dist/lib/fs.ts +111 -20
- package/dist/lib/native.js +142 -8
- package/dist/lib/native.ts +181 -11
- package/dist/lib/task.js +526 -164
- package/dist/lib/task.ts +598 -179
- package/dist/lib/tool.js +48 -1
- package/dist/lib/tool.ts +61 -0
- package/dist/lib/zip.ts +2 -0
- package/dist/theme/familiar.cgt +0 -0
- package/package.json +2 -2
- package/types/index.d.ts +83 -39
- package/dist/app/demo/form/control/greatview/greatview.js +0 -92
- package/dist/app/demo/form/control/overflow/overflow.js +0 -70
- package/dist/app/demo/form/control/overflow/overflow.xml +0 -98
- package/dist/app/demo/form/control/view/view.css +0 -1
- package/dist/app/demo/form/control/view/view.js +0 -73
- package/dist/app/demo/form/control/view/view.scss +0 -18
- package/dist/app/demo/form/control/view/view.xml +0 -94
package/dist/lib/core.ts
CHANGED
|
@@ -19,10 +19,7 @@ import * as fs from './fs';
|
|
|
19
19
|
import * as form from './form';
|
|
20
20
|
import * as task from './task';
|
|
21
21
|
import * as tool from './tool';
|
|
22
|
-
import * as control from './control';
|
|
23
|
-
import * as theme from './theme';
|
|
24
22
|
import * as zip from './zip';
|
|
25
|
-
import * as dom from './dom';
|
|
26
23
|
|
|
27
24
|
/** --- Config 原始参考对象 --- */
|
|
28
25
|
const configOrigin: types.IConfig = {
|
|
@@ -72,153 +69,6 @@ export abstract class AbstractApp {
|
|
|
72
69
|
/** --- App 的入口文件 --- */
|
|
73
70
|
public abstract main(): Promise<void>;
|
|
74
71
|
|
|
75
|
-
/**
|
|
76
|
-
* --- 先设置 App 的配置信息 ---
|
|
77
|
-
* @param config 配置对象
|
|
78
|
-
*/
|
|
79
|
-
public async config(config: types.IAppConfig): Promise<boolean> {
|
|
80
|
-
const t = task.list[this.taskId];
|
|
81
|
-
if (!t) {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
t.config = config;
|
|
85
|
-
// --- 加载余下的 xml 等静态包内资源,仅限 net 的 app 模式 ---
|
|
86
|
-
if (t.app.net) {
|
|
87
|
-
if (!t.config.files) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
const files = t.config.files;
|
|
91
|
-
const net = t.app.net;
|
|
92
|
-
await new Promise<void>(function(resolve) {
|
|
93
|
-
let loaded = 0;
|
|
94
|
-
const total = files.length;
|
|
95
|
-
const beforeTotal = Object.keys(t.app.files).length;
|
|
96
|
-
net.progress?.(loaded + beforeTotal, total + beforeTotal) as unknown;
|
|
97
|
-
for (const file of files) {
|
|
98
|
-
fs.getContent(net.url + file.slice(1), {
|
|
99
|
-
'current': net.current
|
|
100
|
-
}).then(async function(blob) {
|
|
101
|
-
if (blob === null || typeof blob === 'string') {
|
|
102
|
-
clickgo.form.notify({
|
|
103
|
-
'title': 'File not found',
|
|
104
|
-
'content': net.url + file.slice(1),
|
|
105
|
-
'type': 'danger'
|
|
106
|
-
});
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const mime = tool.getMimeByPath(file);
|
|
110
|
-
if (['txt', 'json', 'js', 'css', 'xml', 'html'].includes(mime.ext)) {
|
|
111
|
-
t.app.files[file] = (await tool.blob2Text(blob)).replace(/^\ufeff/, '');
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
t.app.files[file] = blob;
|
|
115
|
-
}
|
|
116
|
-
++loaded;
|
|
117
|
-
net.progress?.(loaded + beforeTotal, total + beforeTotal) as unknown;
|
|
118
|
-
if (net.notify) {
|
|
119
|
-
form.notifyProgress(net.notify, (loaded / total) / 2 + 0.5);
|
|
120
|
-
}
|
|
121
|
-
if (loaded < total) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
resolve();
|
|
125
|
-
}).catch(function() {
|
|
126
|
-
++loaded;
|
|
127
|
-
net.progress?.(loaded + beforeTotal, total + beforeTotal) as unknown;
|
|
128
|
-
if (net.notify) {
|
|
129
|
-
form.notifyProgress(net.notify, (loaded / total) / 2 + 0.5);
|
|
130
|
-
}
|
|
131
|
-
if (loaded < total) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
resolve();
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
if (net.notify) {
|
|
139
|
-
setTimeout(function(): void {
|
|
140
|
-
form.hideNotify(net.notify!);
|
|
141
|
-
}, 2000);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// --- 要加载 control ---
|
|
145
|
-
if (!await control.init(this.taskId)) {
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
// --- theme ---
|
|
149
|
-
if (config.themes?.length) {
|
|
150
|
-
for (let path of config.themes) {
|
|
151
|
-
path += '.cgt';
|
|
152
|
-
path = tool.urlResolve('/', path);
|
|
153
|
-
const file = await fs.getContent(path, {
|
|
154
|
-
'files': t.app.files,
|
|
155
|
-
'current': t.current
|
|
156
|
-
});
|
|
157
|
-
if (file && typeof file !== 'string') {
|
|
158
|
-
const th = await theme.read(file);
|
|
159
|
-
if (th) {
|
|
160
|
-
await theme.load(th, t.id);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
// --- 加载全局主题 ---
|
|
167
|
-
if (theme.global) {
|
|
168
|
-
await theme.load(undefined, this.taskId);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// --- locale ---
|
|
172
|
-
if (config.locales) {
|
|
173
|
-
for (let path in config.locales) {
|
|
174
|
-
const locale = config.locales[path];
|
|
175
|
-
if (!path.endsWith('.json')) {
|
|
176
|
-
path += '.json';
|
|
177
|
-
}
|
|
178
|
-
const lcontent = await fs.getContent(path, {
|
|
179
|
-
'encoding': 'utf8',
|
|
180
|
-
'files': t.app.files,
|
|
181
|
-
'current': t.current
|
|
182
|
-
});
|
|
183
|
-
if (!lcontent) {
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
try {
|
|
187
|
-
const data = JSON.parse(lcontent);
|
|
188
|
-
task.loadLocaleData(locale, data, '', t.id);
|
|
189
|
-
}
|
|
190
|
-
catch {
|
|
191
|
-
// --- 无所谓 ---
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// --- 加载任务级全局样式 ---
|
|
196
|
-
if (config.style) {
|
|
197
|
-
const style = await fs.getContent(config.style + '.css', {
|
|
198
|
-
'encoding': 'utf8',
|
|
199
|
-
'files': t.app.files,
|
|
200
|
-
'current': t.current
|
|
201
|
-
});
|
|
202
|
-
if (style) {
|
|
203
|
-
const r = tool.stylePrepend(style, 'cg-task' + this.taskId.toString() + '_');
|
|
204
|
-
dom.pushStyle(this.taskId, await tool.styleUrl2DataUrl(config.style, r.style, t.app.files));
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
// --- 加载图标 ---
|
|
208
|
-
if (config.icon) {
|
|
209
|
-
const icon = await fs.getContent(config.icon, {
|
|
210
|
-
'files': t.app.files,
|
|
211
|
-
'current': t.current
|
|
212
|
-
});
|
|
213
|
-
if (icon && typeof icon !== 'string') {
|
|
214
|
-
t.app.icon = await tool.blob2DataUrl(icon);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
// --- 全部成功,设置 t.class 为自己 ---
|
|
218
|
-
t.class = this;
|
|
219
|
-
return true;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
72
|
/**
|
|
223
73
|
* --- 以某个窗体进行正式启动这个 app(入口 form),不启动则任务也启动失败 ---
|
|
224
74
|
* @param form 窗体对象
|
|
@@ -329,6 +179,12 @@ export abstract class AbstractApp {
|
|
|
329
179
|
return;
|
|
330
180
|
}
|
|
331
181
|
|
|
182
|
+
/** --- location hash 改变事件 --- */
|
|
183
|
+
public onHashChanged(hash: string): void | Promise<void>;
|
|
184
|
+
public onHashChanged(): void {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
332
188
|
}
|
|
333
189
|
|
|
334
190
|
/** --- CDN 地址 --- */
|
|
@@ -392,7 +248,12 @@ clickgo.vue.watch(config, function() {
|
|
|
392
248
|
});
|
|
393
249
|
|
|
394
250
|
/** --- module 列表 --- */
|
|
395
|
-
const modules: Record<string, {
|
|
251
|
+
const modules: Record<string, {
|
|
252
|
+
func: () => any | Promise<any>;
|
|
253
|
+
'obj': null | any;
|
|
254
|
+
'loading': boolean;
|
|
255
|
+
'resolve': Array<() => void | Promise<void>>;
|
|
256
|
+
}> = {
|
|
396
257
|
'monaco': {
|
|
397
258
|
func: async function() {
|
|
398
259
|
return new Promise(function(resolve, reject) {
|
|
@@ -408,7 +269,8 @@ const modules: Record<string, { func: () => any | Promise<any>; 'obj': null | an
|
|
|
408
269
|
});
|
|
409
270
|
},
|
|
410
271
|
'obj': null,
|
|
411
|
-
'loading': false
|
|
272
|
+
'loading': false,
|
|
273
|
+
'resolve': []
|
|
412
274
|
}
|
|
413
275
|
};
|
|
414
276
|
|
|
@@ -424,97 +286,61 @@ export function regModule(name: string, func: () => any | Promise<any>): boolean
|
|
|
424
286
|
modules[name] = {
|
|
425
287
|
func: func,
|
|
426
288
|
'obj': null,
|
|
427
|
-
'loading': false
|
|
289
|
+
'loading': false,
|
|
290
|
+
'resolve': []
|
|
428
291
|
};
|
|
429
292
|
return true;
|
|
430
293
|
}
|
|
431
294
|
|
|
432
295
|
/**
|
|
433
|
-
* ---
|
|
434
|
-
* @param
|
|
296
|
+
* --- 获取外接模块 ---
|
|
297
|
+
* @param name 模块名
|
|
435
298
|
*/
|
|
436
|
-
export function
|
|
437
|
-
return new Promise(
|
|
438
|
-
if (
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
if (names.length === 0) {
|
|
442
|
-
resolve(0);
|
|
443
|
-
return;
|
|
299
|
+
export function getModule(name: string): Promise<null | any> {
|
|
300
|
+
return new Promise((resolve) => {
|
|
301
|
+
if (!modules[name]) {
|
|
302
|
+
return null;
|
|
444
303
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
for (const name of names) {
|
|
448
|
-
if (!modules[name]) {
|
|
449
|
-
++loaded;
|
|
450
|
-
if (loaded === names.length) {
|
|
451
|
-
resolve(successful);
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
continue;
|
|
455
|
-
}
|
|
456
|
-
if (modules[name].obj) {
|
|
457
|
-
++loaded;
|
|
458
|
-
++successful;
|
|
459
|
-
if (loaded === names.length) {
|
|
460
|
-
resolve(successful);
|
|
461
|
-
return;
|
|
462
|
-
}
|
|
463
|
-
continue;
|
|
464
|
-
}
|
|
304
|
+
if (!modules[name].obj) {
|
|
305
|
+
// --- obj 是 null 判断是否要初始化 ---
|
|
465
306
|
if (modules[name].loading) {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
resolve(
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
continue;
|
|
472
|
-
}
|
|
473
|
-
// --- 正式开始加载 init ---
|
|
474
|
-
modules[name].loading = true;
|
|
475
|
-
const rtn = modules[name].func();
|
|
476
|
-
if (rtn instanceof Promise) {
|
|
477
|
-
rtn.then(function(obj) {
|
|
478
|
-
modules[name].obj = obj;
|
|
479
|
-
modules[name].loading = false;
|
|
480
|
-
++loaded;
|
|
481
|
-
++successful;
|
|
482
|
-
if (loaded === names.length) {
|
|
483
|
-
resolve(successful);
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
}).catch(function() {
|
|
487
|
-
modules[name].loading = false;
|
|
488
|
-
++loaded;
|
|
489
|
-
if (loaded === names.length) {
|
|
490
|
-
resolve(successful);
|
|
491
|
-
}
|
|
307
|
+
// --- 加载中,等待 ---
|
|
308
|
+
modules[name].resolve.push(() => {
|
|
309
|
+
resolve(modules[name].obj);
|
|
492
310
|
});
|
|
493
311
|
}
|
|
494
312
|
else {
|
|
495
|
-
|
|
496
|
-
modules[name].
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
313
|
+
// --- 没加载,开始加载 ---
|
|
314
|
+
const rtn = modules[name].func();
|
|
315
|
+
if (rtn instanceof Promise) {
|
|
316
|
+
modules[name].loading = true;
|
|
317
|
+
rtn.then(function(obj) {
|
|
318
|
+
modules[name].obj = obj;
|
|
319
|
+
modules[name].loading = false;
|
|
320
|
+
resolve(obj);
|
|
321
|
+
for (const r of modules[name].resolve) {
|
|
322
|
+
r() as any;
|
|
323
|
+
}
|
|
324
|
+
}).catch(function() {
|
|
325
|
+
modules[name].loading = false;
|
|
326
|
+
resolve(null);
|
|
327
|
+
for (const r of modules[name].resolve) {
|
|
328
|
+
r() as any;
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
modules[name].obj = rtn;
|
|
334
|
+
resolve(rtn);
|
|
501
335
|
}
|
|
502
336
|
}
|
|
337
|
+
return;
|
|
503
338
|
}
|
|
339
|
+
resolve(modules[name].obj);
|
|
340
|
+
return;
|
|
504
341
|
});
|
|
505
342
|
}
|
|
506
343
|
|
|
507
|
-
/**
|
|
508
|
-
* --- 获取外接模块 ---
|
|
509
|
-
* @param name 模块名
|
|
510
|
-
*/
|
|
511
|
-
export function getModule(name: string): null | any {
|
|
512
|
-
if (!modules[name]) {
|
|
513
|
-
return null;
|
|
514
|
-
}
|
|
515
|
-
return modules[name].obj;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
344
|
/** --- 系统要处理的全局响应事件 --- */
|
|
519
345
|
const globalEvents = {
|
|
520
346
|
screenResize: function(): void {
|
|
@@ -678,7 +504,7 @@ export function trigger(name: types.TGlobalEvent, taskId: number | string | bool
|
|
|
678
504
|
if (typeof formId !== 'string') {
|
|
679
505
|
break;
|
|
680
506
|
}
|
|
681
|
-
if (typeof taskId
|
|
507
|
+
if (typeof taskId !== 'string') {
|
|
682
508
|
taskId = taskId.toString();
|
|
683
509
|
}
|
|
684
510
|
(boot as any)[eventName](taskId, formId);
|
|
@@ -691,6 +517,20 @@ export function trigger(name: types.TGlobalEvent, taskId: number | string | bool
|
|
|
691
517
|
}
|
|
692
518
|
break;
|
|
693
519
|
}
|
|
520
|
+
case 'hashChanged': {
|
|
521
|
+
if (typeof taskId !== 'string') {
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
(boot as any)[eventName](taskId);
|
|
525
|
+
for (const tid in task.list) {
|
|
526
|
+
const t = task.list[tid];
|
|
527
|
+
(t.class as any)?.[eventName](taskId);
|
|
528
|
+
for (const fid in t.forms) {
|
|
529
|
+
t.forms[fid].vroot[eventName]?.(taskId);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
694
534
|
}
|
|
695
535
|
}
|
|
696
536
|
|
|
@@ -707,6 +547,13 @@ export async function readApp(blob: Blob): Promise<false | types.IApp> {
|
|
|
707
547
|
}
|
|
708
548
|
// --- 开始读取文件 ---
|
|
709
549
|
const files: Record<string, Blob | string> = {};
|
|
550
|
+
/** --- 配置文件 --- */
|
|
551
|
+
const configContent = await z.getContent('/config.json');
|
|
552
|
+
if (!configContent) {
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
const config: types.IAppConfig = JSON.parse(configContent);
|
|
556
|
+
// --- 读取包 ---
|
|
710
557
|
const list = z.readDir('/', {
|
|
711
558
|
'hasChildren': true
|
|
712
559
|
});
|
|
@@ -730,8 +577,10 @@ export async function readApp(blob: Blob): Promise<false | types.IApp> {
|
|
|
730
577
|
}
|
|
731
578
|
}
|
|
732
579
|
return {
|
|
733
|
-
'
|
|
734
|
-
'
|
|
580
|
+
'type': 'app',
|
|
581
|
+
'config': config,
|
|
582
|
+
'files': files,
|
|
583
|
+
'icon': icon
|
|
735
584
|
};
|
|
736
585
|
}
|
|
737
586
|
|
|
@@ -798,53 +647,97 @@ export async function fetchApp(
|
|
|
798
647
|
return null;
|
|
799
648
|
}
|
|
800
649
|
}
|
|
801
|
-
// ---
|
|
802
|
-
let
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
if (loaded === total) {
|
|
817
|
-
++total;
|
|
818
|
-
}
|
|
819
|
-
if (opt.notifyId) {
|
|
820
|
-
form.notifyProgress(opt.notifyId, (loaded / total) / 2);
|
|
650
|
+
// --- 从网络加载 app ---
|
|
651
|
+
let config: types.IAppConfig;
|
|
652
|
+
/** --- 已加载的 files --- */
|
|
653
|
+
const files: Record<string, Blob | string> = {};
|
|
654
|
+
try {
|
|
655
|
+
const blob = await fs.getContent(url + 'config.json', {
|
|
656
|
+
'current': current
|
|
657
|
+
});
|
|
658
|
+
if (blob === null || typeof blob === 'string') {
|
|
659
|
+
return null;
|
|
660
|
+
}
|
|
661
|
+
config = JSON.parse(await tool.blob2Text(blob));
|
|
662
|
+
await new Promise<void>(function(resolve) {
|
|
663
|
+
if (!config.files) {
|
|
664
|
+
return;
|
|
821
665
|
}
|
|
666
|
+
const total = config.files.length;
|
|
667
|
+
let loaded = 0;
|
|
822
668
|
if (opt.progress) {
|
|
823
|
-
opt.progress(loaded, total) as unknown;
|
|
669
|
+
opt.progress(loaded + 1, total + 1) as unknown;
|
|
670
|
+
}
|
|
671
|
+
for (const file of config.files) {
|
|
672
|
+
fs.getContent(url + file.slice(1), {
|
|
673
|
+
'current': current
|
|
674
|
+
}).then(async function(blob) {
|
|
675
|
+
if (blob === null || typeof blob === 'string') {
|
|
676
|
+
clickgo.form.notify({
|
|
677
|
+
'title': 'File not found',
|
|
678
|
+
'content': url + file.slice(1),
|
|
679
|
+
'type': 'danger'
|
|
680
|
+
});
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
const mime = tool.getMimeByPath(file);
|
|
684
|
+
if (['txt', 'json', 'js', 'css', 'xml', 'html'].includes(mime.ext)) {
|
|
685
|
+
files[file] = (await tool.blob2Text(blob)).replace(/^\ufeff/, '');
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
files[file] = blob;
|
|
689
|
+
}
|
|
690
|
+
++loaded;
|
|
691
|
+
if (opt.notifyId) {
|
|
692
|
+
form.notifyProgress(opt.notifyId, loaded / total);
|
|
693
|
+
}
|
|
694
|
+
if (opt.progress) {
|
|
695
|
+
opt.progress(loaded + 1, total + 1) as unknown;
|
|
696
|
+
}
|
|
697
|
+
if (loaded < total) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
resolve();
|
|
701
|
+
}).catch(function() {
|
|
702
|
+
++loaded;
|
|
703
|
+
if (opt.notifyId) {
|
|
704
|
+
form.notifyProgress(opt.notifyId, loaded / total);
|
|
705
|
+
}
|
|
706
|
+
if (opt.progress) {
|
|
707
|
+
opt.progress(loaded + 1, total + 1) as unknown;
|
|
708
|
+
}
|
|
709
|
+
if (loaded < total) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
resolve();
|
|
713
|
+
});
|
|
824
714
|
}
|
|
825
|
-
}
|
|
826
|
-
});
|
|
827
|
-
// --- net 模式此处加载完只算到 50%,因为还有 app 类当中 config 中的静态部分,暂定预留 50% ---
|
|
828
|
-
if (opt.notifyId) {
|
|
829
|
-
form.notifyProgress(opt.notifyId, 0.5);
|
|
715
|
+
});
|
|
830
716
|
}
|
|
831
|
-
|
|
717
|
+
catch (e: any) {
|
|
718
|
+
console.log('core.fetchApp', e);
|
|
719
|
+
trigger('error', 0, 0, e, e.message);
|
|
832
720
|
return null;
|
|
833
721
|
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
722
|
+
|
|
723
|
+
let icon = '';
|
|
724
|
+
if (config.icon && (files[config.icon] instanceof Blob)) {
|
|
725
|
+
icon = await tool.blob2DataUrl(files[config.icon] as Blob);
|
|
838
726
|
}
|
|
727
|
+
if (icon === '') {
|
|
728
|
+
const iconBlob = await fs.getContent('/clickgo/icon.png', {
|
|
729
|
+
'current': current
|
|
730
|
+
});
|
|
731
|
+
if (iconBlob instanceof Blob) {
|
|
732
|
+
icon = await tool.blob2DataUrl(iconBlob);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
839
736
|
return {
|
|
840
|
-
'
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
'progress': opt.progress
|
|
845
|
-
},
|
|
846
|
-
'icon': '',
|
|
847
|
-
'files': files
|
|
737
|
+
'type': 'app',
|
|
738
|
+
'config': config,
|
|
739
|
+
'files': files,
|
|
740
|
+
'icon': icon
|
|
848
741
|
};
|
|
849
742
|
}
|
|
850
743
|
|
|
@@ -902,3 +795,27 @@ export function getAvailArea(): types.IAvailArea {
|
|
|
902
795
|
};
|
|
903
796
|
}
|
|
904
797
|
}
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* --- 修改浏览器 hash ---
|
|
801
|
+
* @param hash 修改的值,不含 #
|
|
802
|
+
* @param taskId 基任务,App 模式下无效
|
|
803
|
+
*/
|
|
804
|
+
export function hash(hash: string, taskId?: number): boolean {
|
|
805
|
+
if (!taskId) {
|
|
806
|
+
return false;
|
|
807
|
+
}
|
|
808
|
+
const t = task.list[taskId];
|
|
809
|
+
if (!t) {
|
|
810
|
+
return false;
|
|
811
|
+
}
|
|
812
|
+
if (!t.runtime.permissions.includes('root') && !t.runtime.permissions.includes('hash')) {
|
|
813
|
+
return false;
|
|
814
|
+
}
|
|
815
|
+
window.location.hash = hash;
|
|
816
|
+
return true;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
window.addEventListener('hashchange', function() {
|
|
820
|
+
trigger('hashChanged', window.location.hash ? window.location.hash.slice(1) : '');
|
|
821
|
+
});
|