@tmagic/editor 1.2.0-beta.9 → 1.2.1
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/style.css +62 -34
- package/dist/{tmagic-editor.mjs → tmagic-editor.js} +1641 -1266
- package/dist/tmagic-editor.js.map +1 -0
- package/dist/{tmagic-editor.umd.js → tmagic-editor.umd.cjs} +1649 -1270
- package/dist/tmagic-editor.umd.cjs.map +1 -0
- package/package.json +16 -14
- package/src/Editor.vue +66 -40
- package/src/components/CodeDraftEditor.vue +137 -0
- package/src/components/ContentMenu.vue +1 -1
- package/src/components/FunctionEditor.vue +190 -0
- package/src/components/Icon.vue +1 -1
- package/src/{layouts → components}/Layout.vue +54 -15
- package/src/components/ScrollBar.vue +1 -1
- package/src/components/ScrollViewer.vue +10 -1
- package/src/components/ToolButton.vue +1 -1
- package/src/fields/Code.vue +1 -1
- package/src/fields/CodeLink.vue +1 -1
- package/src/fields/CodeSelect.vue +102 -99
- package/src/fields/UISelect.vue +3 -3
- package/src/index.ts +2 -1
- package/src/layouts/AddPageBox.vue +5 -2
- package/src/layouts/CodeEditor.vue +2 -3
- package/src/layouts/Framework.vue +12 -10
- package/src/layouts/NavMenu.vue +11 -8
- package/src/layouts/PropsPanel.vue +12 -9
- package/src/layouts/Resizer.vue +1 -1
- package/src/layouts/sidebar/ComponentListPanel.vue +2 -3
- package/src/layouts/sidebar/LayerMenu.vue +9 -7
- package/src/layouts/sidebar/LayerPanel.vue +130 -178
- package/src/layouts/sidebar/Sidebar.vue +110 -26
- package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +33 -118
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +93 -126
- package/src/layouts/workspace/Breadcrumb.vue +6 -7
- package/src/layouts/workspace/PageBar.vue +3 -3
- package/src/layouts/workspace/PageBarScrollContainer.vue +5 -3
- package/src/layouts/workspace/Stage.vue +36 -18
- package/src/layouts/workspace/ViewerMenu.vue +16 -15
- package/src/layouts/workspace/Workspace.vue +9 -6
- package/src/services/BaseService.ts +11 -2
- package/src/services/codeBlock.ts +136 -146
- package/src/services/componentList.ts +7 -2
- package/src/services/editor.ts +161 -85
- package/src/services/events.ts +7 -2
- package/src/services/history.ts +8 -17
- package/src/services/props.ts +8 -3
- package/src/services/storage.ts +1 -0
- package/src/services/ui.ts +20 -10
- package/src/theme/code-block.scss +46 -23
- package/src/theme/component-list-panel.scss +8 -5
- package/src/type.ts +84 -63
- package/src/utils/config.ts +1 -1
- package/src/utils/editor.ts +17 -3
- package/src/utils/index.ts +2 -1
- package/src/utils/logger.ts +1 -1
- package/src/utils/operator.ts +12 -12
- package/src/utils/props.ts +3 -3
- package/src/utils/scroll-viewer.ts +18 -2
- package/src/utils/stage.ts +10 -9
- package/src/utils/undo-redo.ts +1 -1
- package/types/Editor.vue.d.ts +48 -28
- package/types/components/CodeDraftEditor.vue.d.ts +55 -0
- package/types/components/ContentMenu.vue.d.ts +11 -87
- package/types/components/FunctionEditor.vue.d.ts +60 -0
- package/types/components/Icon.vue.d.ts +4 -50
- package/types/{layouts → components}/Layout.vue.d.ts +12 -1
- package/types/components/ScrollBar.vue.d.ts +7 -65
- package/types/components/ScrollViewer.vue.d.ts +45 -1
- package/types/components/ToolButton.vue.d.ts +12 -78
- package/types/fields/Code.vue.d.ts +11 -77
- package/types/fields/CodeLink.vue.d.ts +12 -82
- package/types/fields/CodeSelect.vue.d.ts +13 -77
- package/types/fields/UISelect.vue.d.ts +7 -65
- package/types/index.d.ts +1 -0
- package/types/layouts/AddPageBox.vue.d.ts +1 -43
- package/types/layouts/CodeEditor.vue.d.ts +22 -130
- package/types/layouts/NavMenu.vue.d.ts +9 -69
- package/types/layouts/sidebar/LayerMenu.vue.d.ts +16 -48
- package/types/layouts/sidebar/LayerPanel.vue.d.ts +24 -7
- package/types/layouts/sidebar/Sidebar.vue.d.ts +10 -5
- package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +24 -6
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +11 -5
- package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -43
- package/types/layouts/workspace/Stage.vue.d.ts +15 -43
- package/types/layouts/workspace/ViewerMenu.vue.d.ts +11 -66
- package/types/layouts/workspace/Workspace.vue.d.ts +25 -8
- package/types/services/BaseService.d.ts +2 -1
- package/types/services/codeBlock.d.ts +56 -47
- package/types/services/componentList.d.ts +1 -0
- package/types/services/editor.d.ts +10 -11
- package/types/services/events.d.ts +1 -0
- package/types/services/history.d.ts +5 -15
- package/types/services/props.d.ts +3 -2
- package/types/services/ui.d.ts +24 -24
- package/types/type.d.ts +70 -59
- package/types/utils/editor.d.ts +1 -0
- package/types/utils/index.d.ts +1 -0
- package/types/utils/operator.d.ts +1 -1
- package/types/utils/props.d.ts +1 -1
- package/types/utils/scroll-viewer.d.ts +5 -0
- package/dist/tmagic-editor.mjs.map +0 -1
- package/dist/tmagic-editor.umd.js.map +0 -1
- package/src/layouts/sidebar/TabPane.vue +0 -118
- package/types/layouts/sidebar/TabPane.vue.d.ts +0 -82
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
3
3
|
*
|
|
4
|
-
* Copyright (C)
|
|
4
|
+
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|
|
@@ -77,7 +77,7 @@ const doAction = async (
|
|
|
77
77
|
*
|
|
78
78
|
* editorService.usePlugin({
|
|
79
79
|
* beforeAdd(value) { return [value] },
|
|
80
|
-
* afterAdd(
|
|
80
|
+
* afterAdd(result, value) { return result },
|
|
81
81
|
* });
|
|
82
82
|
*
|
|
83
83
|
* editorService.add(); 最终会变成 () => {
|
|
@@ -169,6 +169,15 @@ export default class extends EventEmitter {
|
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
public removeAllPlugins() {
|
|
173
|
+
Object.keys(this.pluginOptionsList).forEach((key) => {
|
|
174
|
+
this.pluginOptionsList[key] = [];
|
|
175
|
+
});
|
|
176
|
+
Object.keys(this.middleware).forEach((key) => {
|
|
177
|
+
this.middleware[key] = [];
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
172
181
|
private async doTask() {
|
|
173
182
|
this.doingTask = true;
|
|
174
183
|
let task = this.taskList.shift();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
3
3
|
*
|
|
4
|
-
* Copyright (C)
|
|
4
|
+
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
20
|
import { cloneDeep, forIn, isEmpty, keys, omit, pick } from 'lodash-es';
|
|
21
21
|
|
|
22
|
-
import { Id, MNode } from '@tmagic/schema';
|
|
22
|
+
import { CodeBlockContent, CodeBlockDSL, HookType, Id, MNode } from '@tmagic/schema';
|
|
23
23
|
|
|
24
24
|
import editorService from '../services/editor';
|
|
25
|
-
import type {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
25
|
+
import type { CodeRelation, CodeState, HookData } from '../type';
|
|
26
|
+
import { CODE_DRAFT_STORAGE_KEY } from '../type';
|
|
27
|
+
import { info } from '../utils/logger';
|
|
28
28
|
|
|
29
29
|
import BaseService from './BaseService';
|
|
30
30
|
|
|
@@ -34,9 +34,9 @@ class CodeBlock extends BaseService {
|
|
|
34
34
|
codeDsl: null,
|
|
35
35
|
id: '',
|
|
36
36
|
editable: true,
|
|
37
|
-
mode: CodeEditorMode.EDITOR,
|
|
38
37
|
combineIds: [],
|
|
39
38
|
undeletableList: [],
|
|
39
|
+
relations: {},
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
constructor() {
|
|
@@ -49,7 +49,6 @@ class CodeBlock extends BaseService {
|
|
|
49
49
|
'setCodeDslById',
|
|
50
50
|
'setCodeEditorShowStatus',
|
|
51
51
|
'setEditStatus',
|
|
52
|
-
'setMode',
|
|
53
52
|
'setCombineIds',
|
|
54
53
|
'setUndeleteableList',
|
|
55
54
|
'deleteCodeDslByIds',
|
|
@@ -70,22 +69,27 @@ class CodeBlock extends BaseService {
|
|
|
70
69
|
|
|
71
70
|
/**
|
|
72
71
|
* 获取活动的代码块dsl数据源(默认从dsl中的codeBlocks字段读取)
|
|
72
|
+
* 方法要支持钩子添加扩展,会被重写为异步方法,因此这里显示写为异步以提醒调用者需以异步形式调用
|
|
73
73
|
* @param {boolean} forceRefresh 是否强制从活动dsl拉取刷新
|
|
74
74
|
* @returns {CodeBlockDSL | null}
|
|
75
75
|
*/
|
|
76
76
|
public async getCodeDsl(forceRefresh = false): Promise<CodeBlockDSL | null> {
|
|
77
|
+
return this.getCodeDslSync(forceRefresh);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public getCodeDslSync(forceRefresh = false): CodeBlockDSL | null {
|
|
77
81
|
if (!this.state.codeDsl || forceRefresh) {
|
|
78
|
-
this.state.codeDsl =
|
|
82
|
+
this.state.codeDsl = editorService.getCodeDslSync();
|
|
79
83
|
}
|
|
80
84
|
return this.state.codeDsl;
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
/**
|
|
84
88
|
* 根据代码块id获取代码块内容
|
|
85
|
-
* @param {
|
|
89
|
+
* @param {Id} id 代码块id
|
|
86
90
|
* @returns {CodeBlockContent | null}
|
|
87
91
|
*/
|
|
88
|
-
public async getCodeContentById(id:
|
|
92
|
+
public async getCodeContentById(id: Id): Promise<CodeBlockContent | null> {
|
|
89
93
|
if (!id) return null;
|
|
90
94
|
const totalCodeDsl = await this.getCodeDsl();
|
|
91
95
|
if (!totalCodeDsl) return null;
|
|
@@ -94,16 +98,24 @@ class CodeBlock extends BaseService {
|
|
|
94
98
|
|
|
95
99
|
/**
|
|
96
100
|
* 设置代码块ID和代码内容到源dsl
|
|
97
|
-
* @param {
|
|
101
|
+
* @param {Id} id 代码块id
|
|
98
102
|
* @param {CodeBlockContent} codeConfig 代码块内容配置信息
|
|
99
103
|
* @returns {void}
|
|
100
104
|
*/
|
|
101
|
-
public async setCodeDslById(id:
|
|
105
|
+
public async setCodeDslById(id: Id, codeConfig: CodeBlockContent): Promise<void> {
|
|
102
106
|
let codeDsl = await this.getCodeDsl();
|
|
107
|
+
const codeConfigProcessed = codeConfig;
|
|
108
|
+
if (codeConfig.content) {
|
|
109
|
+
// 在保存的时候转换代码内容
|
|
110
|
+
// eslint-disable-next-line no-eval
|
|
111
|
+
codeConfigProcessed.content = eval(codeConfig.content);
|
|
112
|
+
}
|
|
103
113
|
if (!codeDsl) {
|
|
104
114
|
// dsl中无代码块字段
|
|
105
115
|
codeDsl = {
|
|
106
|
-
[id]:
|
|
116
|
+
[id]: {
|
|
117
|
+
...codeConfigProcessed,
|
|
118
|
+
},
|
|
107
119
|
};
|
|
108
120
|
} else {
|
|
109
121
|
const existContent = codeDsl[id] || {};
|
|
@@ -111,7 +123,7 @@ class CodeBlock extends BaseService {
|
|
|
111
123
|
...codeDsl,
|
|
112
124
|
[id]: {
|
|
113
125
|
...existContent,
|
|
114
|
-
...
|
|
126
|
+
...codeConfigProcessed,
|
|
115
127
|
},
|
|
116
128
|
};
|
|
117
129
|
}
|
|
@@ -148,10 +160,10 @@ class CodeBlock extends BaseService {
|
|
|
148
160
|
/**
|
|
149
161
|
* 设置代码编辑面板展示状态及展示内容
|
|
150
162
|
* @param {boolean} status 是否展示代码编辑面板
|
|
151
|
-
* @param {
|
|
163
|
+
* @param {Id} id 代码块id
|
|
152
164
|
* @returns {void}
|
|
153
165
|
*/
|
|
154
|
-
public setCodeEditorContent(status: boolean, id:
|
|
166
|
+
public setCodeEditorContent(status: boolean, id: Id): void {
|
|
155
167
|
if (!id) return;
|
|
156
168
|
this.setId(id);
|
|
157
169
|
this.state.isShowCodeEditor = status;
|
|
@@ -161,7 +173,7 @@ class CodeBlock extends BaseService {
|
|
|
161
173
|
* 获取当前选中的代码块内容
|
|
162
174
|
* @returns {CodeBlockContent | null}
|
|
163
175
|
*/
|
|
164
|
-
public async getCurrentDsl() {
|
|
176
|
+
public async getCurrentDsl(): Promise<CodeBlockContent | null> {
|
|
165
177
|
return await this.getCodeContentById(this.state.id);
|
|
166
178
|
}
|
|
167
179
|
|
|
@@ -184,39 +196,22 @@ class CodeBlock extends BaseService {
|
|
|
184
196
|
|
|
185
197
|
/**
|
|
186
198
|
* 设置当前选中的代码块ID
|
|
187
|
-
* @param {
|
|
199
|
+
* @param {Id} id 代码块id
|
|
188
200
|
* @returns {void}
|
|
189
201
|
*/
|
|
190
|
-
public setId(id:
|
|
202
|
+
public setId(id: Id): void {
|
|
191
203
|
if (!id) return;
|
|
192
204
|
this.state.id = id;
|
|
193
205
|
}
|
|
194
206
|
|
|
195
207
|
/**
|
|
196
208
|
* 获取当前选中的代码块ID
|
|
197
|
-
* @returns {
|
|
209
|
+
* @returns {Id} id 代码块id
|
|
198
210
|
*/
|
|
199
|
-
public getId():
|
|
211
|
+
public getId(): Id {
|
|
200
212
|
return this.state.id;
|
|
201
213
|
}
|
|
202
214
|
|
|
203
|
-
/**
|
|
204
|
-
* 获取当前模式
|
|
205
|
-
* @returns {CodeEditorMode}
|
|
206
|
-
*/
|
|
207
|
-
public getMode(): CodeEditorMode {
|
|
208
|
-
return this.state.mode;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* 设置当前模式
|
|
213
|
-
* @param {CodeEditorMode} mode 模式
|
|
214
|
-
* @returns {void}
|
|
215
|
-
*/
|
|
216
|
-
public async setMode(mode: CodeEditorMode): Promise<void> {
|
|
217
|
-
this.state.mode = mode;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
215
|
/**
|
|
221
216
|
* 设置当前选中组件已关联绑定的代码块id数组
|
|
222
217
|
* @param {string[]} ids 代码块id数组
|
|
@@ -235,98 +230,70 @@ class CodeBlock extends BaseService {
|
|
|
235
230
|
}
|
|
236
231
|
|
|
237
232
|
/**
|
|
238
|
-
*
|
|
239
|
-
* @
|
|
240
|
-
* @param {string[]} diffCodeIds 代码块id数组
|
|
241
|
-
* @param {CodeSelectOp} opFlag 操作类型
|
|
242
|
-
* @param {string} hook 代码块挂载hook名称
|
|
243
|
-
* @returns {void}
|
|
233
|
+
* 刷新绑定关系
|
|
234
|
+
* @returns {CodeRelation | null}
|
|
244
235
|
*/
|
|
245
|
-
public
|
|
246
|
-
const
|
|
247
|
-
if (!
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
} else if (opFlag === CodeSelectOp.ADD) {
|
|
262
|
-
try {
|
|
263
|
-
diffCodeIds.forEach((codeId) => {
|
|
264
|
-
const compsContent = codeDsl[codeId].comps;
|
|
265
|
-
const existHooks = compsContent?.[compId];
|
|
266
|
-
if (isEmpty(existHooks)) {
|
|
267
|
-
// comps属性不存在,或者comps为空:新增
|
|
268
|
-
codeDsl[codeId].comps = {
|
|
269
|
-
...(codeDsl[codeId].comps || {}),
|
|
270
|
-
[compId]: [hook],
|
|
271
|
-
};
|
|
272
|
-
} else {
|
|
273
|
-
// 往已有的关系中添加hook
|
|
274
|
-
existHooks?.push(hook);
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
} catch (e) {
|
|
278
|
-
error(e);
|
|
279
|
-
throw new Error('绑定代码块失败');
|
|
280
|
-
}
|
|
281
|
-
} else if (opFlag === CodeSelectOp.CHANGE) {
|
|
282
|
-
// 单选修改
|
|
283
|
-
forIn(codeDsl, (codeBlockContent, codeId) => {
|
|
284
|
-
if (codeId === diffCodeIds[0]) {
|
|
285
|
-
// 增加
|
|
286
|
-
codeBlockContent.comps = {
|
|
287
|
-
...(codeBlockContent?.comps || {}),
|
|
288
|
-
[compId]: [hook],
|
|
289
|
-
};
|
|
290
|
-
} else if (isEmpty(diffCodeIds) || codeId !== diffCodeIds[0]) {
|
|
291
|
-
// 清空或者移除之前的选项
|
|
292
|
-
const compHooks = codeBlockContent?.comps?.[compId];
|
|
293
|
-
// continue
|
|
294
|
-
if (!compHooks) return true;
|
|
295
|
-
const index = compHooks.findIndex((hookName) => hookName === hook);
|
|
296
|
-
if (index !== -1) {
|
|
297
|
-
compHooks.splice(index, 1);
|
|
298
|
-
// break
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
this.setCodeDsl(codeDsl);
|
|
236
|
+
public refreshCombineInfo(): CodeRelation | null {
|
|
237
|
+
const root = editorService.get('root');
|
|
238
|
+
if (!root) return null;
|
|
239
|
+
const relations = {};
|
|
240
|
+
this.recurseMNode(root, relations);
|
|
241
|
+
this.state.relations = relations;
|
|
242
|
+
return this.state.relations;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* 获取绑定关系
|
|
247
|
+
* @returns {CodeRelation}
|
|
248
|
+
*/
|
|
249
|
+
public getCombineInfo(): CodeRelation {
|
|
250
|
+
return this.state.relations;
|
|
305
251
|
}
|
|
306
252
|
|
|
307
253
|
/**
|
|
308
254
|
* 获取不可删除列表
|
|
309
|
-
* @returns {
|
|
255
|
+
* @returns {Id[]}
|
|
310
256
|
*/
|
|
311
|
-
public getUndeletableList():
|
|
257
|
+
public getUndeletableList(): Id[] {
|
|
312
258
|
return this.state.undeletableList;
|
|
313
259
|
}
|
|
314
260
|
|
|
315
261
|
/**
|
|
316
262
|
* 设置不可删除列表:为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除)
|
|
317
|
-
* @param {
|
|
263
|
+
* @param {Id[]} codeIds 代码块id数组
|
|
318
264
|
* @returns {void}
|
|
319
265
|
*/
|
|
320
|
-
public async setUndeleteableList(codeIds:
|
|
266
|
+
public async setUndeleteableList(codeIds: Id[]): Promise<void> {
|
|
321
267
|
this.state.undeletableList = codeIds;
|
|
322
268
|
}
|
|
323
269
|
|
|
270
|
+
/**
|
|
271
|
+
* 设置代码草稿
|
|
272
|
+
*/
|
|
273
|
+
public setCodeDraft(codeId: Id, content: string): void {
|
|
274
|
+
globalThis.localStorage.setItem(`${CODE_DRAFT_STORAGE_KEY}_${codeId}`, content);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* 获取代码草稿
|
|
279
|
+
*/
|
|
280
|
+
public getCodeDraft(codeId: Id): string | null {
|
|
281
|
+
return globalThis.localStorage.getItem(`${CODE_DRAFT_STORAGE_KEY}_${codeId}`);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* 删除代码草稿
|
|
286
|
+
*/
|
|
287
|
+
public removeCodeDraft(codeId: Id): void {
|
|
288
|
+
globalThis.localStorage.removeItem(`${CODE_DRAFT_STORAGE_KEY}_${codeId}`);
|
|
289
|
+
}
|
|
290
|
+
|
|
324
291
|
/**
|
|
325
292
|
* 在dsl数据源中删除指定id的代码块
|
|
326
|
-
* @param {
|
|
293
|
+
* @param {Id[]} codeIds 需要删除的代码块id数组
|
|
327
294
|
* @returns {CodeBlockDSL} 删除后的code dsl
|
|
328
295
|
*/
|
|
329
|
-
public async deleteCodeDslByIds(codeIds:
|
|
296
|
+
public async deleteCodeDslByIds(codeIds: Id[]): Promise<CodeBlockDSL> {
|
|
330
297
|
const currentDsl = await this.getCodeDsl();
|
|
331
298
|
const newDsl = omit(currentDsl, codeIds);
|
|
332
299
|
await this.setCodeDsl(newDsl);
|
|
@@ -335,9 +302,9 @@ class CodeBlock extends BaseService {
|
|
|
335
302
|
|
|
336
303
|
/**
|
|
337
304
|
* 生成代码块唯一id
|
|
338
|
-
* @returns {
|
|
305
|
+
* @returns {Id} 代码块唯一id
|
|
339
306
|
*/
|
|
340
|
-
public async getUniqueId(): Promise<
|
|
307
|
+
public async getUniqueId(): Promise<Id> {
|
|
341
308
|
const newId = `code_${Math.random().toString(10).substring(2).substring(0, 4)}`;
|
|
342
309
|
// 判断是否重复
|
|
343
310
|
const dsl = await this.getCodeDsl();
|
|
@@ -346,57 +313,40 @@ class CodeBlock extends BaseService {
|
|
|
346
313
|
return await this.getUniqueId();
|
|
347
314
|
}
|
|
348
315
|
|
|
349
|
-
/**
|
|
350
|
-
* 一对一解除绑定关系 功能隐藏,暂时注释
|
|
351
|
-
* @param {string} compId 组件id
|
|
352
|
-
* @param {string} codeId 代码块id
|
|
353
|
-
* @param {string[]} codeHooks 代码块挂载hook名称
|
|
354
|
-
* @returns {boolean} 结果
|
|
355
|
-
*/
|
|
356
|
-
// public async unbind(compId: Id, codeId: string, codeHooks: string[]): Promise<boolean> {
|
|
357
|
-
// const nodeInfo = editorService.getNodeById(compId);
|
|
358
|
-
// if (!nodeInfo) return false;
|
|
359
|
-
// // 更新node节点信息
|
|
360
|
-
// codeHooks.forEach((hook) => {
|
|
361
|
-
// if (!isEmpty(nodeInfo[hook])) {
|
|
362
|
-
// const newHookInfo = nodeInfo[hook].filter((item: string) => item !== codeId);
|
|
363
|
-
// nodeInfo[hook] = newHookInfo;
|
|
364
|
-
// editorService.update(nodeInfo);
|
|
365
|
-
// }
|
|
366
|
-
// });
|
|
367
|
-
// // 更新绑定关系
|
|
368
|
-
// const oldRelation = await this.getCompRelation();
|
|
369
|
-
// const oldCodeIds = oldRelation[compId];
|
|
370
|
-
// // 不能直接splice修改原数组,会导致绑定关系更新错乱
|
|
371
|
-
// const newCodeIds = oldCodeIds.filter((item) => item !== codeId);
|
|
372
|
-
// this.setCompRelation(compId, newCodeIds);
|
|
373
|
-
// return true;
|
|
374
|
-
// }
|
|
375
|
-
|
|
376
316
|
/**
|
|
377
317
|
* 通过组件id解除绑定关系(删除组件)
|
|
378
318
|
* @param {MNode} compId 组件节点
|
|
379
319
|
* @returns void
|
|
380
320
|
*/
|
|
381
|
-
public async deleteCompsInRelation(node: MNode) {
|
|
321
|
+
public async deleteCompsInRelation(node: MNode): Promise<void> {
|
|
382
322
|
const codeDsl = cloneDeep(await this.getCodeDsl());
|
|
383
323
|
if (!codeDsl) return;
|
|
384
|
-
this.
|
|
324
|
+
this.refreshRelationDeep(node, codeDsl);
|
|
385
325
|
this.setCodeDsl(codeDsl);
|
|
386
326
|
}
|
|
387
327
|
|
|
388
|
-
public
|
|
328
|
+
public resetState() {
|
|
389
329
|
this.state.isShowCodeEditor = false;
|
|
390
330
|
this.state.codeDsl = null;
|
|
391
331
|
this.state.id = '';
|
|
392
332
|
this.state.editable = true;
|
|
393
|
-
this.state.mode = CodeEditorMode.EDITOR;
|
|
394
333
|
this.state.combineIds = [];
|
|
395
334
|
this.state.undeletableList = [];
|
|
396
335
|
}
|
|
397
336
|
|
|
398
|
-
|
|
399
|
-
|
|
337
|
+
public destroy(): void {
|
|
338
|
+
this.resetState();
|
|
339
|
+
this.removeAllListeners();
|
|
340
|
+
this.removeAllPlugins();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* 删除组件时 如果是容器 需要遍历删除其包含节点的绑定信息
|
|
345
|
+
* @param {MNode} node 节点信息
|
|
346
|
+
* @param {CodeBlockDSL} codeDsl 代码块
|
|
347
|
+
* @returns void
|
|
348
|
+
*/
|
|
349
|
+
private refreshRelationDeep(node: MNode, codeDsl: CodeBlockDSL): void {
|
|
400
350
|
if (!node.id) return;
|
|
401
351
|
forIn(codeDsl, (codeBlockContent) => {
|
|
402
352
|
const compsContent = codeBlockContent.comps || {};
|
|
@@ -404,7 +354,47 @@ class CodeBlock extends BaseService {
|
|
|
404
354
|
});
|
|
405
355
|
if (!isEmpty(node.items)) {
|
|
406
356
|
node.items.forEach((item: MNode) => {
|
|
407
|
-
this.
|
|
357
|
+
this.refreshRelationDeep(item, codeDsl);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* 递归遍历dsl中挂载了代码块的节点,并更新绑定关系数据
|
|
364
|
+
* @param {MContainer} node 节点信息
|
|
365
|
+
* @returns void
|
|
366
|
+
*/
|
|
367
|
+
private recurseMNode(node: MNode, relations: CodeRelation): void {
|
|
368
|
+
forIn(node, (value, key) => {
|
|
369
|
+
let unConfirmedValue: MNode = { id: node.id };
|
|
370
|
+
if (value?.hookType === HookType.CODE && !isEmpty(value.hookData)) {
|
|
371
|
+
value.hookData.forEach((relationItem: HookData) => {
|
|
372
|
+
// continue
|
|
373
|
+
if (!relationItem.codeId) return;
|
|
374
|
+
if (!relations[relationItem.codeId]) {
|
|
375
|
+
relations[relationItem.codeId] = {};
|
|
376
|
+
}
|
|
377
|
+
const codeItem = relations[relationItem.codeId];
|
|
378
|
+
if (isEmpty(codeItem[node.id])) {
|
|
379
|
+
codeItem[node.id] = [];
|
|
380
|
+
}
|
|
381
|
+
codeItem[node.id].push(key);
|
|
382
|
+
});
|
|
383
|
+
// continue
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (typeof value === 'object') {
|
|
387
|
+
// 检查value内部是否有嵌套
|
|
388
|
+
unConfirmedValue = {
|
|
389
|
+
...unConfirmedValue,
|
|
390
|
+
...value,
|
|
391
|
+
};
|
|
392
|
+
this.recurseMNode(unConfirmedValue, relations);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
if (!isEmpty(node.items)) {
|
|
396
|
+
node.items.forEach((item: MNode) => {
|
|
397
|
+
this.recurseMNode(item, relations);
|
|
408
398
|
});
|
|
409
399
|
}
|
|
410
400
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
3
3
|
*
|
|
4
|
-
* Copyright (C)
|
|
4
|
+
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|
|
@@ -42,9 +42,14 @@ class ComponentList extends BaseService {
|
|
|
42
42
|
return this.state.list;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
public
|
|
45
|
+
public resetState() {
|
|
46
46
|
this.state.list = [];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public destroy() {
|
|
50
|
+
this.resetState();
|
|
47
51
|
this.removeAllListeners();
|
|
52
|
+
this.removeAllPlugins();
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
55
|
|