@tmagic/editor 1.8.0-beta.3 → 1.8.0-beta.4

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 (66) hide show
  1. package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +15 -1
  2. package/dist/es/hooks/use-code-block-edit.js +6 -3
  3. package/dist/es/hooks/use-data-source-edit.js +5 -2
  4. package/dist/es/hooks/use-stage.js +6 -3
  5. package/dist/es/layouts/NavMenu.vue_vue_type_script_setup_true_lang.js +1 -1
  6. package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +6 -2
  7. package/dist/es/layouts/history-list/BucketTab.vue_vue_type_script_setup_true_lang.js +3 -0
  8. package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +42 -29
  9. package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +4 -2
  10. package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +5 -1
  11. package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +5 -2
  12. package/dist/es/layouts/history-list/composables.js +53 -1
  13. package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +5 -1
  14. package/dist/es/layouts/sidebar/ComponentListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  15. package/dist/es/layouts/sidebar/code-block/CodeBlockList.vue_vue_type_script_setup_true_lang.js +3 -3
  16. package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  17. package/dist/es/layouts/sidebar/code-block/useContentMenu.js +1 -1
  18. package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  19. package/dist/es/layouts/sidebar/data-source/useContentMenu.js +1 -1
  20. package/dist/es/layouts/sidebar/layer/LayerMenu.vue_vue_type_script_setup_true_lang.js +5 -5
  21. package/dist/es/layouts/sidebar/layer/LayerNodeTool.vue_vue_type_script_setup_true_lang.js +1 -1
  22. package/dist/es/layouts/workspace/viewer/Stage.vue_vue_type_script_setup_true_lang.js +1 -1
  23. package/dist/es/layouts/workspace/viewer/ViewerMenu.vue_vue_type_script_setup_true_lang.js +8 -8
  24. package/dist/es/services/codeBlock.js +25 -10
  25. package/dist/es/services/dataSource.js +24 -10
  26. package/dist/es/services/editor.js +98 -46
  27. package/dist/es/services/history.js +2 -0
  28. package/dist/es/services/keybinding.js +3 -3
  29. package/dist/es/style.css +16 -4
  30. package/dist/es/utils/content-menu.js +17 -9
  31. package/dist/style.css +16 -4
  32. package/dist/tmagic-editor.umd.cjs +343 -144
  33. package/package.json +7 -7
  34. package/src/components/CompareForm.vue +19 -1
  35. package/src/hooks/use-code-block-edit.ts +4 -3
  36. package/src/hooks/use-data-source-edit.ts +2 -2
  37. package/src/hooks/use-stage.ts +3 -3
  38. package/src/layouts/NavMenu.vue +1 -1
  39. package/src/layouts/history-list/Bucket.vue +6 -2
  40. package/src/layouts/history-list/BucketTab.vue +3 -0
  41. package/src/layouts/history-list/GroupRow.vue +20 -3
  42. package/src/layouts/history-list/HistoryDiffDialog.vue +2 -1
  43. package/src/layouts/history-list/HistoryListPanel.vue +4 -0
  44. package/src/layouts/history-list/PageTab.vue +5 -1
  45. package/src/layouts/history-list/composables.ts +60 -0
  46. package/src/layouts/props-panel/PropsPanel.vue +5 -1
  47. package/src/layouts/sidebar/ComponentListPanel.vue +9 -5
  48. package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -5
  49. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +1 -1
  50. package/src/layouts/sidebar/code-block/useContentMenu.ts +1 -1
  51. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -1
  52. package/src/layouts/sidebar/data-source/useContentMenu.ts +1 -1
  53. package/src/layouts/sidebar/layer/LayerMenu.vue +19 -11
  54. package/src/layouts/sidebar/layer/LayerNodeTool.vue +7 -4
  55. package/src/layouts/workspace/viewer/Stage.vue +1 -1
  56. package/src/layouts/workspace/viewer/ViewerMenu.vue +8 -8
  57. package/src/services/codeBlock.ts +33 -9
  58. package/src/services/dataSource.ts +30 -8
  59. package/src/services/editor.ts +111 -34
  60. package/src/services/history.ts +7 -0
  61. package/src/services/keybinding.ts +3 -3
  62. package/src/theme/history-list-panel.scss +15 -1
  63. package/src/theme/props-panel.scss +3 -3
  64. package/src/type.ts +58 -2
  65. package/src/utils/content-menu.ts +18 -9
  66. package/types/index.d.ts +96 -25
@@ -4331,12 +4331,15 @@
4331
4331
  await (0, vue.nextTick)();
4332
4332
  codeBlockEditorRef.value?.show();
4333
4333
  };
4334
- const deleteCode = async (key) => {
4335
- codeBlockService.deleteCodeDslByIds([key]);
4334
+ const deleteCode = async (key, { historySource } = {}) => {
4335
+ codeBlockService.deleteCodeDslByIds([key], { historySource });
4336
4336
  };
4337
4337
  const submitCodeBlockHandler = async (values, eventData) => {
4338
4338
  if (!codeId.value) return;
4339
- await codeBlockService.setCodeDslById(codeId.value, values, { changeRecords: eventData?.changeRecords });
4339
+ await codeBlockService.setCodeDslById(codeId.value, values, {
4340
+ changeRecords: eventData?.changeRecords,
4341
+ historySource: "props"
4342
+ });
4340
4343
  codeBlockEditorRef.value?.hide();
4341
4344
  };
4342
4345
  return {
@@ -5213,6 +5216,7 @@
5213
5216
  newContent: payload.newContent ? cloneDeep$1(payload.newContent) : null,
5214
5217
  changeRecords: payload.changeRecords?.length ? cloneDeep$1(payload.changeRecords) : void 0,
5215
5218
  historyDescription: payload.historyDescription,
5219
+ source: payload.source,
5216
5220
  timestamp: Date.now()
5217
5221
  };
5218
5222
  this.getCodeBlockUndoRedo(codeBlockId).pushElement(step);
@@ -5231,6 +5235,7 @@
5231
5235
  newSchema: payload.newSchema ? cloneDeep$1(payload.newSchema) : null,
5232
5236
  changeRecords: payload.changeRecords?.length ? cloneDeep$1(payload.changeRecords) : void 0,
5233
5237
  historyDescription: payload.historyDescription,
5238
+ source: payload.source,
5234
5239
  timestamp: Date.now()
5235
5240
  };
5236
5241
  this.getDataSourceUndoRedo(dataSourceId).pushElement(step);
@@ -6330,7 +6335,7 @@
6330
6335
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
6331
6336
  * @returns 添加后的节点
6332
6337
  */
6333
- async add(addNode, parent, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription } = {}) {
6338
+ async add(addNode, parent, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
6334
6339
  this.captureSelectionBeforeOp();
6335
6340
  const stage = this.get("stage");
6336
6341
  const addNodes = [];
@@ -6364,16 +6369,21 @@
6364
6369
  if (!((0, _tmagic_utils.isPage)(newNodes[0]) || (0, _tmagic_utils.isPageFragment)(newNodes[0]))) {
6365
6370
  const pageForOp = this.getNodeInfo(newNodes[0].id, false).page;
6366
6371
  if (!doNotPushHistory) this.pushOpHistory("add", {
6367
- nodes: newNodes.map((n) => cloneDeep$1((0, vue.toRaw)(n))),
6368
- parentId: (this.getParentById(newNodes[0].id, false) ?? this.get("root")).id,
6369
- indexMap: Object.fromEntries(newNodes.map((n) => {
6370
- const p = this.getParentById(n.id, false);
6371
- return [n.id, p ? getNodeIndex(n.id, p) : -1];
6372
- }))
6373
- }, {
6374
- name: pageForOp?.name || "",
6375
- id: pageForOp.id
6376
- }, historyDescription);
6372
+ extra: {
6373
+ nodes: newNodes.map((n) => cloneDeep$1((0, vue.toRaw)(n))),
6374
+ parentId: (this.getParentById(newNodes[0].id, false) ?? this.get("root")).id,
6375
+ indexMap: Object.fromEntries(newNodes.map((n) => {
6376
+ const p = this.getParentById(n.id, false);
6377
+ return [n.id, p ? getNodeIndex(n.id, p) : -1];
6378
+ }))
6379
+ },
6380
+ pageData: {
6381
+ name: pageForOp?.name || "",
6382
+ id: pageForOp.id
6383
+ },
6384
+ historyDescription,
6385
+ source: historySource
6386
+ });
6377
6387
  else this.selectionBeforeOp = null;
6378
6388
  }
6379
6389
  this.emit("add", newNodes);
@@ -6440,7 +6450,7 @@
6440
6450
  * @param options.doNotSwitchPage 删除后是否不切换当前页面(默认 false;删除页面 / 页面片段时为 true 会跳过自动切换到首个剩余页面)
6441
6451
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
6442
6452
  */
6443
- async remove(nodeOrNodeList, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription } = {}) {
6453
+ async remove(nodeOrNodeList, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
6444
6454
  this.captureSelectionBeforeOp();
6445
6455
  const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
6446
6456
  const removedItems = [];
@@ -6464,7 +6474,12 @@
6464
6474
  doNotSelect,
6465
6475
  doNotSwitchPage
6466
6476
  })));
6467
- if (removedItems.length > 0 && pageForOp) if (!doNotPushHistory) this.pushOpHistory("remove", { removedItems }, pageForOp, historyDescription);
6477
+ if (removedItems.length > 0 && pageForOp) if (!doNotPushHistory) this.pushOpHistory("remove", {
6478
+ extra: { removedItems },
6479
+ pageData: pageForOp,
6480
+ historyDescription,
6481
+ source: historySource
6482
+ });
6468
6483
  else this.selectionBeforeOp = null;
6469
6484
  this.emit("remove", nodes);
6470
6485
  }
@@ -6525,7 +6540,7 @@
6525
6540
  */
6526
6541
  async update(config, data = {}) {
6527
6542
  this.captureSelectionBeforeOp();
6528
- const { doNotPushHistory = false, changeRecordList, changeRecords, historyDescription } = data;
6543
+ const { doNotPushHistory = false, changeRecordList, changeRecords, historyDescription, historySource } = data;
6529
6544
  const nodes = Array.isArray(config) ? config : [config];
6530
6545
  const updateData = await Promise.all(nodes.map((node, index) => {
6531
6546
  const recordsForNode = changeRecordList ? changeRecordList[index] ?? [] : changeRecords ?? [];
@@ -6534,14 +6549,19 @@
6534
6549
  if (updateData[0].oldNode?.type !== _tmagic_core.NodeType.ROOT) {
6535
6550
  if (this.get("nodes").length) if (!doNotPushHistory) {
6536
6551
  const pageForOp = this.getNodeInfo(nodes[0].id, false).page;
6537
- this.pushOpHistory("update", { updatedItems: updateData.map((d) => ({
6538
- oldNode: cloneDeep$1(d.oldNode),
6539
- newNode: cloneDeep$1((0, vue.toRaw)(d.newNode)),
6540
- changeRecords: d.changeRecords?.length ? cloneDeep$1(d.changeRecords) : void 0
6541
- })) }, {
6542
- name: pageForOp?.name || "",
6543
- id: pageForOp.id
6544
- }, historyDescription);
6552
+ this.pushOpHistory("update", {
6553
+ extra: { updatedItems: updateData.map((d) => ({
6554
+ oldNode: cloneDeep$1(d.oldNode),
6555
+ newNode: cloneDeep$1((0, vue.toRaw)(d.newNode)),
6556
+ changeRecords: d.changeRecords?.length ? cloneDeep$1(d.changeRecords) : void 0
6557
+ })) },
6558
+ pageData: {
6559
+ name: pageForOp?.name || "",
6560
+ id: pageForOp.id
6561
+ },
6562
+ historyDescription,
6563
+ source: historySource
6564
+ });
6545
6565
  } else this.selectionBeforeOp = null;
6546
6566
  }
6547
6567
  this.emit("update", updateData);
@@ -6557,7 +6577,7 @@
6557
6577
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
6558
6578
  * @returns void
6559
6579
  */
6560
- async sort(id1, id2, { doNotSelect = false, doNotPushHistory = false } = {}) {
6580
+ async sort(id1, id2, { doNotSelect = false, doNotPushHistory = false, historySource } = {}) {
6561
6581
  this.captureSelectionBeforeOp();
6562
6582
  const root = this.get("root");
6563
6583
  if (!root) throw new Error("root为空");
@@ -6569,7 +6589,10 @@
6569
6589
  if (index2 < 0) return;
6570
6590
  const index1 = parent.items.findIndex((node) => `${node.id}` === `${id1}`);
6571
6591
  parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
6572
- await this.update(parent, { doNotPushHistory });
6592
+ await this.update(parent, {
6593
+ doNotPushHistory,
6594
+ historySource
6595
+ });
6573
6596
  if (!doNotSelect) await this.select(node);
6574
6597
  this.get("stage")?.update({
6575
6598
  config: cloneDeep$1(node),
@@ -6605,7 +6628,7 @@
6605
6628
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
6606
6629
  * @returns 添加后的组件节点配置
6607
6630
  */
6608
- async paste(position = {}, collectorOptions, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false } = {}) {
6631
+ async paste(position = {}, collectorOptions, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
6609
6632
  const config = storage_default.getItem(COPY_STORAGE_KEY);
6610
6633
  if (!Array.isArray(config)) return;
6611
6634
  const node = this.get("node");
@@ -6619,7 +6642,9 @@
6619
6642
  return this.add(pasteConfigs, parent, {
6620
6643
  doNotSelect,
6621
6644
  doNotSwitchPage,
6622
- doNotPushHistory
6645
+ doNotPushHistory,
6646
+ historyDescription,
6647
+ historySource
6623
6648
  });
6624
6649
  }
6625
6650
  async doPaste(config, position = {}) {
@@ -6647,11 +6672,15 @@
6647
6672
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
6648
6673
  * @returns 当前组件节点配置
6649
6674
  */
6650
- async alignCenter(config, { doNotSelect = false, doNotPushHistory = false } = {}) {
6675
+ async alignCenter(config, { doNotSelect = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
6651
6676
  const nodes = Array.isArray(config) ? config : [config];
6652
6677
  const stage = this.get("stage");
6653
6678
  const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
6654
- const newNode = await this.update(newNodes, { doNotPushHistory });
6679
+ const newNode = await this.update(newNodes, {
6680
+ doNotPushHistory,
6681
+ historyDescription,
6682
+ historySource
6683
+ });
6655
6684
  if (!doNotSelect) if (newNodes.length > 1) await stage?.multiSelect(newNodes.map((node) => node.id));
6656
6685
  else await stage?.select(newNodes[0].id);
6657
6686
  return newNode;
@@ -6662,7 +6691,7 @@
6662
6691
  * @param options 可选配置
6663
6692
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
6664
6693
  */
6665
- async moveLayer(offset, { doNotPushHistory = false } = {}) {
6694
+ async moveLayer(offset, { doNotPushHistory = false, historyDescription, historySource } = {}) {
6666
6695
  this.captureSelectionBeforeOp();
6667
6696
  const root = this.get("root");
6668
6697
  if (!root) throw new Error("root为空");
@@ -6687,12 +6716,17 @@
6687
6716
  this.addModifiedNodeId(parent.id);
6688
6717
  if (!doNotPushHistory) {
6689
6718
  const pageForOp = this.getNodeInfo(node.id, false).page;
6690
- this.pushOpHistory("update", { updatedItems: [{
6691
- oldNode: oldParent,
6692
- newNode: cloneDeep$1((0, vue.toRaw)(parent))
6693
- }] }, {
6694
- name: pageForOp?.name || "",
6695
- id: pageForOp.id
6719
+ this.pushOpHistory("update", {
6720
+ extra: { updatedItems: [{
6721
+ oldNode: oldParent,
6722
+ newNode: cloneDeep$1((0, vue.toRaw)(parent))
6723
+ }] },
6724
+ pageData: {
6725
+ name: pageForOp?.name || "",
6726
+ id: pageForOp.id
6727
+ },
6728
+ historyDescription,
6729
+ source: historySource
6696
6730
  });
6697
6731
  } else this.selectionBeforeOp = null;
6698
6732
  this.emit("move-layer", offset);
@@ -6711,7 +6745,7 @@
6711
6745
  * @param options.doNotSwitchPage 移动后是否不切换当前页面(默认 false;目标容器位于其它页面时为 true 会跳过自动选中以避免页面切换)
6712
6746
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
6713
6747
  */
6714
- async moveToContainer(config, targetId, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false } = {}) {
6748
+ async moveToContainer(config, targetId, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
6715
6749
  const isBatch = Array.isArray(config);
6716
6750
  const configs = (isBatch ? config : [config]).filter((item) => !((0, _tmagic_utils.isPage)(item) || (0, _tmagic_utils.isPageFragment)(item)));
6717
6751
  if (configs.length === 0) throw new Error("没有可移动的节点");
@@ -6759,11 +6793,16 @@
6759
6793
  name: "",
6760
6794
  id: target.id
6761
6795
  };
6762
- this.pushOpHistory("update", { updatedItems }, historyPage);
6796
+ this.pushOpHistory("update", {
6797
+ extra: { updatedItems },
6798
+ pageData: historyPage,
6799
+ historyDescription,
6800
+ source: historySource
6801
+ });
6763
6802
  } else this.selectionBeforeOp = null;
6764
6803
  return isBatch ? newConfigs : newConfigs[0];
6765
6804
  }
6766
- async dragTo(config, targetParent, targetIndex, { doNotPushHistory = false } = {}) {
6805
+ async dragTo(config, targetParent, targetIndex, { doNotPushHistory = false, historyDescription, historySource } = {}) {
6767
6806
  this.captureSelectionBeforeOp();
6768
6807
  if (!targetParent || !Array.isArray(targetParent.items)) return;
6769
6808
  const configs = Array.isArray(config) ? config : [config];
@@ -6805,9 +6844,14 @@
6805
6844
  }
6806
6845
  if (!doNotPushHistory) {
6807
6846
  const pageForOp = this.getNodeInfo(configs[0].id, false).page;
6808
- this.pushOpHistory("update", { updatedItems }, {
6809
- name: pageForOp?.name || "",
6810
- id: pageForOp.id
6847
+ this.pushOpHistory("update", {
6848
+ extra: { updatedItems },
6849
+ pageData: {
6850
+ name: pageForOp?.name || "",
6851
+ id: pageForOp.id
6852
+ },
6853
+ historyDescription,
6854
+ source: historySource
6811
6855
  });
6812
6856
  } else this.selectionBeforeOp = null;
6813
6857
  this.emit("drag-to", {
@@ -6855,6 +6899,10 @@
6855
6899
  if (!entry?.applied) return null;
6856
6900
  const { step } = entry;
6857
6901
  if (!this.get("root")) return null;
6902
+ if (step.opType === "update") {
6903
+ const items = step.updatedItems ?? [];
6904
+ if (!items.length || !items.every((item) => item.changeRecords?.length)) return null;
6905
+ }
6858
6906
  let revertedStep = null;
6859
6907
  const captureRevert = (s) => {
6860
6908
  revertedStep = s;
@@ -6864,7 +6912,8 @@
6864
6912
  const opts = {
6865
6913
  doNotSelect: true,
6866
6914
  doNotSwitchPage: true,
6867
- historyDescription
6915
+ historyDescription,
6916
+ historySource: "rollback"
6868
6917
  };
6869
6918
  try {
6870
6919
  switch (step.opType) {
@@ -6900,7 +6949,10 @@
6900
6949
  }
6901
6950
  return cloneDeep$1(oldNode);
6902
6951
  });
6903
- if (configs.length) await this.update(configs, { historyDescription });
6952
+ if (configs.length) await this.update(configs, {
6953
+ historyDescription,
6954
+ historySource: "rollback"
6955
+ });
6904
6956
  break;
6905
6957
  }
6906
6958
  }
@@ -6934,7 +6986,7 @@
6934
6986
  }
6935
6987
  return cursor;
6936
6988
  }
6937
- async move(left, top, { doNotPushHistory = false } = {}) {
6989
+ async move(left, top, { doNotPushHistory = false, historyDescription, historySource } = {}) {
6938
6990
  const node = (0, vue.toRaw)(this.get("node"));
6939
6991
  if (!node || (0, _tmagic_utils.isPage)(node)) return;
6940
6992
  const newStyle = calcMoveStyle(node.style || {}, left, top);
@@ -6943,7 +6995,11 @@
6943
6995
  id: node.id,
6944
6996
  type: node.type,
6945
6997
  style: newStyle
6946
- }, { doNotPushHistory });
6998
+ }, {
6999
+ doNotPushHistory,
7000
+ historyDescription,
7001
+ historySource
7002
+ });
6947
7003
  }
6948
7004
  resetState() {
6949
7005
  this.set("root", null);
@@ -6983,7 +7039,7 @@
6983
7039
  if (this.selectionBeforeOp) return;
6984
7040
  this.selectionBeforeOp = this.get("nodes").map((n) => n.id);
6985
7041
  }
6986
- pushOpHistory(opType, extra, pageData, historyDescription) {
7042
+ pushOpHistory(opType, { extra, pageData, historyDescription, source }) {
6987
7043
  const step = {
6988
7044
  data: pageData,
6989
7045
  opType,
@@ -6993,6 +7049,7 @@
6993
7049
  ...extra
6994
7050
  };
6995
7051
  if (historyDescription) step.historyDescription = historyDescription;
7052
+ if (source) step.source = source;
6996
7053
  history_default.push(step, pageData.id);
6997
7054
  this.selectionBeforeOp = null;
6998
7055
  }
@@ -7319,14 +7376,17 @@
7319
7376
  changeRecordList.push(buildChangeRecords(style, "style"));
7320
7377
  });
7321
7378
  if (configs.length === 0) return;
7322
- editor_default.update(configs, { changeRecordList });
7379
+ editor_default.update(configs, {
7380
+ changeRecordList,
7381
+ historySource: "stage"
7382
+ });
7323
7383
  });
7324
7384
  stage.on("sort", (ev) => {
7325
- editor_default.sort(ev.src, ev.dist);
7385
+ editor_default.sort(ev.src, ev.dist, { historySource: "stage" });
7326
7386
  });
7327
7387
  stage.on("remove", (ev) => {
7328
7388
  const nodes = ev.data.map(({ el }) => editor_default.getNodeById((0, _tmagic_utils.getIdFromEl)()(el) || ""));
7329
- editor_default.remove(nodes.filter((node) => Boolean(node)));
7389
+ editor_default.remove(nodes.filter((node) => Boolean(node)), { historySource: "stage" });
7330
7390
  });
7331
7391
  stage.on("select-parent", () => {
7332
7392
  const parent = editor_default.get("parent");
@@ -9433,6 +9493,28 @@
9433
9493
  default: return "修改";
9434
9494
  }
9435
9495
  };
9496
+ /** 内置操作途径的中文文案;自定义来源直接回显原值,未知 / 缺省返回空串(UI 据此不渲染)。 */
9497
+ var HISTORY_SOURCE_LABELS = {
9498
+ stage: "画布",
9499
+ tree: "树面板",
9500
+ "component-panel": "组件面板",
9501
+ props: "配置面板",
9502
+ code: "源码",
9503
+ "stage-contextmenu": "画布菜单",
9504
+ "tree-contextmenu": "树菜单",
9505
+ toolbar: "工具栏",
9506
+ shortcut: "快捷键",
9507
+ rollback: "回滚",
9508
+ api: "接口",
9509
+ ai: "AI",
9510
+ unknown: "未知"
9511
+ };
9512
+ /** 操作途径文案:用于历史面板展示「画布 / 树面板 / 配置面板…」标签。 */
9513
+ var sourceLabel = (source = "unknown") => {
9514
+ return HISTORY_SOURCE_LABELS[source] ?? `${source}`;
9515
+ };
9516
+ /** 取一组历史步骤里最后一步(最近一次)的操作途径,用于组头部展示。 */
9517
+ var groupSource = (group) => group.steps[group.steps.length - 1]?.step.source;
9436
9518
  var nameOf = (node) => node?.name || node?.type || `${node?.id ?? ""}`;
9437
9519
  /**
9438
9520
  * 默认描述里展示「名称 (id: xxx)」,便于区分同名实体。
@@ -9528,27 +9610,59 @@
9528
9610
  const target = labelWithId(group.steps[group.steps.length - 1].step.newContent?.name || group.steps[0].step.oldContent?.name, group.id);
9529
9611
  return pathList ? `修改 ${target} · ${pathList}${paths.size > 3 ? "…" : ""}` : `修改 ${target}`;
9530
9612
  };
9613
+ /**
9614
+ * 页面 step 是否支持「回滚」(类 git revert):
9615
+ * - 新增 / 删除:不依赖 changeRecords,反向应用即删除 / 加回,始终可回滚;
9616
+ * - 更新:必须每个被更新节点都带有 changeRecords,才支持按 propPath 局部反向 patch。
9617
+ * 缺失 changeRecords 的更新只能整节点替换,会冲掉该节点后续的无关变更,因此不支持回滚。
9618
+ */
9619
+ var isPageStepRevertable = (step) => {
9620
+ if (step.opType !== "update") return true;
9621
+ const items = step.updatedItems ?? [];
9622
+ if (!items.length) return false;
9623
+ return items.every((item) => Boolean(item.changeRecords?.length));
9624
+ };
9625
+ /**
9626
+ * 数据源 step 是否支持「回滚」:
9627
+ * - 新增(oldSchema=null)/ 删除(newSchema=null):不依赖 changeRecords,始终可回滚;
9628
+ * - 更新(前后 schema 都存在):必须有 changeRecords 才支持局部反向 patch,否则不支持回滚。
9629
+ */
9630
+ var isDataSourceStepRevertable = (step) => {
9631
+ if (step.oldSchema === null || step.newSchema === null) return true;
9632
+ return Boolean(step.changeRecords?.length);
9633
+ };
9634
+ /**
9635
+ * 代码块 step 是否支持「回滚」:
9636
+ * - 新增(oldContent=null)/ 删除(newContent=null):不依赖 changeRecords,始终可回滚;
9637
+ * - 更新(前后 content 都存在):必须有 changeRecords 才支持局部反向 patch,否则不支持回滚。
9638
+ */
9639
+ var isCodeBlockStepRevertable = (step) => {
9640
+ if (step.oldContent === null || step.newContent === null) return true;
9641
+ return Boolean(step.changeRecords?.length);
9642
+ };
9531
9643
  //#endregion
9532
9644
  //#region packages/editor/src/layouts/history-list/GroupRow.vue?vue&type=script&setup=true&lang.ts
9533
9645
  var _hoisted_1$61 = ["title"];
9534
9646
  var _hoisted_2$21 = ["title"];
9535
9647
  var _hoisted_3$8 = { class: "m-editor-history-list-item-desc" };
9536
9648
  var _hoisted_4$7 = ["title"];
9537
- var _hoisted_5$3 = {
9538
- key: 1,
9649
+ var _hoisted_5$3 = ["title"];
9650
+ var _hoisted_6$3 = {
9651
+ key: 2,
9539
9652
  class: "m-editor-history-list-item-merge"
9540
9653
  };
9541
- var _hoisted_6$3 = {
9654
+ var _hoisted_7$1 = {
9542
9655
  key: 0,
9543
9656
  class: "m-editor-history-list-substeps"
9544
9657
  };
9545
- var _hoisted_7$1 = ["title"];
9546
- var _hoisted_8 = { class: "m-editor-history-list-item-index" };
9547
- var _hoisted_9 = { class: "m-editor-history-list-substep-desc" };
9548
- var _hoisted_10 = ["title"];
9549
- var _hoisted_11 = ["onClick"];
9550
- var _hoisted_12 = ["onClick"];
9658
+ var _hoisted_8 = ["title"];
9659
+ var _hoisted_9 = { class: "m-editor-history-list-item-index" };
9660
+ var _hoisted_10 = { class: "m-editor-history-list-substep-desc" };
9661
+ var _hoisted_11 = ["title"];
9662
+ var _hoisted_12 = ["title"];
9551
9663
  var _hoisted_13 = ["onClick"];
9664
+ var _hoisted_14 = ["onClick"];
9665
+ var _hoisted_15 = ["onClick"];
9552
9666
  var GroupRow_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
9553
9667
  name: "MEditorHistoryListGroupRow",
9554
9668
  __name: "GroupRow",
@@ -9558,6 +9672,7 @@
9558
9672
  merged: { type: Boolean },
9559
9673
  opType: {},
9560
9674
  desc: {},
9675
+ source: {},
9561
9676
  time: {},
9562
9677
  timeTitle: {},
9563
9678
  stepCount: {},
@@ -9656,35 +9771,40 @@
9656
9771
  }, (0, vue.toDisplayString)(headIndexLabel.value), 9, _hoisted_2$21),
9657
9772
  (0, vue.createElementVNode)("span", { class: (0, vue.normalizeClass)(["m-editor-history-list-item-op", `op-${__props.opType}`]) }, (0, vue.toDisplayString)((0, vue.unref)(opLabel)(__props.opType)), 3),
9658
9773
  (0, vue.createElementVNode)("span", _hoisted_3$8, (0, vue.toDisplayString)(__props.desc), 1),
9659
- __props.time ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9774
+ !__props.merged && (0, vue.unref)(sourceLabel)(__props.source) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9660
9775
  key: 0,
9776
+ class: "m-editor-history-list-item-source",
9777
+ title: `操作途径:${(0, vue.unref)(sourceLabel)(__props.source)}`
9778
+ }, (0, vue.toDisplayString)((0, vue.unref)(sourceLabel)(__props.source)), 9, _hoisted_4$7)) : (0, vue.createCommentVNode)("v-if", true),
9779
+ !__props.merged && __props.time ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9780
+ key: 1,
9661
9781
  class: "m-editor-history-list-item-time",
9662
9782
  title: __props.timeTitle || __props.time
9663
- }, (0, vue.toDisplayString)(__props.time), 9, _hoisted_4$7)) : (0, vue.createCommentVNode)("v-if", true),
9664
- __props.merged ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_5$3, "合并 " + (0, vue.toDisplayString)(__props.stepCount) + " 步", 1)) : (0, vue.createCommentVNode)("v-if", true),
9783
+ }, (0, vue.toDisplayString)(__props.time), 9, _hoisted_5$3)) : (0, vue.createCommentVNode)("v-if", true),
9784
+ __props.merged ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_6$3, "合并 " + (0, vue.toDisplayString)(__props.stepCount) + " 步", 1)) : (0, vue.createCommentVNode)("v-if", true),
9665
9785
  !__props.merged && headRevertable.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9666
- key: 2,
9786
+ key: 3,
9667
9787
  class: "m-editor-history-list-item-revert",
9668
9788
  title: "将该步骤的修改作为一次新操作反向应用(不影响后续历史)",
9669
9789
  onClick: _cache[0] || (_cache[0] = (0, vue.withModifiers)(($event) => onRevertClick(__props.subSteps[0].index), ["stop"]))
9670
9790
  }, "回滚")) : (0, vue.createCommentVNode)("v-if", true),
9671
9791
  !__props.merged && __props.gotoEnabled && !__props.isCurrent && __props.subSteps.length ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9672
- key: 3,
9792
+ key: 4,
9673
9793
  class: "m-editor-history-list-item-goto",
9674
9794
  title: "回到该记录",
9675
9795
  onClick: _cache[1] || (_cache[1] = (0, vue.withModifiers)(($event) => onGotoClick(__props.subSteps[0].index), ["stop"]))
9676
9796
  }, "回到")) : (0, vue.createCommentVNode)("v-if", true),
9677
9797
  !__props.merged && headDiffable.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9678
- key: 4,
9798
+ key: 5,
9679
9799
  class: "m-editor-history-list-item-diff",
9680
9800
  title: "查看修改差异",
9681
9801
  onClick: _cache[2] || (_cache[2] = (0, vue.withModifiers)(($event) => onDiffClick(__props.subSteps[0].index), ["stop"]))
9682
9802
  }, "查看差异")) : (0, vue.createCommentVNode)("v-if", true),
9683
9803
  __props.merged ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9684
- key: 5,
9804
+ key: 6,
9685
9805
  class: (0, vue.normalizeClass)(["m-editor-history-list-group-toggle", { "is-expanded": __props.expanded }])
9686
9806
  }, "▾", 2)) : (0, vue.createCommentVNode)("v-if", true)
9687
- ], 10, _hoisted_1$61), __props.merged && __props.expanded ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("ul", _hoisted_6$3, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(subStepsDisplay.value, (s) => {
9807
+ ], 10, _hoisted_1$61), __props.merged && __props.expanded ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("ul", _hoisted_7$1, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(subStepsDisplay.value, (s) => {
9688
9808
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("li", {
9689
9809
  key: s.index,
9690
9810
  class: (0, vue.normalizeClass)({
@@ -9693,32 +9813,37 @@
9693
9813
  }),
9694
9814
  title: subStepTitle(s)
9695
9815
  }, [
9696
- (0, vue.createElementVNode)("span", _hoisted_8, "#" + (0, vue.toDisplayString)(s.index + 1), 1),
9697
- (0, vue.createElementVNode)("span", _hoisted_9, (0, vue.toDisplayString)(s.desc), 1),
9698
- s.time ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9816
+ (0, vue.createElementVNode)("span", _hoisted_9, "#" + (0, vue.toDisplayString)(s.index + 1), 1),
9817
+ (0, vue.createElementVNode)("span", _hoisted_10, (0, vue.toDisplayString)(s.desc), 1),
9818
+ (0, vue.unref)(sourceLabel)(s.source) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9699
9819
  key: 0,
9820
+ class: "m-editor-history-list-item-source",
9821
+ title: `操作途径:${(0, vue.unref)(sourceLabel)(s.source)}`
9822
+ }, (0, vue.toDisplayString)((0, vue.unref)(sourceLabel)(s.source)), 9, _hoisted_11)) : (0, vue.createCommentVNode)("v-if", true),
9823
+ s.time ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9824
+ key: 1,
9700
9825
  class: "m-editor-history-list-item-time",
9701
9826
  title: s.timeTitle || s.time
9702
- }, (0, vue.toDisplayString)(s.time), 9, _hoisted_10)) : (0, vue.createCommentVNode)("v-if", true),
9827
+ }, (0, vue.toDisplayString)(s.time), 9, _hoisted_12)) : (0, vue.createCommentVNode)("v-if", true),
9703
9828
  s.revertable ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9704
- key: 1,
9829
+ key: 2,
9705
9830
  class: "m-editor-history-list-item-revert",
9706
9831
  title: "将该步骤的修改作为一次新操作反向应用(不影响后续历史)",
9707
9832
  onClick: (0, vue.withModifiers)(($event) => onRevertClick(s.index), ["stop"])
9708
- }, "回滚", 8, _hoisted_11)) : (0, vue.createCommentVNode)("v-if", true),
9833
+ }, "回滚", 8, _hoisted_13)) : (0, vue.createCommentVNode)("v-if", true),
9709
9834
  __props.gotoEnabled && !s.isCurrent ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9710
- key: 2,
9835
+ key: 3,
9711
9836
  class: "m-editor-history-list-item-goto",
9712
9837
  title: "回到该记录",
9713
9838
  onClick: (0, vue.withModifiers)(($event) => onGotoClick(s.index), ["stop"])
9714
- }, "回到", 8, _hoisted_12)) : (0, vue.createCommentVNode)("v-if", true),
9839
+ }, "回到", 8, _hoisted_14)) : (0, vue.createCommentVNode)("v-if", true),
9715
9840
  s.diffable ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9716
- key: 3,
9841
+ key: 4,
9717
9842
  class: "m-editor-history-list-item-diff",
9718
9843
  title: "查看修改差异",
9719
9844
  onClick: (0, vue.withModifiers)(($event) => onDiffClick(s.index), ["stop"])
9720
- }, "查看差异", 8, _hoisted_13)) : (0, vue.createCommentVNode)("v-if", true)
9721
- ], 10, _hoisted_7$1);
9845
+ }, "查看差异", 8, _hoisted_15)) : (0, vue.createCommentVNode)("v-if", true)
9846
+ ], 10, _hoisted_8);
9722
9847
  }), 128))])) : (0, vue.createCommentVNode)("v-if", true)], 2);
9723
9848
  };
9724
9849
  }
@@ -9802,6 +9927,7 @@
9802
9927
  describeGroup: {},
9803
9928
  describeStep: {},
9804
9929
  isStepDiffable: {},
9930
+ isStepRevertable: {},
9805
9931
  expanded: {},
9806
9932
  gotoEnabled: {
9807
9933
  type: Boolean,
@@ -9833,6 +9959,7 @@
9833
9959
  merged: group.steps.length > 1,
9834
9960
  "op-type": group.opType,
9835
9961
  desc: __props.describeGroup(group),
9962
+ source: (0, vue.unref)(groupSource)(group),
9836
9963
  time: (0, vue.unref)(formatHistoryTime)((0, vue.unref)(groupTimestamp)(group)),
9837
9964
  "time-title": (0, vue.unref)(formatHistoryFullTime)((0, vue.unref)(groupTimestamp)(group)),
9838
9965
  "step-count": group.steps.length,
@@ -9842,7 +9969,8 @@
9842
9969
  isCurrent: s.isCurrent,
9843
9970
  desc: __props.describeStep(s.step),
9844
9971
  diffable: __props.isStepDiffable ? __props.isStepDiffable(s.step) : false,
9845
- revertable: s.applied,
9972
+ revertable: s.applied && (__props.isStepRevertable ? __props.isStepRevertable(s.step) : true),
9973
+ source: s.step.source,
9846
9974
  time: (0, vue.unref)(formatHistoryTime)(s.step.timestamp),
9847
9975
  timeTitle: (0, vue.unref)(formatHistoryFullTime)(s.step.timestamp)
9848
9976
  })),
@@ -9859,6 +9987,7 @@
9859
9987
  "merged",
9860
9988
  "op-type",
9861
9989
  "desc",
9990
+ "source",
9862
9991
  "time",
9863
9992
  "time-title",
9864
9993
  "step-count",
@@ -9898,6 +10027,7 @@
9898
10027
  describeGroup: {},
9899
10028
  describeStep: {},
9900
10029
  isStepDiffable: {},
10030
+ isStepRevertable: {},
9901
10031
  expanded: {},
9902
10032
  gotoEnabled: {
9903
10033
  type: Boolean,
@@ -9927,6 +10057,7 @@
9927
10057
  "describe-group": __props.describeGroup,
9928
10058
  "describe-step": __props.describeStep,
9929
10059
  "is-step-diffable": __props.isStepDiffable,
10060
+ "is-step-revertable": __props.isStepRevertable,
9930
10061
  expanded: __props.expanded,
9931
10062
  "goto-enabled": __props.gotoEnabled,
9932
10063
  onToggle: _cache[0] || (_cache[0] = (key) => _ctx.$emit("toggle", key)),
@@ -9942,6 +10073,7 @@
9942
10073
  "describe-group",
9943
10074
  "describe-step",
9944
10075
  "is-step-diffable",
10076
+ "is-step-revertable",
9945
10077
  "expanded",
9946
10078
  "goto-enabled"
9947
10079
  ]);
@@ -10030,6 +10162,20 @@
10030
10162
  }
10031
10163
  return !isEqual(curValue, lastValue);
10032
10164
  };
10165
+ const removeStyleDisplayConfig = (formConfig) => formConfig.map((item) => {
10166
+ if (!("type" in item)) return item;
10167
+ if (item?.type !== "tab" || !Array.isArray(item.items)) return item;
10168
+ return {
10169
+ ...item,
10170
+ items: item.items.map((tabPane) => {
10171
+ if (tabPane?.title !== "样式" || !Array.isArray(tabPane.items)) return tabPane;
10172
+ return {
10173
+ ...tabPane,
10174
+ display: true
10175
+ };
10176
+ })
10177
+ };
10178
+ });
10033
10179
  /**
10034
10180
  * 内置的默认 FormConfig 加载逻辑:按 `category` 从对应 service / 工具取配置。
10035
10181
  * 作为 ctx.defaultLoadConfig 透传给自定义 `loadConfig`,方便复用与二次加工。
@@ -10038,7 +10184,7 @@
10038
10184
  switch (props.category) {
10039
10185
  case "node":
10040
10186
  if (!props.type) return [];
10041
- return await propsService.getPropsConfig(props.type);
10187
+ return removeStyleDisplayConfig(await propsService.getPropsConfig(props.type));
10042
10188
  case "data-source": return dataSourceService.getFormConfig(props.type || "base");
10043
10189
  case "code-block": return getCodeBlockFormConfig({
10044
10190
  paramColConfig: codeBlockService.getParamsColConfig(),
@@ -10207,11 +10353,13 @@
10207
10353
  };
10208
10354
  const targetText = (0, vue.computed)(() => {
10209
10355
  if (!payload.value) return "";
10210
- const prefix = {
10356
+ const categoryText = {
10211
10357
  node: "节点",
10212
10358
  "data-source": "数据源",
10213
10359
  "code-block": "代码块"
10214
- }[payload.value.category] || "";
10360
+ };
10361
+ const { category } = payload.value;
10362
+ const prefix = category ? categoryText[category] : "";
10215
10363
  const label = payload.value.targetLabel || payload.value.type || "";
10216
10364
  const { id } = payload.value;
10217
10365
  return [prefix, id !== void 0 && id !== "" ? `${label}(${id})` : label].filter(Boolean).join(":");
@@ -10418,6 +10566,7 @@
10418
10566
  merged: group.steps.length > 1,
10419
10567
  "op-type": group.opType,
10420
10568
  desc: (0, vue.unref)(describePageGroup)(group),
10569
+ source: (0, vue.unref)(groupSource)(group),
10421
10570
  time: (0, vue.unref)(formatHistoryTime)((0, vue.unref)(groupTimestamp)(group)),
10422
10571
  "time-title": (0, vue.unref)(formatHistoryFullTime)((0, vue.unref)(groupTimestamp)(group)),
10423
10572
  "step-count": group.steps.length,
@@ -10427,7 +10576,8 @@
10427
10576
  isCurrent: s.isCurrent,
10428
10577
  desc: (0, vue.unref)(describePageStep)(s.step),
10429
10578
  diffable: isPageStepDiffable(s.step),
10430
- revertable: s.applied,
10579
+ revertable: s.applied && (0, vue.unref)(isPageStepRevertable)(s.step),
10580
+ source: s.step.source,
10431
10581
  time: (0, vue.unref)(formatHistoryTime)(s.step.timestamp),
10432
10582
  timeTitle: (0, vue.unref)(formatHistoryFullTime)(s.step.timestamp)
10433
10583
  })),
@@ -10443,6 +10593,7 @@
10443
10593
  "merged",
10444
10594
  "op-type",
10445
10595
  "desc",
10596
+ "source",
10446
10597
  "time",
10447
10598
  "time-title",
10448
10599
  "step-count",
@@ -10733,6 +10884,7 @@
10733
10884
  "describe-group": (0, vue.unref)(describeDataSourceGroup),
10734
10885
  "describe-step": (0, vue.unref)(describeDataSourceStep),
10735
10886
  "is-step-diffable": isDataSourceStepDiffable,
10887
+ "is-step-revertable": (0, vue.unref)(isDataSourceStepRevertable),
10736
10888
  onToggle: (0, vue.unref)(toggleGroup),
10737
10889
  onGoto: onDataSourceGoto,
10738
10890
  onGotoInitial: onDataSourceGotoInitial,
@@ -10743,6 +10895,7 @@
10743
10895
  "expanded",
10744
10896
  "describe-group",
10745
10897
  "describe-step",
10898
+ "is-step-revertable",
10746
10899
  "onToggle"
10747
10900
  ])]),
10748
10901
  _: 1
@@ -10759,6 +10912,7 @@
10759
10912
  "describe-group": (0, vue.unref)(describeCodeBlockGroup),
10760
10913
  "describe-step": (0, vue.unref)(describeCodeBlockStep),
10761
10914
  "is-step-diffable": isCodeBlockStepDiffable,
10915
+ "is-step-revertable": (0, vue.unref)(isCodeBlockStepRevertable),
10762
10916
  onToggle: (0, vue.unref)(toggleGroup),
10763
10917
  onGoto: onCodeBlockGoto,
10764
10918
  onGotoInitial: onCodeBlockGotoInitial,
@@ -10769,6 +10923,7 @@
10769
10923
  "expanded",
10770
10924
  "describe-group",
10771
10925
  "describe-step",
10926
+ "is-step-revertable",
10772
10927
  "onToggle"
10773
10928
  ])]),
10774
10929
  _: 1
@@ -11038,7 +11193,7 @@
11038
11193
  disabled: () => editorService.get("node")?.type === _tmagic_core.NodeType.PAGE,
11039
11194
  handler: () => {
11040
11195
  const node = editorService.get("node");
11041
- node && editorService.remove(node);
11196
+ node && editorService.remove(node, { historySource: "toolbar" });
11042
11197
  }
11043
11198
  });
11044
11199
  break;
@@ -11402,7 +11557,11 @@
11402
11557
  if (record.propPath?.startsWith("style") && record.value === "") (0, _tmagic_utils.setValueByKeyPath)(record.propPath, record.value, newValue);
11403
11558
  });
11404
11559
  }
11405
- editorService.update(newValue, { changeRecords: eventData?.changeRecords });
11560
+ const historySource = eventData ? "props" : "code";
11561
+ editorService.update(newValue, {
11562
+ changeRecords: eventData?.changeRecords,
11563
+ historySource
11564
+ });
11406
11565
  } catch (e) {
11407
11566
  emit("submit-error", e);
11408
11567
  }
@@ -12371,7 +12530,7 @@
12371
12530
  const editCode = (id) => {
12372
12531
  emit("edit", id);
12373
12532
  };
12374
- const deleteCode = async (id) => {
12533
+ const deleteCode = async (id, { historySource } = {}) => {
12375
12534
  const currentCode = codeList.value.find((codeItem) => codeItem.id === id);
12376
12535
  const existBinds = Boolean(currentCode?.items?.length);
12377
12536
  const undeleteableList = codeBlockService.getUndeletableList() || [];
@@ -12381,7 +12540,7 @@
12381
12540
  cancelButtonText: "取消",
12382
12541
  type: "warning"
12383
12542
  });
12384
- emit("remove", id);
12543
+ emit("remove", id, { historySource });
12385
12544
  } else if (typeof props.customError === "function") props.customError(id, existBinds ? CodeDeleteErrorType.BIND : CodeDeleteErrorType.UNDELETEABLE);
12386
12545
  else if (existBinds) _tmagic_design.tMagicMessage.error("代码块存在绑定关系,不可删除");
12387
12546
  else _tmagic_design.tMagicMessage.error("代码块不可删除");
@@ -12431,7 +12590,7 @@
12431
12590
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)(Icon_default, {
12432
12591
  icon: (0, vue.unref)(_element_plus_icons_vue.Close),
12433
12592
  class: "edit-icon",
12434
- onClick: (0, vue.withModifiers)(($event) => deleteCode(`${data.key}`), ["stop"])
12593
+ onClick: (0, vue.withModifiers)(($event) => deleteCode(`${data.key}`, { historySource: "tree" }), ["stop"])
12435
12594
  }, null, 8, ["icon", "onClick"])]),
12436
12595
  _: 2
12437
12596
  }, 1024)) : (0, vue.createCommentVNode)("v-if", true),
@@ -12479,7 +12638,7 @@
12479
12638
  const codeBlock = codeBlockService.getCodeContentById(selectId);
12480
12639
  if (!codeBlock) return;
12481
12640
  const newCodeId = await codeBlockService.getUniqueId();
12482
- codeBlockService.setCodeDslById(newCodeId, cloneDeep$1(codeBlock));
12641
+ codeBlockService.setCodeDslById(newCodeId, cloneDeep$1(codeBlock), { historySource: "tree-contextmenu" });
12483
12642
  }
12484
12643
  },
12485
12644
  {
@@ -12541,7 +12700,7 @@
12541
12700
  if (codeBlockListRef.value) for (const [, status] of codeBlockListRef.value.nodeStatusMap.entries()) status.selected = false;
12542
12701
  };
12543
12702
  const { nodeContentMenuHandler, menuData: contentMenuData, contentMenuHideHandler } = useContentMenu$1((id) => {
12544
- codeBlockListRef.value?.deleteCode(id);
12703
+ codeBlockListRef.value?.deleteCode(id, { historySource: "tree-contextmenu" });
12545
12704
  });
12546
12705
  const menuData = (0, vue.computed)(() => props.customContentMenu(contentMenuData, "code-block"));
12547
12706
  return (_ctx, _cache) => {
@@ -12629,8 +12788,11 @@
12629
12788
  editDialog.value.show();
12630
12789
  };
12631
12790
  const submitDataSourceHandler = (value, eventData) => {
12632
- if (value.id) dataSourceService.update(value, { changeRecords: eventData.changeRecords });
12633
- else dataSourceService.add(value);
12791
+ if (value.id) dataSourceService.update(value, {
12792
+ changeRecords: eventData.changeRecords,
12793
+ historySource: "props"
12794
+ });
12795
+ else dataSourceService.add(value, { historySource: "props" });
12634
12796
  editDialog.value?.hide();
12635
12797
  };
12636
12798
  return {
@@ -12963,7 +13125,7 @@
12963
13125
  if (!selectId) return;
12964
13126
  const ds = dataSourceService.getDataSourceById(selectId);
12965
13127
  if (!ds) return;
12966
- dataSourceService.add(cloneDeep$1(ds));
13128
+ dataSourceService.add(cloneDeep$1(ds), { historySource: "tree-contextmenu" });
12967
13129
  }
12968
13130
  },
12969
13131
  {
@@ -13040,7 +13202,7 @@
13040
13202
  cancelButtonText: "取消",
13041
13203
  type: "warning"
13042
13204
  });
13043
- dataSourceService.remove(id);
13205
+ dataSourceService.remove(id, { historySource: "tree-contextmenu" });
13044
13206
  };
13045
13207
  const dataSourceListRef = (0, vue.useTemplateRef)("dataSourceList");
13046
13208
  const filterTextChangeHandler = (val) => {
@@ -13147,7 +13309,12 @@
13147
13309
  var FolderMinusIcon_default = FolderMinusIcon_vue_vue_type_script_setup_true_lang_default;
13148
13310
  //#endregion
13149
13311
  //#region packages/editor/src/utils/content-menu.ts
13150
- var useDeleteMenu = () => ({
13312
+ /**
13313
+ * 共享的右键菜单项构造器(画布 ViewerMenu 与图层树 LayerMenu 共用)。
13314
+ * `historySource` 用于标记本次操作的途径,调用方按所在面板传入:
13315
+ * 画布传 `'stage-contextmenu'`,树形面板传 `'tree-contextmenu'`。
13316
+ */
13317
+ var useDeleteMenu = (historySource) => ({
13151
13318
  type: "button",
13152
13319
  text: "删除",
13153
13320
  icon: _element_plus_icons_vue.Delete,
@@ -13157,7 +13324,7 @@
13157
13324
  },
13158
13325
  handler: ({ editorService }) => {
13159
13326
  const nodes = editorService.get("nodes");
13160
- nodes && editorService.remove(nodes);
13327
+ nodes && editorService.remove(nodes, { historySource });
13161
13328
  }
13162
13329
  });
13163
13330
  var useCopyMenu = () => ({
@@ -13169,7 +13336,7 @@
13169
13336
  nodes && editorService?.copy(nodes);
13170
13337
  }
13171
13338
  });
13172
- var usePasteMenu = (menu) => ({
13339
+ var usePasteMenu = (historySource, menu) => ({
13173
13340
  type: "button",
13174
13341
  text: "粘贴",
13175
13342
  icon: (0, vue.markRaw)(_element_plus_icons_vue.DocumentCopy),
@@ -13186,17 +13353,20 @@
13186
13353
  editorService.paste({
13187
13354
  left: initialLeft,
13188
13355
  top: initialTop
13189
- });
13190
- } else editorService.paste();
13356
+ }, void 0, { historySource });
13357
+ } else editorService.paste(void 0, void 0, { historySource });
13191
13358
  }
13192
13359
  });
13193
- var moveTo = async (id, { editorService }) => {
13360
+ var moveTo = async (id, { editorService }, historySource) => {
13194
13361
  const nodes = editorService.get("nodes") || [];
13195
13362
  const parent = editorService.getNodeById(id);
13196
13363
  if (!parent || nodes.length === 0) return;
13197
- await editorService.moveToContainer((0, _tmagic_core.cloneDeep)(nodes), parent.id, { doNotSwitchPage: true });
13364
+ await editorService.moveToContainer((0, _tmagic_core.cloneDeep)(nodes), parent.id, {
13365
+ doNotSwitchPage: true,
13366
+ historySource
13367
+ });
13198
13368
  };
13199
- var useMoveToMenu = ({ editorService }) => {
13369
+ var useMoveToMenu = ({ editorService }, historySource) => {
13200
13370
  return {
13201
13371
  type: "button",
13202
13372
  text: "移动至",
@@ -13209,7 +13379,7 @@
13209
13379
  text: `${page.name}(${page.id})`,
13210
13380
  type: "button",
13211
13381
  handler: (services) => {
13212
- moveTo(page.id, services);
13382
+ moveTo(page.id, services, historySource);
13213
13383
  }
13214
13384
  }))
13215
13385
  };
@@ -13242,7 +13412,7 @@
13242
13412
  name: component.text,
13243
13413
  type: component.type,
13244
13414
  ...component.data || {}
13245
- });
13415
+ }, void 0, { historySource: "tree-contextmenu" });
13246
13416
  }
13247
13417
  }));
13248
13418
  const getSubMenuData = (0, vue.computed)(() => {
@@ -13251,7 +13421,7 @@
13251
13421
  type: "button",
13252
13422
  icon: _element_plus_icons_vue.Files,
13253
13423
  handler: () => {
13254
- editorService.add({ type: "tab-pane" });
13424
+ editorService.add({ type: "tab-pane" }, void 0, { historySource: "tree-contextmenu" });
13255
13425
  }
13256
13426
  }];
13257
13427
  if (node.value?.items) return componentList.value.reduce((subMenuData, group, index) => subMenuData.concat(createMenuItems(group), index < componentList.value.length - 1 ? [{
@@ -13278,9 +13448,9 @@
13278
13448
  items: getSubMenuData.value
13279
13449
  },
13280
13450
  useCopyMenu(),
13281
- usePasteMenu(),
13282
- useDeleteMenu(),
13283
- useMoveToMenu(services),
13451
+ usePasteMenu("tree-contextmenu"),
13452
+ useDeleteMenu("tree-contextmenu"),
13453
+ useMoveToMenu(services, "tree-contextmenu"),
13284
13454
  ...props.layerContentMenu
13285
13455
  ], "layer"));
13286
13456
  const show = (e) => {
@@ -13311,7 +13481,7 @@
13311
13481
  editorService.update({
13312
13482
  id: props.data.id,
13313
13483
  visible
13314
- });
13484
+ }, { historySource: "tree" });
13315
13485
  };
13316
13486
  return (_ctx, _cache) => {
13317
13487
  return __props.data.type !== "page" ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicButton), {
@@ -13927,7 +14097,7 @@
13927
14097
  name: text,
13928
14098
  type,
13929
14099
  ...data
13930
- });
14100
+ }, void 0, { historySource: "component-panel" });
13931
14101
  };
13932
14102
  const dragstartHandler = ({ text, type, data = {} }, e) => {
13933
14103
  e.dataTransfer?.setData("text/json", (0, serialize_javascript.default)({
@@ -14732,11 +14902,11 @@
14732
14902
  display: () => canCenter.value,
14733
14903
  handler: () => {
14734
14904
  if (!nodes.value) return;
14735
- editorService.alignCenter(nodes.value);
14905
+ editorService.alignCenter(nodes.value, { historySource: "stage-contextmenu" });
14736
14906
  }
14737
14907
  },
14738
14908
  useCopyMenu(),
14739
- usePasteMenu(menuRef),
14909
+ usePasteMenu("stage-contextmenu", menuRef),
14740
14910
  {
14741
14911
  type: "divider",
14742
14912
  direction: "horizontal",
@@ -14751,7 +14921,7 @@
14751
14921
  icon: (0, vue.markRaw)(_element_plus_icons_vue.Top),
14752
14922
  display: () => !(0, _tmagic_utils.isPage)(node.value) && !(0, _tmagic_utils.isPageFragment)(node.value) && !props.isMultiSelect,
14753
14923
  handler: () => {
14754
- editorService.moveLayer(1);
14924
+ editorService.moveLayer(1, { historySource: "stage-contextmenu" });
14755
14925
  }
14756
14926
  },
14757
14927
  {
@@ -14760,7 +14930,7 @@
14760
14930
  icon: (0, vue.markRaw)(_element_plus_icons_vue.Bottom),
14761
14931
  display: () => !(0, _tmagic_utils.isPage)(node.value) && !(0, _tmagic_utils.isPageFragment)(node.value) && !props.isMultiSelect,
14762
14932
  handler: () => {
14763
- editorService.moveLayer(-1);
14933
+ editorService.moveLayer(-1, { historySource: "stage-contextmenu" });
14764
14934
  }
14765
14935
  },
14766
14936
  {
@@ -14769,7 +14939,7 @@
14769
14939
  icon: (0, vue.markRaw)(_element_plus_icons_vue.Top),
14770
14940
  display: () => !(0, _tmagic_utils.isPage)(node.value) && !(0, _tmagic_utils.isPageFragment)(node.value) && !props.isMultiSelect,
14771
14941
  handler: () => {
14772
- editorService.moveLayer(LayerOffset.TOP);
14942
+ editorService.moveLayer(LayerOffset.TOP, { historySource: "stage-contextmenu" });
14773
14943
  }
14774
14944
  },
14775
14945
  {
@@ -14778,16 +14948,16 @@
14778
14948
  icon: (0, vue.markRaw)(_element_plus_icons_vue.Bottom),
14779
14949
  display: () => !(0, _tmagic_utils.isPage)(node.value) && !(0, _tmagic_utils.isPageFragment)(node.value) && !props.isMultiSelect,
14780
14950
  handler: () => {
14781
- editorService.moveLayer(LayerOffset.BOTTOM);
14951
+ editorService.moveLayer(LayerOffset.BOTTOM, { historySource: "stage-contextmenu" });
14782
14952
  }
14783
14953
  },
14784
- useMoveToMenu(services),
14954
+ useMoveToMenu(services, "stage-contextmenu"),
14785
14955
  {
14786
14956
  type: "divider",
14787
14957
  direction: "horizontal",
14788
14958
  display: () => !(0, _tmagic_utils.isPage)(node.value) && !(0, _tmagic_utils.isPageFragment)(node.value) && !props.isMultiSelect
14789
14959
  },
14790
- useDeleteMenu(),
14960
+ useDeleteMenu("stage-contextmenu"),
14791
14961
  {
14792
14962
  type: "divider",
14793
14963
  direction: "horizontal"
@@ -15044,7 +15214,7 @@
15044
15214
  left: (0, _tmagic_utils.calcValueByFontsize)(doc, left / zoom.value)
15045
15215
  };
15046
15216
  config.data.inputEvent = e;
15047
- editorService.add(config.data, parent);
15217
+ editorService.add(config.data, parent, { historySource: "component-panel" });
15048
15218
  }
15049
15219
  };
15050
15220
  return (_ctx, _cache) => {
@@ -15332,10 +15502,12 @@
15332
15502
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
15333
15503
  * @returns {void}
15334
15504
  */
15335
- async setCodeDslById(id, codeConfig, { changeRecords, doNotPushHistory = false } = {}) {
15505
+ async setCodeDslById(id, codeConfig, { changeRecords, doNotPushHistory = false, historyDescription, historySource } = {}) {
15336
15506
  this.setCodeDslByIdSync(id, codeConfig, true, {
15337
15507
  changeRecords,
15338
- doNotPushHistory
15508
+ doNotPushHistory,
15509
+ historyDescription,
15510
+ historySource
15339
15511
  });
15340
15512
  }
15341
15513
  /**
@@ -15350,7 +15522,7 @@
15350
15522
  * @param options.historyDescription 入栈时附带的人类可读描述,用于历史面板展示
15351
15523
  * @returns {void}
15352
15524
  */
15353
- setCodeDslByIdSync(id, codeConfig, force = true, { changeRecords, doNotPushHistory = false, historyDescription } = {}) {
15525
+ setCodeDslByIdSync(id, codeConfig, force = true, { changeRecords, doNotPushHistory = false, historyDescription, historySource } = {}) {
15354
15526
  const codeDsl = this.getCodeDsl();
15355
15527
  if (!codeDsl) throw new Error("dsl中没有codeBlocks");
15356
15528
  if (codeDsl[id] && !force) return;
@@ -15369,7 +15541,8 @@
15369
15541
  oldContent,
15370
15542
  newContent,
15371
15543
  changeRecords,
15372
- historyDescription
15544
+ historyDescription,
15545
+ source: historySource
15373
15546
  });
15374
15547
  this.emit("addOrUpdate", id, codeDsl[id]);
15375
15548
  }
@@ -15450,7 +15623,7 @@
15450
15623
  * @param options 可选配置
15451
15624
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
15452
15625
  */
15453
- async deleteCodeDslByIds(codeIds, { doNotPushHistory = false, historyDescription } = {}) {
15626
+ async deleteCodeDslByIds(codeIds, { doNotPushHistory = false, historyDescription, historySource } = {}) {
15454
15627
  const currentDsl = await this.getCodeDsl();
15455
15628
  if (!currentDsl) return;
15456
15629
  codeIds.forEach((id) => {
@@ -15459,7 +15632,8 @@
15459
15632
  if (oldContent && !doNotPushHistory) history_default.pushCodeBlock(id, {
15460
15633
  oldContent,
15461
15634
  newContent: null,
15462
- historyDescription
15635
+ historyDescription,
15636
+ source: historySource
15463
15637
  });
15464
15638
  this.emit("remove", id);
15465
15639
  });
@@ -15539,6 +15713,7 @@
15539
15713
  async revert(id, index) {
15540
15714
  const entry = history_default.getCodeBlockStepList(id)[index];
15541
15715
  if (!entry?.applied) return null;
15716
+ if (entry.step.oldContent && entry.step.newContent && !entry.step.changeRecords?.length) return null;
15542
15717
  const description = `回滚 #${index + 1}: ${describeRevertCodeBlockStep(entry.step)}`;
15543
15718
  return await this.applyRevertStep(entry.step, description);
15544
15719
  }
@@ -15609,11 +15784,17 @@
15609
15784
  async applyRevertStep(step, historyDescription) {
15610
15785
  const { id, oldContent, newContent, changeRecords } = step;
15611
15786
  if (oldContent === null && newContent) {
15612
- await this.deleteCodeDslByIds([id], { historyDescription });
15787
+ await this.deleteCodeDslByIds([id], {
15788
+ historyDescription,
15789
+ historySource: "rollback"
15790
+ });
15613
15791
  return history_default.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
15614
15792
  }
15615
15793
  if (oldContent && newContent === null) {
15616
- this.setCodeDslByIdSync(id, cloneDeep$1(oldContent), true, { historyDescription });
15794
+ this.setCodeDslByIdSync(id, cloneDeep$1(oldContent), true, {
15795
+ historyDescription,
15796
+ historySource: "rollback"
15797
+ });
15617
15798
  return history_default.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
15618
15799
  }
15619
15800
  if (!oldContent || !newContent) return null;
@@ -15632,11 +15813,15 @@
15632
15813
  }
15633
15814
  this.setCodeDslByIdSync(id, fallbackToFullReplace ? cloneDeep$1(oldContent) : patched, true, {
15634
15815
  changeRecords,
15635
- historyDescription
15816
+ historyDescription,
15817
+ historySource: "rollback"
15636
15818
  });
15637
15819
  return history_default.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
15638
15820
  }
15639
- this.setCodeDslByIdSync(id, cloneDeep$1(oldContent), true, { historyDescription });
15821
+ this.setCodeDslByIdSync(id, cloneDeep$1(oldContent), true, {
15822
+ historyDescription,
15823
+ historySource: "rollback"
15824
+ });
15640
15825
  return history_default.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
15641
15826
  }
15642
15827
  /**
@@ -15800,7 +15985,7 @@
15800
15985
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
15801
15986
  * @param options.historyDescription 入栈时附带的人类可读描述,用于历史面板展示
15802
15987
  */
15803
- add(config, { doNotPushHistory = false, historyDescription } = {}) {
15988
+ add(config, { doNotPushHistory = false, historyDescription, historySource } = {}) {
15804
15989
  const newConfig = {
15805
15990
  ...config,
15806
15991
  id: config.id && !this.getDataSourceById(config.id) ? config.id : this.createId()
@@ -15809,7 +15994,8 @@
15809
15994
  if (!doNotPushHistory) history_default.pushDataSource(newConfig.id, {
15810
15995
  oldSchema: null,
15811
15996
  newSchema: newConfig,
15812
- historyDescription
15997
+ historyDescription,
15998
+ source: historySource
15813
15999
  });
15814
16000
  this.emit("add", newConfig);
15815
16001
  return newConfig;
@@ -15822,7 +16008,7 @@
15822
16008
  * @param data.doNotPushHistory 是否不写入历史记录(默认 false)
15823
16009
  * @param data.historyDescription 入栈时附带的人类可读描述,用于历史面板展示
15824
16010
  */
15825
- update(config, { changeRecords = [], doNotPushHistory = false, historyDescription } = {}) {
16011
+ update(config, { changeRecords = [], doNotPushHistory = false, historyDescription, historySource } = {}) {
15826
16012
  const dataSources = this.get("dataSources");
15827
16013
  const index = dataSources.findIndex((ds) => ds.id === config.id);
15828
16014
  const oldConfig = dataSources[index];
@@ -15832,7 +16018,8 @@
15832
16018
  oldSchema: oldConfig ? cloneDeep$1(oldConfig) : null,
15833
16019
  newSchema: newConfig,
15834
16020
  changeRecords,
15835
- historyDescription
16021
+ historyDescription,
16022
+ source: historySource
15836
16023
  });
15837
16024
  this.emit("update", newConfig, {
15838
16025
  oldConfig,
@@ -15847,7 +16034,7 @@
15847
16034
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
15848
16035
  * @param options.historyDescription 入栈时附带的人类可读描述,用于历史面板展示
15849
16036
  */
15850
- remove(id, { doNotPushHistory = false, historyDescription } = {}) {
16037
+ remove(id, { doNotPushHistory = false, historyDescription, historySource } = {}) {
15851
16038
  const dataSources = this.get("dataSources");
15852
16039
  const index = dataSources.findIndex((ds) => ds.id === id);
15853
16040
  const oldConfig = index !== -1 ? dataSources[index] : null;
@@ -15855,7 +16042,8 @@
15855
16042
  if (oldConfig && !doNotPushHistory) history_default.pushDataSource(id, {
15856
16043
  oldSchema: cloneDeep$1(oldConfig),
15857
16044
  newSchema: null,
15858
- historyDescription
16045
+ historyDescription,
16046
+ source: historySource
15859
16047
  });
15860
16048
  this.emit("remove", id);
15861
16049
  }
@@ -15927,6 +16115,7 @@
15927
16115
  revert(id, index) {
15928
16116
  const entry = history_default.getDataSourceStepList(id)[index];
15929
16117
  if (!entry?.applied) return null;
16118
+ if (entry.step.oldSchema && entry.step.newSchema && !entry.step.changeRecords?.length) return null;
15930
16119
  const description = `回滚 #${index + 1}: ${describeRevertDataSourceStep(entry.step)}`;
15931
16120
  return this.applyRevertStep(entry.step, description);
15932
16121
  }
@@ -15990,11 +16179,17 @@
15990
16179
  applyRevertStep(step, historyDescription) {
15991
16180
  const { id, oldSchema, newSchema, changeRecords } = step;
15992
16181
  if (oldSchema === null && newSchema) {
15993
- this.remove(`${id}`, { historyDescription });
16182
+ this.remove(`${id}`, {
16183
+ historyDescription,
16184
+ historySource: "rollback"
16185
+ });
15994
16186
  return history_default.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
15995
16187
  }
15996
16188
  if (oldSchema && newSchema === null) {
15997
- this.add(cloneDeep$1(oldSchema), { historyDescription });
16189
+ this.add(cloneDeep$1(oldSchema), {
16190
+ historyDescription,
16191
+ historySource: "rollback"
16192
+ });
15998
16193
  return history_default.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
15999
16194
  }
16000
16195
  if (!oldSchema || !newSchema) return null;
@@ -16013,11 +16208,15 @@
16013
16208
  }
16014
16209
  this.update(fallbackToFullReplace ? cloneDeep$1(oldSchema) : patched, {
16015
16210
  changeRecords,
16016
- historyDescription
16211
+ historyDescription,
16212
+ historySource: "rollback"
16017
16213
  });
16018
16214
  return history_default.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
16019
16215
  }
16020
- this.update(cloneDeep$1(oldSchema), { historyDescription });
16216
+ this.update(cloneDeep$1(oldSchema), {
16217
+ historyDescription,
16218
+ historySource: "rollback"
16219
+ });
16021
16220
  return history_default.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
16022
16221
  }
16023
16222
  /**
@@ -16334,7 +16533,7 @@
16334
16533
  [KeyBindingCommand.DELETE_NODE]: () => {
16335
16534
  const nodes = editor_default.get("nodes");
16336
16535
  if (!nodes || (0, _tmagic_utils.isPage)(nodes[0]) || (0, _tmagic_utils.isPageFragment)(nodes[0])) return;
16337
- editor_default.remove(nodes);
16536
+ editor_default.remove(nodes, { historySource: "shortcut" });
16338
16537
  },
16339
16538
  [KeyBindingCommand.COPY_NODE]: () => {
16340
16539
  const nodes = editor_default.get("nodes");
@@ -16344,13 +16543,13 @@
16344
16543
  const nodes = editor_default.get("nodes");
16345
16544
  if (!nodes || (0, _tmagic_utils.isPage)(nodes[0]) || (0, _tmagic_utils.isPageFragment)(nodes[0])) return;
16346
16545
  editor_default.copy(nodes);
16347
- editor_default.remove(nodes);
16546
+ editor_default.remove(nodes, { historySource: "shortcut" });
16348
16547
  },
16349
16548
  [KeyBindingCommand.PASTE_NODE]: () => {
16350
16549
  editor_default.get("nodes") && editor_default.paste({
16351
16550
  offsetX: 10,
16352
16551
  offsetY: 10
16353
- });
16552
+ }, void 0, { historySource: "shortcut" });
16354
16553
  },
16355
16554
  [KeyBindingCommand.UNDO]: () => {
16356
16555
  editor_default.undo();