@tmagic/editor 1.2.0 → 1.2.2
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 +4 -0
- package/dist/tmagic-editor.js +305 -249
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +308 -253
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +9 -9
- package/src/Editor.vue +1 -1
- package/src/components/CodeDraftEditor.vue +2 -10
- package/src/components/FunctionEditor.vue +58 -13
- package/src/components/Layout.vue +1 -1
- package/src/fields/CodeSelect.vue +23 -7
- package/src/fields/UISelect.vue +2 -2
- package/src/index.ts +1 -1
- package/src/layouts/AddPageBox.vue +4 -1
- package/src/layouts/Framework.vue +10 -8
- package/src/layouts/NavMenu.vue +9 -6
- package/src/layouts/PropsPanel.vue +3 -7
- package/src/layouts/sidebar/ComponentListPanel.vue +1 -2
- package/src/layouts/sidebar/LayerPanel.vue +8 -9
- package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +10 -39
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -6
- package/src/layouts/workspace/Breadcrumb.vue +5 -6
- package/src/layouts/workspace/PageBar.vue +2 -2
- package/src/layouts/workspace/PageBarScrollContainer.vue +4 -2
- package/src/layouts/workspace/Stage.vue +11 -10
- package/src/layouts/workspace/ViewerMenu.vue +5 -6
- package/src/layouts/workspace/Workspace.vue +2 -3
- package/src/services/BaseService.ts +1 -1
- package/src/services/codeBlock.ts +15 -24
- package/src/services/componentList.ts +1 -1
- package/src/services/editor.ts +119 -79
- package/src/services/events.ts +1 -1
- package/src/services/history.ts +1 -1
- package/src/services/props.ts +1 -1
- package/src/services/ui.ts +8 -10
- package/src/theme/code-block.scss +4 -0
- package/src/type.ts +7 -13
- package/src/utils/config.ts +1 -1
- package/src/utils/editor.ts +8 -2
- package/src/utils/index.ts +1 -1
- package/src/utils/logger.ts +1 -1
- package/src/utils/operator.ts +12 -12
- package/src/utils/props.ts +1 -1
- package/src/utils/stage.ts +6 -6
- package/src/utils/undo-redo.ts +1 -1
- package/types/Editor.vue.d.ts +1 -1
- package/types/components/CodeDraftEditor.vue.d.ts +1 -2
- package/types/components/FunctionEditor.vue.d.ts +17 -0
- package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +23 -5
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +5 -0
- package/types/layouts/workspace/Workspace.vue.d.ts +2 -3
- package/types/services/codeBlock.d.ts +0 -12
- package/types/services/editor.d.ts +6 -6
- package/types/services/ui.d.ts +23 -24
- package/types/type.d.ts +5 -11
- package/types/utils/operator.d.ts +1 -1
package/src/services/editor.ts
CHANGED
|
@@ -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.
|
|
@@ -27,7 +27,7 @@ import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
|
|
|
27
27
|
import codeBlockService from '../services/codeBlock';
|
|
28
28
|
import historyService from '../services/history';
|
|
29
29
|
import storageService, { Protocol } from '../services/storage';
|
|
30
|
-
import type { AddMNode, EditorNodeInfo, PastePosition, StepValue, StoreState } from '../type';
|
|
30
|
+
import type { AddMNode, EditorNodeInfo, PastePosition, StepValue, StoreState, StoreStateKey } from '../type';
|
|
31
31
|
import { LayerOffset, Layout } from '../type';
|
|
32
32
|
import {
|
|
33
33
|
change2Fixed,
|
|
@@ -94,15 +94,26 @@ class Editor extends BaseService {
|
|
|
94
94
|
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength'
|
|
95
95
|
* @param value MNode
|
|
96
96
|
*/
|
|
97
|
-
public set<T
|
|
97
|
+
public set<K extends StoreStateKey, T extends StoreState[K]>(name: K, value: T) {
|
|
98
98
|
const preValue = this.state[name];
|
|
99
|
-
this.state[name] = value
|
|
99
|
+
this.state[name] = value;
|
|
100
|
+
|
|
100
101
|
// set nodes时将node设置为nodes第一个元素
|
|
101
|
-
if (name === 'nodes') {
|
|
102
|
-
this.set('node',
|
|
102
|
+
if (name === 'nodes' && Array.isArray(value)) {
|
|
103
|
+
this.set('node', value[0]);
|
|
103
104
|
}
|
|
105
|
+
|
|
104
106
|
if (name === 'root') {
|
|
105
|
-
|
|
107
|
+
if (Array.isArray(value)) {
|
|
108
|
+
throw new Error('root 不能为数组');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (value && isObject(value) && !(value instanceof StageCore) && !(value instanceof Map)) {
|
|
112
|
+
this.state.pageLength = value.items?.length || 0;
|
|
113
|
+
} else {
|
|
114
|
+
this.state.pageLength = 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
106
117
|
this.emit('root-change', value, preValue);
|
|
107
118
|
}
|
|
108
119
|
}
|
|
@@ -112,8 +123,8 @@ class Editor extends BaseService {
|
|
|
112
123
|
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength'
|
|
113
124
|
* @returns MNode
|
|
114
125
|
*/
|
|
115
|
-
public get<
|
|
116
|
-
return
|
|
126
|
+
public get<K extends StoreStateKey>(name: K): StoreState[K] {
|
|
127
|
+
return this.state[name];
|
|
117
128
|
}
|
|
118
129
|
|
|
119
130
|
/**
|
|
@@ -123,22 +134,29 @@ class Editor extends BaseService {
|
|
|
123
134
|
* @returns {EditorNodeInfo}
|
|
124
135
|
*/
|
|
125
136
|
public getNodeInfo(id: Id, raw = true): EditorNodeInfo {
|
|
126
|
-
let root = this.get
|
|
137
|
+
let root = this.get('root');
|
|
127
138
|
if (raw) {
|
|
128
139
|
root = toRaw(root);
|
|
129
140
|
}
|
|
130
|
-
|
|
141
|
+
|
|
142
|
+
const info: EditorNodeInfo = {
|
|
143
|
+
node: null,
|
|
144
|
+
parent: null,
|
|
145
|
+
page: null,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
if (!root) return info;
|
|
131
149
|
|
|
132
150
|
if (id === root.id) {
|
|
133
|
-
|
|
151
|
+
info.node = root;
|
|
152
|
+
return info;
|
|
134
153
|
}
|
|
135
154
|
|
|
136
155
|
const path = getNodePath(id, root.items);
|
|
137
156
|
|
|
138
|
-
if (!path.length) return
|
|
157
|
+
if (!path.length) return info;
|
|
139
158
|
|
|
140
159
|
path.unshift(root);
|
|
141
|
-
const info: EditorNodeInfo = {};
|
|
142
160
|
|
|
143
161
|
info.node = path[path.length - 1] as MComponent;
|
|
144
162
|
info.parent = path[path.length - 2] as MContainer;
|
|
@@ -159,7 +177,7 @@ class Editor extends BaseService {
|
|
|
159
177
|
* @param {boolean} raw 是否使用toRaw
|
|
160
178
|
* @returns 组件节点配置
|
|
161
179
|
*/
|
|
162
|
-
public getNodeById(id: Id, raw = true): MNode |
|
|
180
|
+
public getNodeById(id: Id, raw = true): MNode | null {
|
|
163
181
|
const { node } = this.getNodeInfo(id, raw);
|
|
164
182
|
return node;
|
|
165
183
|
}
|
|
@@ -170,8 +188,7 @@ class Editor extends BaseService {
|
|
|
170
188
|
* @param {boolean} raw 是否使用toRaw
|
|
171
189
|
* @returns 指点组件的父节点配置
|
|
172
190
|
*/
|
|
173
|
-
public getParentById(id: Id, raw = true): MContainer |
|
|
174
|
-
if (!this.get<MApp | null>('root')) return;
|
|
191
|
+
public getParentById(id: Id, raw = true): MContainer | null {
|
|
175
192
|
const { parent } = this.getNodeInfo(id, raw);
|
|
176
193
|
return parent;
|
|
177
194
|
}
|
|
@@ -201,9 +218,9 @@ class Editor extends BaseService {
|
|
|
201
218
|
*/
|
|
202
219
|
public async select(config: MNode | Id): Promise<MNode> | never {
|
|
203
220
|
const { node, page, parent } = this.selectedConfigExceptionHandler(config);
|
|
204
|
-
this.set('nodes', [node]);
|
|
205
|
-
this.set('page', page
|
|
206
|
-
this.set('parent', parent
|
|
221
|
+
this.set('nodes', node ? [node] : []);
|
|
222
|
+
this.set('page', page);
|
|
223
|
+
this.set('parent', parent);
|
|
207
224
|
|
|
208
225
|
if (page) {
|
|
209
226
|
historyService.changePage(toRaw(page));
|
|
@@ -212,7 +229,7 @@ class Editor extends BaseService {
|
|
|
212
229
|
}
|
|
213
230
|
|
|
214
231
|
if (node?.id) {
|
|
215
|
-
this.get
|
|
232
|
+
this.get('stage')
|
|
216
233
|
?.renderer.runtime?.getApp?.()
|
|
217
234
|
?.emit(
|
|
218
235
|
'editor:select',
|
|
@@ -221,7 +238,7 @@ class Editor extends BaseService {
|
|
|
221
238
|
page,
|
|
222
239
|
parent,
|
|
223
240
|
},
|
|
224
|
-
getNodePath(node.id, this.get
|
|
241
|
+
getNodePath(node.id, this.get('root')?.items),
|
|
225
242
|
);
|
|
226
243
|
}
|
|
227
244
|
|
|
@@ -230,7 +247,7 @@ class Editor extends BaseService {
|
|
|
230
247
|
return node!;
|
|
231
248
|
}
|
|
232
249
|
|
|
233
|
-
public async selectNextNode(): Promise<MNode> | never {
|
|
250
|
+
public async selectNextNode(): Promise<MNode | null> | never {
|
|
234
251
|
const node = toRaw(this.get('node'));
|
|
235
252
|
|
|
236
253
|
if (!node || isPage(node) || node.type === NodeType.ROOT) return node;
|
|
@@ -244,21 +261,24 @@ class Editor extends BaseService {
|
|
|
244
261
|
const nextNode = parent.items[index + 1] || parent.items[0];
|
|
245
262
|
|
|
246
263
|
await this.select(nextNode);
|
|
247
|
-
this.get
|
|
264
|
+
this.get('stage')?.select(nextNode.id);
|
|
248
265
|
|
|
249
266
|
return nextNode;
|
|
250
267
|
}
|
|
251
268
|
|
|
252
269
|
public async selectNextPage(): Promise<MNode> | never {
|
|
253
|
-
const root = toRaw(this.get
|
|
270
|
+
const root = toRaw(this.get('root'));
|
|
254
271
|
const page = toRaw(this.get('page'));
|
|
255
272
|
|
|
273
|
+
if (!page) throw new Error('page不能为空');
|
|
274
|
+
if (!root) throw new Error('root不能为空');
|
|
275
|
+
|
|
256
276
|
const index = getNodeIndex(page, root);
|
|
257
277
|
|
|
258
278
|
const nextPage = root.items[index + 1] || root.items[0];
|
|
259
279
|
|
|
260
280
|
await this.select(nextPage);
|
|
261
|
-
this.get
|
|
281
|
+
this.get('stage')?.select(nextPage.id);
|
|
262
282
|
|
|
263
283
|
return nextPage;
|
|
264
284
|
}
|
|
@@ -292,20 +312,25 @@ class Editor extends BaseService {
|
|
|
292
312
|
}
|
|
293
313
|
|
|
294
314
|
public async doAdd(node: MNode, parent: MContainer): Promise<MNode> {
|
|
295
|
-
const root = this.get
|
|
296
|
-
|
|
297
|
-
|
|
315
|
+
const root = this.get('root');
|
|
316
|
+
|
|
317
|
+
if (!root) throw new Error('root为空');
|
|
318
|
+
|
|
319
|
+
const curNode = this.get('node');
|
|
320
|
+
const stage = this.get('stage');
|
|
321
|
+
|
|
322
|
+
if (!curNode) throw new Error('当前选中节点为空');
|
|
298
323
|
|
|
299
|
-
if ((parent
|
|
324
|
+
if ((parent.type === NodeType.ROOT || curNode?.type === NodeType.ROOT) && node.type !== NodeType.PAGE) {
|
|
300
325
|
throw new Error('app下不能添加组件');
|
|
301
326
|
}
|
|
302
327
|
|
|
303
328
|
if (parent.id !== curNode.id && node.type !== NodeType.PAGE) {
|
|
304
329
|
const index = parent.items.indexOf(curNode);
|
|
305
|
-
parent
|
|
330
|
+
parent.items?.splice(index + 1, 0, node);
|
|
306
331
|
} else {
|
|
307
332
|
// 新增节点添加到配置中
|
|
308
|
-
parent
|
|
333
|
+
parent.items?.push(node);
|
|
309
334
|
}
|
|
310
335
|
|
|
311
336
|
const layout = await this.getLayout(toRaw(parent), node as MNode);
|
|
@@ -337,7 +362,7 @@ class Editor extends BaseService {
|
|
|
337
362
|
* @returns 添加后的节点
|
|
338
363
|
*/
|
|
339
364
|
public async add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]> {
|
|
340
|
-
const stage = this.get
|
|
365
|
+
const stage = this.get('stage');
|
|
341
366
|
|
|
342
367
|
// 新增多个组件只存在于粘贴多个组件,粘贴的是一个完整的config,所以不再需要getPropsValue
|
|
343
368
|
const addNodes = [];
|
|
@@ -353,8 +378,9 @@ class Editor extends BaseService {
|
|
|
353
378
|
|
|
354
379
|
const newNodes = await Promise.all(
|
|
355
380
|
addNodes.map((node) => {
|
|
356
|
-
|
|
357
|
-
|
|
381
|
+
const root = this.get('root');
|
|
382
|
+
if (isPage(node) && root) {
|
|
383
|
+
return this.doAdd(node, root);
|
|
358
384
|
}
|
|
359
385
|
const parentNode = parent && typeof parent !== 'function' ? parent : getAddParent(node);
|
|
360
386
|
if (!parentNode) throw new Error('未找到父元素');
|
|
@@ -388,9 +414,8 @@ class Editor extends BaseService {
|
|
|
388
414
|
}
|
|
389
415
|
|
|
390
416
|
public async doRemove(node: MNode): Promise<void> {
|
|
391
|
-
const root = this.get
|
|
392
|
-
|
|
393
|
-
if (!root) throw new Error('没有root');
|
|
417
|
+
const root = this.get('root');
|
|
418
|
+
if (!root) throw new Error('root不能为空');
|
|
394
419
|
|
|
395
420
|
const { parent, node: curNode } = this.getNodeInfo(node.id);
|
|
396
421
|
|
|
@@ -401,7 +426,7 @@ class Editor extends BaseService {
|
|
|
401
426
|
if (typeof index !== 'number' || index === -1) throw new Error('找不要删除的节点');
|
|
402
427
|
|
|
403
428
|
parent.items?.splice(index, 1);
|
|
404
|
-
const stage = this.get
|
|
429
|
+
const stage = this.get('stage');
|
|
405
430
|
stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
|
|
406
431
|
|
|
407
432
|
if (node.type === NodeType.PAGE) {
|
|
@@ -450,6 +475,9 @@ class Editor extends BaseService {
|
|
|
450
475
|
}
|
|
451
476
|
|
|
452
477
|
public async doUpdate(config: MNode) {
|
|
478
|
+
const root = this.get('root');
|
|
479
|
+
if (!root) throw new Error('root为空');
|
|
480
|
+
|
|
453
481
|
if (!config?.id) throw new Error('没有配置或者配置缺少id值');
|
|
454
482
|
|
|
455
483
|
const info = this.getNodeInfo(config.id, false);
|
|
@@ -458,7 +486,7 @@ class Editor extends BaseService {
|
|
|
458
486
|
|
|
459
487
|
const node = cloneDeep(toRaw(info.node));
|
|
460
488
|
|
|
461
|
-
let newConfig = await this.toggleFixedPosition(toRaw(config), node,
|
|
489
|
+
let newConfig = await this.toggleFixedPosition(toRaw(config), node, root);
|
|
462
490
|
|
|
463
491
|
newConfig = mergeWith(cloneDeep(node), newConfig, (objValue, srcValue) => {
|
|
464
492
|
if (isObject(srcValue) && Array.isArray(objValue)) {
|
|
@@ -473,7 +501,7 @@ class Editor extends BaseService {
|
|
|
473
501
|
if (!newConfig.type) throw new Error('配置缺少type值');
|
|
474
502
|
|
|
475
503
|
if (newConfig.type === NodeType.ROOT) {
|
|
476
|
-
this.set('root', newConfig);
|
|
504
|
+
this.set('root', newConfig as MApp);
|
|
477
505
|
return newConfig;
|
|
478
506
|
}
|
|
479
507
|
|
|
@@ -494,19 +522,19 @@ class Editor extends BaseService {
|
|
|
494
522
|
parentNodeItems[index] = newConfig;
|
|
495
523
|
|
|
496
524
|
// 将update后的配置更新到nodes中
|
|
497
|
-
const nodes = this.get
|
|
525
|
+
const nodes = this.get('nodes');
|
|
498
526
|
const targetIndex = nodes.findIndex((nodeItem: MNode) => `${nodeItem.id}` === `${newConfig.id}`);
|
|
499
527
|
nodes.splice(targetIndex, 1, newConfig);
|
|
500
528
|
this.set('nodes', [...nodes]);
|
|
501
529
|
|
|
502
|
-
this.get
|
|
530
|
+
this.get('stage')?.update({
|
|
503
531
|
config: cloneDeep(newConfig),
|
|
504
532
|
parentId: parent.id,
|
|
505
|
-
root: cloneDeep(
|
|
533
|
+
root: cloneDeep(root),
|
|
506
534
|
});
|
|
507
535
|
|
|
508
536
|
if (newConfig.type === NodeType.PAGE) {
|
|
509
|
-
this.set('page', newConfig);
|
|
537
|
+
this.set('page', newConfig as MPage);
|
|
510
538
|
}
|
|
511
539
|
|
|
512
540
|
this.addModifiedNodeId(newConfig.id);
|
|
@@ -538,8 +566,15 @@ class Editor extends BaseService {
|
|
|
538
566
|
* @returns void
|
|
539
567
|
*/
|
|
540
568
|
public async sort(id1: Id, id2: Id): Promise<void> {
|
|
541
|
-
const
|
|
542
|
-
|
|
569
|
+
const root = this.get('root');
|
|
570
|
+
if (!root) throw new Error('root为空');
|
|
571
|
+
|
|
572
|
+
const node = this.get('node');
|
|
573
|
+
if (!node) throw new Error('当前节点为空');
|
|
574
|
+
|
|
575
|
+
const parent = cloneDeep(toRaw(this.get('parent')));
|
|
576
|
+
if (!parent) throw new Error('父节点为空');
|
|
577
|
+
|
|
543
578
|
const index2 = parent.items.findIndex((node: MNode) => `${node.id}` === `${id2}`);
|
|
544
579
|
// 在 id1 的兄弟组件中若无 id2 则直接 return
|
|
545
580
|
if (index2 < 0) return;
|
|
@@ -550,10 +585,10 @@ class Editor extends BaseService {
|
|
|
550
585
|
await this.update(parent);
|
|
551
586
|
await this.select(node);
|
|
552
587
|
|
|
553
|
-
this.get
|
|
588
|
+
this.get('stage')?.update({
|
|
554
589
|
config: cloneDeep(node),
|
|
555
590
|
parentId: parent.id,
|
|
556
|
-
root: cloneDeep(
|
|
591
|
+
root: cloneDeep(root),
|
|
557
592
|
});
|
|
558
593
|
|
|
559
594
|
this.addModifiedNodeId(parent.id);
|
|
@@ -581,14 +616,14 @@ class Editor extends BaseService {
|
|
|
581
616
|
|
|
582
617
|
if (!Array.isArray(config)) return;
|
|
583
618
|
|
|
584
|
-
const node = this.get
|
|
619
|
+
const node = this.get('node');
|
|
585
620
|
|
|
586
|
-
let parent: MContainer |
|
|
621
|
+
let parent: MContainer | null = null;
|
|
587
622
|
// 粘贴的组件为当前选中组件的副本时,则添加到当前选中组件的父组件中
|
|
588
|
-
if (config.length === 1 && config[0].id === node
|
|
589
|
-
parent = this.get
|
|
590
|
-
if (parent
|
|
591
|
-
parent = this.get
|
|
623
|
+
if (config.length === 1 && config[0].id === node?.id) {
|
|
624
|
+
parent = this.get('parent');
|
|
625
|
+
if (parent?.type === NodeType.ROOT) {
|
|
626
|
+
parent = this.get('page');
|
|
592
627
|
}
|
|
593
628
|
}
|
|
594
629
|
|
|
@@ -615,7 +650,7 @@ class Editor extends BaseService {
|
|
|
615
650
|
|
|
616
651
|
if (!node.style) return config;
|
|
617
652
|
|
|
618
|
-
const stage = this.get
|
|
653
|
+
const stage = this.get('stage');
|
|
619
654
|
const doc = stage?.renderer.contentWindow?.document;
|
|
620
655
|
|
|
621
656
|
if (doc) {
|
|
@@ -638,7 +673,7 @@ class Editor extends BaseService {
|
|
|
638
673
|
*/
|
|
639
674
|
public async alignCenter(config: MNode | MNode[]): Promise<MNode | MNode[]> {
|
|
640
675
|
const nodes = Array.isArray(config) ? config : [config];
|
|
641
|
-
const stage = this.get
|
|
676
|
+
const stage = this.get('stage');
|
|
642
677
|
|
|
643
678
|
const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
|
|
644
679
|
|
|
@@ -658,9 +693,16 @@ class Editor extends BaseService {
|
|
|
658
693
|
* @param offset 偏移量
|
|
659
694
|
*/
|
|
660
695
|
public async moveLayer(offset: number | LayerOffset): Promise<void> {
|
|
661
|
-
const
|
|
662
|
-
|
|
663
|
-
|
|
696
|
+
const root = this.get('root');
|
|
697
|
+
if (!root) throw new Error('root为空');
|
|
698
|
+
|
|
699
|
+
const parent = this.get('parent');
|
|
700
|
+
if (!parent) throw new Error('父节点为空');
|
|
701
|
+
|
|
702
|
+
const node = this.get('node');
|
|
703
|
+
if (!node) throw new Error('当前节点为空');
|
|
704
|
+
|
|
705
|
+
const brothers: MNode[] = parent.items || [];
|
|
664
706
|
const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
|
|
665
707
|
|
|
666
708
|
// 流式布局与绝对定位布局操作的相反的
|
|
@@ -678,10 +720,10 @@ class Editor extends BaseService {
|
|
|
678
720
|
}
|
|
679
721
|
|
|
680
722
|
const grandparent = this.getParentById(parent.id);
|
|
681
|
-
this.get
|
|
723
|
+
this.get('stage')?.update({
|
|
682
724
|
config: cloneDeep(toRaw(parent)),
|
|
683
725
|
parentId: grandparent?.id,
|
|
684
|
-
root: cloneDeep(
|
|
726
|
+
root: cloneDeep(root),
|
|
685
727
|
});
|
|
686
728
|
|
|
687
729
|
this.addModifiedNodeId(parent.id);
|
|
@@ -694,13 +736,12 @@ class Editor extends BaseService {
|
|
|
694
736
|
* @param targetId 容器ID
|
|
695
737
|
*/
|
|
696
738
|
public async moveToContainer(config: MNode, targetId: Id): Promise<MNode | undefined> {
|
|
739
|
+
const root = cloneDeep(this.get('root'));
|
|
697
740
|
const { node, parent } = this.getNodeInfo(config.id, false);
|
|
698
741
|
const target = this.getNodeById(targetId, false) as MContainer;
|
|
699
742
|
|
|
700
|
-
const stage = this.get
|
|
701
|
-
|
|
702
|
-
if (node && parent && stage) {
|
|
703
|
-
const root = cloneDeep(this.get<MApp>('root'));
|
|
743
|
+
const stage = this.get('stage');
|
|
744
|
+
if (root && node && parent && stage) {
|
|
704
745
|
const index = getNodeIndex(node, parent);
|
|
705
746
|
parent.items?.splice(index, 1);
|
|
706
747
|
|
|
@@ -783,7 +824,7 @@ class Editor extends BaseService {
|
|
|
783
824
|
this.set('stage', null);
|
|
784
825
|
this.set('highlightNode', null);
|
|
785
826
|
this.set('modifiedNodeIds', new Map());
|
|
786
|
-
this.set('pageLength',
|
|
827
|
+
this.set('pageLength', 0);
|
|
787
828
|
}
|
|
788
829
|
|
|
789
830
|
public destroy() {
|
|
@@ -793,7 +834,7 @@ class Editor extends BaseService {
|
|
|
793
834
|
}
|
|
794
835
|
|
|
795
836
|
public resetModifiedNodeId() {
|
|
796
|
-
this.get
|
|
837
|
+
this.get('modifiedNodeIds').clear();
|
|
797
838
|
}
|
|
798
839
|
|
|
799
840
|
/**
|
|
@@ -801,15 +842,13 @@ class Editor extends BaseService {
|
|
|
801
842
|
* @returns {CodeBlockDSL | null}
|
|
802
843
|
*/
|
|
803
844
|
public async getCodeDsl(): Promise<CodeBlockDSL | null> {
|
|
804
|
-
const root = this.get
|
|
805
|
-
|
|
806
|
-
return root.codeBlocks || null;
|
|
845
|
+
const root = this.get('root');
|
|
846
|
+
return root?.codeBlocks || null;
|
|
807
847
|
}
|
|
808
848
|
|
|
809
849
|
public getCodeDslSync(): CodeBlockDSL | null {
|
|
810
|
-
const root = this.get
|
|
811
|
-
|
|
812
|
-
return root.codeBlocks || null;
|
|
850
|
+
const root = this.get('root');
|
|
851
|
+
return root?.codeBlocks || null;
|
|
813
852
|
}
|
|
814
853
|
|
|
815
854
|
/**
|
|
@@ -824,16 +863,17 @@ class Editor extends BaseService {
|
|
|
824
863
|
|
|
825
864
|
private addModifiedNodeId(id: Id) {
|
|
826
865
|
if (!this.isHistoryStateChange) {
|
|
827
|
-
this.get
|
|
866
|
+
this.get('modifiedNodeIds').set(id, id);
|
|
828
867
|
}
|
|
829
868
|
}
|
|
830
869
|
|
|
831
870
|
private pushHistoryState() {
|
|
832
871
|
const curNode = cloneDeep(toRaw(this.get('node')));
|
|
833
|
-
|
|
872
|
+
const page = this.get('page');
|
|
873
|
+
if (!this.isHistoryStateChange && curNode && page) {
|
|
834
874
|
historyService.push({
|
|
835
|
-
data: cloneDeep(toRaw(
|
|
836
|
-
modifiedNodeIds: this.get
|
|
875
|
+
data: cloneDeep(toRaw(page)),
|
|
876
|
+
modifiedNodeIds: this.get('modifiedNodeIds'),
|
|
837
877
|
nodeId: curNode.id,
|
|
838
878
|
});
|
|
839
879
|
}
|
|
@@ -849,7 +889,7 @@ class Editor extends BaseService {
|
|
|
849
889
|
setTimeout(async () => {
|
|
850
890
|
if (!value.nodeId) return;
|
|
851
891
|
await this.select(value.nodeId);
|
|
852
|
-
this.get
|
|
892
|
+
this.get('stage')?.select(value.nodeId);
|
|
853
893
|
}, 0);
|
|
854
894
|
}
|
|
855
895
|
|
package/src/services/events.ts
CHANGED
|
@@ -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.
|
package/src/services/history.ts
CHANGED
|
@@ -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.
|
package/src/services/props.ts
CHANGED
|
@@ -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.
|
package/src/services/ui.ts
CHANGED
|
@@ -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.
|
|
@@ -18,8 +18,6 @@
|
|
|
18
18
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
20
|
|
|
21
|
-
import type StageCore from '@tmagic/stage';
|
|
22
|
-
|
|
23
21
|
import editorService from '../services/editor';
|
|
24
22
|
import type { StageRect, UiState } from '../type';
|
|
25
23
|
|
|
@@ -53,8 +51,8 @@ class Ui extends BaseService {
|
|
|
53
51
|
super(['zoom', 'calcZoom']);
|
|
54
52
|
}
|
|
55
53
|
|
|
56
|
-
public set<T
|
|
57
|
-
const mask = editorService.get
|
|
54
|
+
public set<K extends keyof UiState, T extends UiState[K]>(name: K, value: T) {
|
|
55
|
+
const mask = editorService.get('stage')?.mask;
|
|
58
56
|
|
|
59
57
|
if (name === 'stageRect') {
|
|
60
58
|
this.setStageRect(value as unknown as StageRect);
|
|
@@ -69,16 +67,16 @@ class Ui extends BaseService {
|
|
|
69
67
|
mask?.showRule(value as unknown as boolean);
|
|
70
68
|
}
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
state[name] = value;
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
public get<
|
|
76
|
-
return
|
|
73
|
+
public get<K extends keyof UiState>(name: K) {
|
|
74
|
+
return state[name];
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
public async zoom(zoom: number) {
|
|
80
|
-
this.set('zoom', (this.get
|
|
81
|
-
if (this.get
|
|
78
|
+
this.set('zoom', (this.get('zoom') * 100 + zoom * 100) / 100);
|
|
79
|
+
if (this.get('zoom') < 0.1) this.set('zoom', 0.1);
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
public async calcZoom() {
|
package/src/type.ts
CHANGED
|
@@ -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.
|
|
@@ -82,6 +82,8 @@ export interface StoreState {
|
|
|
82
82
|
pageLength: number;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
export type StoreStateKey = keyof StoreState;
|
|
86
|
+
|
|
85
87
|
export interface PropsState {
|
|
86
88
|
propsConfigMap: Record<string, FormConfig>;
|
|
87
89
|
propsValueMap: Record<string, MNode>;
|
|
@@ -138,9 +140,9 @@ export interface UiState {
|
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
export interface EditorNodeInfo {
|
|
141
|
-
node
|
|
142
|
-
parent
|
|
143
|
-
page
|
|
143
|
+
node: MNode | null;
|
|
144
|
+
parent: MContainer | null;
|
|
145
|
+
page: MPage | null;
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
export interface AddMNode {
|
|
@@ -333,8 +335,6 @@ export type CodeState = {
|
|
|
333
335
|
id: Id;
|
|
334
336
|
/** 代码块是否可编辑 */
|
|
335
337
|
editable: boolean;
|
|
336
|
-
/** 代码编辑面板的展示模式 */
|
|
337
|
-
mode: CodeEditorMode;
|
|
338
338
|
/** list模式下左侧展示的代码列表 */
|
|
339
339
|
combineIds: string[];
|
|
340
340
|
/** 为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除) */
|
|
@@ -357,13 +357,6 @@ export type CodeRelation = {
|
|
|
357
357
|
};
|
|
358
358
|
};
|
|
359
359
|
|
|
360
|
-
export enum CodeEditorMode {
|
|
361
|
-
/** 左侧菜单,右侧代码 */
|
|
362
|
-
LIST = 'list',
|
|
363
|
-
/** 全屏代码 */
|
|
364
|
-
EDITOR = 'editor',
|
|
365
|
-
}
|
|
366
|
-
|
|
367
360
|
export interface CodeDslItem {
|
|
368
361
|
/** 代码块id */
|
|
369
362
|
id: Id;
|
|
@@ -404,6 +397,7 @@ export interface CodeParamStatement {
|
|
|
404
397
|
name: string;
|
|
405
398
|
/** 参数类型 */
|
|
406
399
|
type?: string;
|
|
400
|
+
[key: string]: any;
|
|
407
401
|
}
|
|
408
402
|
|
|
409
403
|
export interface StepValue {
|
package/src/utils/config.ts
CHANGED
|
@@ -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.
|
package/src/utils/editor.ts
CHANGED
|
@@ -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.
|
|
@@ -110,10 +110,16 @@ const getMiddleTop = (node: MNode, parentNode: MNode, stage: StageCore | null) =
|
|
|
110
110
|
|
|
111
111
|
export const getInitPositionStyle = (style: Record<string, any> = {}, layout: Layout) => {
|
|
112
112
|
if (layout === Layout.ABSOLUTE) {
|
|
113
|
-
|
|
113
|
+
const newStyle: Record<string, any> = {
|
|
114
114
|
...style,
|
|
115
115
|
position: 'absolute',
|
|
116
116
|
};
|
|
117
|
+
|
|
118
|
+
if (typeof newStyle.left === 'undefined' && typeof newStyle.right === 'undefined') {
|
|
119
|
+
newStyle.left = 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return newStyle;
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
if (layout === Layout.RELATIVE) {
|