clickgo 6.2.0 → 6.4.0
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/dist/app/demo.cga +0 -0
- package/dist/app/task.cga +0 -0
- package/dist/control/common.cgc +0 -0
- package/dist/index.js +1 -1
- package/doc/clickgo-rag.md +35 -1
- package/package.json +1 -1
- package/test/web-drag-mask.mjs +96 -0
package/doc/clickgo-rag.md
CHANGED
|
@@ -7076,7 +7076,7 @@ SVG 内容或 URL 地址。
|
|
|
7076
7076
|
|
|
7077
7077
|
`(event: ISwitchChangeEvent) => void`
|
|
7078
7078
|
|
|
7079
|
-
|
|
7079
|
+
值切换前触发,可调用 `event.preventDefault()` 阻止本次切换。`event.detail.value` 是切换前的当前值;未阻止时,随后更新状态并触发 `update:modelValue`。需要根据新状态执行重绘等操作时,应监听双向绑定的值,不要在此事件中读取尚未更新的值。
|
|
7080
7080
|
|
|
7081
7081
|
### 样式
|
|
7082
7082
|
|
|
@@ -7092,6 +7092,7 @@ SVG 内容或 URL 地址。
|
|
|
7092
7092
|
<switch v-model="val"></switch>
|
|
7093
7093
|
```
|
|
7094
7094
|
|
|
7095
|
+
|
|
7095
7096
|
## tab
|
|
7096
7097
|
---
|
|
7097
7098
|
|
|
@@ -8033,6 +8034,8 @@ number 类型下增减按钮、键盘上下键及拖拽调值的步长,必须
|
|
|
8033
8034
|
|
|
8034
8035
|
工具栏主要命令。
|
|
8035
8036
|
|
|
8037
|
+
使用 `<toolbar-split></toolbar-split>` 分隔不同功能组,无需业务侧自定义分隔线样式。
|
|
8038
|
+
|
|
8036
8039
|
#### right
|
|
8037
8040
|
|
|
8038
8041
|
始终固定在工具栏右侧的命令。可在这里放置带 `pop` 插槽的按钮,将低优先级命令保留为 ClickGo 菜单。
|
|
@@ -8043,6 +8046,8 @@ number 类型下增减按钮、键盘上下键及拖拽调值的步长,必须
|
|
|
8043
8046
|
<toolbar>
|
|
8044
8047
|
<button type="tool">Open</button>
|
|
8045
8048
|
<button type="tool">Save</button>
|
|
8049
|
+
<toolbar-split></toolbar-split>
|
|
8050
|
+
<button type="tool">Undo</button>
|
|
8046
8051
|
<template v-slot:right>
|
|
8047
8052
|
<button type="tool" area="mark">
|
|
8048
8053
|
More
|
|
@@ -8057,6 +8062,32 @@ number 类型下增减按钮、键盘上下键及拖拽调值的步长,必须
|
|
|
8057
8062
|
```
|
|
8058
8063
|
|
|
8059
8064
|
|
|
8065
|
+
## toolbar-split
|
|
8066
|
+
---
|
|
8067
|
+
|
|
8068
|
+
工具栏分隔线组件,用于分隔不同功能组的命令。
|
|
8069
|
+
|
|
8070
|
+
### 样式
|
|
8071
|
+
|
|
8072
|
+
作为 Toolbar 默认插槽或右侧插槽的子组件,显示居中的竖向分隔线。
|
|
8073
|
+
|
|
8074
|
+
线宽为 1px,高度使用主题的 `--g-size-m`,颜色使用 `--g-border-color`,自动适应亮暗主题。命令间距由 Toolbar 管理,组件不额外添加边距,也不参与点击和键盘焦点。
|
|
8075
|
+
|
|
8076
|
+
组件无参数、事件或插槽,提供 `separator` 角色和 `vertical` 方向供辅助技术识别。
|
|
8077
|
+
|
|
8078
|
+
### 示例
|
|
8079
|
+
|
|
8080
|
+
```xml
|
|
8081
|
+
<toolbar>
|
|
8082
|
+
<button type="tool">Open</button>
|
|
8083
|
+
<button type="tool">Save</button>
|
|
8084
|
+
<toolbar-split></toolbar-split>
|
|
8085
|
+
<button type="tool">Undo</button>
|
|
8086
|
+
<button type="tool">Redo</button>
|
|
8087
|
+
</toolbar>
|
|
8088
|
+
```
|
|
8089
|
+
|
|
8090
|
+
|
|
8060
8091
|
## tuieditor
|
|
8061
8092
|
---
|
|
8062
8093
|
|
|
@@ -8680,12 +8711,15 @@ TUMS 监控组件。
|
|
|
8680
8711
|
|
|
8681
8712
|
使用 iframe 元素,填满容器空间。无边框显示。
|
|
8682
8713
|
|
|
8714
|
+
拖动或调整窗体大小时,会临时遮住网页以保持拖拽操作连续;结束后恢复网页交互。
|
|
8715
|
+
|
|
8683
8716
|
### 示例
|
|
8684
8717
|
|
|
8685
8718
|
```xml
|
|
8686
8719
|
<web :src="pageUrl"></web>
|
|
8687
8720
|
```
|
|
8688
8721
|
|
|
8722
|
+
|
|
8689
8723
|
## xterm
|
|
8690
8724
|
---
|
|
8691
8725
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Run: node --experimental-vm-modules test/web-drag-mask.mjs
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { SourceTextModule, SyntheticModule } from 'node:vm';
|
|
5
|
+
import { JSDOM } from 'jsdom';
|
|
6
|
+
import ts from 'typescript';
|
|
7
|
+
|
|
8
|
+
const dom = new JSDOM('<!doctype html><html><head></head><body></body></html>');
|
|
9
|
+
for (const name of ['window', 'document', 'Element', 'SVGElement', 'Node', 'HTMLElement']) {
|
|
10
|
+
globalThis[name] = dom.window[name];
|
|
11
|
+
}
|
|
12
|
+
globalThis.getComputedStyle = dom.window.getComputedStyle.bind(dom.window);
|
|
13
|
+
const { createApp, compile, reactive, nextTick } = await import('vue');
|
|
14
|
+
const pointer = await import('@litert/pointer');
|
|
15
|
+
const state = reactive({ move: false });
|
|
16
|
+
const clickgo = new SyntheticModule(['control', 'dom'], function() {
|
|
17
|
+
this.setExport('control', { AbstractControl: class {} });
|
|
18
|
+
this.setExport('dom', { is: state });
|
|
19
|
+
});
|
|
20
|
+
const source = await readFile(new URL('../dist/sources/control/web/code.ts', import.meta.url), 'utf8');
|
|
21
|
+
const web = new SourceTextModule(ts.transpileModule(source, {
|
|
22
|
+
compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext },
|
|
23
|
+
}).outputText);
|
|
24
|
+
await web.link(() => clickgo);
|
|
25
|
+
await web.evaluate();
|
|
26
|
+
const control = new web.namespace.default();
|
|
27
|
+
|
|
28
|
+
// Exercise the actual launcher hooks with the installed Pointer library.
|
|
29
|
+
const launcher = await readFile(new URL('../dist/clickgo.ts', import.meta.url), 'utf8');
|
|
30
|
+
const hookSource = launcher.match(/ modules\.pointer\.addMoveHook\('down',[\s\S]*? modules\.pointer\.addMoveHook\('up',[\s\S]*? \}\);/)[0];
|
|
31
|
+
const hooks = new SourceTextModule(`import { pointer, is } from 'bridge';
|
|
32
|
+
const modules = { pointer }; const lDom = { is }; ${hookSource}`);
|
|
33
|
+
const bridge = new SyntheticModule(['pointer', 'is'], function() {
|
|
34
|
+
this.setExport('pointer', pointer);
|
|
35
|
+
this.setExport('is', state);
|
|
36
|
+
});
|
|
37
|
+
await hooks.link(() => bridge);
|
|
38
|
+
await hooks.evaluate();
|
|
39
|
+
|
|
40
|
+
const template = await readFile(new URL('../dist/sources/control/web/layout.html', import.meta.url), 'utf8');
|
|
41
|
+
const host = document.createElement('div');
|
|
42
|
+
document.body.append(host);
|
|
43
|
+
const app = createApp({
|
|
44
|
+
render: compile(template),
|
|
45
|
+
data: () => ({ src: 'about:blank' }),
|
|
46
|
+
computed: { showMask: () => control.showMask },
|
|
47
|
+
});
|
|
48
|
+
app.mount(host);
|
|
49
|
+
const iframe = host.querySelector('iframe');
|
|
50
|
+
const mask = host.querySelector('.mask');
|
|
51
|
+
assert.equal(iframe.getAttribute('src'), 'about:blank');
|
|
52
|
+
assert.equal(mask.style.display, 'none');
|
|
53
|
+
|
|
54
|
+
function event(type, x, y) {
|
|
55
|
+
const e = new dom.window.Event(type, { bubbles: true, cancelable: true });
|
|
56
|
+
Object.assign(e, { clientX: x, clientY: y, pointerId: 1, pointerType: 'mouse', button: 0 });
|
|
57
|
+
return e;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const operation of ['move', 'resize']) {
|
|
61
|
+
for (const finish of ['pointerup', 'pointercancel']) {
|
|
62
|
+
let updates = 0;
|
|
63
|
+
const handle = document.createElement('div');
|
|
64
|
+
document.body.append(handle);
|
|
65
|
+
handle.addEventListener('pointerdown', e => {
|
|
66
|
+
if (operation === 'resize') {
|
|
67
|
+
pointer.resize(e, {
|
|
68
|
+
border: 'rb', objectLeft: 0, objectTop: 0,
|
|
69
|
+
objectWidth: 400, objectHeight: 300,
|
|
70
|
+
move: () => { ++updates; },
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
pointer.move(e, { move: () => { ++updates; } });
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
handle.dispatchEvent(event('pointerdown', 400, 300));
|
|
78
|
+
await nextTick();
|
|
79
|
+
assert.equal(state.move, true);
|
|
80
|
+
assert.notEqual(mask.style.display, 'none');
|
|
81
|
+
mask.dispatchEvent(event('pointermove', 350, 250));
|
|
82
|
+
mask.dispatchEvent(event('pointermove', 320, 230));
|
|
83
|
+
assert.equal(updates, 2);
|
|
84
|
+
mask.dispatchEvent(event(finish, 320, 230));
|
|
85
|
+
await nextTick();
|
|
86
|
+
assert.equal(state.move, false);
|
|
87
|
+
assert.equal(mask.style.display, 'none');
|
|
88
|
+
mask.dispatchEvent(event('pointermove', 300, 200));
|
|
89
|
+
assert.equal(updates, 2);
|
|
90
|
+
assert.equal(host.querySelector('iframe'), iframe);
|
|
91
|
+
handle.remove();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
app.unmount();
|
|
95
|
+
dom.window.close();
|
|
96
|
+
console.log('WEB drag/resize mask, pointerup/cancel cleanup and iframe preservation checks passed.');
|