@tmagic/editor 1.7.14-beta.3 → 1.8.0-beta.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.
Files changed (35) hide show
  1. package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +11 -2
  2. package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +8 -2
  3. package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +10 -2
  4. package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +3 -1
  5. package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +10 -2
  6. package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +16 -3
  7. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +10 -2
  8. package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +14 -2
  9. package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +10 -2
  10. package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +10 -2
  11. package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  12. package/dist/es/layouts/sidebar/layer/use-node-status.js +37 -3
  13. package/dist/es/services/editor.js +58 -27
  14. package/dist/es/style.css +15 -14
  15. package/dist/es/utils/editor.js +1 -1
  16. package/dist/style.css +15 -14
  17. package/dist/tmagic-editor.umd.cjs +199 -52
  18. package/package.json +7 -7
  19. package/src/fields/DataSourceFieldSelect/Index.vue +8 -1
  20. package/src/fields/StyleSetter/Index.vue +6 -0
  21. package/src/fields/StyleSetter/components/Border.vue +15 -1
  22. package/src/fields/StyleSetter/components/Box.vue +2 -0
  23. package/src/fields/StyleSetter/pro/Background.vue +15 -1
  24. package/src/fields/StyleSetter/pro/Border.vue +24 -2
  25. package/src/fields/StyleSetter/pro/Font.vue +15 -1
  26. package/src/fields/StyleSetter/pro/Layout.vue +17 -1
  27. package/src/fields/StyleSetter/pro/Position.vue +15 -1
  28. package/src/fields/StyleSetter/pro/Transform.vue +15 -1
  29. package/src/layouts/props-panel/FormPanel.vue +1 -1
  30. package/src/layouts/sidebar/layer/use-node-status.ts +55 -6
  31. package/src/services/editor.ts +74 -43
  32. package/src/theme/props-panel.scss +20 -20
  33. package/src/type.ts +10 -0
  34. package/src/utils/editor.ts +4 -1
  35. package/types/index.d.ts +31 -22
@@ -95,6 +95,10 @@ var Index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
95
95
  emit("change", [dsId], eventData);
96
96
  }
97
97
  };
98
+ const onToggleDataSourceFieldSelectHandler = () => {
99
+ if (props.disabled || mForm?.isCompare) return;
100
+ showDataSourceFieldSelect.value = !showDataSourceFieldSelect.value;
101
+ };
98
102
  return (_ctx, _cache) => {
99
103
  return openBlock(), createElementBlock("div", _hoisted_1, [!disabledDataSource.value && (showDataSourceFieldSelect.value || !__props.config.fieldConfig) ? (openBlock(), createBlock(FieldSelect_default, {
100
104
  key: 0,
@@ -144,11 +148,16 @@ var Index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
144
148
  default: withCtx(() => [createVNode(unref(TMagicButton), {
145
149
  type: showDataSourceFieldSelect.value ? "primary" : "default",
146
150
  size: __props.size,
147
- onClick: _cache[0] || (_cache[0] = ($event) => showDataSourceFieldSelect.value = !showDataSourceFieldSelect.value)
151
+ disabled: __props.disabled || unref(mForm)?.isCompare,
152
+ onClick: onToggleDataSourceFieldSelectHandler
148
153
  }, {
149
154
  default: withCtx(() => [createVNode(Icon_default, { icon: unref(Coin) }, null, 8, ["icon"])]),
150
155
  _: 1
151
- }, 8, ["type", "size"])]),
156
+ }, 8, [
157
+ "type",
158
+ "size",
159
+ "disabled"
160
+ ])]),
152
161
  _: 1
153
162
  }, 8, ["disabled"])) : createCommentVNode("v-if", true)]);
154
163
  };
@@ -24,7 +24,7 @@ var Index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
24
24
  lastValues: {},
25
25
  isCompare: { type: Boolean }
26
26
  },
27
- emits: ["change"],
27
+ emits: ["change", "addDiffCount"],
28
28
  setup(__props, { emit: __emit }) {
29
29
  const props = __props;
30
30
  const emit = __emit;
@@ -63,6 +63,7 @@ var Index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
63
63
  });
64
64
  emit("change", v, eventData);
65
65
  };
66
+ const onAddDiffCount = () => emit("addDiffCount");
66
67
  return (_ctx, _cache) => {
67
68
  return openBlock(), createBlock(unref(TMagicCollapse), {
68
69
  class: "m-fields-style-setter",
@@ -78,11 +79,16 @@ var Index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCo
78
79
  default: withCtx(() => [item.component ? (openBlock(), createBlock(resolveDynamicComponent(item.component), {
79
80
  key: 0,
80
81
  values: __props.model[__props.name],
82
+ "last-values": __props.lastValues?.[__props.name],
83
+ "is-compare": __props.isCompare,
81
84
  size: __props.size,
82
85
  disabled: __props.disabled,
83
- onChange: change
86
+ onChange: change,
87
+ onAddDiffCount
84
88
  }, null, 40, [
85
89
  "values",
90
+ "last-values",
91
+ "is-compare",
86
92
  "size",
87
93
  "disabled"
88
94
  ])) : createCommentVNode("v-if", true)]),
@@ -11,10 +11,12 @@ var Border_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
11
11
  __name: "Border",
12
12
  props: {
13
13
  model: {},
14
+ lastValues: {},
15
+ isCompare: { type: Boolean },
14
16
  disabled: { type: Boolean },
15
17
  size: {}
16
18
  },
17
- emits: ["change"],
19
+ emits: ["change", "addDiffCount"],
18
20
  setup(__props, { emit: __emit }) {
19
21
  const direction = ref("");
20
22
  const config = computed(() => defineFormItem({ items: [
@@ -57,6 +59,7 @@ var Border_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
57
59
  emit("change", record.value, { modifyKey: record.propPath });
58
60
  });
59
61
  };
62
+ const onAddDiffCount = () => emit("addDiffCount");
60
63
  return (_ctx, _cache) => {
61
64
  return openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("div", _hoisted_2, [
62
65
  createElementVNode("div", _hoisted_3, [createElementVNode("div", {
@@ -84,12 +87,17 @@ var Border_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
84
87
  ]), createElementVNode("div", _hoisted_6, [createVNode(unref(MContainer), {
85
88
  config: config.value,
86
89
  model: __props.model,
90
+ "last-values": __props.lastValues,
91
+ "is-compare": __props.isCompare,
87
92
  size: __props.size,
88
93
  disabled: __props.disabled,
89
- onChange: change
94
+ onChange: change,
95
+ onAddDiffCount
90
96
  }, null, 8, [
91
97
  "config",
92
98
  "model",
99
+ "last-values",
100
+ "is-compare",
93
101
  "size",
94
102
  "disabled"
95
103
  ])])]);
@@ -17,7 +17,9 @@ var Box_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
17
17
  props: {
18
18
  disabled: { type: Boolean },
19
19
  size: {},
20
- model: {}
20
+ model: {},
21
+ lastValues: {},
22
+ isCompare: { type: Boolean }
21
23
  },
22
24
  emits: ["change"],
23
25
  setup(__props, { emit: __emit }) {
@@ -10,10 +10,12 @@ var Background_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
10
10
  __name: "Background",
11
11
  props: {
12
12
  values: {},
13
+ lastValues: {},
14
+ isCompare: { type: Boolean },
13
15
  disabled: { type: Boolean },
14
16
  size: {}
15
17
  },
16
- emits: ["change"],
18
+ emits: ["change", "addDiffCount"],
17
19
  setup(__props, { emit: __emit }) {
18
20
  const emit = __emit;
19
21
  const config = defineFormItem({ items: [
@@ -95,16 +97,22 @@ var Background_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
95
97
  const change = (value, eventData) => {
96
98
  emit("change", value, eventData);
97
99
  };
100
+ const onAddDiffCount = () => emit("addDiffCount");
98
101
  return (_ctx, _cache) => {
99
102
  return openBlock(), createBlock(unref(MContainer), {
100
103
  config: unref(config),
101
104
  model: __props.values,
105
+ "last-values": __props.lastValues,
106
+ "is-compare": __props.isCompare,
102
107
  size: __props.size,
103
108
  disabled: __props.disabled,
104
- onChange: change
109
+ onChange: change,
110
+ onAddDiffCount
105
111
  }, null, 8, [
106
112
  "config",
107
113
  "model",
114
+ "last-values",
115
+ "is-compare",
108
116
  "size",
109
117
  "disabled"
110
118
  ]);
@@ -6,10 +6,12 @@ var Border_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
6
6
  __name: "Border",
7
7
  props: {
8
8
  values: {},
9
+ lastValues: {},
10
+ isCompare: { type: Boolean },
9
11
  disabled: { type: Boolean },
10
12
  size: {}
11
13
  },
12
- emits: ["change"],
14
+ emits: ["change", "addDiffCount"],
13
15
  setup(__props, { emit: __emit }) {
14
16
  const emit = __emit;
15
17
  const config = defineFormItem({ items: [{
@@ -22,25 +24,36 @@ var Border_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
22
24
  const change = (value, eventData) => {
23
25
  emit("change", value, eventData);
24
26
  };
27
+ const onAddDiffCount = () => emit("addDiffCount");
25
28
  return (_ctx, _cache) => {
26
29
  return openBlock(), createElementBlock(Fragment, null, [createVNode(unref(MContainer), {
27
30
  config: unref(config),
28
31
  model: __props.values,
32
+ "last-values": __props.lastValues,
33
+ "is-compare": __props.isCompare,
29
34
  size: __props.size,
30
35
  disabled: __props.disabled,
31
- onChange: change
36
+ onChange: change,
37
+ onAddDiffCount
32
38
  }, null, 8, [
33
39
  "config",
34
40
  "model",
41
+ "last-values",
42
+ "is-compare",
35
43
  "size",
36
44
  "disabled"
37
45
  ]), createVNode(Border_default, {
38
46
  model: __props.values,
47
+ "last-values": __props.lastValues,
48
+ "is-compare": __props.isCompare,
39
49
  size: __props.size,
40
50
  disabled: __props.disabled,
41
- onChange: change
51
+ onChange: change,
52
+ onAddDiffCount
42
53
  }, null, 8, [
43
54
  "model",
55
+ "last-values",
56
+ "is-compare",
44
57
  "size",
45
58
  "disabled"
46
59
  ])], 64);
@@ -8,10 +8,12 @@ var Font_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
8
8
  __name: "Font",
9
9
  props: {
10
10
  values: {},
11
+ lastValues: {},
12
+ isCompare: { type: Boolean },
11
13
  disabled: { type: Boolean },
12
14
  size: {}
13
15
  },
14
- emits: ["change"],
16
+ emits: ["change", "addDiffCount"],
15
17
  setup(__props, { emit: __emit }) {
16
18
  const emit = __emit;
17
19
  const config = defineFormItem({ items: [
@@ -79,16 +81,22 @@ var Font_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
79
81
  const change = (value, eventData) => {
80
82
  emit("change", value, eventData);
81
83
  };
84
+ const onAddDiffCount = () => emit("addDiffCount");
82
85
  return (_ctx, _cache) => {
83
86
  return openBlock(), createBlock(unref(MContainer), {
84
87
  config: unref(config),
85
88
  model: __props.values,
89
+ "last-values": __props.lastValues,
90
+ "is-compare": __props.isCompare,
86
91
  size: __props.size,
87
92
  disabled: __props.disabled,
88
- onChange: change
93
+ onChange: change,
94
+ onAddDiffCount
89
95
  }, null, 8, [
90
96
  "config",
91
97
  "model",
98
+ "last-values",
99
+ "is-compare",
92
100
  "size",
93
101
  "disabled"
94
102
  ]);
@@ -20,10 +20,12 @@ var Layout_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
20
20
  __name: "Layout",
21
21
  props: {
22
22
  values: {},
23
+ lastValues: {},
24
+ isCompare: { type: Boolean },
23
25
  disabled: { type: Boolean },
24
26
  size: {}
25
27
  },
26
- emits: ["change"],
28
+ emits: ["change", "addDiffCount"],
27
29
  setup(__props, { emit: __emit }) {
28
30
  const emit = __emit;
29
31
  const config = defineFormItem({ items: [
@@ -259,25 +261,35 @@ var Layout_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineC
259
261
  const change = (value, eventData) => {
260
262
  emit("change", value, eventData);
261
263
  };
264
+ const onAddDiffCount = () => emit("addDiffCount");
262
265
  return (_ctx, _cache) => {
263
266
  return openBlock(), createElementBlock(Fragment, null, [createVNode(unref(MContainer), {
264
267
  config: unref(config),
265
268
  model: __props.values,
269
+ "last-values": __props.lastValues,
270
+ "is-compare": __props.isCompare,
266
271
  size: __props.size,
267
272
  disabled: __props.disabled,
268
- onChange: change
273
+ onChange: change,
274
+ onAddDiffCount
269
275
  }, null, 8, [
270
276
  "config",
271
277
  "model",
278
+ "last-values",
279
+ "is-compare",
272
280
  "size",
273
281
  "disabled"
274
282
  ]), withDirectives(createVNode(Box_default, {
275
283
  model: __props.values,
284
+ "last-values": __props.lastValues,
285
+ "is-compare": __props.isCompare,
276
286
  size: __props.size,
277
287
  disabled: __props.disabled,
278
288
  onChange: change
279
289
  }, null, 8, [
280
290
  "model",
291
+ "last-values",
292
+ "is-compare",
281
293
  "size",
282
294
  "disabled"
283
295
  ]), [[vShow, !["fixed", "absolute"].includes(__props.values.position)]])], 64);
@@ -5,10 +5,12 @@ var Position_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defin
5
5
  __name: "Position",
6
6
  props: {
7
7
  values: {},
8
+ lastValues: {},
9
+ isCompare: { type: Boolean },
8
10
  disabled: { type: Boolean },
9
11
  size: {}
10
12
  },
11
- emits: ["change"],
13
+ emits: ["change", "addDiffCount"],
12
14
  setup(__props, { emit: __emit }) {
13
15
  const props = __props;
14
16
  const emit = __emit;
@@ -76,16 +78,22 @@ var Position_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defin
76
78
  const change = (value, eventData) => {
77
79
  emit("change", value, eventData);
78
80
  };
81
+ const onAddDiffCount = () => emit("addDiffCount");
79
82
  return (_ctx, _cache) => {
80
83
  return openBlock(), createBlock(unref(MContainer), {
81
84
  config: unref(config),
82
85
  model: __props.values,
86
+ "last-values": __props.lastValues,
87
+ "is-compare": __props.isCompare,
83
88
  size: __props.size,
84
89
  disabled: __props.disabled,
85
- onChange: change
90
+ onChange: change,
91
+ onAddDiffCount
86
92
  }, null, 8, [
87
93
  "config",
88
94
  "model",
95
+ "last-values",
96
+ "is-compare",
89
97
  "size",
90
98
  "disabled"
91
99
  ]);
@@ -5,10 +5,12 @@ var Transform_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
5
5
  __name: "Transform",
6
6
  props: {
7
7
  values: {},
8
+ lastValues: {},
9
+ isCompare: { type: Boolean },
8
10
  disabled: { type: Boolean },
9
11
  size: {}
10
12
  },
11
- emits: ["change"],
13
+ emits: ["change", "addDiffCount"],
12
14
  setup(__props, { emit: __emit }) {
13
15
  const emit = __emit;
14
16
  const config = defineFormItem({ items: [{
@@ -34,16 +36,22 @@ var Transform_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
34
36
  const change = (value, eventData) => {
35
37
  emit("change", value, eventData);
36
38
  };
39
+ const onAddDiffCount = () => emit("addDiffCount");
37
40
  return (_ctx, _cache) => {
38
41
  return openBlock(), createBlock(unref(MContainer), {
39
42
  config: unref(config),
40
43
  model: __props.values,
44
+ "last-values": __props.lastValues,
45
+ "is-compare": __props.isCompare,
41
46
  size: __props.size,
42
47
  disabled: __props.disabled,
43
- onChange: change
48
+ onChange: change,
49
+ onAddDiffCount
44
50
  }, null, 8, [
45
51
  "config",
46
52
  "model",
53
+ "last-values",
54
+ "is-compare",
47
55
  "size",
48
56
  "disabled"
49
57
  ]);
@@ -74,7 +74,7 @@ var FormPanel_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defi
74
74
  createVNode(unref(TMagicScrollbar), null, {
75
75
  default: withCtx(() => [createVNode(unref(MForm), {
76
76
  ref: "configForm",
77
- class: normalizeClass(propsPanelSize.value),
77
+ class: normalizeClass([propsPanelSize.value, "m-editor-props-form-panel-form"]),
78
78
  "popper-class": `m-editor-props-panel-popper ${propsPanelSize.value}`,
79
79
  "label-width": __props.labelWidth,
80
80
  "label-position": __props.labelPosition,
@@ -27,10 +27,43 @@ var useNodeStatus = ({ editorService }) => {
27
27
  const nodeStatusMaps = ref(/* @__PURE__ */ new Map());
28
28
  /** 当前页面的节点状态 */
29
29
  const nodeStatusMap = computed(() => page.value ? nodeStatusMaps.value.get(page.value.id) : /* @__PURE__ */ new Map());
30
- watch(() => page.value?.id, (pageId) => {
31
- if (!pageId) return;
32
- nodeStatusMaps.value.set(pageId, createPageNodeStatus(page.value, nodeStatusMaps.value.get(pageId)));
30
+ watch(page, (newPage) => {
31
+ if (!newPage?.id) return;
32
+ nodeStatusMaps.value.set(newPage.id, createPageNodeStatus(newPage, nodeStatusMaps.value.get(newPage.id)));
33
33
  }, { immediate: true });
34
+ /**
35
+ * root 整体被替换时(外部 modelValue 变化、历史版本恢复、套件编辑模式进入/退出等):
36
+ * - 仅 watch page 引用还不够,因为 root-change 同步触发时 page 还是旧引用,
37
+ * 等 initService 的异步 IIFE 跑完 editorService.select(...) 后 page 才会
38
+ * 被替换为新 dsl 中的 page;此时上面的 page watch 才会触发重建。
39
+ * - 但若直接同步清空 nodeStatusMaps,会让 nodeStatusMap (computed) 立刻变
40
+ * undefined。上层 LayerPanel 用 `v-if="page && nodeStatusMap"` 渲染组件树,
41
+ * 会瞬间销毁整个面板;若紧接着的异步 select 链路(套件退出等场景)发生
42
+ * 竞态、page 引用未变 / 解析失败,watch(page) 不触发重建,组件树就再也回
43
+ * 不来。
44
+ * - 此外「污染」问题本质来自 createPageNodeStatus 用旧 status 作为新节点
45
+ * initial 值:只要新 root 的 page 是新引用,watch(page) 会触发重建,重建
46
+ * 时基于新 page.items 生成的 map 只会包含新节点 id;旧节点 id 即便残留在
47
+ * initialLayerNodeStatus 中也不会被写入新 map。真正的风险只有「同一 page
48
+ * id 下,新旧 dsl 都存在同一节点 id 但其实是不同节点」这种极端情况——这
49
+ * 在常规业务中不会发生(id 是 uuid)。
50
+ *
51
+ * 综合:root-change 时仅清理「在新 root 中已不存在的 page id」对应缓存,
52
+ * 保留仍然有效的 page status 不动;既避免 v-if 闪断,也不会保留无关 page 的
53
+ * 死缓存。同 page id 的重建交给下方 watch(page) 触发。
54
+ */
55
+ const rootChangeHandler = (value) => {
56
+ if (!value) {
57
+ nodeStatusMaps.value = /* @__PURE__ */ new Map();
58
+ return;
59
+ }
60
+ const validPageIds = /* @__PURE__ */ new Set();
61
+ (value.items || []).forEach((p) => {
62
+ if (p?.id !== void 0) validPageIds.add(p.id);
63
+ });
64
+ for (const cachedPageId of Array.from(nodeStatusMaps.value.keys())) if (!validPageIds.has(cachedPageId)) nodeStatusMaps.value.delete(cachedPageId);
65
+ };
66
+ editorService.on("root-change", rootChangeHandler);
34
67
  watch(nodes, (nodes) => {
35
68
  if (!nodeStatusMap.value) return;
36
69
  for (const [id, status] of nodeStatusMap.value.entries()) {
@@ -63,6 +96,7 @@ var useNodeStatus = ({ editorService }) => {
63
96
  };
64
97
  editorService.on("remove", removeHandler);
65
98
  onBeforeUnmount(() => {
99
+ editorService.off("root-change", rootChangeHandler);
66
100
  editorService.off("remove", removeHandler);
67
101
  editorService.off("add", addHandler);
68
102
  });
@@ -121,6 +121,19 @@ var Editor = class extends BaseService_default {
121
121
  return parent;
122
122
  }
123
123
  /**
124
+ * 判断给定节点是否位于非当前页面(即选中该节点将会引起当前页面切换)
125
+ * @param node 节点
126
+ * @returns true 表示该节点位于非当前页面
127
+ */
128
+ isOnDifferentPage(node) {
129
+ const currentPageId = this.get("page")?.id;
130
+ if (currentPageId === void 0 || currentPageId === null) return false;
131
+ if (isPage(node) || isPageFragment(node)) return `${node.id}` !== `${currentPageId}`;
132
+ const nodePage = this.getNodeInfo(node.id, false).page;
133
+ if (!nodePage) return false;
134
+ return `${nodePage.id}` !== `${currentPageId}`;
135
+ }
136
+ /**
124
137
  * 只有容器拥有布局
125
138
  */
126
139
  async getLayout(parent, node) {
@@ -241,11 +254,12 @@ var Editor = class extends BaseService_default {
241
254
  * @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
242
255
  * @param options 可选配置
243
256
  * @param options.doNotSelect 添加后是否不更新当前选中节点(默认 false,添加后会选中新增的节点)
257
+ * @param options.doNotSwitchPage 添加后是否不切换当前页面(默认 false;新增页面 / 跨页新增时为 true 会跳过会引发页面切换的选中操作)
244
258
  * @returns 添加后的节点
245
259
  */
246
260
  async add(addNode, parent, options) {
247
261
  const safeParentNode = safeParent(parent);
248
- const { doNotSelect = false } = safeOptions(options);
262
+ const { doNotSelect = false, doNotSwitchPage = false } = safeOptions(options);
249
263
  this.captureSelectionBeforeOp();
250
264
  const stage = this.get("stage");
251
265
  const addNodes = [];
@@ -262,16 +276,19 @@ var Editor = class extends BaseService_default {
262
276
  return this.doAdd(node, parentNode);
263
277
  }));
264
278
  if (newNodes.length > 1) {
265
- if (!doNotSelect) {
279
+ const wouldSwitchPage = newNodes.some((n) => this.isOnDifferentPage(n));
280
+ if (!doNotSelect && !(doNotSwitchPage && wouldSwitchPage)) {
266
281
  const newNodeIds = newNodes.map((node) => node.id);
267
282
  stage?.multiSelect(newNodeIds);
268
283
  await this.multiSelect(newNodeIds);
269
284
  }
270
285
  } else {
271
- if (!doNotSelect) await this.select(newNodes[0]);
286
+ const wouldSwitchPage = this.isOnDifferentPage(newNodes[0]);
287
+ const skipSelect = doNotSelect || doNotSwitchPage && wouldSwitchPage;
288
+ if (!skipSelect) await this.select(newNodes[0]);
272
289
  if (isPage(newNodes[0])) this.state.pageLength += 1;
273
290
  else if (isPageFragment(newNodes[0])) this.state.pageFragmentLength += 1;
274
- else if (!doNotSelect) stage?.select(newNodes[0].id);
291
+ else if (!skipSelect) stage?.select(newNodes[0].id);
275
292
  }
276
293
  if (!(isPage(newNodes[0]) || isPageFragment(newNodes[0]))) {
277
294
  const pageForOp = this.getNodeInfo(newNodes[0].id, false).page;
@@ -291,7 +308,7 @@ var Editor = class extends BaseService_default {
291
308
  return Array.isArray(addNode) ? newNodes : newNodes[0];
292
309
  }
293
310
  async doRemove(node, options) {
294
- const { doNotSelect = false } = safeOptions(options);
311
+ const { doNotSelect = false, doNotSwitchPage = false } = safeOptions(options);
295
312
  const root = this.get("root");
296
313
  if (!root) throw new Error("root不能为空");
297
314
  const { parent, node: curNode } = this.getNodeInfo(node.id, false);
@@ -305,18 +322,16 @@ var Editor = class extends BaseService_default {
305
322
  parentId: parent.id,
306
323
  root: cloneDeep(root)
307
324
  });
308
- if (doNotSelect) {
309
- const selectedNodes = this.get("nodes");
310
- const removedSelectedIndex = selectedNodes.findIndex((n) => `${n.id}` === `${node.id}`);
311
- if (removedSelectedIndex !== -1) {
312
- const nextSelected = [...selectedNodes];
313
- nextSelected.splice(removedSelectedIndex, 1);
314
- this.set("nodes", nextSelected);
315
- }
316
- if (isPage(node) || isPageFragment(node)) {
317
- const currentPage = this.get("page");
318
- if (currentPage && `${currentPage.id}` === `${node.id}`) this.set("page", null);
319
- }
325
+ const selectedNodes = this.get("nodes");
326
+ const removedSelectedIndex = selectedNodes.findIndex((n) => `${n.id}` === `${node.id}`);
327
+ if (removedSelectedIndex !== -1) {
328
+ const nextSelected = [...selectedNodes];
329
+ nextSelected.splice(removedSelectedIndex, 1);
330
+ this.set("nodes", nextSelected);
331
+ }
332
+ if (isPage(node) || isPageFragment(node)) {
333
+ const currentPage = this.get("page");
334
+ if (currentPage && `${currentPage.id}` === `${node.id}`) this.set("page", null);
320
335
  }
321
336
  const selectDefault = async (pages) => {
322
337
  if (pages[0]) {
@@ -330,10 +345,10 @@ var Editor = class extends BaseService_default {
330
345
  const rootItems = root.items || [];
331
346
  if (isPage(node)) {
332
347
  this.state.pageLength -= 1;
333
- if (!doNotSelect) await selectDefault(rootItems);
348
+ if (!doNotSelect && !doNotSwitchPage) await selectDefault(rootItems);
334
349
  } else if (isPageFragment(node)) {
335
350
  this.state.pageFragmentLength -= 1;
336
- if (!doNotSelect) await selectDefault(rootItems);
351
+ if (!doNotSelect && !doNotSwitchPage) await selectDefault(rootItems);
337
352
  } else {
338
353
  if (!doNotSelect) {
339
354
  await this.select(parent);
@@ -351,9 +366,10 @@ var Editor = class extends BaseService_default {
351
366
  * @param {Object} node 要删除的节点或节点集合
352
367
  * @param options 可选配置
353
368
  * @param options.doNotSelect 删除后是否不更新当前选中节点(默认 false,删除后会选中父节点或首个页面)
369
+ * @param options.doNotSwitchPage 删除后是否不切换当前页面(默认 false;删除页面 / 页面片段时为 true 会跳过自动切换到首个剩余页面)
354
370
  */
355
371
  async remove(nodeOrNodeList, options) {
356
- const { doNotSelect = false } = safeOptions(options);
372
+ const { doNotSelect = false, doNotSwitchPage = false } = safeOptions(options);
357
373
  this.captureSelectionBeforeOp();
358
374
  const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
359
375
  const removedItems = [];
@@ -373,7 +389,10 @@ var Editor = class extends BaseService_default {
373
389
  });
374
390
  }
375
391
  }
376
- await Promise.all(nodes.map((node) => this.doRemove(node, { doNotSelect })));
392
+ await Promise.all(nodes.map((node) => this.doRemove(node, {
393
+ doNotSelect,
394
+ doNotSwitchPage
395
+ })));
377
396
  if (removedItems.length > 0 && pageForOp) this.pushOpHistory("remove", { removedItems }, pageForOp);
378
397
  this.emit("remove", nodes);
379
398
  }
@@ -410,7 +429,10 @@ var Editor = class extends BaseService_default {
410
429
  selectedNodes.splice(targetIndex, 1, newConfig);
411
430
  this.set("nodes", [...selectedNodes]);
412
431
  }
413
- if (isPage(newConfig) || isPageFragment(newConfig)) this.set("page", newConfig);
432
+ if (isPage(newConfig) || isPageFragment(newConfig)) {
433
+ const currentPage = this.get("page");
434
+ if (currentPage && `${currentPage.id}` === `${newConfig.id}`) this.set("page", newConfig);
435
+ }
414
436
  this.addModifiedNodeId(newConfig.id);
415
437
  return {
416
438
  oldNode: node,
@@ -451,6 +473,7 @@ var Editor = class extends BaseService_default {
451
473
  * @param id2 组件ID
452
474
  * @param options 可选配置
453
475
  * @param options.doNotSelect 排序后是否不更新当前选中节点(默认 false)
476
+ * @param options.doNotSwitchPage 排序后是否不切换当前页面(排序只发生在同一父节点内,方法内为空操作;保留以与其它 DSL 操作 API 一致)
454
477
  * @returns void
455
478
  */
456
479
  async sort(id1, id2, options) {
@@ -498,10 +521,11 @@ var Editor = class extends BaseService_default {
498
521
  * @param collectorOptions 可选的依赖收集器配置
499
522
  * @param options 可选配置
500
523
  * @param options.doNotSelect 粘贴后是否不更新当前选中节点(默认 false)
524
+ * @param options.doNotSwitchPage 粘贴后是否不切换当前页面(默认 false;跨页粘贴时为 true 会跳过页面切换)
501
525
  * @returns 添加后的组件节点配置
502
526
  */
503
527
  async paste(position = {}, collectorOptions, options) {
504
- const { doNotSelect = false } = safeOptions(options);
528
+ const { doNotSelect = false, doNotSwitchPage = false } = safeOptions(options);
505
529
  const config = storage_default.getItem(COPY_STORAGE_KEY);
506
530
  if (!Array.isArray(config)) return;
507
531
  const node = this.get("node");
@@ -512,7 +536,10 @@ var Editor = class extends BaseService_default {
512
536
  }
513
537
  const pasteConfigs = await this.doPaste(config, position);
514
538
  if (collectorOptions && typeof collectorOptions.isTarget === "function") props_default.replaceRelateId(config, pasteConfigs, collectorOptions);
515
- return this.add(pasteConfigs, parent, { doNotSelect });
539
+ return this.add(pasteConfigs, parent, {
540
+ doNotSelect,
541
+ doNotSwitchPage
542
+ });
516
543
  }
517
544
  async doPaste(config, position = {}) {
518
545
  props_default.clearRelateId();
@@ -535,6 +562,7 @@ var Editor = class extends BaseService_default {
535
562
  * @param config 组件节点配置
536
563
  * @param options 可选配置
537
564
  * @param options.doNotSelect 居中后是否不更新当前选中节点(默认 false)
565
+ * @param options.doNotSwitchPage 居中后是否不切换当前页面(居中只更新节点 style,方法内为空操作;保留以与其它 DSL 操作 API 一致)
538
566
  * @returns 当前组件节点配置
539
567
  */
540
568
  async alignCenter(config, options) {
@@ -590,9 +618,10 @@ var Editor = class extends BaseService_default {
590
618
  * @param targetId 容器ID
591
619
  * @param options 可选配置
592
620
  * @param options.doNotSelect 移动后是否不更新当前选中节点(默认 false)
621
+ * @param options.doNotSwitchPage 移动后是否不切换当前页面(默认 false;目标容器位于其它页面时为 true 会跳过自动选中以避免页面切换)
593
622
  */
594
623
  async moveToContainer(config, targetId, options) {
595
- const { doNotSelect = false } = safeOptions(options);
624
+ const { doNotSelect = false, doNotSwitchPage = false } = safeOptions(options);
596
625
  this.captureSelectionBeforeOp();
597
626
  const root = this.get("root");
598
627
  const { node, parent, page: pageForOp } = this.getNodeInfo(config.id, false);
@@ -614,14 +643,16 @@ var Editor = class extends BaseService_default {
614
643
  });
615
644
  newConfig.style = getInitPositionStyle(newConfig.style, layout);
616
645
  target.items.push(newConfig);
617
- if (!doNotSelect) await stage.select(targetId);
646
+ const targetWouldSwitchPage = this.isOnDifferentPage(target);
647
+ const skipSelect = doNotSelect || doNotSwitchPage && targetWouldSwitchPage;
648
+ if (!skipSelect) await stage.select(targetId);
618
649
  const targetParent = this.getParentById(target.id);
619
650
  await stage.update({
620
651
  config: cloneDeep(target),
621
652
  parentId: targetParent?.id,
622
653
  root: cloneDeep(root)
623
654
  });
624
- if (!doNotSelect) {
655
+ if (!skipSelect) {
625
656
  await this.select(newConfig);
626
657
  stage.select(newConfig.id);
627
658
  }