@tmagic/editor 1.8.0-beta.26 → 1.8.0-beta.27
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/es/hooks/use-form-context.js +18 -8
- package/dist/es/initService.js +1 -0
- package/dist/es/services/events.js +2 -2
- package/dist/es/utils/code-block.js +14 -7
- package/dist/tmagic-editor-headless.umd.cjs +2 -2
- package/dist/tmagic-editor.umd.cjs +29 -16
- package/package.json +7 -7
- package/src/hooks/use-form-context.ts +22 -6
- package/src/initService.ts +1 -0
- package/src/services/events.ts +5 -4
- package/src/type.ts +6 -0
- package/src/utils/code-block.ts +1 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FORM_CONTEXT_KEY, mergeFormContexts } from "@tmagic/form";
|
|
2
|
+
import { computed, inject, unref } from "vue";
|
|
2
3
|
//#region packages/editor/src/hooks/use-form-context.ts
|
|
3
4
|
/**
|
|
4
5
|
* 编辑器注入给表单的业务上下文:`services` 与当前画布 `stage`。
|
|
@@ -6,14 +7,23 @@ import { computed } from "vue";
|
|
|
6
7
|
* 由 `Editor.vue`(provide `FORM_CONTEXT_KEY`)、`FormPanel.vue` 与 `useCompareForm`
|
|
7
8
|
* 共用。`stage` 走 computed 而非快照,保证切换画布后配置回调读到的是最新实例。
|
|
8
9
|
*
|
|
10
|
+
* 宿主可能在 `<MEditor>` 外层 provide 了自己的业务字段,这里必须把那一层合并进来:
|
|
11
|
+
* 否则编辑器再 provide 一次会把宿主整层遮蔽掉,属性面板、对比表单里的配置回调就
|
|
12
|
+
* 读不到宿主字段了。`services` / `stage` 由编辑器兜底,优先级高于宿主同名字段。
|
|
13
|
+
*
|
|
9
14
|
* 字段类型见 `@editor/type` 里对 `@tmagic/form-schema` 的 `FormContext` 模块增强。
|
|
10
15
|
*/
|
|
11
|
-
var useEditorFormContext = (getServices) =>
|
|
12
|
-
const
|
|
13
|
-
return {
|
|
14
|
-
services
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
var useEditorFormContext = (getServices) => {
|
|
17
|
+
const hostContext = inject(FORM_CONTEXT_KEY, void 0);
|
|
18
|
+
return computed(() => {
|
|
19
|
+
const services = getServices();
|
|
20
|
+
const host = unref(hostContext);
|
|
21
|
+
if (host && host.services === services) return host;
|
|
22
|
+
return mergeFormContexts(host, {
|
|
23
|
+
services,
|
|
24
|
+
stage: services?.editorService.get("stage")
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
};
|
|
18
28
|
//#endregion
|
|
19
29
|
export { useEditorFormContext };
|
package/dist/es/initService.js
CHANGED
|
@@ -73,6 +73,7 @@ var initServiceState = (props, { editorService, historyService, componentListSer
|
|
|
73
73
|
uiService.resetState();
|
|
74
74
|
componentListService.resetState();
|
|
75
75
|
codeBlockService.resetState();
|
|
76
|
+
eventsService.resetState();
|
|
76
77
|
keybindingService.reset();
|
|
77
78
|
depService.reset();
|
|
78
79
|
});
|
|
@@ -47,8 +47,8 @@ var Events = class extends BaseService {
|
|
|
47
47
|
return cloneDeep(methodMap[toLine(type)]) || [];
|
|
48
48
|
}
|
|
49
49
|
resetState() {
|
|
50
|
-
eventMap
|
|
51
|
-
methodMap
|
|
50
|
+
Object.keys(eventMap).forEach((type) => delete eventMap[type]);
|
|
51
|
+
Object.keys(methodMap).forEach((type) => delete methodMap[type]);
|
|
52
52
|
}
|
|
53
53
|
destroy() {
|
|
54
54
|
this.resetState();
|
|
@@ -55,13 +55,20 @@ var getCodeBlockFormConfig = (options = {}) => {
|
|
|
55
55
|
name: "timing",
|
|
56
56
|
type: "select",
|
|
57
57
|
options: () => {
|
|
58
|
-
const list = [
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
const list = [
|
|
59
|
+
{
|
|
60
|
+
text: "初始化前",
|
|
61
|
+
value: "beforeInit"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
text: "初始化后",
|
|
65
|
+
value: "afterInit"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
text: "页面渲染后",
|
|
69
|
+
value: "mounted"
|
|
70
|
+
}
|
|
71
|
+
];
|
|
65
72
|
if (dataSourceType?.() !== "base") {
|
|
66
73
|
list.push({
|
|
67
74
|
text: "请求前",
|
|
@@ -9120,8 +9120,8 @@
|
|
|
9120
9120
|
return cloneDeep(methodMap[(0, _tmagic_utils.toLine)(type)]) || [];
|
|
9121
9121
|
}
|
|
9122
9122
|
resetState() {
|
|
9123
|
-
eventMap
|
|
9124
|
-
methodMap
|
|
9123
|
+
Object.keys(eventMap).forEach((type) => delete eventMap[type]);
|
|
9124
|
+
Object.keys(methodMap).forEach((type) => delete methodMap[type]);
|
|
9125
9125
|
}
|
|
9126
9126
|
destroy() {
|
|
9127
9127
|
this.resetState();
|
|
@@ -5057,13 +5057,18 @@
|
|
|
5057
5057
|
//#region packages/editor/src/hooks/use-form-context.ts
|
|
5058
5058
|
var useEditorFormContext;
|
|
5059
5059
|
var init_use_form_context = __esmMin((() => {
|
|
5060
|
-
useEditorFormContext = (getServices) =>
|
|
5061
|
-
const
|
|
5062
|
-
return {
|
|
5063
|
-
services
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5060
|
+
useEditorFormContext = (getServices) => {
|
|
5061
|
+
const hostContext = (0, vue.inject)(_tmagic_form.FORM_CONTEXT_KEY, void 0);
|
|
5062
|
+
return (0, vue.computed)(() => {
|
|
5063
|
+
const services = getServices();
|
|
5064
|
+
const host = (0, vue.unref)(hostContext);
|
|
5065
|
+
if (host && host.services === services) return host;
|
|
5066
|
+
return (0, _tmagic_form.mergeFormContexts)(host, {
|
|
5067
|
+
services,
|
|
5068
|
+
stage: services?.editorService.get("stage")
|
|
5069
|
+
});
|
|
5070
|
+
});
|
|
5071
|
+
};
|
|
5067
5072
|
}));
|
|
5068
5073
|
//#endregion
|
|
5069
5074
|
//#region packages/editor/src/utils/config.ts
|
|
@@ -5130,13 +5135,20 @@
|
|
|
5130
5135
|
name: "timing",
|
|
5131
5136
|
type: "select",
|
|
5132
5137
|
options: () => {
|
|
5133
|
-
const list = [
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5138
|
+
const list = [
|
|
5139
|
+
{
|
|
5140
|
+
text: "初始化前",
|
|
5141
|
+
value: "beforeInit"
|
|
5142
|
+
},
|
|
5143
|
+
{
|
|
5144
|
+
text: "初始化后",
|
|
5145
|
+
value: "afterInit"
|
|
5146
|
+
},
|
|
5147
|
+
{
|
|
5148
|
+
text: "页面渲染后",
|
|
5149
|
+
value: "mounted"
|
|
5150
|
+
}
|
|
5151
|
+
];
|
|
5140
5152
|
if (dataSourceType?.() !== "base") {
|
|
5141
5153
|
list.push({
|
|
5142
5154
|
text: "请求前",
|
|
@@ -11208,8 +11220,8 @@
|
|
|
11208
11220
|
return cloneDeep$1(methodMap[(0, _tmagic_utils.toLine)(type)]) || [];
|
|
11209
11221
|
}
|
|
11210
11222
|
resetState() {
|
|
11211
|
-
eventMap
|
|
11212
|
-
methodMap
|
|
11223
|
+
Object.keys(eventMap).forEach((type) => delete eventMap[type]);
|
|
11224
|
+
Object.keys(methodMap).forEach((type) => delete methodMap[type]);
|
|
11213
11225
|
}
|
|
11214
11226
|
destroy() {
|
|
11215
11227
|
this.resetState();
|
|
@@ -20074,6 +20086,7 @@
|
|
|
20074
20086
|
uiService.resetState();
|
|
20075
20087
|
componentListService.resetState();
|
|
20076
20088
|
codeBlockService.resetState();
|
|
20089
|
+
eventsService.resetState();
|
|
20077
20090
|
keybindingService.reset();
|
|
20078
20091
|
depService.reset();
|
|
20079
20092
|
});
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.8.0-beta.
|
|
2
|
+
"version": "1.8.0-beta.27",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -63,11 +63,11 @@
|
|
|
63
63
|
"moveable": "^0.53.0",
|
|
64
64
|
"serialize-javascript": "^7.0.7",
|
|
65
65
|
"sortablejs": "^1.15.7",
|
|
66
|
-
"@tmagic/design": "1.8.0-beta.
|
|
67
|
-
"@tmagic/
|
|
68
|
-
"@tmagic/
|
|
69
|
-
"@tmagic/
|
|
70
|
-
"@tmagic/utils": "1.8.0-beta.
|
|
66
|
+
"@tmagic/design": "1.8.0-beta.27",
|
|
67
|
+
"@tmagic/stage": "1.8.0-beta.27",
|
|
68
|
+
"@tmagic/table": "1.8.0-beta.27",
|
|
69
|
+
"@tmagic/form": "1.8.0-beta.27",
|
|
70
|
+
"@tmagic/utils": "1.8.0-beta.27"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@types/events": "^3.0.3",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"type-fest": "^5.2.0",
|
|
82
82
|
"typescript": "^6.0.3",
|
|
83
83
|
"vue": "^3.5.41",
|
|
84
|
-
"@tmagic/core": "1.8.0-beta.
|
|
84
|
+
"@tmagic/core": "1.8.0-beta.27"
|
|
85
85
|
},
|
|
86
86
|
"peerDependenciesMeta": {
|
|
87
87
|
"typescript": {
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { computed, type ComputedRef } from 'vue';
|
|
19
|
+
import { computed, type ComputedRef, inject, unref } from 'vue';
|
|
20
20
|
|
|
21
|
-
import type
|
|
21
|
+
import { FORM_CONTEXT_KEY, type FormContext, mergeFormContexts } from '@tmagic/form';
|
|
22
22
|
|
|
23
23
|
import type { Services } from '@editor/type';
|
|
24
24
|
|
|
@@ -28,13 +28,29 @@ import type { Services } from '@editor/type';
|
|
|
28
28
|
* 由 `Editor.vue`(provide `FORM_CONTEXT_KEY`)、`FormPanel.vue` 与 `useCompareForm`
|
|
29
29
|
* 共用。`stage` 走 computed 而非快照,保证切换画布后配置回调读到的是最新实例。
|
|
30
30
|
*
|
|
31
|
+
* 宿主可能在 `<MEditor>` 外层 provide 了自己的业务字段,这里必须把那一层合并进来:
|
|
32
|
+
* 否则编辑器再 provide 一次会把宿主整层遮蔽掉,属性面板、对比表单里的配置回调就
|
|
33
|
+
* 读不到宿主字段了。`services` / `stage` 由编辑器兜底,优先级高于宿主同名字段。
|
|
34
|
+
*
|
|
31
35
|
* 字段类型见 `@editor/type` 里对 `@tmagic/form-schema` 的 `FormContext` 模块增强。
|
|
32
36
|
*/
|
|
33
|
-
export const useEditorFormContext = (getServices: () => Services | undefined): ComputedRef<FormContext> =>
|
|
34
|
-
|
|
37
|
+
export const useEditorFormContext = (getServices: () => Services | undefined): ComputedRef<FormContext> => {
|
|
38
|
+
// inject 只能在 setup 期取值,因此本 hook 必须在 setup 中调用(`use` 前缀即此约定)。
|
|
39
|
+
// 返回的 computed 可以随便传递,但 hook 本身不能延迟到事件回调或 onMounted 里再调。
|
|
40
|
+
const hostContext = inject(FORM_CONTEXT_KEY, undefined);
|
|
41
|
+
|
|
42
|
+
return computed(() => {
|
|
35
43
|
const services = getServices();
|
|
36
|
-
|
|
44
|
+
const host = unref(hostContext);
|
|
45
|
+
|
|
46
|
+
// 上层(通常是 Editor.vue)已经用同一份 services 合并过了。FormPanel / useCompareForm
|
|
47
|
+
// 都是它的后代,再合并一次只会多套一层 Proxy,让每次属性 miss 多一轮线性查找。
|
|
48
|
+
// services 相同即可判定 stage 也相同——两边都是从同一个 editorService 读的。
|
|
49
|
+
if (host && host.services === services) return host;
|
|
50
|
+
|
|
51
|
+
return mergeFormContexts(host, {
|
|
37
52
|
services,
|
|
38
53
|
stage: services?.editorService.get('stage'),
|
|
39
|
-
};
|
|
54
|
+
});
|
|
40
55
|
});
|
|
56
|
+
};
|
package/src/initService.ts
CHANGED
package/src/services/events.ts
CHANGED
|
@@ -35,8 +35,8 @@ const canUsePluginMethods = {
|
|
|
35
35
|
type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
|
|
36
36
|
type SyncMethodName = Writable<(typeof canUsePluginMethods)['sync']>;
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const eventMap: Record<string, EventOption[]> = reactive({});
|
|
39
|
+
const methodMap: Record<string, EventOption[]> = reactive({});
|
|
40
40
|
|
|
41
41
|
class Events extends BaseService {
|
|
42
42
|
constructor() {
|
|
@@ -75,8 +75,9 @@ class Events extends BaseService {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
public resetState() {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
// 原地清空而不是重新赋值,保留 reactive 代理身份,已建立的 computed / 渲染副作用才能收到更新
|
|
79
|
+
Object.keys(eventMap).forEach((type) => delete eventMap[type]);
|
|
80
|
+
Object.keys(methodMap).forEach((type) => delete methodMap[type]);
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
public destroy() {
|
package/src/type.ts
CHANGED
|
@@ -225,6 +225,7 @@ export interface StageOptions {
|
|
|
225
225
|
beforeDblclick?: (event: MouseEvent) => Promise<boolean | void> | boolean | void;
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
// #region NodeInvalidInfo
|
|
228
229
|
/**
|
|
229
230
|
* 节点校验错误信息,按来源(属性表单 / 样式表单)分别保存错误文案。
|
|
230
231
|
* 属性表单与样式表单是两个独立的 FormPanel,均指向同一节点,故以来源为键,
|
|
@@ -237,9 +238,12 @@ export interface NodeInvalidInfo {
|
|
|
237
238
|
/** 样式表单校验错误文案(可能为包含 <br> 的 HTML) */
|
|
238
239
|
style?: string;
|
|
239
240
|
}
|
|
241
|
+
// #endregion NodeInvalidInfo
|
|
240
242
|
|
|
243
|
+
// #region NodeInvalidSource
|
|
241
244
|
/** 节点校验错误来源 */
|
|
242
245
|
export type NodeInvalidSource = keyof NodeInvalidInfo;
|
|
246
|
+
// #endregion NodeInvalidSource
|
|
243
247
|
|
|
244
248
|
export interface StoreState {
|
|
245
249
|
root: MApp | null;
|
|
@@ -312,6 +316,7 @@ export interface StageRect {
|
|
|
312
316
|
height: number | string;
|
|
313
317
|
}
|
|
314
318
|
|
|
319
|
+
// #region UiState
|
|
315
320
|
export interface UiState {
|
|
316
321
|
/** 当前点击画布是否触发选中,true: 不触发,false: 触发,默认为false */
|
|
317
322
|
uiSelectMode: boolean;
|
|
@@ -369,6 +374,7 @@ export interface UiState {
|
|
|
369
374
|
height: number;
|
|
370
375
|
};
|
|
371
376
|
}
|
|
377
|
+
// #endregion UiState
|
|
372
378
|
|
|
373
379
|
// #region EditorNodeInfo
|
|
374
380
|
export interface EditorNodeInfo {
|
package/src/utils/code-block.ts
CHANGED
|
@@ -103,6 +103,7 @@ export const getCodeBlockFormConfig = (options: GetCodeBlockFormConfigOptions =
|
|
|
103
103
|
const list = [
|
|
104
104
|
{ text: '初始化前', value: 'beforeInit' },
|
|
105
105
|
{ text: '初始化后', value: 'afterInit' },
|
|
106
|
+
{ text: '页面渲染后', value: 'mounted' },
|
|
106
107
|
];
|
|
107
108
|
if (dataSourceType?.() !== 'base') {
|
|
108
109
|
list.push({ text: '请求前', value: 'beforeRequest' });
|