clickgo 3.1.1-dev10 → 3.1.3-dev12

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 (106) hide show
  1. package/dist/app/demo/app.js +0 -72
  2. package/dist/app/demo/config.json +109 -0
  3. package/dist/app/demo/form/control/button/button.js +12 -11
  4. package/dist/app/demo/form/control/button/button.xml +6 -6
  5. package/dist/app/demo/form/control/check/check.js +14 -10
  6. package/dist/app/demo/form/control/file/file.js +15 -13
  7. package/dist/app/demo/form/control/{overflow/overflow.css → flow/flow.css} +0 -0
  8. package/dist/app/demo/form/control/flow/flow.js +64 -0
  9. package/dist/app/demo/form/control/{overflow/overflow.scss → flow/flow.scss} +0 -0
  10. package/dist/app/demo/form/control/flow/flow.xml +101 -0
  11. package/dist/app/demo/form/control/form/form.js +1 -1
  12. package/dist/app/demo/form/control/form/form.xml +3 -3
  13. package/dist/app/demo/form/control/img/img.xml +2 -2
  14. package/dist/app/demo/form/control/list/list.js +95 -75
  15. package/dist/app/demo/form/control/list/list.xml +15 -11
  16. package/dist/app/demo/form/control/marquee/marquee.js +12 -10
  17. package/dist/app/demo/form/control/menu/menu.js +10 -6
  18. package/dist/app/demo/form/control/monaco/monaco.js +50 -60
  19. package/dist/app/demo/form/control/monaco/monaco.xml +6 -5
  20. package/dist/app/demo/form/control/property/property.js +131 -127
  21. package/dist/app/demo/form/control/radio/radio.js +9 -5
  22. package/dist/app/demo/form/control/scroll/scroll.js +16 -12
  23. package/dist/app/demo/form/control/scroll/scroll.xml +10 -10
  24. package/dist/app/demo/form/control/select/select.js +132 -71
  25. package/dist/app/demo/form/control/select/select.xml +69 -67
  26. package/dist/app/demo/form/control/tab/tab.js +21 -20
  27. package/dist/app/demo/form/control/tab/tab.xml +2 -2
  28. package/dist/app/demo/form/control/text/text.js +53 -45
  29. package/dist/app/demo/form/control/text/text.xml +3 -3
  30. package/dist/app/demo/form/control/{greatview/greatview.css → vflow/vflow.css} +0 -0
  31. package/dist/app/demo/form/control/vflow/vflow.js +79 -0
  32. package/dist/app/demo/form/control/{greatview/greatview.scss → vflow/vflow.scss} +0 -0
  33. package/dist/app/demo/form/control/{greatview/greatview.xml → vflow/vflow.xml} +25 -25
  34. package/dist/app/demo/form/event/form/form.js +58 -56
  35. package/dist/app/demo/form/event/form/form.xml +3 -3
  36. package/dist/app/demo/form/event/screen/screen.js +30 -28
  37. package/dist/app/demo/form/event/screen/screen.xml +2 -2
  38. package/dist/app/demo/form/event/task/task.js +31 -31
  39. package/dist/app/demo/form/event/task/task.xml +3 -3
  40. package/dist/app/demo/form/main.js +166 -5
  41. package/dist/app/demo/form/main.xml +37 -35
  42. package/dist/app/demo/form/method/aform/aform.js +57 -0
  43. package/dist/app/demo/form/method/aform/aform.xml +35 -0
  44. package/dist/app/demo/form/method/aform/test.xml +6 -0
  45. package/dist/app/demo/form/method/core/core.js +11 -8
  46. package/dist/app/demo/form/method/core/core.xml +2 -1
  47. package/dist/app/demo/form/method/dom/dom.js +91 -99
  48. package/dist/app/demo/form/method/dom/dom.xml +6 -7
  49. package/dist/app/demo/form/method/form/form.js +10 -28
  50. package/dist/app/demo/form/method/form/form.xml +8 -15
  51. package/dist/app/demo/form/method/fs/fs.js +34 -33
  52. package/dist/app/demo/form/method/fs/fs.xml +1 -1
  53. package/dist/app/demo/form/method/fs/text.js +12 -12
  54. package/dist/app/demo/form/method/native/native.js +50 -0
  55. package/dist/app/demo/form/method/native/native.xml +12 -0
  56. package/dist/app/demo/form/method/system/system.js +50 -0
  57. package/dist/app/demo/form/method/system/system.xml +11 -0
  58. package/dist/app/demo/form/method/task/task.js +59 -61
  59. package/dist/app/demo/form/method/task/task.xml +4 -6
  60. package/dist/app/demo/form/method/theme/theme.js +14 -14
  61. package/dist/app/demo/form/method/tool/tool.js +29 -28
  62. package/dist/app/demo/form/method/tool/tool.xml +3 -3
  63. package/dist/app/demo/form/method/zip/zip.js +46 -41
  64. package/dist/app/demo/form/method/zip/zip.xml +1 -1
  65. package/dist/app/task/app.js +0 -25
  66. package/dist/app/task/config.json +29 -0
  67. package/dist/app/task/form/bar/bar.js +2 -2
  68. package/dist/app/task/form/bar/bar.xml +1 -1
  69. package/dist/clickgo.js +17 -5
  70. package/dist/clickgo.ts +22 -3
  71. package/dist/control/common.cgc +0 -0
  72. package/dist/control/form.cgc +0 -0
  73. package/dist/control/monaco.cgc +0 -0
  74. package/dist/control/property.cgc +0 -0
  75. package/dist/control/task.cgc +0 -0
  76. package/dist/global.css +1 -1
  77. package/dist/index.js +28 -8
  78. package/dist/index.ts +33 -7
  79. package/dist/lib/control.js +75 -105
  80. package/dist/lib/control.ts +102 -124
  81. package/dist/lib/core.js +108 -252
  82. package/dist/lib/core.ts +122 -268
  83. package/dist/lib/dom.js +564 -483
  84. package/dist/lib/dom.ts +703 -546
  85. package/dist/lib/form.js +170 -153
  86. package/dist/lib/form.ts +132 -99
  87. package/dist/lib/fs.js +1 -1
  88. package/dist/lib/fs.ts +1 -1
  89. package/dist/lib/native.js +135 -8
  90. package/dist/lib/native.ts +176 -12
  91. package/dist/lib/task.js +301 -175
  92. package/dist/lib/task.ts +330 -207
  93. package/dist/lib/tool.js +48 -1
  94. package/dist/lib/tool.ts +61 -0
  95. package/dist/lib/zip.ts +2 -0
  96. package/dist/theme/familiar.cgt +0 -0
  97. package/package.json +1 -1
  98. package/types/index.d.ts +26 -29
  99. package/dist/app/demo/form/control/greatview/greatview.js +0 -92
  100. package/dist/app/demo/form/control/overflow/overflow.js +0 -70
  101. package/dist/app/demo/form/control/overflow/overflow.xml +0 -98
  102. package/dist/app/demo/form/control/view/view.css +0 -1
  103. package/dist/app/demo/form/control/view/view.js +0 -73
  104. package/dist/app/demo/form/control/view/view.scss +0 -18
  105. package/dist/app/demo/form/control/view/view.xml +0 -94
  106. package/dist/app/demo/form/method/form/test.xml +0 -5
package/dist/lib/task.ts CHANGED
@@ -21,6 +21,7 @@ import * as tool from './tool';
21
21
  import * as form from './form';
22
22
  import * as control from './control';
23
23
  import * as fs from './fs';
24
+ import * as theme from './theme';
24
25
  import * as native from './native';
25
26
 
26
27
  /** --- 当前运行的程序,App 模式下无效 --- */
@@ -29,27 +30,20 @@ export const list: Record<number, types.ITask> = {};
29
30
  /** --- 最后一个 task id,App 模式下无效 --- */
30
31
  export let lastId: number = 0;
31
32
 
32
- /** --- 当前是否设置的主任务的任务 ID,全局只可设置一次 --- */
33
- let mainTaskId: number = 0;
33
+ /** --- 当前有焦点的任务 ID --- */
34
+ let focusId: number | null = null;
34
35
 
35
36
  /**
36
- * --- 将一个任务设置为主任务,全局只可设置一次 ---
37
- * @param taskId 任务 ID
37
+ * --- 设置 task focus id ---
38
+ * @param id id 或 null
38
39
  */
39
- export function setMain(taskId: number): boolean {
40
- if (mainTaskId > 0) {
41
- return false;
42
- }
43
- mainTaskId = taskId;
44
- return true;
40
+ export function setFocus(id?: number): void {
41
+ focusId = id ?? null;
45
42
  }
46
43
 
47
- /**
48
- * --- 判断一个任务 ID 是不是主任务 ---
49
- * @param taskId 任务 ID
50
- */
51
- export function isMain(taskId: number): boolean {
52
- return taskId === mainTaskId;
44
+ /** --- 获取当前有焦点的任务 ID --- */
45
+ export function getFocus(): number | null {
46
+ return focusId;
53
47
  }
54
48
 
55
49
  /** --- task lib 用到的语言包 --- */
@@ -77,7 +71,7 @@ const frameMaps: Record<string, number> = {};
77
71
  /**
78
72
  * --- 创建 frame 监听,formId 存在则为窗体范围,否则为任务级范围 ---
79
73
  * @param fun 监听回调
80
- * @param opt 选项,count:执行次数,默认无限次,taskId:APP模式下无效,formId:APP模式下无效
74
+ * @param opt 选项,count:执行次数,默认无限次,formId:限定在当前任务的某个窗体,taskId:APP模式下无效
81
75
  */
82
76
  export function onFrame(fun: () => void | Promise<void>, opt: {
83
77
  'count'?: number;
@@ -190,7 +184,7 @@ export function get(tid: number): types.ITaskInfo | null {
190
184
  return null;
191
185
  }
192
186
  return {
193
- 'name': list[tid].config.name,
187
+ 'name': list[tid].app.config.name,
194
188
  'locale': list[tid].locale.lang,
195
189
  'customTheme': list[tid].customTheme,
196
190
  'formCount': Object.keys(list[tid].forms).length,
@@ -208,7 +202,7 @@ export function getList(): Record<string, types.ITaskInfo> {
208
202
  for (const tid in list) {
209
203
  const item = list[tid];
210
204
  rtn[tid] = {
211
- 'name': item.config.name,
205
+ 'name': item.app.config.name,
212
206
  'locale': item.locale.lang,
213
207
  'customTheme': item.customTheme,
214
208
  'formCount': Object.keys(item.forms).length,
@@ -256,33 +250,46 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
256
250
  'current': ntask ? ntask.current : undefined,
257
251
  'progress': opt.progress
258
252
  });
259
- if (!app) {
260
- // --- fetch 失败,则返回错误,隐藏 notify ---
261
- if (notifyId) {
262
- setTimeout(function(): void {
263
- form.hideNotify(notifyId);
264
- }, 2000);
265
- }
266
- return -1;
267
- }
268
- if (notifyId && !app.net) {
269
- // --- 仅 app 模式隐藏,net 模式还要在 config 当中加载 xml 等非 js 资源文件 ---
253
+ // --- 无论是否成功,都可以先隐藏 notify 了 ---
254
+ if (notifyId) {
270
255
  setTimeout(function(): void {
271
256
  form.hideNotify(notifyId);
272
257
  }, 2000);
273
258
  }
259
+ if (!app) {
260
+ return -1;
261
+ }
274
262
  // --- 申请任务ID ---
275
263
  const taskId = ++lastId;
276
264
  // --- 注入的参数,屏蔽浏览器全局对象,注入新的对象 ---
277
265
  /** --- 不屏蔽的全局对象 --- */
278
- const unblock = opt.unblock ?? [];
266
+ const unblock = opt.unblock ? tool.clone(opt.unblock) : [];
267
+ const unblockSys = [
268
+ 'require',
269
+ '__awaiter', 'eval', 'Math', 'Array', 'Blob', 'Error', 'Infinity', 'parseInt', 'parseFloat', 'Promise', 'Date', 'JSON', 'fetch'
270
+ ];
271
+ for (const name of unblockSys) {
272
+ if (unblock.includes(name)) {
273
+ continue;
274
+ }
275
+ unblock.push(name);
276
+ }
279
277
  /** --- 最终注入的对象 --- */
280
278
  const invoke: Record<string, any> = {};
281
279
  if (!unblock.includes('window')) {
282
- invoke.window = undefined;
280
+ invoke.window = {};
281
+ for (const name of unblock) {
282
+ if (window[name] === undefined) {
283
+ continue;
284
+ }
285
+ invoke.window[name] = window[name];
286
+ }
283
287
  }
284
288
  const ks = Object.getOwnPropertyNames(window);
285
289
  for (const k of ks) {
290
+ if (k.includes('window')) {
291
+ continue;
292
+ }
286
293
  if (k.includes('Event')) {
287
294
  continue;
288
295
  }
@@ -292,11 +299,6 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
292
299
  if (/^[0-9]+$/.test(k)) {
293
300
  continue;
294
301
  }
295
- if ([
296
- 'require',
297
- '__awaiter', 'eval', 'Math', 'Array', 'Blob', 'Infinity', 'parseInt', 'parseFloat', 'Promise', 'Date', 'JSON', 'fetch'].includes(k)) {
298
- continue;
299
- }
300
302
  if (unblock.includes(k)) {
301
303
  continue;
302
304
  }
@@ -347,12 +349,18 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
347
349
  getVersion: function(): string {
348
350
  return clickgo.getVersion();
349
351
  },
350
- getNative(): boolean {
351
- return clickgo.getNative();
352
+ isNative(): boolean {
353
+ return clickgo.isNative();
352
354
  },
353
355
  getPlatform(): string {
354
356
  return clickgo.getPlatform();
355
357
  },
358
+ isImmersion(): boolean {
359
+ return clickgo.isImmersion();
360
+ },
361
+ hasFrame(): boolean {
362
+ return clickgo.hasFrame();
363
+ },
356
364
  'control': {
357
365
  'AbstractControl': class extends control.AbstractControl {
358
366
  public get taskId(): number {
@@ -378,101 +386,109 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
378
386
  getCdn: function() {
379
387
  return core.getCdn();
380
388
  },
381
- initModules: function(names: string | string[]): Promise<number> {
382
- return clickgo.core.initModules(names);
383
- },
384
389
  getModule: function(name: string): null | any {
385
- return clickgo.core.getModule(name);
390
+ return core.getModule(name);
386
391
  },
387
392
  readApp: function(blob: Blob): Promise<false | types.IApp> {
388
- return clickgo.core.readApp(blob);
393
+ return core.readApp(blob);
389
394
  },
390
395
  getAvailArea: function(): types.IAvailArea {
391
- return clickgo.core.getAvailArea();
396
+ return core.getAvailArea();
392
397
  }
393
398
  },
394
399
  'dom': {
395
400
  setGlobalCursor: function(type?: string): void {
396
- clickgo.dom.setGlobalCursor(type);
401
+ dom.setGlobalCursor(type);
397
402
  },
398
403
  hasTouchButMouse: function(e: MouseEvent | TouchEvent | PointerEvent): boolean {
399
- return clickgo.dom.hasTouchButMouse(e);
404
+ return dom.hasTouchButMouse(e);
400
405
  },
401
406
  getStyleCount: function(taskId: number, type: 'theme' | 'control' | 'form'): number {
402
- return clickgo.dom.getStyleCount(taskId, type);
403
- },
404
- getSize: function(el: HTMLElement): types.IDomSize {
405
- return clickgo.dom.getSize(el);
407
+ return dom.getStyleCount(taskId, type);
406
408
  },
407
409
  watchSize: function(
408
410
  el: HTMLElement,
409
- cb: (size: types.IDomSize) => Promise<void> | void,
411
+ cb: () => void | Promise<void>,
410
412
  immediate: boolean = false
411
- ): types.IDomSize {
412
- return clickgo.dom.watchSize(el, cb, immediate, taskId);
413
+ ): boolean {
414
+ return dom.watchSize(el, cb, immediate, taskId);
413
415
  },
414
416
  unwatchSize: function(el: HTMLElement): void {
415
- clickgo.dom.unwatchSize(el, taskId);
417
+ dom.unwatchSize(el, taskId);
416
418
  },
417
- clearWatchSize(): void {
418
- clickgo.dom.clearWatchSize(taskId);
419
+ isWatchSize(el: HTMLElement): boolean {
420
+ return dom.isWatchSize(el);
419
421
  },
420
422
  watch: function(el: HTMLElement, cb: () => void, mode: 'child' | 'childsub' | 'style' | 'default' = 'default', immediate: boolean = false): void {
421
- clickgo.dom.watch(el, cb, mode, immediate, taskId);
423
+ dom.watch(el, cb, mode, immediate, taskId);
422
424
  },
423
425
  unwatch: function(el: HTMLElement): void {
424
- clickgo.dom.unwatch(el, taskId);
426
+ dom.unwatch(el, taskId);
425
427
  },
426
- clearWatch: function(): void {
427
- clickgo.dom.clearWatch(taskId);
428
+ isWatch(el: HTMLElement): boolean {
429
+ return dom.isWatch(el);
428
430
  },
429
431
  watchStyle: function(
430
432
  el: HTMLElement,
431
433
  name: string | string[],
432
- cb: (name: string, value: string) => void,
434
+ cb: (name: string, value: string, old: string) => void,
433
435
  immediate: boolean = false
434
436
  ): void {
435
- clickgo.dom.watchStyle(el, name, cb, immediate);
437
+ dom.watchStyle(el, name, cb, immediate);
436
438
  },
437
439
  isWatchStyle: function(el: HTMLElement): boolean {
438
- return clickgo.dom.isWatchStyle(el);
440
+ return dom.isWatchStyle(el);
441
+ },
442
+ watchProperty(
443
+ el: HTMLElement,
444
+ name: string | string[],
445
+ cb: (name: string, value: string) => void,
446
+ immediate: boolean = false
447
+ ): void {
448
+ dom.watchProperty(el, name, cb, immediate);
449
+ },
450
+ isWatchProperty(el: HTMLElement): boolean {
451
+ return dom.isWatchProperty(el);
452
+ },
453
+ bindClick(e: MouseEvent | TouchEvent, handler: () => void): void {
454
+ dom.bindClick(e, handler);
439
455
  },
440
456
  bindDown: function(oe: MouseEvent | TouchEvent, opt: types.IBindDownOptions) {
441
- clickgo.dom.bindDown(oe, opt);
457
+ dom.bindDown(oe, opt);
442
458
  },
443
- bindGesture: function(e: MouseEvent | TouchEvent | WheelEvent | { 'x'?: number; 'y'?: number; }, opt: types.IBindGestureOptions): void {
444
- clickgo.dom.bindGesture(e, opt);
459
+ bindGesture: function(oe: MouseEvent | TouchEvent | WheelEvent, before: (e: MouseEvent | TouchEvent | WheelEvent, dir: 'top' | 'right' | 'bottom' | 'left') => boolean, handler: (dir: 'top' | 'right' | 'bottom' | 'left') => void): void {
460
+ dom.bindGesture(oe, before, handler);
445
461
  },
446
462
  bindLong: function(
447
463
  e: MouseEvent | TouchEvent,
448
464
  long: (e: MouseEvent | TouchEvent) => void | Promise<void>
449
465
  ): void {
450
- clickgo.dom.bindLong(e, long);
466
+ dom.bindLong(e, long);
451
467
  },
452
468
  bindDrag: function(e: MouseEvent | TouchEvent, opt: { 'el': HTMLElement; 'data'?: any; }): void {
453
- clickgo.dom.bindDrag(e, opt);
469
+ dom.bindDrag(e, opt);
454
470
  },
455
- 'is': clickgo.dom.is,
471
+ 'is': dom.is,
456
472
  bindMove: function(e: MouseEvent | TouchEvent, opt: types.IBindMoveOptions): types.IBindMoveResult {
457
- return clickgo.dom.bindMove(e, opt);
473
+ return dom.bindMove(e, opt);
458
474
  },
459
475
  bindResize: function(e: MouseEvent | TouchEvent, opt: types.IBindResizeOptions): void {
460
- clickgo.dom.bindResize(e, opt);
476
+ dom.bindResize(e, opt);
461
477
  },
462
478
  findParentByData: function(el: HTMLElement, name: string): HTMLElement | null {
463
- return clickgo.dom.findParentByData(el, name);
479
+ return dom.findParentByData(el, name);
464
480
  },
465
481
  findParentByClass: function(el: HTMLElement, name: string): HTMLElement | null {
466
- return clickgo.dom.findParentByClass(el, name);
482
+ return dom.findParentByClass(el, name);
467
483
  },
468
484
  siblings: function(el: HTMLElement): HTMLElement[] {
469
- return clickgo.dom.siblings(el);
485
+ return dom.siblings(el);
470
486
  },
471
487
  siblingsData: function(el: HTMLElement, name: string): HTMLElement[] {
472
- return clickgo.dom.siblingsData(el, name);
488
+ return dom.siblingsData(el, name);
473
489
  },
474
490
  fullscreen: function(): boolean {
475
- return clickgo.dom.fullscreen();
491
+ return dom.fullscreen();
476
492
  }
477
493
  },
478
494
  'form': {
@@ -482,76 +498,79 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
482
498
  }
483
499
  },
484
500
  min: function(fid: number): boolean {
485
- return clickgo.form.min(fid);
501
+ return form.min(fid);
486
502
  },
487
503
  max: function max(fid: number): boolean {
488
- return clickgo.form.max(fid);
504
+ return form.max(fid);
489
505
  },
490
506
  close: function(fid: number): boolean {
491
- return clickgo.form.close(fid);
507
+ return form.close(fid);
492
508
  },
493
509
  bindResize: function(e: MouseEvent | TouchEvent, border: types.TDomBorder): void {
494
- clickgo.form.bindResize(e, border);
510
+ form.bindResize(e, border);
495
511
  },
496
512
  bindDrag: function(e: MouseEvent | TouchEvent): void {
497
- clickgo.form.bindDrag(e);
513
+ form.bindDrag(e);
498
514
  },
499
515
  getTaskId: function(fid: number): number {
500
- return clickgo.form.getTaskId(fid);
516
+ return form.getTaskId(fid);
501
517
  },
502
518
  get: function(fid: number): types.IFormInfo | null {
503
- return clickgo.form.get(fid);
519
+ return form.get(fid);
504
520
  },
505
521
  getList: function(tid: number): Record<string, types.IFormInfo> {
506
- return clickgo.form.getList(tid);
522
+ return form.getList(tid);
523
+ },
524
+ getFocus: function(): number | null {
525
+ return form.getFocus();
507
526
  },
508
527
  changeFocus: function(fid: number = 0): void {
509
- clickgo.form.changeFocus(fid);
528
+ form.changeFocus(fid);
510
529
  },
511
530
  getMaxZIndexID: function(out?: {
512
531
  'taskIds'?: number[];
513
532
  'formIds'?: number[];
514
533
  }): number | null {
515
- return clickgo.form.getMaxZIndexID(out);
534
+ return form.getMaxZIndexID(out);
516
535
  },
517
536
  getRectByBorder: function(border: types.TDomBorder): { 'width': number; 'height': number; 'left': number; 'top': number; } {
518
- return clickgo.form.getRectByBorder(border);
537
+ return form.getRectByBorder(border);
519
538
  },
520
539
  showCircular: function(x: number, y: number): void {
521
- clickgo.form.showCircular(x, y);
540
+ form.showCircular(x, y);
522
541
  },
523
542
  moveRectangle: function(border: types.TDomBorder): void {
524
- clickgo.form.moveRectangle(border);
543
+ form.moveRectangle(border);
525
544
  },
526
545
  showRectangle: function(x: number, y: number, border: types.TDomBorder): void {
527
- clickgo.form.showRectangle(x, y, border);
546
+ form.showRectangle(x, y, border);
528
547
  },
529
548
  hideRectangle: function(): void {
530
- clickgo.form.hideRectangle();
549
+ form.hideRectangle();
531
550
  },
532
551
  showDrag: function(): void {
533
- clickgo.form.showDrag();
552
+ form.showDrag();
534
553
  },
535
554
  moveDrag: function(opt: types.IMoveDragOptions): void {
536
- clickgo.form.moveDrag(opt);
555
+ form.moveDrag(opt);
537
556
  },
538
557
  hideDrag: function(): void {
539
- clickgo.form.hideDrag();
558
+ form.hideDrag();
540
559
  },
541
560
  notify: function(opt: types.INotifyOptions): number {
542
- return clickgo.form.notify(opt);
561
+ return form.notify(opt);
543
562
  },
544
563
  notifyProgress: function(notifyId: number, per: number): void {
545
- clickgo.form.notifyProgress(notifyId, per);
564
+ form.notifyProgress(notifyId, per);
546
565
  },
547
566
  hideNotify: function(notifyId: number): void {
548
- clickgo.form.hideNotify(notifyId);
567
+ form.hideNotify(notifyId);
549
568
  },
550
569
  showPop: function(el: HTMLElement, pop: HTMLElement | undefined, direction: 'h' | 'v' | MouseEvent | TouchEvent | { x: number; y: number; }, opt: { 'size'?: { width?: number; height?: number; }; 'null'?: boolean; } = {}): void {
551
- clickgo.form.showPop(el, pop, direction, opt);
570
+ form.showPop(el, pop, direction, opt);
552
571
  },
553
572
  hidePop: function(pop?: HTMLElement): void {
554
- clickgo.form.hidePop(pop);
573
+ form.hidePop(pop);
555
574
  },
556
575
  dialog: function(opt: string | types.IFormDialogOptions): Promise<string> {
557
576
  if (typeof opt === 'string') {
@@ -560,7 +579,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
560
579
  };
561
580
  }
562
581
  opt.taskId = taskId;
563
- return clickgo.form.dialog(opt);
582
+ return form.dialog(opt);
564
583
  },
565
584
  confirm: function(opt: string | types.IFormConfirmOptions): Promise<boolean | number> {
566
585
  if (typeof opt === 'string') {
@@ -569,16 +588,16 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
569
588
  };
570
589
  }
571
590
  opt.taskId = taskId;
572
- return clickgo.form.confirm(opt);
591
+ return form.confirm(opt);
573
592
  },
574
593
  flash: function(fid: number): void {
575
- clickgo.form.flash(fid, taskId);
594
+ form.flash(fid, taskId);
576
595
  },
577
596
  showLauncher: function(): void {
578
- clickgo.form.showLauncher();
597
+ form.showLauncher();
579
598
  },
580
599
  hideLauncher: function(): void {
581
- clickgo.form.hideLauncher();
600
+ form.hideLauncher();
582
601
  }
583
602
  },
584
603
  'fs': {
@@ -592,31 +611,31 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
592
611
  if (!options.current) {
593
612
  options.current = list[taskId].current;
594
613
  }
595
- return clickgo.fs.getContent(path, options);
614
+ return fs.getContent(path, options);
596
615
  },
597
616
  putContent: function(path: string, data: string | Buffer, options: any = {}) {
598
617
  if (!options.current) {
599
618
  options.current = list[taskId].current;
600
619
  }
601
- return clickgo.fs.putContent(path, data, options);
620
+ return fs.putContent(path, data, options);
602
621
  },
603
622
  readLink: function(path: string, options: any = {}): Promise<string | null> {
604
623
  if (!options.current) {
605
624
  options.current = list[taskId].current;
606
625
  }
607
- return clickgo.fs.readLink(path, options);
626
+ return fs.readLink(path, options);
608
627
  },
609
628
  symlink: function(fPath: string, linkPath: string, options: any = {}): Promise<boolean> {
610
629
  if (!options.current) {
611
630
  options.current = list[taskId].current;
612
631
  }
613
- return clickgo.fs.symlink(fPath, linkPath, options);
632
+ return fs.symlink(fPath, linkPath, options);
614
633
  },
615
634
  unlink: function(path: string, options: any = {}): Promise<boolean> {
616
635
  if (!options.current) {
617
636
  options.current = list[taskId].current;
618
637
  }
619
- return clickgo.fs.unlink(path, options);
638
+ return fs.unlink(path, options);
620
639
  },
621
640
  stats: function(path: string, options: any = {}): Promise<types.IStats | null> {
622
641
  if (!options.files) {
@@ -625,7 +644,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
625
644
  if (!options.current) {
626
645
  options.current = list[taskId].current;
627
646
  }
628
- return clickgo.fs.stats(path, options);
647
+ return fs.stats(path, options);
629
648
  },
630
649
  isDir: function(path: string, options: any = {}): Promise<types.IStats | false> {
631
650
  if (!options.files) {
@@ -634,7 +653,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
634
653
  if (!options.current) {
635
654
  options.current = list[taskId].current;
636
655
  }
637
- return clickgo.fs.isDir(path, options);
656
+ return fs.isDir(path, options);
638
657
  },
639
658
  isFile: function(path: string, options: any = {}): Promise<types.IStats | false> {
640
659
  if (!options.files) {
@@ -643,37 +662,37 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
643
662
  if (!options.current) {
644
663
  options.current = list[taskId].current;
645
664
  }
646
- return clickgo.fs.isFile(path, options);
665
+ return fs.isFile(path, options);
647
666
  },
648
667
  mkdir: function(path: string, mode?: number, options: any = {}): Promise<boolean> {
649
668
  if (!options.current) {
650
669
  options.current = list[taskId].current;
651
670
  }
652
- return clickgo.fs.mkdir(path, mode, options);
671
+ return fs.mkdir(path, mode, options);
653
672
  },
654
673
  rmdir: function(path: string, options: any = {}): Promise<boolean> {
655
674
  if (!options.current) {
656
675
  options.current = list[taskId].current;
657
676
  }
658
- return clickgo.fs.rmdir(path, options);
677
+ return fs.rmdir(path, options);
659
678
  },
660
679
  rmdirDeep: function(path: string, options: any = {}): Promise<boolean> {
661
680
  if (!options.current) {
662
681
  options.current = list[taskId].current;
663
682
  }
664
- return clickgo.fs.rmdirDeep(path, options);
683
+ return fs.rmdirDeep(path, options);
665
684
  },
666
685
  chmod: function(path: string, mod: string | number, options: any = {}): Promise<boolean> {
667
686
  if (!options.current) {
668
687
  options.current = list[taskId].current;
669
688
  }
670
- return clickgo.fs.chmod(path, mod, options);
689
+ return fs.chmod(path, mod, options);
671
690
  },
672
691
  rename(oldPath: string, newPath: string, options: any = {}): Promise<boolean> {
673
692
  if (!options.current) {
674
693
  options.current = list[taskId].current;
675
694
  }
676
- return clickgo.fs.rename(oldPath, newPath, options);
695
+ return fs.rename(oldPath, newPath, options);
677
696
  },
678
697
  readDir(path: string, options: any = {}): Promise<types.IDirent[]> {
679
698
  if (!options.files) {
@@ -682,83 +701,123 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
682
701
  if (!options.current) {
683
702
  options.current = list[taskId].current;
684
703
  }
685
- return clickgo.fs.readDir(path, options);
704
+ return fs.readDir(path, options);
686
705
  },
687
706
  copyFolder(from: string, to: string, options: any = {}): Promise<number> {
688
707
  if (!options.current) {
689
708
  options.current = list[taskId].current;
690
709
  }
691
- return clickgo.fs.copyFolder(from, to, options);
710
+ return fs.copyFolder(from, to, options);
692
711
  },
693
712
  copyFile(src: string, dest: string, options: any = {}): Promise<boolean> {
694
713
  if (!options.current) {
695
714
  options.current = list[taskId].current;
696
715
  }
697
- return clickgo.fs.copyFile(src, dest, options);
716
+ return fs.copyFile(src, dest, options);
698
717
  }
699
718
  },
700
719
  'native': {
701
- invoke: function(name: string, ...param: any[]): any {
702
- return clickgo.native.invoke(name, ...param);
720
+ on(
721
+ name: string,
722
+ handler: (...param: any[]) => any | Promise<any>,
723
+ once: boolean = false,
724
+ formId?: number
725
+ ): void {
726
+ native.on(name, handler, once, formId, taskId);
703
727
  },
704
- max: function(): void {
705
- clickgo.native.max();
728
+ once(
729
+ name: string,
730
+ handler: (...param: any[]) => any | Promise<any>,
731
+ formId?: number
732
+ ): void {
733
+ native.once(name, handler, formId, taskId);
734
+ },
735
+ off(name: string, formId?: number): void {
736
+ native.off(name, formId, taskId);
737
+ },
738
+ clear(formId?: number, taskId?: number): void {
739
+ native.clear(formId, taskId);
740
+ },
741
+ getListenerList(taskId?: number): Record<string, Record<string, Record<string, number>>> {
742
+ return native.getListenerList(taskId);
743
+ },
744
+ invoke: function(name: string, ...param: any[]): Promise<any> {
745
+ return native.invoke(name, ...param);
706
746
  },
707
- min: function(): void {
708
- clickgo.native.min();
747
+ max: async function(): Promise<void> {
748
+ await native.max();
709
749
  },
710
- restore: function(): void {
711
- clickgo.native.restore();
750
+ min: async function(): Promise<void> {
751
+ await native.min();
712
752
  },
713
- size: function(width: number, height: number): void {
714
- clickgo.native.size(width, height);
753
+ restore: async function(): Promise<void> {
754
+ await native.restore();
755
+ },
756
+ size: async function(width: number, height: number): Promise<void> {
757
+ await native.size(width, height);
758
+ },
759
+ ping: function(val: string): Promise<string> {
760
+ return native.ping(val);
761
+ },
762
+ isMax: function(): Promise<boolean> {
763
+ return native.isMax();
715
764
  }
716
765
  },
717
766
  'task': {
718
- isMain(taskId: number): boolean {
719
- return isMain(taskId);
767
+ getFocus(): number | null {
768
+ return focusId;
720
769
  },
721
770
  onFrame: function(fun: () => void | Promise<void>, opt: any = {}): number {
722
771
  opt.taskId = taskId;
723
- return clickgo.task.onFrame(fun, opt);
772
+ return onFrame(fun, opt);
724
773
  },
725
774
  offFrame: function(ft: number, opt: {
726
775
  'taskId'?: number;
727
776
  } = {}): void {
728
777
  opt.taskId = taskId;
729
- clickgo.task.offFrame(ft, opt);
778
+ offFrame(ft, opt);
730
779
  },
731
780
  get: function(tid: number): types.ITaskInfo | null {
732
- return clickgo.task.get(tid);
781
+ return get(tid);
733
782
  },
734
783
  getList: function(): Record<string, types.ITaskInfo> {
735
- return clickgo.task.getList();
784
+ return getList();
736
785
  },
737
786
  run: function(url: string, opt: types.ITaskRunOptions = {}): Promise<number> {
738
787
  opt.taskId = taskId;
739
- opt.main = false;
740
- return clickgo.task.run(url, opt);
788
+ if (opt.unblock) {
789
+ const inUnblock: string[] = [];
790
+ // --- 只能解除屏蔽当前函数里面被解除的变量 ---
791
+ for (const item of opt.unblock) {
792
+ if (!unblock.includes(item)) {
793
+ continue;
794
+ }
795
+ inUnblock.push(item);
796
+ }
797
+ opt.unblock = inUnblock;
798
+ }
799
+ return run(url, opt);
741
800
  },
742
801
  end: function(tid: number): boolean {
743
- return clickgo.task.end(tid ?? taskId);
802
+ return end(tid ?? taskId);
744
803
  },
745
804
  loadLocaleData: function(lang: string, data: Record<string, any>, pre: string = ''): void {
746
- clickgo.task.loadLocaleData(lang, data, pre, taskId);
805
+ loadLocaleData(lang, data, pre, taskId);
747
806
  },
748
807
  loadLocale: function(lang: string, path: string): Promise<boolean> {
749
- return clickgo.task.loadLocale(lang, path, taskId);
808
+ return loadLocale(lang, path, taskId);
750
809
  },
751
810
  clearLocale: function(): void {
752
- clickgo.task.clearLocale(taskId);
811
+ clearLocale(taskId);
753
812
  },
754
813
  setLocale: function(lang: string, path: string): Promise<boolean> {
755
- return clickgo.task.setLocale(lang, path, taskId);
814
+ return setLocale(lang, path, taskId);
756
815
  },
757
816
  setLocaleLang: function(lang: string): void {
758
- clickgo.task.setLocaleLang(lang, taskId);
817
+ setLocaleLang(lang, taskId);
759
818
  },
760
819
  clearLocaleLang: function(): void {
761
- clickgo.task.clearLocaleLang(taskId);
820
+ clearLocaleLang(taskId);
762
821
  },
763
822
  createTimer: function(
764
823
  fun: () => void | Promise<void>,
@@ -766,20 +825,20 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
766
825
  opt: types.ICreateTimerOptions = {}
767
826
  ): number {
768
827
  opt.taskId = taskId;
769
- return clickgo.task.createTimer(fun, delay, opt);
828
+ return createTimer(fun, delay, opt);
770
829
  },
771
830
  removeTimer: function(timer: number): void {
772
- clickgo.task.removeTimer(timer, taskId);
831
+ removeTimer(timer, taskId);
773
832
  },
774
833
  sleep: function(fun: () => void | Promise<void>, delay: number): number {
775
- return clickgo.task.sleep(fun, delay, taskId);
834
+ return sleep(fun, delay, taskId);
776
835
  },
777
- systemTaskInfo: clickgo.task.systemTaskInfo,
836
+ 'systemTaskInfo': clickgo.task.systemTaskInfo,
778
837
  setSystem: function(fid: number): boolean {
779
- return clickgo.task.setSystem(fid, taskId);
838
+ return setSystem(fid, taskId);
780
839
  },
781
840
  clearSystem: function(): boolean {
782
- return clickgo.task.clearSystem(taskId);
841
+ return clearSystem(taskId);
783
842
  }
784
843
  },
785
844
  'theme': {
@@ -807,58 +866,67 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
807
866
  },
808
867
  'tool': {
809
868
  blob2ArrayBuffer: function(blob: Blob): Promise<ArrayBuffer> {
810
- return clickgo.tool.blob2ArrayBuffer(blob);
869
+ return tool.blob2ArrayBuffer(blob);
811
870
  },
812
871
  clone: function(obj: Record<string, any> | any[]): any[] | any {
813
- return clickgo.tool.clone(obj);
872
+ return tool.clone(obj);
814
873
  },
815
874
  sleep: function(ms: number = 0): Promise<boolean> {
816
- return clickgo.tool.sleep(ms);
875
+ return tool.sleep(ms);
876
+ },
877
+ nextFrame(): Promise<void> {
878
+ return tool.nextFrame();
879
+ },
880
+ sleepFrame(count: number): Promise<void> {
881
+ return tool.sleepFrame(count);
817
882
  },
818
883
  purify: function(text: string): string {
819
- return clickgo.tool.purify(text);
884
+ return tool.purify(text);
820
885
  },
821
886
  rand: function(min: number, max: number): number {
822
- return clickgo.tool.rand(min, max);
823
- },
824
- 'RANDOM_N': clickgo.tool.RANDOM_N,
825
- 'RANDOM_U': clickgo.tool.RANDOM_U,
826
- 'RANDOM_L': clickgo.tool.RANDOM_L,
827
- 'RANDOM_UN': clickgo.tool.RANDOM_UN,
828
- 'RANDOM_LN': clickgo.tool.RANDOM_LN,
829
- 'RANDOM_LU': clickgo.tool.RANDOM_LU,
830
- 'RANDOM_LUN': clickgo.tool.RANDOM_LUN,
831
- 'RANDOM_V': clickgo.tool.RANDOM_V,
832
- 'RANDOM_LUNS': clickgo.tool.RANDOM_LUNS,
833
- random: function(length: number = 8, source: string = clickgo.tool.RANDOM_LN, block: string = ''): string {
834
- return clickgo.tool.random(length, source, block);
887
+ return tool.rand(min, max);
888
+ },
889
+ 'RANDOM_N': tool.RANDOM_N,
890
+ 'RANDOM_U': tool.RANDOM_U,
891
+ 'RANDOM_L': tool.RANDOM_L,
892
+ 'RANDOM_UN': tool.RANDOM_UN,
893
+ 'RANDOM_LN': tool.RANDOM_LN,
894
+ 'RANDOM_LU': tool.RANDOM_LU,
895
+ 'RANDOM_LUN': tool.RANDOM_LUN,
896
+ 'RANDOM_V': tool.RANDOM_V,
897
+ 'RANDOM_LUNS': tool.RANDOM_LUNS,
898
+ random: function(length: number = 8, source: string = tool.RANDOM_LN, block: string = ''): string {
899
+ return tool.random(length, source, block);
835
900
  },
836
901
  getBoolean: function(param: boolean | string | number): boolean {
837
- return clickgo.tool.getBoolean(param);
902
+ return tool.getBoolean(param);
838
903
  },
839
904
  getNumber: function(param: string | number): number {
840
- return clickgo.tool.getNumber(param);
905
+ return tool.getNumber(param);
906
+ },
907
+ getArray(param: string | any[]): any[] {
908
+ return tool.getArray(param);
841
909
  },
842
910
  escapeHTML: function(html: string): string {
843
- return clickgo.tool.escapeHTML(html);
911
+ return tool.escapeHTML(html);
844
912
  },
845
913
  request: function(url: string, opt: types.IRequestOptions): Promise<null | any> {
846
- return clickgo.tool.request(url, opt);
914
+ return tool.request(url, opt);
847
915
  },
848
916
  parseUrl: function(url: string): ILoaderUrl {
849
- return clickgo.tool.parseUrl(url);
917
+ return tool.parseUrl(url);
850
918
  },
851
919
  urlResolve: function(from: string, to: string): string {
852
- return clickgo.tool.urlResolve(from, to);
920
+ return tool.urlResolve(from, to);
853
921
  },
854
922
  blob2Text: function(blob: Blob): Promise<string> {
855
- return clickgo.tool.blob2Text(blob);
923
+ return tool.blob2Text(blob);
856
924
  },
857
925
  blob2DataUrl: function(blob: Blob): Promise<string> {
858
- return clickgo.tool.blob2DataUrl(blob);
926
+ return tool.blob2DataUrl(blob);
859
927
  },
860
928
  execCommand: function(ac: string): void {
861
- clickgo.tool.execCommand(ac);
929
+ tool.execCommand(ac);
862
930
  }
863
931
  },
864
932
  'zip': {
@@ -890,12 +958,11 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
890
958
  const path = url;
891
959
  const lio = path.endsWith('.cga') ? path.lastIndexOf('/') : path.slice(0, -1).lastIndexOf('/');
892
960
  const current = path.slice(0, lio);
893
- // --- 创建任务对象 task.IRT ---
961
+ // --- 创建任务对象 ---
894
962
  list[taskId] = {
895
963
  'id': taskId,
896
964
  'app': app,
897
965
  // 'class': null,
898
- // 'config': {},
899
966
  'customTheme': false,
900
967
  'locale': clickgo.vue.reactive({
901
968
  'lang': '',
@@ -913,6 +980,30 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
913
980
  'timers': {},
914
981
  'invoke': invoke
915
982
  } as any;
983
+ // --- locale ---
984
+ if (app.config.locales) {
985
+ for (let path in app.config.locales) {
986
+ const locale = app.config.locales[path];
987
+ if (!path.endsWith('.json')) {
988
+ path += '.json';
989
+ }
990
+ const lcontent = await fs.getContent(path, {
991
+ 'encoding': 'utf8',
992
+ 'files': app.files,
993
+ 'current': current
994
+ });
995
+ if (!lcontent) {
996
+ continue;
997
+ }
998
+ try {
999
+ const data = JSON.parse(lcontent);
1000
+ loadLocaleData(locale, data, '', taskId);
1001
+ }
1002
+ catch {
1003
+ // --- 无所谓 ---
1004
+ }
1005
+ }
1006
+ }
916
1007
  let expo: any = [];
917
1008
  try {
918
1009
  expo = loader.require('/app.js', app.files, {
@@ -935,33 +1026,58 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}): Promise
935
1026
  }
936
1027
  // --- 创建 Task 总 style ---
937
1028
  dom.createToStyleList(taskId);
938
- // --- 执行 app ---
939
- const appCls: core.AbstractApp = new expo.default();
940
- await appCls.main();
941
- if (!list[taskId].class) {
942
- // --- 创建任务失败,也可能没设置 config,报弹窗错误,清理启动应用并返回错误 ---
943
- // --- 结束任务 ---
944
- delete list[taskId];
1029
+ // --- 加载 control ---
1030
+ const r = await control.init(taskId, invoke);
1031
+ if (r < 0) {
945
1032
  dom.removeFromStyleList(taskId);
946
- return -4;
1033
+ delete list[taskId];
1034
+ return -400 + r;
1035
+ }
1036
+ // --- 加载 theme ---
1037
+ if (app.config.themes?.length) {
1038
+ for (let path of app.config.themes) {
1039
+ path += '.cgt';
1040
+ path = tool.urlResolve('/', path);
1041
+ const file = await fs.getContent(path, {
1042
+ 'files': app.files,
1043
+ 'current': current
1044
+ });
1045
+ if (file && typeof file !== 'string') {
1046
+ const th = await theme.read(file);
1047
+ if (th) {
1048
+ await theme.load(th, taskId);
1049
+ }
1050
+ }
1051
+ }
1052
+ }
1053
+ else {
1054
+ // --- 加载全局主题 ---
1055
+ if (theme.global) {
1056
+ await theme.load(undefined, taskId);
1057
+ }
1058
+ }
1059
+ // --- 加载任务级全局样式 ---
1060
+ if (app.config.style) {
1061
+ const style = await fs.getContent(app.config.style + '.css', {
1062
+ 'encoding': 'utf8',
1063
+ 'files': app.files,
1064
+ 'current': current
1065
+ });
1066
+ if (style) {
1067
+ const r = tool.stylePrepend(style, 'cg-task' + taskId.toString() + '_');
1068
+ dom.pushStyle(taskId, await tool.styleUrl2DataUrl(app.config.style, r.style, app.files));
1069
+ }
947
1070
  }
948
1071
  // --- 触发 taskStarted 事件 ---
949
1072
  core.trigger('taskStarted', taskId);
950
- // --- native 发送任务启动成功的消息 ---
1073
+ // --- 第一个任务给 native 发送任务启动成功的消息 ---
951
1074
  if (taskId === 1) {
952
- native.invoke('cg-init', native.getToken());
953
- }
954
- // --- 提交 sync ---
955
- /*
956
- if (clickgo.getNative() && opt.sync) {
957
- f.vroot.$refs.form.isNativeSync = true;
958
- native.invoke('cg-set-size', native.getToken(), f.vroot.$refs.form.widthData, f.vroot.$refs.form.heightData);
959
- window.addEventListener('resize', function(): void {
960
- f.vroot.$refs.form.setPropData('width', window.innerWidth);
961
- f.vroot.$refs.form.setPropData('height', window.innerHeight);
962
- });
1075
+ await native.invoke('cg-init', native.getToken());
963
1076
  }
964
- */
1077
+ // --- 执行 app ---
1078
+ const appCls: core.AbstractApp = new expo.default();
1079
+ list[taskId].class = appCls;
1080
+ await appCls.main();
965
1081
  return taskId;
966
1082
  }
967
1083
 
@@ -975,8 +1091,8 @@ export function end(taskId: number): boolean {
975
1091
  return true;
976
1092
  }
977
1093
  // --- 如果是 native 模式 ---
978
- if (clickgo.getNative() && isMain(taskId)) {
979
- native.invoke('cg-close', native.getToken());
1094
+ if (clickgo.isNative() && (taskId === 1)) {
1095
+ native.invoke('cg-close', native.getToken()) as any;
980
1096
  }
981
1097
  // --- 获取最大的 z index 窗体,并让他获取焦点 ---
982
1098
  const fid = form.getMaxZIndexID({
@@ -990,23 +1106,28 @@ export function end(taskId: number): boolean {
990
1106
  }
991
1107
  // --- 移除窗体 list ---
992
1108
  for (const fid in task.forms) {
1109
+ // --- 结束任务挨个关闭窗体 ---
993
1110
  const f = task.forms[fid];
994
- core.trigger('formRemoved', taskId, f.id, f.vroot.$refs.form.title, f.vroot.$refs.form.iconData);
1111
+ core.trigger('formRemoved', taskId, f.id, f.vroot.$refs.form.title, f.vroot.$refs.form.iconDataUrl);
995
1112
  try {
996
1113
  f.vapp.unmount();
997
1114
  }
998
1115
  catch (err: any) {
999
1116
  const msg = `Message: ${err.message}\nTask id: ${task.id}\nForm id: ${fid}\nFunction: task.end, unmount.`;
1000
1117
  form.notify({
1001
- 'title': 'Runtime Error',
1118
+ 'title': 'Form Unmount Error',
1002
1119
  'content': msg,
1003
1120
  'type': 'danger'
1004
1121
  });
1005
- console.log('Runtime Error', msg, err);
1122
+ console.log('Form Unmount Error', msg, err);
1006
1123
  }
1007
1124
  f.vapp._container.remove();
1125
+ form.elements.popList.querySelector('[data-form-id="' + f.id.toString() + '"]')?.remove();
1126
+ dom.clearWatchStyle(fid);
1127
+ dom.clearWatchProperty(fid);
1008
1128
  }
1009
- const flist = document.querySelectorAll('#cg-form-list > [data-task-id="' + taskId.toString() + '"]');
1129
+ // --- 移除可能残留的 form wrap ---
1130
+ const flist = form.elements.list.querySelectorAll('.cg-form-wrap[data-task-id="' + taskId.toString() + '"]');
1010
1131
  for (const f of flist) {
1011
1132
  f.remove();
1012
1133
  }
@@ -1025,6 +1146,8 @@ export function end(taskId: number): boolean {
1025
1146
  }
1026
1147
  // --- 移除各类监听 ---
1027
1148
  dom.clearWatchSize(taskId);
1149
+ dom.clearWatch(taskId);
1150
+ native.clear(undefined, taskId);
1028
1151
  // --- 移除 task ---
1029
1152
  delete list[taskId];
1030
1153
  // --- 触发 taskEnded 事件 ---