@tmagic/editor 1.0.0-beta.12 → 1.0.0-beta.15

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 (102) hide show
  1. package/coverage/clover.xml +1540 -0
  2. package/coverage/coverage-final.json +35 -0
  3. package/coverage/lcov-report/base.css +224 -0
  4. package/coverage/lcov-report/block-navigation.js +87 -0
  5. package/coverage/lcov-report/favicon.png +0 -0
  6. package/coverage/lcov-report/index.html +206 -0
  7. package/coverage/lcov-report/prettify.css +1 -0
  8. package/coverage/lcov-report/prettify.js +2 -0
  9. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  10. package/coverage/lcov-report/sorter.js +196 -0
  11. package/coverage/lcov-report/src/Editor.vue.html +787 -0
  12. package/coverage/lcov-report/src/components/ContentMenu.vue.html +406 -0
  13. package/coverage/lcov-report/src/components/Icon.vue.html +172 -0
  14. package/coverage/lcov-report/src/components/ScrollViewer.vue.html +283 -0
  15. package/coverage/lcov-report/src/components/ToolButton.vue.html +772 -0
  16. package/coverage/lcov-report/src/components/index.html +161 -0
  17. package/coverage/lcov-report/src/index.html +131 -0
  18. package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +214 -0
  19. package/coverage/lcov-report/src/layouts/Framework.vue.html +304 -0
  20. package/coverage/lcov-report/src/layouts/NavMenu.vue.html +208 -0
  21. package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +316 -0
  22. package/coverage/lcov-report/src/layouts/Resizer.vue.html +268 -0
  23. package/coverage/lcov-report/src/layouts/index.html +176 -0
  24. package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +358 -0
  25. package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +421 -0
  26. package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +775 -0
  27. package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +343 -0
  28. package/coverage/lcov-report/src/layouts/sidebar/index.html +161 -0
  29. package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +718 -0
  30. package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +757 -0
  31. package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +532 -0
  32. package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +586 -0
  33. package/coverage/lcov-report/src/layouts/workspace/index.html +161 -0
  34. package/coverage/lcov-report/src/services/BaseService.ts.html +643 -0
  35. package/coverage/lcov-report/src/services/componentList.ts.html +229 -0
  36. package/coverage/lcov-report/src/services/editor.ts.html +2077 -0
  37. package/coverage/lcov-report/src/services/events.ts.html +331 -0
  38. package/coverage/lcov-report/src/services/history.ts.html +478 -0
  39. package/coverage/lcov-report/src/services/index.html +206 -0
  40. package/coverage/lcov-report/src/services/props.ts.html +415 -0
  41. package/coverage/lcov-report/src/services/ui.ts.html +514 -0
  42. package/coverage/lcov-report/src/type.ts.html +844 -0
  43. package/coverage/lcov-report/src/utils/compose.ts.html +184 -0
  44. package/coverage/lcov-report/src/utils/config.ts.html +172 -0
  45. package/coverage/lcov-report/src/utils/editor.ts.html +838 -0
  46. package/coverage/lcov-report/src/utils/index.html +221 -0
  47. package/coverage/lcov-report/src/utils/index.ts.html +151 -0
  48. package/coverage/lcov-report/src/utils/logger.ts.html +226 -0
  49. package/coverage/lcov-report/src/utils/props.ts.html +796 -0
  50. package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +733 -0
  51. package/coverage/lcov-report/src/utils/undo-redo.ts.html +313 -0
  52. package/coverage/lcov-report/undo-redo.ts.html +313 -0
  53. package/coverage/lcov.info +3676 -0
  54. package/dist/style.css +47 -22
  55. package/dist/tmagic-editor.es.js +921 -603
  56. package/dist/tmagic-editor.es.js.map +1 -1
  57. package/dist/tmagic-editor.umd.js +920 -602
  58. package/dist/tmagic-editor.umd.js.map +1 -1
  59. package/dist/types/src/Editor.vue.d.ts +1 -1
  60. package/dist/types/src/components/ToolButton.vue.d.ts +12 -1
  61. package/dist/types/src/index.d.ts +1 -0
  62. package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -0
  63. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +2 -0
  64. package/dist/types/src/services/editor.d.ts +5 -2
  65. package/dist/types/src/services/history.d.ts +1 -0
  66. package/dist/types/src/services/props.d.ts +2 -2
  67. package/dist/types/src/services/ui.d.ts +1 -0
  68. package/dist/types/src/type.d.ts +6 -8
  69. package/dist/types/src/utils/editor.d.ts +2 -2
  70. package/dist/types/src/utils/polyfills.d.ts +0 -0
  71. package/package.json +26 -12
  72. package/src/components/ContentMenu.vue +107 -0
  73. package/src/components/ScrollViewer.vue +1 -1
  74. package/src/components/ToolButton.vue +69 -30
  75. package/src/index.ts +2 -0
  76. package/src/layouts/Framework.vue +6 -6
  77. package/src/layouts/sidebar/ComponentListPanel.vue +23 -1
  78. package/src/layouts/sidebar/LayerMenu.vue +91 -72
  79. package/src/layouts/sidebar/LayerPanel.vue +23 -49
  80. package/src/layouts/workspace/PageBar.vue +35 -6
  81. package/src/layouts/workspace/Stage.vue +41 -44
  82. package/src/layouts/workspace/ViewerMenu.vue +104 -67
  83. package/src/layouts/workspace/Workspace.vue +74 -16
  84. package/src/services/BaseService.ts +1 -1
  85. package/src/services/editor.ts +97 -10
  86. package/src/services/history.ts +7 -0
  87. package/src/services/props.ts +2 -3
  88. package/src/services/ui.ts +5 -0
  89. package/src/theme/common/var.scss +1 -0
  90. package/src/theme/component-list-panel.scss +2 -0
  91. package/src/theme/content-menu.scss +33 -26
  92. package/src/theme/layer-panel.scss +2 -1
  93. package/src/theme/nav-menu.scss +6 -2
  94. package/src/theme/page-bar.scss +22 -1
  95. package/src/type.ts +6 -8
  96. package/src/utils/editor.ts +7 -3
  97. package/{vite.config.ts → src/utils/polyfills.ts} +4 -12
  98. package/src/utils/props.ts +19 -0
  99. package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +0 -980
  100. package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -188
  101. package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
  102. package/tsconfig.json +0 -9
@@ -8,7 +8,7 @@
8
8
 
9
9
  function _interopNamespace(e) {
10
10
  if (e && e.__esModule) return e;
11
- var n = {__proto__: null, [Symbol.toStringTag]: 'Module'};
11
+ var n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
12
12
  if (e) {
13
13
  Object.keys(e).forEach(function (k) {
14
14
  if (k !== 'default') {
@@ -29,6 +29,10 @@
29
29
  var KeyController__default = /*#__PURE__*/_interopDefaultLegacy(KeyController);
30
30
  var StageCore__default = /*#__PURE__*/_interopDefaultLegacy(StageCore);
31
31
 
32
+ if (typeof window.global === "undefined") {
33
+ window.global = window;
34
+ }
35
+
32
36
  var _export_sfc = (sfc, props) => {
33
37
  const target = sfc.__vccOpts || sfc;
34
38
  for (const [key, val] of props) {
@@ -37,7 +41,7 @@
37
41
  return target;
38
42
  };
39
43
 
40
- const _sfc_main$k = vue.defineComponent({
44
+ const _sfc_main$l = vue.defineComponent({
41
45
  name: "m-fields-vs-code",
42
46
  props: ["model", "name", "config", "prop"],
43
47
  emits: ["change"],
@@ -54,7 +58,7 @@
54
58
  };
55
59
  }
56
60
  });
57
- function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
61
+ function _sfc_render$l(_ctx, _cache, $props, $setup, $data, $options) {
58
62
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
59
63
  return vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
60
64
  style: vue.normalizeStyle(`height: ${_ctx.height}`),
@@ -63,9 +67,9 @@
63
67
  onSave: _ctx.save
64
68
  }, null, 8, ["style", "init-values", "language", "onSave"]);
65
69
  }
66
- var Code = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
70
+ var Code = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$l]]);
67
71
 
68
- const _sfc_main$j = vue.defineComponent({
72
+ const _sfc_main$k = vue.defineComponent({
69
73
  name: "m-fields-code-link",
70
74
  props: {
71
75
  config: {
@@ -120,7 +124,7 @@
120
124
  };
121
125
  }
122
126
  });
123
- function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
127
+ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
124
128
  const _component_m_fields_link = vue.resolveComponent("m-fields-link");
125
129
  return vue.openBlock(), vue.createBlock(_component_m_fields_link, {
126
130
  config: _ctx.formConfig,
@@ -129,11 +133,11 @@
129
133
  onChange: _ctx.changeHandler
130
134
  }, null, 8, ["config", "model", "onChange"]);
131
135
  }
132
- var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
136
+ var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
133
137
 
134
138
  var UISelect_vue_vue_type_style_index_0_lang = '';
135
139
 
136
- const _sfc_main$i = vue.defineComponent({
140
+ const _sfc_main$j = vue.defineComponent({
137
141
  name: "m-fields-ui-select",
138
142
  props: {
139
143
  labelWidth: String,
@@ -195,25 +199,25 @@
195
199
  };
196
200
  }
197
201
  });
198
- const _hoisted_1$e = /* @__PURE__ */ vue.createElementVNode("i", {
202
+ const _hoisted_1$c = /* @__PURE__ */ vue.createElementVNode("i", {
199
203
  class: "el-icon-delete",
200
204
  style: { "color": "rgb(221, 75, 57)" }
201
205
  }, "\u53D6\u6D88", -1);
202
- const _hoisted_2$7 = [
203
- _hoisted_1$e
206
+ const _hoisted_2$5 = [
207
+ _hoisted_1$c
204
208
  ];
205
- const _hoisted_3$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
206
- function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
209
+ const _hoisted_3$3 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
210
+ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
207
211
  return _ctx.uiSelectMode ? (vue.openBlock(), vue.createElementBlock("div", {
208
212
  key: 0,
209
213
  class: "m-fields-ui-select",
210
214
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.cancelHandler && _ctx.cancelHandler(...args))
211
- }, _hoisted_2$7)) : (vue.openBlock(), vue.createElementBlock("div", {
215
+ }, _hoisted_2$5)) : (vue.openBlock(), vue.createElementBlock("div", {
212
216
  key: 1,
213
217
  class: "m-fields-ui-select",
214
218
  onClick: _cache[2] || (_cache[2] = (...args) => _ctx.startSelect && _ctx.startSelect(...args))
215
219
  }, [
216
- _hoisted_3$5,
220
+ _hoisted_3$3,
217
221
  vue.createElementVNode("span", null, vue.toDisplayString(_ctx.val ? _ctx.toName + "_" + _ctx.val : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"), 1),
218
222
  _ctx.val ? (vue.openBlock(), vue.createElementBlock("i", {
219
223
  key: 0,
@@ -222,7 +226,7 @@
222
226
  })) : vue.createCommentVNode("", true)
223
227
  ]));
224
228
  }
225
- var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
229
+ var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
226
230
 
227
231
  const toString = (v, language) => {
228
232
  let value = "";
@@ -239,7 +243,7 @@
239
243
  }
240
244
  return value;
241
245
  };
242
- const _sfc_main$h = vue.defineComponent({
246
+ const _sfc_main$i = vue.defineComponent({
243
247
  name: "magic-code-editor",
244
248
  props: {
245
249
  initValues: {
@@ -344,14 +348,14 @@
344
348
  };
345
349
  }
346
350
  });
347
- const _hoisted_1$d = {
351
+ const _hoisted_1$b = {
348
352
  ref: "codeEditor",
349
353
  class: "magic-code-editor"
350
354
  };
351
- function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
352
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$d, null, 512);
355
+ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
356
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, null, 512);
353
357
  }
354
- var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
358
+ var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
355
359
 
356
360
  let $TMAGIC_EDITOR = {};
357
361
  const setConfig = (option) => {
@@ -360,9 +364,6 @@
360
364
  const getConfig = (key) => $TMAGIC_EDITOR[key];
361
365
 
362
366
  class UndoRedo {
363
- elementList;
364
- listCursor;
365
- listMaxSize;
366
367
  constructor(listMaxSize = 200) {
367
368
  const minListMaxSize = 2;
368
369
  this.elementList = [];
@@ -453,7 +454,7 @@
453
454
  }
454
455
  let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
455
456
  for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
456
- returnValue = await afterMethod(...beforeArgs, returnValue);
457
+ returnValue = await afterMethod(returnValue, ...beforeArgs);
457
458
  if (isError(returnValue))
458
459
  throw returnValue;
459
460
  }
@@ -463,12 +464,12 @@
463
464
  }
464
465
  };
465
466
  class BaseService extends events.EventEmitter {
466
- pluginOptionsList = {};
467
- middleware = {};
468
- taskList = [];
469
- doingTask = false;
470
467
  constructor(methods = [], serialMethods = []) {
471
468
  super();
469
+ this.pluginOptionsList = {};
470
+ this.middleware = {};
471
+ this.taskList = [];
472
+ this.doingTask = false;
472
473
  methods.forEach((propertyName) => {
473
474
  const scope = this;
474
475
  const sourceMethod = scope[propertyName];
@@ -525,16 +526,22 @@
525
526
  }
526
527
 
527
528
  class History extends BaseService {
528
- state = vue.reactive({
529
- pageSteps: {},
530
- pageId: void 0,
531
- canRedo: false,
532
- canUndo: false
533
- });
534
529
  constructor() {
535
530
  super([]);
531
+ this.state = vue.reactive({
532
+ pageSteps: {},
533
+ pageId: void 0,
534
+ canRedo: false,
535
+ canUndo: false
536
+ });
536
537
  this.on("change", this.setCanUndoRedo);
537
538
  }
539
+ reset() {
540
+ this.state.pageSteps = {};
541
+ this.state.pageId = void 0;
542
+ this.state.canRedo = false;
543
+ this.state.canUndo = false;
544
+ }
538
545
  changePage(page) {
539
546
  if (!page)
540
547
  return;
@@ -598,12 +605,12 @@
598
605
  var historyService = new History();
599
606
 
600
607
  class Props extends BaseService {
601
- state = vue.reactive({
602
- propsConfigMap: {},
603
- propsValueMap: {}
604
- });
605
608
  constructor() {
606
609
  super(["setPropsConfig", "getPropsConfig", "setPropsValue", "getPropsValue"]);
610
+ this.state = vue.reactive({
611
+ propsConfigMap: {},
612
+ propsValueMap: {}
613
+ });
607
614
  }
608
615
  setPropsConfigs(configs) {
609
616
  Object.keys(configs).forEach((type) => {
@@ -640,8 +647,7 @@
640
647
  }
641
648
  return lodashEs.cloneDeep({
642
649
  ...getDefaultPropsValue(type),
643
- ...defaultValue,
644
- ...this.state.propsValueMap[type] || {}
650
+ ...lodashEs.mergeWith(this.state.propsValueMap[type] || {}, defaultValue)
645
651
  });
646
652
  }
647
653
  }
@@ -728,7 +734,7 @@
728
734
  const setTop2Middle = (node, parentNode, stage) => {
729
735
  const style = node.style || {};
730
736
  const height = style.height || 0;
731
- if (!stage || style.top || !parentNode.style || !utils.isNumber(height))
737
+ if (!stage || typeof style.top !== "undefined" || !parentNode.style || !utils.isNumber(height))
732
738
  return style;
733
739
  const { height: parentHeight } = parentNode.style;
734
740
  if (utils.isPage(parentNode)) {
@@ -826,16 +832,6 @@
826
832
  };
827
833
 
828
834
  class Editor$1 extends BaseService {
829
- isHistoryStateChange = false;
830
- state = vue.reactive({
831
- root: null,
832
- page: null,
833
- parent: null,
834
- node: null,
835
- stage: null,
836
- highlightNode: null,
837
- modifiedNodeIds: /* @__PURE__ */ new Map()
838
- });
839
835
  constructor() {
840
836
  super([
841
837
  "getLayout",
@@ -848,14 +844,27 @@
848
844
  "paste",
849
845
  "alignCenter",
850
846
  "moveLayer",
847
+ "move",
851
848
  "undo",
852
849
  "redo",
853
850
  "highlight"
854
851
  ], ["select", "update", "moveLayer"]);
852
+ this.isHistoryStateChange = false;
853
+ this.state = vue.reactive({
854
+ root: null,
855
+ page: null,
856
+ parent: null,
857
+ node: null,
858
+ stage: null,
859
+ highlightNode: null,
860
+ modifiedNodeIds: /* @__PURE__ */ new Map(),
861
+ pageLength: 0
862
+ });
855
863
  }
856
864
  set(name, value) {
857
865
  this.state[name] = value;
858
866
  if (name === "root") {
867
+ this.state.pageLength = value?.items?.length || 0;
859
868
  this.emit("root-change", value);
860
869
  }
861
870
  }
@@ -863,7 +872,7 @@
863
872
  return this.state[name];
864
873
  }
865
874
  getNodeInfo(id) {
866
- const root = this.get("root");
875
+ const root = vue.toRaw(this.get("root"));
867
876
  if (!root)
868
877
  return {};
869
878
  if (id === root.id) {
@@ -894,11 +903,13 @@
894
903
  const { parent } = this.getNodeInfo(id);
895
904
  return parent;
896
905
  }
897
- async getLayout(node) {
898
- if (node.layout) {
899
- return node.layout;
906
+ async getLayout(parent, node) {
907
+ if (node && typeof node !== "function" && isFixed(node))
908
+ return Layout.FIXED;
909
+ if (parent.layout) {
910
+ return parent.layout;
900
911
  }
901
- if (!node.style?.position) {
912
+ if (!parent.style?.position) {
902
913
  return Layout.RELATIVE;
903
914
  }
904
915
  return Layout.ABSOLUTE;
@@ -913,8 +924,31 @@
913
924
  } else {
914
925
  historyService.empty();
915
926
  }
927
+ this.emit("select", node);
916
928
  return node;
917
929
  }
930
+ async selectNextNode() {
931
+ const node = vue.toRaw(this.get("node"));
932
+ if (!node || utils.isPage(node) || node.type === schema.NodeType.ROOT)
933
+ return node;
934
+ const parent = vue.toRaw(this.getParentById(node.id));
935
+ if (!parent)
936
+ return node;
937
+ const index = getNodeIndex(node, parent);
938
+ const nextNode = parent.items[index + 1] || parent.items[0];
939
+ await this.select(nextNode);
940
+ this.get("stage")?.select(nextNode.id);
941
+ return nextNode;
942
+ }
943
+ async selectNextPage() {
944
+ const root = vue.toRaw(this.get("root"));
945
+ const page = vue.toRaw(this.get("page"));
946
+ const index = getNodeIndex(page, root);
947
+ const nextPage = root.items[index + 1] || root.items[0];
948
+ await this.select(nextPage);
949
+ this.get("stage")?.select(nextPage.id);
950
+ return nextPage;
951
+ }
918
952
  highlight(config2) {
919
953
  const { node } = this.selectedConfigExceptionHandler(config2);
920
954
  const currentHighlightNode = this.get("highlightNode");
@@ -922,10 +956,12 @@
922
956
  return;
923
957
  this.set("highlightNode", node);
924
958
  }
925
- async add({ type, ...config2 }, parent) {
959
+ async add(addNode, parent) {
960
+ const { type, ...config2 } = addNode;
926
961
  const curNode = this.get("node");
927
962
  let parentNode;
928
- if (type === schema.NodeType.PAGE) {
963
+ const isPage2 = type === schema.NodeType.PAGE;
964
+ if (isPage2) {
929
965
  parentNode = this.get("root");
930
966
  } else if (parent && typeof parent !== "function") {
931
967
  parentNode = parent;
@@ -936,7 +972,7 @@
936
972
  }
937
973
  if (!parentNode)
938
974
  throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
939
- const layout = await this.getLayout(parentNode);
975
+ const layout = await this.getLayout(vue.toRaw(parentNode), addNode);
940
976
  const newNode = initPosition({ ...vue.toRaw(await propsService.getPropsValue(type, config2)) }, layout, parentNode, this.get("stage"));
941
977
  if ((parentNode?.type === schema.NodeType.ROOT || curNode.type === schema.NodeType.ROOT) && newNode.type !== schema.NodeType.PAGE) {
942
978
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
@@ -950,6 +986,10 @@
950
986
  this.pushHistoryState();
951
987
  }
952
988
  stage?.select(newNode.id);
989
+ if (isPage2) {
990
+ this.state.pageLength += 1;
991
+ }
992
+ this.emit("add", newNode);
953
993
  return newNode;
954
994
  }
955
995
  async remove(node) {
@@ -968,9 +1008,20 @@
968
1008
  const stage = this.get("stage");
969
1009
  stage?.remove({ id: node.id, root: this.get("root") });
970
1010
  if (node.type === schema.NodeType.PAGE) {
1011
+ this.state.pageLength -= 1;
971
1012
  if (root.items[0]) {
972
1013
  await this.select(root.items[0]);
973
1014
  stage?.select(root.items[0].id);
1015
+ } else {
1016
+ this.set("node", null);
1017
+ this.set("parent", null);
1018
+ this.set("page", null);
1019
+ this.set("stage", null);
1020
+ this.set("highlightNode", null);
1021
+ this.resetModifiedNodeId();
1022
+ historyService.reset();
1023
+ this.emit("remove", node);
1024
+ return node;
974
1025
  }
975
1026
  } else {
976
1027
  await this.select(parent);
@@ -978,6 +1029,7 @@
978
1029
  }
979
1030
  this.addModifiedNodeId(parent.id);
980
1031
  this.pushHistoryState();
1032
+ this.emit("remove", node);
981
1033
  return node;
982
1034
  }
983
1035
  async update(config2) {
@@ -1021,6 +1073,7 @@
1021
1073
  }
1022
1074
  this.addModifiedNodeId(newConfig.id);
1023
1075
  this.pushHistoryState();
1076
+ this.emit("update", newConfig);
1024
1077
  return newConfig;
1025
1078
  }
1026
1079
  async sort(id1, id2) {
@@ -1064,7 +1117,7 @@
1064
1117
  async alignCenter(config2) {
1065
1118
  const parent = this.get("parent");
1066
1119
  const node = this.get("node");
1067
- const layout = await this.getLayout(parent);
1120
+ const layout = await this.getLayout(vue.toRaw(parent), vue.toRaw(node));
1068
1121
  if (layout === Layout.RELATIVE) {
1069
1122
  return;
1070
1123
  }
@@ -1101,6 +1154,26 @@
1101
1154
  await this.changeHistoryState(value);
1102
1155
  return value;
1103
1156
  }
1157
+ async move(left, top) {
1158
+ const node = vue.toRaw(this.get("node"));
1159
+ if (!node || utils.isPage(node))
1160
+ return;
1161
+ const { style, id } = node;
1162
+ if (!style || style.position !== "absolute")
1163
+ return;
1164
+ if (top && !utils.isNumber(style.top))
1165
+ return;
1166
+ if (left && !utils.isNumber(style.left))
1167
+ return;
1168
+ this.update({
1169
+ id,
1170
+ style: {
1171
+ ...style,
1172
+ left: Number(style.left) + left,
1173
+ top: Number(style.top) + top
1174
+ }
1175
+ });
1176
+ }
1104
1177
  destroy() {
1105
1178
  this.removeAllListeners();
1106
1179
  this.set("root", null);
@@ -1330,6 +1403,25 @@
1330
1403
  defaultValue: "100% 100%"
1331
1404
  }
1332
1405
  ]
1406
+ },
1407
+ {
1408
+ type: "fieldset",
1409
+ legend: "\u5B57\u4F53",
1410
+ items: [
1411
+ {
1412
+ name: "color",
1413
+ text: "\u989C\u8272",
1414
+ type: "colorPicker"
1415
+ },
1416
+ {
1417
+ name: "fontSize",
1418
+ text: "\u5927\u5C0F"
1419
+ },
1420
+ {
1421
+ name: "fontWeight",
1422
+ text: "\u7C97\u7EC6"
1423
+ }
1424
+ ]
1333
1425
  }
1334
1426
  ]
1335
1427
  }
@@ -1397,7 +1489,7 @@
1397
1489
  name: type
1398
1490
  });
1399
1491
 
1400
- const _sfc_main$g = vue.defineComponent({
1492
+ const _sfc_main$h = vue.defineComponent({
1401
1493
  components: { Plus: icons.Plus },
1402
1494
  setup() {
1403
1495
  const services = vue.inject("services");
@@ -1414,14 +1506,14 @@
1414
1506
  };
1415
1507
  }
1416
1508
  });
1417
- const _hoisted_1$c = { class: "m-editor-empty-panel" };
1418
- const _hoisted_2$6 = { class: "m-editor-empty-content" };
1419
- const _hoisted_3$4 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1420
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
1509
+ const _hoisted_1$a = { class: "m-editor-empty-panel" };
1510
+ const _hoisted_2$4 = { class: "m-editor-empty-content" };
1511
+ const _hoisted_3$2 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1512
+ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
1421
1513
  const _component_plus = vue.resolveComponent("plus");
1422
1514
  const _component_el_icon = vue.resolveComponent("el-icon");
1423
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, [
1424
- vue.createElementVNode("div", _hoisted_2$6, [
1515
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
1516
+ vue.createElementVNode("div", _hoisted_2$4, [
1425
1517
  vue.createElementVNode("div", {
1426
1518
  class: "m-editor-empty-button",
1427
1519
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.clickHandler && _ctx.clickHandler(...args))
@@ -1434,12 +1526,12 @@
1434
1526
  _: 1
1435
1527
  })
1436
1528
  ]),
1437
- _hoisted_3$4
1529
+ _hoisted_3$2
1438
1530
  ])
1439
1531
  ])
1440
1532
  ]);
1441
1533
  }
1442
- var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
1534
+ var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
1443
1535
 
1444
1536
  /*
1445
1537
  Copyright (c) 2018 Daybrush
@@ -1843,8 +1935,8 @@
1843
1935
  name: gesto
1844
1936
  license: MIT
1845
1937
  author: Daybrush
1846
- repository: git+https://github.com/daybrush/gesture.git
1847
- version: 1.5.0
1938
+ repository: git+https://github.com/daybrush/gesto.git
1939
+ version: 1.7.0
1848
1940
  */
1849
1941
 
1850
1942
  /*! *****************************************************************************
@@ -2013,19 +2105,6 @@
2013
2105
 
2014
2106
  var __proto = ClientStore.prototype;
2015
2107
 
2016
- __proto.addClients = function (clients) {
2017
- if (clients === void 0) {
2018
- clients = this.prevClients;
2019
- }
2020
-
2021
- var position = this.getPosition(clients);
2022
- var deltaX = position.deltaX,
2023
- deltaY = position.deltaY;
2024
- this.movement += Math.sqrt(deltaX * deltaX + deltaY * deltaY);
2025
- this.prevClients = clients;
2026
- return position;
2027
- };
2028
-
2029
2108
  __proto.getAngle = function (clients) {
2030
2109
  if (clients === void 0) {
2031
2110
  clients = this.prevClients;
@@ -2042,8 +2121,17 @@
2042
2121
  return getRotatiion(clients) - getRotatiion(this.startClients);
2043
2122
  };
2044
2123
 
2045
- __proto.getPosition = function (clients) {
2046
- return getPosition(clients || this.prevClients, this.prevClients, this.startClients);
2124
+ __proto.getPosition = function (clients, isAdd) {
2125
+ if (clients === void 0) {
2126
+ clients = this.prevClients;
2127
+ }
2128
+
2129
+ var position = getPosition(clients || this.prevClients, this.prevClients, this.startClients);
2130
+ var deltaX = position.deltaX,
2131
+ deltaY = position.deltaY;
2132
+ this.movement += Math.sqrt(deltaX * deltaX + deltaY * deltaY);
2133
+ this.prevClients = clients;
2134
+ return position;
2047
2135
  };
2048
2136
 
2049
2137
  __proto.getPositions = function (clients) {
@@ -2092,10 +2180,6 @@
2092
2180
  client.clientX -= deltaX;
2093
2181
  client.clientY -= deltaY;
2094
2182
  });
2095
- this.prevClients.forEach(function (client) {
2096
- client.clientX -= deltaX;
2097
- client.clientY -= deltaY;
2098
- });
2099
2183
  };
2100
2184
 
2101
2185
  return ClientStore;
@@ -2134,6 +2218,7 @@
2134
2218
  _this.targets = [];
2135
2219
  _this.prevTime = 0;
2136
2220
  _this.doubleFlag = false;
2221
+ _this._dragFlag = false;
2137
2222
 
2138
2223
  _this.onDragStart = function (e, isTrusted) {
2139
2224
  if (isTrusted === void 0) {
@@ -2164,7 +2249,8 @@
2164
2249
  if (checkInput || activeElement === target) {
2165
2250
  // force false or already focused.
2166
2251
  return false;
2167
- }
2252
+ } // no focus
2253
+
2168
2254
 
2169
2255
  if (activeElement && hasContentEditable && activeElement.isContentEditable && activeElement.contains(target)) {
2170
2256
  return false;
@@ -2180,6 +2266,7 @@
2180
2266
  _this.clientStores = [new ClientStore(getEventClients(e))];
2181
2267
  _this.flag = true;
2182
2268
  _this.isDrag = false;
2269
+ _this._dragFlag = true;
2183
2270
  _this.datas = {};
2184
2271
 
2185
2272
  if (preventRightClick && (e.which === 3 || e.button === 2)) {
@@ -2195,7 +2282,14 @@
2195
2282
  inputEvent: e,
2196
2283
  isTrusted: isTrusted,
2197
2284
  isDouble: _this.doubleFlag
2198
- }, _this.getCurrentStore().getPosition()));
2285
+ }, _this.getCurrentStore().getPosition(), {
2286
+ preventDefault: function () {
2287
+ e.preventDefault();
2288
+ },
2289
+ preventDrag: function () {
2290
+ _this._dragFlag = false;
2291
+ }
2292
+ }));
2199
2293
 
2200
2294
  if (result === false) {
2201
2295
  _this.initDrag();
@@ -2244,24 +2338,26 @@
2244
2338
 
2245
2339
  var result = _this.moveClients(clients, e, false);
2246
2340
 
2247
- if (_this.pinchFlag || result.deltaX || result.deltaY) {
2248
- var dragResult = _this.emit("drag", __assign({}, result, {
2249
- isScroll: !!isScroll,
2250
- inputEvent: e
2251
- }));
2341
+ if (_this._dragFlag) {
2342
+ if (_this.pinchFlag || result.deltaX || result.deltaY) {
2343
+ var dragResult = _this.emit("drag", __assign({}, result, {
2344
+ isScroll: !!isScroll,
2345
+ inputEvent: e
2346
+ }));
2252
2347
 
2253
- if (dragResult === false) {
2254
- _this.stop();
2348
+ if (dragResult === false) {
2349
+ _this.stop();
2255
2350
 
2256
- return;
2351
+ return;
2352
+ }
2257
2353
  }
2258
- }
2259
2354
 
2260
- if (_this.pinchFlag) {
2261
- _this.onPinch(e, clients);
2355
+ if (_this.pinchFlag) {
2356
+ _this.onPinch(e, clients);
2357
+ }
2262
2358
  }
2263
2359
 
2264
- _this.getCurrentStore().addClients(clients);
2360
+ _this.getCurrentStore().getPosition(clients, true);
2265
2361
  };
2266
2362
 
2267
2363
  _this.onDragEnd = function (e) {
@@ -2279,7 +2375,7 @@
2279
2375
 
2280
2376
  _this.flag = false;
2281
2377
 
2282
- var position = _this.getCurrentStore().getPosition();
2378
+ var position = _this._getPosition();
2283
2379
 
2284
2380
  var currentTime = now();
2285
2381
  var isDouble = !_this.isDrag && _this.doubleFlag;
@@ -2473,7 +2569,23 @@
2473
2569
  return this;
2474
2570
  };
2475
2571
  /**
2476
- * Set the event data while dragging.
2572
+ * Get the current event state while dragging.
2573
+ */
2574
+
2575
+
2576
+ __proto.getCurrentEvent = function (inputEvent) {
2577
+ return __assign({
2578
+ datas: this.datas
2579
+ }, this._getPosition(), {
2580
+ movement: this.getMovement(),
2581
+ isDrag: this.isDrag,
2582
+ isPinch: this.isPinch,
2583
+ isScroll: false,
2584
+ inputEvent: inputEvent
2585
+ });
2586
+ };
2587
+ /**
2588
+ * Get & Set the event data while dragging.
2477
2589
  */
2478
2590
 
2479
2591
 
@@ -2589,9 +2701,12 @@
2589
2701
  };
2590
2702
 
2591
2703
  __proto.moveClients = function (clients, inputEvent, isAdd) {
2592
- var store = this.getCurrentStore();
2593
- var position = store[isAdd ? "addClients" : "getPosition"](clients);
2594
- this.isDrag = true;
2704
+ var position = this._getPosition(clients, isAdd);
2705
+
2706
+ if (position.deltaX || position.deltaY) {
2707
+ this.isDrag = true;
2708
+ }
2709
+
2595
2710
  return __assign({
2596
2711
  datas: this.datas
2597
2712
  }, position, {
@@ -2603,12 +2718,31 @@
2603
2718
  });
2604
2719
  };
2605
2720
 
2721
+ __proto._getPosition = function (clients, isAdd) {
2722
+ var store = this.getCurrentStore();
2723
+ var position = store.getPosition(clients, isAdd);
2724
+
2725
+ var _a = this.clientStores.slice(1).reduce(function (prev, cur) {
2726
+ var storePosition = cur.getPosition();
2727
+ prev.distX += storePosition.distX;
2728
+ prev.distY += storePosition.distY;
2729
+ return prev;
2730
+ }, position),
2731
+ distX = _a.distX,
2732
+ distY = _a.distY;
2733
+
2734
+ return __assign({}, position, {
2735
+ distX: distX,
2736
+ distY: distY
2737
+ });
2738
+ };
2739
+
2606
2740
  return Gesto;
2607
2741
  }(EventEmitter$1);
2608
2742
 
2609
2743
  var Gesto$1 = Gesto;
2610
2744
 
2611
- const _sfc_main$f = vue.defineComponent({
2745
+ const _sfc_main$g = vue.defineComponent({
2612
2746
  name: "m-editor-resize",
2613
2747
  props: {
2614
2748
  type: {
@@ -2650,33 +2784,33 @@
2650
2784
  };
2651
2785
  }
2652
2786
  });
2653
- const _hoisted_1$b = {
2787
+ const _hoisted_1$9 = {
2654
2788
  ref: "target",
2655
2789
  class: "m-editor-resizer"
2656
2790
  };
2657
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2658
- return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$b, [
2791
+ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
2792
+ return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$9, [
2659
2793
  vue.renderSlot(_ctx.$slots, "default")
2660
2794
  ], 512);
2661
2795
  }
2662
- var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2796
+ var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
2663
2797
 
2664
- const _sfc_main$e = vue.defineComponent({
2798
+ const _sfc_main$f = vue.defineComponent({
2665
2799
  components: {
2666
2800
  AddPageBox,
2667
2801
  Resizer
2668
2802
  },
2669
2803
  setup() {
2670
- const services = vue.inject("services");
2671
- const root = vue.computed(() => services?.editorService.get("root"));
2804
+ const { editorService, uiService } = vue.inject("services") || {};
2805
+ const root = vue.computed(() => editorService?.get("root"));
2672
2806
  return {
2673
2807
  root,
2674
- pageLength: vue.computed(() => root.value?.items?.length || 0),
2675
- showSrc: vue.computed(() => services?.uiService.get("showSrc")),
2676
- columnWidth: vue.computed(() => services?.uiService.get("columnWidth")),
2808
+ pageLength: vue.computed(() => editorService?.get("pageLength") || 0),
2809
+ showSrc: vue.computed(() => uiService?.get("showSrc")),
2810
+ columnWidth: vue.computed(() => uiService?.get("columnWidth")),
2677
2811
  saveCode(value) {
2678
2812
  try {
2679
- services?.editorService.set("root", eval(value));
2813
+ editorService?.set("root", eval(value));
2680
2814
  } catch (e) {
2681
2815
  console.error(e);
2682
2816
  }
@@ -2684,24 +2818,24 @@
2684
2818
  };
2685
2819
  }
2686
2820
  });
2687
- const _hoisted_1$a = { class: "m-editor" };
2688
- const _hoisted_2$5 = {
2821
+ const _hoisted_1$8 = { class: "m-editor" };
2822
+ const _hoisted_2$3 = {
2689
2823
  key: 1,
2690
2824
  class: "m-editor-content"
2691
2825
  };
2692
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2826
+ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2693
2827
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
2694
2828
  const _component_resizer = vue.resolveComponent("resizer");
2695
2829
  const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
2696
2830
  const _component_add_page_box = vue.resolveComponent("add-page-box");
2697
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
2831
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
2698
2832
  vue.renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
2699
2833
  _ctx.showSrc ? (vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
2700
2834
  key: 0,
2701
2835
  class: "m-editor-content",
2702
2836
  "init-values": _ctx.root,
2703
2837
  onSave: _ctx.saveCode
2704
- }, null, 8, ["init-values", "onSave"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$5, [
2838
+ }, null, 8, ["init-values", "onSave"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$3, [
2705
2839
  vue.createElementVNode("div", {
2706
2840
  class: "m-editor-framework-left",
2707
2841
  style: vue.normalizeStyle(`width: ${_ctx.columnWidth?.left}px`)
@@ -2734,9 +2868,9 @@
2734
2868
  ]))
2735
2869
  ]);
2736
2870
  }
2737
- var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2871
+ var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2738
2872
 
2739
- const _sfc_main$d = vue.defineComponent({
2873
+ const _sfc_main$e = vue.defineComponent({
2740
2874
  name: "m-icon",
2741
2875
  components: { Edit: icons.Edit },
2742
2876
  props: {
@@ -2750,8 +2884,8 @@
2750
2884
  };
2751
2885
  }
2752
2886
  });
2753
- const _hoisted_1$9 = ["src"];
2754
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2887
+ const _hoisted_1$7 = ["src"];
2888
+ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2755
2889
  const _component_edit = vue.resolveComponent("edit");
2756
2890
  const _component_el_icon = vue.resolveComponent("el-icon");
2757
2891
  return !_ctx.icon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
@@ -2762,7 +2896,7 @@
2762
2896
  })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (vue.openBlock(), vue.createElementBlock("img", {
2763
2897
  key: 1,
2764
2898
  src: _ctx.icon
2765
- }, null, 8, _hoisted_1$9)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2899
+ }, null, 8, _hoisted_1$7)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2766
2900
  key: 2,
2767
2901
  class: vue.normalizeClass(_ctx.icon)
2768
2902
  }, null, 2)) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 3 }, {
@@ -2772,9 +2906,9 @@
2772
2906
  _: 1
2773
2907
  }));
2774
2908
  }
2775
- var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2909
+ var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2776
2910
 
2777
- const _sfc_main$c = vue.defineComponent({
2911
+ const _sfc_main$d = vue.defineComponent({
2778
2912
  components: { MIcon, ArrowDown: icons.ArrowDown },
2779
2913
  props: {
2780
2914
  data: {
@@ -2784,16 +2918,20 @@
2784
2918
  type: "text",
2785
2919
  display: false
2786
2920
  })
2921
+ },
2922
+ eventType: {
2923
+ type: String,
2924
+ default: "click"
2787
2925
  }
2788
2926
  },
2789
2927
  setup(props) {
2790
2928
  const services = vue.inject("services");
2791
2929
  const uiService = services?.uiService;
2792
- const zoomInHandler = () => uiService?.set("zoom", zoom.value + 0.1);
2793
- const zoomOutHandler = () => uiService?.set("zoom", zoom.value - 0.1);
2794
2930
  const zoom = vue.computed(() => uiService?.get("zoom") ?? 1);
2795
2931
  const showGuides = vue.computed(() => uiService?.get("showGuides") ?? true);
2796
2932
  const showRule = vue.computed(() => uiService?.get("showRule") ?? true);
2933
+ const zoomInHandler = () => uiService?.zoom(0.1);
2934
+ const zoomOutHandler = () => uiService?.zoom(-0.1);
2797
2935
  const item = vue.computed(() => {
2798
2936
  if (typeof props.data !== "string") {
2799
2937
  return props.data;
@@ -2810,7 +2948,7 @@
2810
2948
  case "delete":
2811
2949
  return {
2812
2950
  type: "button",
2813
- icon: icons.Delete,
2951
+ icon: vue.markRaw(icons.Delete),
2814
2952
  tooltip: "\u522A\u9664",
2815
2953
  disabled: () => services?.editorService.get("node")?.type === schema.NodeType.PAGE,
2816
2954
  handler: () => services?.editorService.remove(services?.editorService.get("node"))
@@ -2818,7 +2956,7 @@
2818
2956
  case "undo":
2819
2957
  return {
2820
2958
  type: "button",
2821
- icon: icons.Back,
2959
+ icon: vue.markRaw(icons.Back),
2822
2960
  tooltip: "\u540E\u9000",
2823
2961
  disabled: () => !services?.historyService.state.canUndo,
2824
2962
  handler: () => services?.editorService.undo()
@@ -2826,7 +2964,7 @@
2826
2964
  case "redo":
2827
2965
  return {
2828
2966
  type: "button",
2829
- icon: icons.Right,
2967
+ icon: vue.markRaw(icons.Right),
2830
2968
  tooltip: "\u524D\u8FDB",
2831
2969
  disabled: () => !services?.historyService.state.canRedo,
2832
2970
  handler: () => services?.editorService.redo()
@@ -2834,28 +2972,28 @@
2834
2972
  case "zoom-in":
2835
2973
  return {
2836
2974
  type: "button",
2837
- icon: icons.ZoomIn,
2975
+ icon: vue.markRaw(icons.ZoomIn),
2838
2976
  tooltip: "\u653E\u5927",
2839
2977
  handler: zoomInHandler
2840
2978
  };
2841
2979
  case "zoom-out":
2842
2980
  return {
2843
2981
  type: "button",
2844
- icon: icons.ZoomOut,
2982
+ icon: vue.markRaw(icons.ZoomOut),
2845
2983
  tooltip: "\u7E2E\u5C0F",
2846
2984
  handler: zoomOutHandler
2847
2985
  };
2848
2986
  case "rule":
2849
2987
  return {
2850
2988
  type: "button",
2851
- icon: icons.ScaleToOriginal,
2989
+ icon: vue.markRaw(icons.ScaleToOriginal),
2852
2990
  tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2853
2991
  handler: () => uiService?.set("showRule", !showRule.value)
2854
2992
  };
2855
2993
  case "guides":
2856
2994
  return {
2857
2995
  type: "button",
2858
- icon: icons.Grid,
2996
+ icon: vue.markRaw(icons.Grid),
2859
2997
  tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2860
2998
  handler: () => uiService?.set("showGuides", !showGuides.value)
2861
2999
  };
@@ -2876,9 +3014,16 @@
2876
3014
  }
2877
3015
  return item.value.disabled;
2878
3016
  });
3017
+ const buttonHandler = (item2, event) => {
3018
+ if (disabled.value)
3019
+ return;
3020
+ if (typeof item2.handler === "function" && services) {
3021
+ item2.handler?.(services, event);
3022
+ }
3023
+ };
2879
3024
  return {
2880
- ZoomIn: icons.ZoomIn,
2881
- ZoomOut: icons.ZoomOut,
3025
+ ZoomIn: vue.markRaw(icons.ZoomIn),
3026
+ ZoomOut: vue.markRaw(icons.ZoomOut),
2882
3027
  item,
2883
3028
  zoom,
2884
3029
  disabled,
@@ -2899,31 +3044,42 @@
2899
3044
  command.item.handler(services);
2900
3045
  }
2901
3046
  },
2902
- buttonHandler(item2) {
2903
- if (disabled.value)
3047
+ clickHandler(item2, event) {
3048
+ if (props.eventType !== "click")
2904
3049
  return;
2905
- if (typeof item2.handler === "function") {
2906
- item2.handler?.(services);
3050
+ if (item2.type === "button") {
3051
+ buttonHandler(item2, event);
3052
+ }
3053
+ },
3054
+ mousedownHandler(item2, event) {
3055
+ if (props.eventType !== "mousedown")
3056
+ return;
3057
+ if (item2.type === "button") {
3058
+ buttonHandler(item2, event);
3059
+ }
3060
+ },
3061
+ mouseupHandler(item2, event) {
3062
+ if (props.eventType !== "mouseup")
3063
+ return;
3064
+ if (item2.type === "button") {
3065
+ buttonHandler(item2, event);
2907
3066
  }
2908
3067
  }
2909
3068
  };
2910
3069
  }
2911
3070
  });
2912
- const _hoisted_1$8 = {
2913
- key: 0,
2914
- class: "menu-item"
2915
- };
2916
- const _hoisted_2$4 = {
3071
+ const _hoisted_1$6 = {
2917
3072
  key: 1,
2918
3073
  class: "menu-item-text"
2919
3074
  };
2920
- const _hoisted_3$3 = {
3075
+ const _hoisted_2$2 = {
2921
3076
  class: "menu-item-text",
2922
3077
  style: { "margin": "0 5px" }
2923
3078
  };
2924
- const _hoisted_4$2 = { class: "el-dropdown-link menubar-menu-button" };
2925
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
3079
+ const _hoisted_3$1 = { class: "el-dropdown-link menubar-menu-button" };
3080
+ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2926
3081
  const _component_el_divider = vue.resolveComponent("el-divider");
3082
+ const _component_tool_button = vue.resolveComponent("tool-button", true);
2927
3083
  const _component_m_icon = vue.resolveComponent("m-icon");
2928
3084
  const _component_el_button = vue.resolveComponent("el-button");
2929
3085
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -2932,60 +3088,66 @@
2932
3088
  const _component_el_dropdown_item = vue.resolveComponent("el-dropdown-item");
2933
3089
  const _component_el_dropdown_menu = vue.resolveComponent("el-dropdown-menu");
2934
3090
  const _component_el_dropdown = vue.resolveComponent("el-dropdown");
2935
- return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
3091
+ return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", {
3092
+ key: 0,
3093
+ class: vue.normalizeClass(["menu-item", _ctx.item.type]),
3094
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.clickHandler(_ctx.item, $event)),
3095
+ onMousedown: _cache[1] || (_cache[1] = ($event) => _ctx.mousedownHandler(_ctx.item, $event)),
3096
+ onMouseup: _cache[2] || (_cache[2] = ($event) => _ctx.mouseupHandler(_ctx.item, $event))
3097
+ }, [
2936
3098
  _ctx.item.type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
2937
3099
  key: 0,
2938
- direction: "vertical"
2939
- })) : _ctx.item.type === "text" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$4, vue.toDisplayString(_ctx.item.text), 1)) : _ctx.item.type === "zoom" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
2940
- vue.createVNode(_component_el_button, {
2941
- size: "small",
2942
- type: "text"
3100
+ direction: _ctx.item.direction || "vertical"
3101
+ }, null, 8, ["direction"])) : _ctx.item.type === "text" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, vue.toDisplayString(_ctx.item.text), 1)) : _ctx.item.type === "zoom" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
3102
+ vue.createVNode(_component_tool_button, {
3103
+ data: { type: "button", icon: _ctx.ZoomIn, handler: _ctx.zoomInHandler, tooltip: "\u653E\u5927" },
3104
+ "event-type": _ctx.eventType
3105
+ }, null, 8, ["data", "event-type"]),
3106
+ vue.createElementVNode("span", _hoisted_2$2, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
3107
+ vue.createVNode(_component_tool_button, {
3108
+ data: { type: "button", icon: _ctx.ZoomOut, handler: _ctx.zoomOutHandler, tooltip: "\u7F29\u5C0F" },
3109
+ "event-type": _ctx.eventType
3110
+ }, null, 8, ["data", "event-type"])
3111
+ ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
3112
+ _ctx.item.tooltip ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
3113
+ key: 0,
3114
+ effect: "dark",
3115
+ placement: "bottom-start",
3116
+ content: _ctx.item.tooltip
2943
3117
  }, {
2944
3118
  default: vue.withCtx(() => [
2945
- vue.createVNode(_component_m_icon, {
2946
- icon: _ctx.ZoomIn,
2947
- onClick: _ctx.zoomInHandler
2948
- }, null, 8, ["icon", "onClick"])
3119
+ vue.createVNode(_component_el_button, {
3120
+ size: "small",
3121
+ text: "",
3122
+ disabled: _ctx.disabled
3123
+ }, {
3124
+ default: vue.withCtx(() => [
3125
+ _ctx.item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3126
+ key: 0,
3127
+ icon: _ctx.item.icon
3128
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3129
+ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
3130
+ ]),
3131
+ _: 1
3132
+ }, 8, ["disabled"])
2949
3133
  ]),
2950
3134
  _: 1
2951
- }),
2952
- vue.createElementVNode("span", _hoisted_3$3, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
2953
- vue.createVNode(_component_el_button, {
3135
+ }, 8, ["content"])) : (vue.openBlock(), vue.createBlock(_component_el_button, {
3136
+ key: 1,
2954
3137
  size: "small",
2955
- type: "text"
3138
+ text: "",
3139
+ disabled: _ctx.disabled
2956
3140
  }, {
2957
3141
  default: vue.withCtx(() => [
2958
- vue.createVNode(_component_m_icon, {
2959
- icon: _ctx.ZoomOut,
2960
- onClick: _ctx.zoomOutHandler
2961
- }, null, 8, ["icon", "onClick"])
3142
+ _ctx.item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3143
+ key: 0,
3144
+ icon: _ctx.item.icon
3145
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3146
+ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
2962
3147
  ]),
2963
3148
  _: 1
2964
- })
2965
- ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
2966
- key: 3,
2967
- effect: "dark",
2968
- placement: "bottom-start",
2969
- content: _ctx.item.tooltip || _ctx.item.text
2970
- }, {
2971
- default: vue.withCtx(() => [
2972
- vue.createVNode(_component_el_button, {
2973
- size: "small",
2974
- type: "text",
2975
- disabled: _ctx.disabled,
2976
- onClick: _cache[0] || (_cache[0] = ($event) => _ctx.buttonHandler(_ctx.item))
2977
- }, {
2978
- default: vue.withCtx(() => [
2979
- vue.createVNode(_component_m_icon, {
2980
- icon: _ctx.item.icon
2981
- }, null, 8, ["icon"]),
2982
- vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
2983
- ]),
2984
- _: 1
2985
- }, 8, ["disabled"])
2986
- ]),
2987
- _: 1
2988
- }, 8, ["content"])) : _ctx.item.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
3149
+ }, 8, ["disabled"]))
3150
+ ], 64)) : _ctx.item.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
2989
3151
  key: 4,
2990
3152
  trigger: "click",
2991
3153
  disabled: _ctx.disabled,
@@ -3010,7 +3172,7 @@
3010
3172
  })) : vue.createCommentVNode("", true)
3011
3173
  ]),
3012
3174
  default: vue.withCtx(() => [
3013
- vue.createElementVNode("span", _hoisted_4$2, [
3175
+ vue.createElementVNode("span", _hoisted_3$1, [
3014
3176
  vue.createTextVNode(vue.toDisplayString(_ctx.item.text), 1),
3015
3177
  vue.createVNode(_component_el_icon, { class: "el-icon--right" }, {
3016
3178
  default: vue.withCtx(() => [
@@ -3022,11 +3184,11 @@
3022
3184
  ]),
3023
3185
  _: 1
3024
3186
  }, 8, ["disabled", "onCommand"])) : _ctx.item.type === "component" ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.item.component), vue.normalizeProps(vue.mergeProps({ key: 5 }, _ctx.item.props || {})), null, 16)) : vue.createCommentVNode("", true)
3025
- ])) : vue.createCommentVNode("", true);
3187
+ ], 34)) : vue.createCommentVNode("", true);
3026
3188
  }
3027
- var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
3189
+ var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
3028
3190
 
3029
- const _sfc_main$b = vue.defineComponent({
3191
+ const _sfc_main$c = vue.defineComponent({
3030
3192
  name: "nav-menu",
3031
3193
  components: { ToolButton },
3032
3194
  props: {
@@ -3046,7 +3208,7 @@
3046
3208
  };
3047
3209
  }
3048
3210
  });
3049
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
3211
+ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
3050
3212
  const _component_tool_button = vue.resolveComponent("tool-button");
3051
3213
  return vue.openBlock(), vue.createElementBlock("div", {
3052
3214
  class: "m-editor-nav-menu",
@@ -3068,9 +3230,9 @@
3068
3230
  }), 128))
3069
3231
  ], 4);
3070
3232
  }
3071
- var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3233
+ var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
3072
3234
 
3073
- const _sfc_main$a = vue.defineComponent({
3235
+ const _sfc_main$b = vue.defineComponent({
3074
3236
  name: "m-editor-props-panel",
3075
3237
  emits: ["mounted"],
3076
3238
  setup(props, { emit }) {
@@ -3116,7 +3278,7 @@
3116
3278
  };
3117
3279
  }
3118
3280
  });
3119
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3281
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
3120
3282
  const _component_m_form = vue.resolveComponent("m-form");
3121
3283
  return vue.openBlock(), vue.createBlock(_component_m_form, {
3122
3284
  class: "m-editor-props-panel",
@@ -3128,9 +3290,9 @@
3128
3290
  onChange: _ctx.submit
3129
3291
  }, null, 8, ["init-values", "config", "onChange"]);
3130
3292
  }
3131
- var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3293
+ var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3132
3294
 
3133
- const _sfc_main$9 = vue.defineComponent({
3295
+ const _sfc_main$a = vue.defineComponent({
3134
3296
  name: "ui-component-panel",
3135
3297
  components: { MIcon },
3136
3298
  setup() {
@@ -3151,13 +3313,23 @@
3151
3313
  type,
3152
3314
  ...data
3153
3315
  });
3316
+ },
3317
+ dragstartHandler({ text, type, data = {} }, e) {
3318
+ if (e.dataTransfer) {
3319
+ e.dataTransfer.effectAllowed = "move";
3320
+ e.dataTransfer.setData("data", serialize__default["default"]({
3321
+ name: text,
3322
+ type,
3323
+ ...data
3324
+ }).replace(/"(\w+)":\s/g, "$1: "));
3325
+ }
3154
3326
  }
3155
3327
  };
3156
3328
  }
3157
3329
  });
3158
- const _hoisted_1$7 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3159
- const _hoisted_2$3 = ["onClick"];
3160
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3330
+ const _hoisted_1$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3331
+ const _hoisted_2$1 = ["onClick", "onDragstart"];
3332
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3161
3333
  const _component_el_input = vue.resolveComponent("el-input");
3162
3334
  const _component_m_icon = vue.resolveComponent("m-icon");
3163
3335
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -3187,15 +3359,17 @@
3187
3359
  name: index
3188
3360
  }, {
3189
3361
  title: vue.withCtx(() => [
3190
- _hoisted_1$7,
3362
+ _hoisted_1$5,
3191
3363
  vue.createTextVNode(vue.toDisplayString(group.title), 1)
3192
3364
  ]),
3193
3365
  default: vue.withCtx(() => [
3194
3366
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(group.items, (item) => {
3195
3367
  return vue.openBlock(), vue.createElementBlock("div", {
3196
3368
  class: "component-item",
3369
+ draggable: "true",
3197
3370
  key: item.type,
3198
- onClick: ($event) => _ctx.appendComponent(item)
3371
+ onClick: ($event) => _ctx.appendComponent(item),
3372
+ onDragstart: ($event) => _ctx.dragstartHandler(item, $event)
3199
3373
  }, [
3200
3374
  vue.createVNode(_component_m_icon, {
3201
3375
  icon: item.icon
@@ -3210,7 +3384,7 @@
3210
3384
  ]),
3211
3385
  _: 2
3212
3386
  }, 1032, ["content"])
3213
- ], 8, _hoisted_2$3);
3387
+ ], 40, _hoisted_2$1);
3214
3388
  }), 128))
3215
3389
  ]),
3216
3390
  _: 2
@@ -3224,98 +3398,194 @@
3224
3398
  _: 1
3225
3399
  });
3226
3400
  }
3227
- var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3401
+ var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3402
+
3403
+ const _sfc_main$9 = vue.defineComponent({
3404
+ components: { ToolButton },
3405
+ props: {
3406
+ menuData: {
3407
+ type: Array,
3408
+ default: () => []
3409
+ }
3410
+ },
3411
+ setup() {
3412
+ const menu = vue.ref();
3413
+ const subMenu = vue.ref();
3414
+ const visible = vue.ref(false);
3415
+ const subMenuData = vue.ref([]);
3416
+ const menuStyle = vue.ref({
3417
+ left: "0",
3418
+ top: "0"
3419
+ });
3420
+ const hide = () => {
3421
+ visible.value = false;
3422
+ };
3423
+ vue.onMounted(() => {
3424
+ globalThis.addEventListener("mousedown", (e) => {
3425
+ if (!visible.value || e.target && menu.value?.contains(e.target)) {
3426
+ return;
3427
+ }
3428
+ hide();
3429
+ }, true);
3430
+ });
3431
+ return {
3432
+ menu,
3433
+ subMenu,
3434
+ visible,
3435
+ menuStyle,
3436
+ subMenuData,
3437
+ hide,
3438
+ show(e) {
3439
+ visible.value = true;
3440
+ vue.nextTick(() => {
3441
+ const menuHeight = menu.value?.clientHeight || 0;
3442
+ let top = e.clientY;
3443
+ if (menuHeight + e.clientY > document.body.clientHeight) {
3444
+ top = document.body.clientHeight - menuHeight;
3445
+ }
3446
+ menuStyle.value = {
3447
+ top: `${top}px`,
3448
+ left: `${e.clientX}px`
3449
+ };
3450
+ });
3451
+ },
3452
+ showSubMenu(item) {
3453
+ const menuItem = item;
3454
+ if (typeof item !== "object" || !menuItem.items?.length) {
3455
+ return;
3456
+ }
3457
+ subMenuData.value = menuItem.items;
3458
+ if (menu.value) {
3459
+ subMenu.value.show({
3460
+ clientX: menu.value.offsetLeft + menu.value.clientWidth,
3461
+ clientY: menu.value.offsetTop
3462
+ });
3463
+ }
3464
+ }
3465
+ };
3466
+ }
3467
+ });
3468
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3469
+ const _component_tool_button = vue.resolveComponent("tool-button");
3470
+ const _component_content_menu = vue.resolveComponent("content-menu", true);
3471
+ return _ctx.menuData.length ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", {
3472
+ key: 0,
3473
+ class: "magic-editor-content-menu",
3474
+ ref: "menu",
3475
+ style: vue.normalizeStyle(_ctx.menuStyle)
3476
+ }, [
3477
+ vue.createElementVNode("div", null, [
3478
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.menuData, (item, index) => {
3479
+ return vue.openBlock(), vue.createBlock(_component_tool_button, {
3480
+ "event-type": "mouseup",
3481
+ data: item,
3482
+ key: index,
3483
+ onMouseup: _ctx.hide,
3484
+ onMouseenter: ($event) => _ctx.showSubMenu(item)
3485
+ }, null, 8, ["data", "onMouseup", "onMouseenter"]);
3486
+ }), 128))
3487
+ ]),
3488
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3489
+ vue.createVNode(_component_content_menu, {
3490
+ class: "sub-menu",
3491
+ ref: "subMenu",
3492
+ "menu-data": _ctx.subMenuData
3493
+ }, null, 8, ["menu-data"])
3494
+ ]))
3495
+ ], 4)), [
3496
+ [vue.vShow, _ctx.visible]
3497
+ ]) : vue.createCommentVNode("", true);
3498
+ }
3499
+ var ContentMenu = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3228
3500
 
3229
3501
  const _sfc_main$8 = vue.defineComponent({
3230
- name: "magic-editor-content-menu",
3502
+ components: { ContentMenu },
3231
3503
  setup() {
3232
3504
  const services = vue.inject("services");
3233
- const subVisible = vue.ref(false);
3505
+ const menu = vue.ref();
3234
3506
  const node = vue.computed(() => services?.editorService.get("node"));
3235
- return {
3236
- subVisible,
3237
- node,
3238
- componentGroupList: vue.computed(() => services?.componentListService.getList()),
3239
- append(config) {
3507
+ const isRoot = vue.computed(() => node.value?.type === schema.NodeType.ROOT);
3508
+ const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
3509
+ const componentList = vue.computed(() => services?.componentListService.getList() || []);
3510
+ const createMenuItems = (group) => group.items.map((component) => ({
3511
+ text: component.text,
3512
+ type: "button",
3513
+ icon: component.icon,
3514
+ handler: () => {
3240
3515
  services?.editorService.add({
3241
- name: config.text,
3242
- type: config.type,
3243
- ...config.data || {}
3516
+ name: component.text,
3517
+ type: component.type,
3518
+ ...component.data || {}
3244
3519
  });
3245
- },
3246
- remove() {
3247
- node.value && services?.editorService.remove(node.value);
3248
- },
3249
- copy(node2) {
3250
- node2 && services?.editorService.copy(node2);
3251
- },
3252
- setSubVisitable(v) {
3253
- subVisible.value = v;
3520
+ }
3521
+ }));
3522
+ const getSubMenuData = vue.computed(() => {
3523
+ if (node.value?.type === "tabs") {
3524
+ return [
3525
+ {
3526
+ text: "\u6807\u7B7E\u9875",
3527
+ type: "button",
3528
+ icon: icons.Files,
3529
+ handler: () => {
3530
+ services?.editorService.add({
3531
+ type: "tab-pane"
3532
+ });
3533
+ }
3534
+ }
3535
+ ];
3536
+ }
3537
+ if (node.value?.items) {
3538
+ return componentList.value.reduce((subMenuData, group, index) => subMenuData.concat(createMenuItems(group), index < componentList.value.length - 1 ? [
3539
+ {
3540
+ type: "divider",
3541
+ direction: "horizontal"
3542
+ }
3543
+ ] : []), []) || [];
3544
+ }
3545
+ return [];
3546
+ });
3547
+ return {
3548
+ menu,
3549
+ menuData: vue.computed(() => [
3550
+ {
3551
+ type: "button",
3552
+ text: "\u65B0\u589E",
3553
+ icon: vue.markRaw(icons.Plus),
3554
+ display: () => node.value?.items,
3555
+ items: getSubMenuData.value
3556
+ },
3557
+ {
3558
+ type: "button",
3559
+ text: "\u590D\u5236",
3560
+ icon: vue.markRaw(icons.DocumentCopy),
3561
+ display: () => !isRoot.value,
3562
+ handler: () => {
3563
+ node.value && services?.editorService.copy(node.value);
3564
+ }
3565
+ },
3566
+ {
3567
+ type: "button",
3568
+ text: "\u5220\u9664",
3569
+ icon: vue.markRaw(icons.Delete),
3570
+ display: () => !isRoot.value && !isPage.value,
3571
+ handler: () => {
3572
+ node.value && services?.editorService.remove(node.value);
3573
+ }
3574
+ }
3575
+ ]),
3576
+ show(e) {
3577
+ menu.value?.show(e);
3254
3578
  }
3255
3579
  };
3256
3580
  }
3257
3581
  });
3258
- const _hoisted_1$6 = {
3259
- key: 0,
3260
- class: "magic-editor-content-menu"
3261
- };
3262
- const _hoisted_2$2 = ["onClick"];
3263
- const _hoisted_3$2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3264
3582
  function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3265
- const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
3266
- return _ctx.node ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
3267
- _ctx.node.items ? (vue.openBlock(), vue.createElementBlock("div", {
3268
- key: 0,
3269
- class: "magic-editor-content-menu-item",
3270
- onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisitable(true)),
3271
- onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisitable(false))
3272
- }, " \u65B0\u589E ", 32)) : vue.createCommentVNode("", true),
3273
- _ctx.node.type !== "app" ? (vue.openBlock(), vue.createElementBlock("div", {
3274
- key: 1,
3275
- class: "magic-editor-content-menu-item",
3276
- onClick: _cache[2] || (_cache[2] = () => _ctx.copy(_ctx.node))
3277
- }, "\u590D\u5236")) : vue.createCommentVNode("", true),
3278
- _ctx.node.type !== "app" && _ctx.node.type !== "page" ? (vue.openBlock(), vue.createElementBlock("div", {
3279
- key: 2,
3280
- class: "magic-editor-content-menu-item",
3281
- onClick: _cache[3] || (_cache[3] = () => _ctx.remove())
3282
- }, " \u5220\u9664 ")) : vue.createCommentVNode("", true),
3283
- vue.withDirectives(vue.createElementVNode("div", {
3284
- class: "subMenu",
3285
- onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisitable(true)),
3286
- onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisitable(false))
3287
- }, [
3288
- vue.createVNode(_component_el_scrollbar, null, {
3289
- default: vue.withCtx(() => [
3290
- _ctx.node.type === "tabs" ? (vue.openBlock(), vue.createElementBlock("div", {
3291
- key: 0,
3292
- class: "magic-editor-content-menu-item",
3293
- onClick: _cache[4] || (_cache[4] = () => _ctx.append({
3294
- type: "tab-pane"
3295
- }))
3296
- }, " \u6807\u7B7E ")) : _ctx.node.items ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(_ctx.componentGroupList, (list) => {
3297
- return vue.openBlock(), vue.createElementBlock("div", {
3298
- key: list.title
3299
- }, [
3300
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(list.items, (item) => {
3301
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
3302
- item ? (vue.openBlock(), vue.createElementBlock("div", {
3303
- class: "magic-editor-content-menu-item",
3304
- key: item.type,
3305
- onClick: () => _ctx.append(item)
3306
- }, vue.toDisplayString(item.text), 9, _hoisted_2$2)) : vue.createCommentVNode("", true)
3307
- ], 64);
3308
- }), 256)),
3309
- _hoisted_3$2
3310
- ]);
3311
- }), 128)) : vue.createCommentVNode("", true)
3312
- ]),
3313
- _: 1
3314
- })
3315
- ], 544), [
3316
- [vue.vShow, _ctx.subVisible]
3317
- ])
3318
- ])) : vue.createCommentVNode("", true);
3583
+ const _component_content_menu = vue.resolveComponent("content-menu");
3584
+ return vue.openBlock(), vue.createBlock(_component_content_menu, {
3585
+ "menu-data": _ctx.menuData,
3586
+ ref: "menu",
3587
+ style: { "overflow": "initial" }
3588
+ }, null, 8, ["menu-data"]);
3319
3589
  }
3320
3590
  var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3321
3591
 
@@ -3409,56 +3679,37 @@
3409
3679
  tree.value?.filter(val);
3410
3680
  }
3411
3681
  });
3412
- const useContentMenu = (editorService) => {
3413
- const menuStyle = vue.ref({
3414
- position: "absolute",
3415
- left: "0",
3416
- top: "0",
3417
- display: "none"
3418
- });
3419
- vue.onMounted(() => {
3420
- document.addEventListener("click", () => {
3421
- menuStyle.value.display = "none";
3422
- }, true);
3423
- });
3424
- return {
3425
- menuStyle,
3426
- contextmenu(event, data) {
3427
- const bodyHeight = globalThis.document.body.clientHeight;
3428
- const left = `${event.clientX + 20}px`;
3429
- let top = `${event.clientY - 10}px`;
3430
- if (event.clientY + 300 > bodyHeight) {
3431
- top = `${bodyHeight - 300}px`;
3432
- }
3433
- menuStyle.value.left = left;
3434
- menuStyle.value.top = top;
3435
- menuStyle.value.display = "";
3436
- select(data, editorService);
3437
- }
3438
- };
3439
- };
3440
3682
  const _sfc_main$7 = vue.defineComponent({
3441
3683
  name: "magic-editor-layer-panel",
3442
3684
  components: { LayerMenu },
3443
3685
  setup() {
3444
3686
  const services = vue.inject("services");
3445
3687
  const tree = vue.ref();
3688
+ const menu = vue.ref();
3446
3689
  const clicked = vue.ref(false);
3447
3690
  const editorService = services?.editorService;
3448
3691
  const highlightHandler = lodashEs.throttle((data) => {
3449
3692
  highlight(data, editorService);
3450
3693
  }, throttleTime);
3451
- const toogleClickFlag = () => {
3694
+ const toggleClickFlag = () => {
3452
3695
  clicked.value = !clicked.value;
3453
3696
  };
3454
3697
  const statusData = useStatus(tree, editorService);
3455
3698
  const canHighlight = vue.computed(() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value);
3699
+ editorService?.on("remove", () => {
3700
+ setTimeout(() => {
3701
+ tree.value?.getNode(editorService.get("node").id)?.updateChildren();
3702
+ }, 0);
3703
+ });
3456
3704
  return {
3457
3705
  tree,
3706
+ menu,
3458
3707
  ...statusData,
3459
3708
  ...useDrop(tree, editorService),
3460
3709
  ...useFilter(tree),
3461
- ...useContentMenu(editorService),
3710
+ highlightHandler,
3711
+ toggleClickFlag,
3712
+ canHighlight,
3462
3713
  clickHandler(data) {
3463
3714
  if (services?.uiService.get("uiSelectMode")) {
3464
3715
  document.dispatchEvent(new CustomEvent("ui-select", { detail: data }));
@@ -3467,13 +3718,15 @@
3467
3718
  tree.value?.setCurrentKey(data.id);
3468
3719
  select(data, editorService);
3469
3720
  },
3470
- highlightHandler,
3471
- toogleClickFlag,
3472
- canHighlight
3721
+ async contextmenu(event, data) {
3722
+ event.preventDefault();
3723
+ await select(data, editorService);
3724
+ menu.value?.show(event);
3725
+ }
3473
3726
  };
3474
3727
  }
3475
3728
  });
3476
- const _hoisted_1$5 = ["id", "onMouseenter"];
3729
+ const _hoisted_1$4 = ["id", "onMouseenter"];
3477
3730
  function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3478
3731
  const _component_el_input = vue.resolveComponent("el-input");
3479
3732
  const _component_el_tree = vue.resolveComponent("el-tree");
@@ -3514,8 +3767,8 @@
3514
3767
  vue.createElementVNode("div", {
3515
3768
  id: data.id,
3516
3769
  class: vue.normalizeClass(["cus-tree-node", { "cus-tree-node-hover": _ctx.canHighlight && data.id === _ctx.highlightNode?.id }]),
3517
- onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3518
- onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3770
+ onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toggleClickFlag && _ctx.toggleClickFlag(...args)),
3771
+ onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toggleClickFlag && _ctx.toggleClickFlag(...args)),
3519
3772
  onMouseenter: ($event) => _ctx.highlightHandler(data)
3520
3773
  }, [
3521
3774
  vue.renderSlot(_ctx.$slots, "layer-node-content", {
@@ -3524,14 +3777,12 @@
3524
3777
  }, () => [
3525
3778
  vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
3526
3779
  ])
3527
- ], 42, _hoisted_1$5)
3780
+ ], 42, _hoisted_1$4)
3528
3781
  ]),
3529
3782
  _: 3
3530
3783
  }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : vue.createCommentVNode("", true),
3531
3784
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3532
- vue.createVNode(_component_layer_menu, {
3533
- style: vue.normalizeStyle(_ctx.menuStyle)
3534
- }, null, 8, ["style"])
3785
+ vue.createVNode(_component_layer_menu, { ref: "menu" }, null, 512)
3535
3786
  ]))
3536
3787
  ]),
3537
3788
  _: 3
@@ -3583,7 +3834,7 @@
3583
3834
  };
3584
3835
  }
3585
3836
  });
3586
- const _hoisted_1$4 = {
3837
+ const _hoisted_1$3 = {
3587
3838
  key: 1,
3588
3839
  class: "magic-editor-tab-panel-title"
3589
3840
  };
@@ -3611,7 +3862,7 @@
3611
3862
  key: 0,
3612
3863
  icon: item.icon
3613
3864
  }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3614
- item.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$4, vue.toDisplayString(item.text), 1)) : vue.createCommentVNode("", true)
3865
+ item.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, vue.toDisplayString(item.text), 1)) : vue.createCommentVNode("", true)
3615
3866
  ])
3616
3867
  ]),
3617
3868
  default: vue.withCtx(() => [
@@ -3701,12 +3952,14 @@
3701
3952
  };
3702
3953
  };
3703
3954
  const _sfc_main$5 = vue.defineComponent({
3704
- components: { ArrowLeftBold: icons.ArrowLeftBold, ArrowRightBold: icons.ArrowRightBold, CaretBottom: icons.CaretBottom, Plus: icons.Plus },
3955
+ components: { ArrowLeftBold: icons.ArrowLeftBold, ArrowRightBold: icons.ArrowRightBold, CaretBottom: icons.CaretBottom, Plus: icons.Plus, ToolButton },
3705
3956
  setup() {
3706
3957
  const services = vue.inject("services");
3707
3958
  const editorService = services?.editorService;
3708
3959
  const root = vue.computed(() => editorService?.get("root"));
3709
3960
  return {
3961
+ Delete: vue.markRaw(icons.Delete),
3962
+ DocumentCopy: vue.markRaw(icons.DocumentCopy),
3710
3963
  ...useScroll(root),
3711
3964
  root,
3712
3965
  page: vue.computed(() => editorService?.get("page")),
@@ -3735,23 +3988,22 @@
3735
3988
  };
3736
3989
  }
3737
3990
  });
3738
- const _hoisted_1$3 = {
3991
+ const _hoisted_1$2 = {
3739
3992
  class: "m-editor-page-bar",
3740
3993
  ref: "pageBar"
3741
3994
  };
3742
- const _hoisted_2$1 = ["onClick"];
3743
- const _hoisted_3$1 = { class: "m-editor-page-bar-title" };
3744
- const _hoisted_4$1 = ["onClick"];
3745
- const _hoisted_5 = ["onClick"];
3995
+ const _hoisted_2 = ["onClick"];
3996
+ const _hoisted_3 = { class: "m-editor-page-bar-title" };
3746
3997
  function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3747
3998
  const _component_plus = vue.resolveComponent("plus");
3748
3999
  const _component_el_icon = vue.resolveComponent("el-icon");
3749
4000
  const _component_arrow_left_bold = vue.resolveComponent("arrow-left-bold");
3750
4001
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
4002
+ const _component_tool_button = vue.resolveComponent("tool-button");
3751
4003
  const _component_caret_bottom = vue.resolveComponent("caret-bottom");
3752
4004
  const _component_el_popover = vue.resolveComponent("el-popover");
3753
4005
  const _component_arrow_right_bold = vue.resolveComponent("arrow-right-bold");
3754
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [
4006
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
3755
4007
  vue.createElementVNode("div", {
3756
4008
  id: "m-editor-page-bar-add-icon",
3757
4009
  class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
@@ -3788,7 +4040,7 @@
3788
4040
  class: vue.normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3789
4041
  onClick: ($event) => _ctx.switchPage(item)
3790
4042
  }, [
3791
- vue.createElementVNode("div", _hoisted_3$1, [
4043
+ vue.createElementVNode("div", _hoisted_3, [
3792
4044
  vue.renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3793
4045
  vue.createVNode(_component_el_tooltip, {
3794
4046
  effect: "dark",
@@ -3803,6 +4055,7 @@
3803
4055
  ])
3804
4056
  ]),
3805
4057
  vue.createVNode(_component_el_popover, {
4058
+ "popper-class": "page-bar-popover",
3806
4059
  placement: "top",
3807
4060
  width: 160,
3808
4061
  trigger: "hover"
@@ -3818,20 +4071,28 @@
3818
4071
  default: vue.withCtx(() => [
3819
4072
  vue.createElementVNode("div", null, [
3820
4073
  vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3821
- vue.createElementVNode("div", {
3822
- class: "magic-editor-content-menu-item",
3823
- onClick: () => _ctx.copy(item)
3824
- }, "\u590D\u5236", 8, _hoisted_4$1),
3825
- vue.createElementVNode("div", {
3826
- class: "magic-editor-content-menu-item",
3827
- onClick: () => _ctx.remove(item)
3828
- }, "\u5220\u9664", 8, _hoisted_5)
4074
+ vue.createVNode(_component_tool_button, {
4075
+ data: {
4076
+ type: "button",
4077
+ text: "\u590D\u5236",
4078
+ icon: _ctx.DocumentCopy,
4079
+ handler: () => _ctx.copy(item)
4080
+ }
4081
+ }, null, 8, ["data"]),
4082
+ vue.createVNode(_component_tool_button, {
4083
+ data: {
4084
+ type: "button",
4085
+ text: "\u5220\u9664",
4086
+ icon: _ctx.Delete,
4087
+ handler: () => _ctx.remove(item)
4088
+ }
4089
+ }, null, 8, ["data"])
3829
4090
  ])
3830
4091
  ])
3831
4092
  ]),
3832
4093
  _: 2
3833
4094
  }, 1024)
3834
- ], 10, _hoisted_2$1);
4095
+ ], 10, _hoisted_2);
3835
4096
  }), 128))
3836
4097
  ], 4)) : vue.createCommentVNode("", true),
3837
4098
  _ctx.canScroll ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -3851,33 +4112,104 @@
3851
4112
  var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3852
4113
 
3853
4114
  class ScrollViewer$1 {
3854
- enter = false;
3855
- targetEnter = false;
3856
- keydown = false;
3857
- container;
3858
- target;
3859
- zoom = 1;
3860
- scrollLeft = 0;
3861
- scrollTop = 0;
3862
- x = 0;
3863
- y = 0;
3864
- resizeObserver = new ResizeObserver((entries) => {
3865
- for (const { contentRect } of entries) {
3866
- const { width, height } = contentRect;
3867
- const targetRect = this.target.getBoundingClientRect();
3868
- const targetWidth = targetRect.width * this.zoom;
3869
- const targetMarginTop = Number(this.target.style.marginTop) || 0;
3870
- const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3871
- if (targetWidth < width) {
3872
- this.target._left = 0;
3873
- }
3874
- if (targetHeight < height) {
3875
- this.target._top = 0;
4115
+ constructor(options) {
4116
+ this.enter = false;
4117
+ this.targetEnter = false;
4118
+ this.keydown = false;
4119
+ this.zoom = 1;
4120
+ this.scrollLeft = 0;
4121
+ this.scrollTop = 0;
4122
+ this.x = 0;
4123
+ this.y = 0;
4124
+ this.resizeObserver = new ResizeObserver((entries) => {
4125
+ for (const { contentRect } of entries) {
4126
+ const { width, height } = contentRect;
4127
+ const targetRect = this.target.getBoundingClientRect();
4128
+ const targetWidth = targetRect.width * this.zoom;
4129
+ const targetMarginTop = Number(this.target.style.marginTop) || 0;
4130
+ const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
4131
+ if (targetWidth < width) {
4132
+ this.target._left = 0;
4133
+ }
4134
+ if (targetHeight < height) {
4135
+ this.target._top = 0;
4136
+ }
4137
+ this.scroll();
3876
4138
  }
4139
+ });
4140
+ this.wheelHandler = (event) => {
4141
+ if (this.targetEnter)
4142
+ return;
4143
+ const { deltaX, deltaY, currentTarget } = event;
4144
+ if (currentTarget !== this.container)
4145
+ return;
4146
+ this.setScrollOffset(deltaX, deltaY);
3877
4147
  this.scroll();
3878
- }
3879
- });
3880
- constructor(options) {
4148
+ this.scrollLeft = this.target._left;
4149
+ this.scrollTop = this.target._top;
4150
+ };
4151
+ this.mouseEnterHandler = () => {
4152
+ this.enter = true;
4153
+ };
4154
+ this.mouseLeaveHandler = () => {
4155
+ this.enter = false;
4156
+ };
4157
+ this.targetMouseEnterHandler = () => {
4158
+ this.targetEnter = true;
4159
+ };
4160
+ this.targetMouseLeaveHandler = () => {
4161
+ this.targetEnter = false;
4162
+ };
4163
+ this.mousedownHandler = (event) => {
4164
+ if (!this.keydown)
4165
+ return;
4166
+ event.stopImmediatePropagation();
4167
+ event.stopPropagation();
4168
+ this.target.style.cursor = "grabbing";
4169
+ this.x = event.clientX;
4170
+ this.y = event.clientY;
4171
+ document.addEventListener("mousemove", this.mousemoveHandler);
4172
+ document.addEventListener("mouseup", this.mouseupHandler);
4173
+ };
4174
+ this.mouseupHandler = () => {
4175
+ this.x = 0;
4176
+ this.y = 0;
4177
+ this.scrollLeft = this.target._left;
4178
+ this.scrollTop = this.target._top;
4179
+ this.removeHandler();
4180
+ };
4181
+ this.mousemoveHandler = (event) => {
4182
+ event.stopImmediatePropagation();
4183
+ event.stopPropagation();
4184
+ const deltaX = event.clientX - this.x;
4185
+ const deltaY = event.clientY - this.y;
4186
+ this.setScrollOffset(deltaX, deltaY);
4187
+ this.scroll();
4188
+ };
4189
+ this.keydownHandler = (event) => {
4190
+ if (event.code === Keys.ESCAPE && this.enter) {
4191
+ event.preventDefault();
4192
+ event.stopImmediatePropagation();
4193
+ event.stopPropagation();
4194
+ }
4195
+ if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
4196
+ return;
4197
+ }
4198
+ this.keydown = true;
4199
+ this.target.style.cursor = "grab";
4200
+ this.container.addEventListener("mousedown", this.mousedownHandler);
4201
+ };
4202
+ this.keyupHandler = (event) => {
4203
+ if (event.code !== Keys.ESCAPE || !this.keydown) {
4204
+ return;
4205
+ }
4206
+ event.preventDefault();
4207
+ event.stopImmediatePropagation();
4208
+ event.stopPropagation();
4209
+ this.keydown = false;
4210
+ event.preventDefault();
4211
+ this.removeHandler();
4212
+ };
3881
4213
  this.container = options.container;
3882
4214
  this.target = options.target;
3883
4215
  this.zoom = options.zoom;
@@ -3913,79 +4245,6 @@
3913
4245
  document.removeEventListener("mousemove", this.mousemoveHandler);
3914
4246
  document.removeEventListener("mouseup", this.mouseupHandler);
3915
4247
  }
3916
- wheelHandler = (event) => {
3917
- if (this.targetEnter)
3918
- return;
3919
- const { deltaX, deltaY, currentTarget } = event;
3920
- if (currentTarget !== this.container)
3921
- return;
3922
- this.setScrollOffset(deltaX, deltaY);
3923
- this.scroll();
3924
- this.scrollLeft = this.target._left;
3925
- this.scrollTop = this.target._top;
3926
- };
3927
- mouseEnterHandler = () => {
3928
- this.enter = true;
3929
- };
3930
- mouseLeaveHandler = () => {
3931
- this.enter = false;
3932
- };
3933
- targetMouseEnterHandler = () => {
3934
- this.targetEnter = true;
3935
- };
3936
- targetMouseLeaveHandler = () => {
3937
- this.targetEnter = false;
3938
- };
3939
- mousedownHandler = (event) => {
3940
- if (!this.keydown)
3941
- return;
3942
- event.stopImmediatePropagation();
3943
- event.stopPropagation();
3944
- this.target.style.cursor = "grabbing";
3945
- this.x = event.clientX;
3946
- this.y = event.clientY;
3947
- document.addEventListener("mousemove", this.mousemoveHandler);
3948
- document.addEventListener("mouseup", this.mouseupHandler);
3949
- };
3950
- mouseupHandler = () => {
3951
- this.x = 0;
3952
- this.y = 0;
3953
- this.scrollLeft = this.target._left;
3954
- this.scrollTop = this.target._top;
3955
- this.removeHandler();
3956
- };
3957
- mousemoveHandler = (event) => {
3958
- event.stopImmediatePropagation();
3959
- event.stopPropagation();
3960
- const deltaX = event.clientX - this.x;
3961
- const deltaY = event.clientY - this.y;
3962
- this.setScrollOffset(deltaX, deltaY);
3963
- this.scroll();
3964
- };
3965
- keydownHandler = (event) => {
3966
- if (event.code === Keys.ESCAPE && this.enter) {
3967
- event.preventDefault();
3968
- event.stopImmediatePropagation();
3969
- event.stopPropagation();
3970
- }
3971
- if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3972
- return;
3973
- }
3974
- this.keydown = true;
3975
- this.target.style.cursor = "grab";
3976
- this.container.addEventListener("mousedown", this.mousedownHandler);
3977
- };
3978
- keyupHandler = (event) => {
3979
- if (event.code !== Keys.ESCAPE || !this.keydown) {
3980
- return;
3981
- }
3982
- event.preventDefault();
3983
- event.stopImmediatePropagation();
3984
- event.stopPropagation();
3985
- this.keydown = false;
3986
- event.preventDefault();
3987
- this.removeHandler();
3988
- };
3989
4248
  setScrollOffset(deltaX, deltaY) {
3990
4249
  const { width, height } = this.container.getBoundingClientRect();
3991
4250
  const targetRect = this.target.getBoundingClientRect();
@@ -4046,19 +4305,19 @@
4046
4305
  el,
4047
4306
  style: vue.computed(() => `
4048
4307
  width: ${props.width}px;
4049
- height: ${props.height}px;
4308
+ height: ${(props.height || 0) - 40}px;
4050
4309
  position: absolute;
4051
4310
  margin-top: 30px;
4052
4311
  `)
4053
4312
  };
4054
4313
  }
4055
4314
  });
4056
- const _hoisted_1$2 = {
4315
+ const _hoisted_1$1 = {
4057
4316
  class: "m-editor-scroll-viewer-container",
4058
4317
  ref: "container"
4059
4318
  };
4060
4319
  function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
4061
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
4320
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
4062
4321
  vue.createElementVNode("div", {
4063
4322
  ref: "el",
4064
4323
  style: vue.normalizeStyle(_ctx.style)
@@ -4070,7 +4329,7 @@
4070
4329
  var ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
4071
4330
 
4072
4331
  const _sfc_main$3 = vue.defineComponent({
4073
- name: "magic-editor-ui-viewer-menu",
4332
+ components: { ContentMenu },
4074
4333
  setup() {
4075
4334
  const services = vue.inject("services");
4076
4335
  const editorService = services?.editorService;
@@ -4079,6 +4338,7 @@
4079
4338
  const canCenter = vue.ref(false);
4080
4339
  const node = vue.computed(() => editorService?.get("node"));
4081
4340
  const parent = vue.computed(() => editorService?.get("parent"));
4341
+ const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
4082
4342
  vue.onMounted(() => {
4083
4343
  const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY);
4084
4344
  canPaste.value = data !== "undefined" && !!data;
@@ -4091,133 +4351,114 @@
4091
4351
  }, { immediate: true });
4092
4352
  return {
4093
4353
  menu,
4094
- canPaste,
4095
- canDelete: vue.computed(() => node.value?.type !== schema.NodeType.PAGE),
4096
- canMoveZPos: vue.computed(() => node.value?.type !== schema.NodeType.PAGE),
4097
- canCenter,
4098
- center() {
4099
- node.value && editorService?.alignCenter(node.value);
4100
- },
4101
- copy() {
4102
- node.value && editorService?.copy(node.value);
4103
- canPaste.value = true;
4104
- },
4105
- paste() {
4106
- const top = menu.value?.offsetTop || 0;
4107
- const left = menu.value?.offsetLeft || 0;
4108
- editorService?.paste({ left, top });
4109
- },
4110
- remove() {
4111
- node.value && editorService?.remove(node.value);
4112
- },
4113
- top() {
4114
- editorService?.moveLayer(LayerOffset.TOP);
4115
- },
4116
- bottom() {
4117
- editorService?.moveLayer(LayerOffset.BOTTOM);
4118
- },
4119
- topItem() {
4120
- editorService?.moveLayer(1);
4121
- },
4122
- bottomItem() {
4123
- editorService?.moveLayer(-1);
4124
- },
4125
- clearGuides() {
4126
- editorService?.get("stage").clearGuides();
4354
+ menuData: vue.reactive([
4355
+ {
4356
+ type: "button",
4357
+ text: "\u6C34\u5E73\u5C45\u4E2D",
4358
+ display: () => canCenter.value,
4359
+ handler: () => {
4360
+ node.value && editorService?.alignCenter(node.value);
4361
+ }
4362
+ },
4363
+ {
4364
+ type: "button",
4365
+ text: "\u590D\u5236",
4366
+ icon: vue.markRaw(icons.DocumentCopy),
4367
+ handler: () => {
4368
+ node.value && editorService?.copy(node.value);
4369
+ canPaste.value = true;
4370
+ }
4371
+ },
4372
+ {
4373
+ type: "button",
4374
+ text: "\u7C98\u8D34",
4375
+ display: () => canPaste.value,
4376
+ handler: () => {
4377
+ const top = menu.value?.$el.offsetTop || 0;
4378
+ const left = menu.value?.$el.offsetLeft || 0;
4379
+ editorService?.paste({ left, top });
4380
+ }
4381
+ },
4382
+ {
4383
+ type: "divider",
4384
+ direction: "horizontal",
4385
+ display: () => !isPage.value
4386
+ },
4387
+ {
4388
+ type: "button",
4389
+ text: "\u4E0A\u79FB\u4E00\u5C42",
4390
+ icon: vue.markRaw(icons.Top),
4391
+ display: () => !isPage.value,
4392
+ handler: () => {
4393
+ editorService?.moveLayer(1);
4394
+ }
4395
+ },
4396
+ {
4397
+ type: "button",
4398
+ text: "\u4E0B\u79FB\u4E00\u5C42",
4399
+ icon: vue.markRaw(icons.Bottom),
4400
+ display: () => !isPage.value,
4401
+ handler: () => {
4402
+ editorService?.moveLayer(-1);
4403
+ }
4404
+ },
4405
+ {
4406
+ type: "button",
4407
+ text: "\u7F6E\u9876",
4408
+ display: () => !isPage.value,
4409
+ handler: () => {
4410
+ editorService?.moveLayer(LayerOffset.TOP);
4411
+ }
4412
+ },
4413
+ {
4414
+ type: "button",
4415
+ text: "\u7F6E\u5E95",
4416
+ display: () => !isPage.value,
4417
+ handler: () => {
4418
+ editorService?.moveLayer(LayerOffset.BOTTOM);
4419
+ }
4420
+ },
4421
+ {
4422
+ type: "divider",
4423
+ direction: "horizontal",
4424
+ display: () => !isPage.value
4425
+ },
4426
+ {
4427
+ type: "button",
4428
+ text: "\u5220\u9664",
4429
+ icon: icons.Delete,
4430
+ display: () => !isPage.value,
4431
+ handler: () => {
4432
+ node.value && editorService?.remove(node.value);
4433
+ }
4434
+ },
4435
+ {
4436
+ type: "divider",
4437
+ direction: "horizontal"
4438
+ },
4439
+ {
4440
+ type: "button",
4441
+ text: "\u6E05\u7A7A\u53C2\u8003\u7EBF",
4442
+ handler: () => {
4443
+ editorService?.get("stage").clearGuides();
4444
+ }
4445
+ }
4446
+ ]),
4447
+ show(e) {
4448
+ menu.value?.show(e);
4127
4449
  }
4128
4450
  };
4129
4451
  }
4130
4452
  });
4131
- const _hoisted_1$1 = {
4132
- class: "magic-editor-content-menu",
4133
- ref: "menu"
4134
- };
4135
- const _hoisted_2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4136
- const _hoisted_3 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4137
- const _hoisted_4 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4138
4453
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
4139
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
4140
- vue.createElementVNode("div", null, [
4141
- _ctx.canCenter ? (vue.openBlock(), vue.createElementBlock("div", {
4142
- key: 0,
4143
- class: "magic-editor-content-menu-item",
4144
- onClick: _cache[0] || (_cache[0] = () => _ctx.center())
4145
- }, "\u6C34\u5E73\u5C45\u4E2D")) : vue.createCommentVNode("", true),
4146
- vue.createElementVNode("div", {
4147
- class: "magic-editor-content-menu-item",
4148
- onClick: _cache[1] || (_cache[1] = () => _ctx.copy())
4149
- }, "\u590D\u5236"),
4150
- _ctx.canPaste ? (vue.openBlock(), vue.createElementBlock("div", {
4151
- key: 1,
4152
- class: "magic-editor-content-menu-item",
4153
- onClick: _cache[2] || (_cache[2] = (...args) => _ctx.paste && _ctx.paste(...args))
4154
- }, "\u7C98\u8D34")) : vue.createCommentVNode("", true),
4155
- _ctx.canMoveZPos ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
4156
- _hoisted_2,
4157
- vue.createElementVNode("div", {
4158
- class: "magic-editor-content-menu-item",
4159
- onClick: _cache[3] || (_cache[3] = (...args) => _ctx.topItem && _ctx.topItem(...args))
4160
- }, "\u4E0A\u79FB\u4E00\u5C42"),
4161
- vue.createElementVNode("div", {
4162
- class: "magic-editor-content-menu-item",
4163
- onClick: _cache[4] || (_cache[4] = (...args) => _ctx.bottomItem && _ctx.bottomItem(...args))
4164
- }, "\u4E0B\u79FB\u4E00\u5C42"),
4165
- vue.createElementVNode("div", {
4166
- class: "magic-editor-content-menu-item",
4167
- onClick: _cache[5] || (_cache[5] = (...args) => _ctx.top && _ctx.top(...args))
4168
- }, "\u7F6E\u9876"),
4169
- vue.createElementVNode("div", {
4170
- class: "magic-editor-content-menu-item",
4171
- onClick: _cache[6] || (_cache[6] = (...args) => _ctx.bottom && _ctx.bottom(...args))
4172
- }, "\u7F6E\u5E95")
4173
- ], 64)) : vue.createCommentVNode("", true),
4174
- _ctx.canDelete ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
4175
- _hoisted_3,
4176
- vue.createElementVNode("div", {
4177
- class: "magic-editor-content-menu-item",
4178
- onClick: _cache[7] || (_cache[7] = () => _ctx.remove())
4179
- }, "\u5220\u9664")
4180
- ], 64)) : vue.createCommentVNode("", true),
4181
- _hoisted_4,
4182
- vue.createElementVNode("div", {
4183
- class: "magic-editor-content-menu-item",
4184
- onClick: _cache[8] || (_cache[8] = (...args) => _ctx.clearGuides && _ctx.clearGuides(...args))
4185
- }, "\u6E05\u7A7A\u53C2\u8003\u7EBF")
4186
- ])
4187
- ], 512);
4454
+ const _component_content_menu = vue.resolveComponent("content-menu");
4455
+ return vue.openBlock(), vue.createBlock(_component_content_menu, {
4456
+ "menu-data": _ctx.menuData,
4457
+ ref: "menu"
4458
+ }, null, 8, ["menu-data"]);
4188
4459
  }
4189
4460
  var ViewerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3]]);
4190
4461
 
4191
- const useMenu = () => {
4192
- const menu = vue.ref();
4193
- const menuStyle = vue.ref({
4194
- display: "none",
4195
- left: "0",
4196
- top: "0"
4197
- });
4198
- vue.onMounted(() => {
4199
- document.addEventListener("click", () => {
4200
- menuStyle.value.display = "none";
4201
- }, true);
4202
- });
4203
- return {
4204
- menu,
4205
- menuStyle,
4206
- contextmenuHandler(e) {
4207
- e.preventDefault();
4208
- const menuHeight = menu.value?.$el.clientHeight;
4209
- let top = e.clientY;
4210
- if (menuHeight + e.clientY > document.body.clientHeight) {
4211
- top = document.body.clientHeight - menuHeight;
4212
- }
4213
- menuStyle.value = {
4214
- display: "block",
4215
- top: `${top}px`,
4216
- left: `${e.clientX}px`
4217
- };
4218
- }
4219
- };
4220
- };
4221
4462
  const _sfc_main$2 = vue.defineComponent({
4222
4463
  name: "magic-stage",
4223
4464
  components: {
@@ -4244,11 +4485,12 @@
4244
4485
  const services = vue.inject("services");
4245
4486
  const stageWrap = vue.ref();
4246
4487
  const stageContainer = vue.ref();
4488
+ const menu = vue.ref();
4247
4489
  const stageRect = vue.computed(() => services?.uiService.get("stageRect"));
4248
4490
  const uiSelectMode = vue.computed(() => services?.uiService.get("uiSelectMode"));
4249
4491
  const root = vue.computed(() => services?.editorService.get("root"));
4250
4492
  const page = vue.computed(() => services?.editorService.get("page"));
4251
- const zoom = vue.computed(() => services?.uiService.get("zoom"));
4493
+ const zoom = vue.computed(() => services?.uiService.get("zoom") || 1);
4252
4494
  const node = vue.computed(() => services?.editorService.get("node"));
4253
4495
  let stage = null;
4254
4496
  let runtime = null;
@@ -4330,9 +4572,36 @@
4330
4572
  return {
4331
4573
  stageWrap,
4332
4574
  stageContainer,
4575
+ menu,
4333
4576
  stageRect,
4334
4577
  zoom,
4335
- ...useMenu()
4578
+ contextmenuHandler(e2) {
4579
+ e2.preventDefault();
4580
+ menu.value?.show(e2);
4581
+ },
4582
+ dragoverHandler(e2) {
4583
+ e2.preventDefault();
4584
+ if (e2.dataTransfer) {
4585
+ e2.dataTransfer.dropEffect = "move";
4586
+ }
4587
+ },
4588
+ async dropHandler(e) {
4589
+ e.preventDefault();
4590
+ if (e.dataTransfer && page.value && stageContainer.value && stage) {
4591
+ const config = eval(`(${e.dataTransfer.getData("data")})`);
4592
+ const layout = await services?.editorService.getLayout(page.value);
4593
+ const containerRect = stageContainer.value.getBoundingClientRect();
4594
+ const { scrollTop, scrollLeft } = stage.mask;
4595
+ if (layout === Layout.ABSOLUTE) {
4596
+ config.style = {
4597
+ position: "absolute",
4598
+ top: e.clientY - containerRect.top + scrollTop,
4599
+ left: e.clientX - containerRect.left + scrollLeft
4600
+ };
4601
+ }
4602
+ services?.editorService.add(config, page.value);
4603
+ }
4604
+ }
4336
4605
  };
4337
4606
  }
4338
4607
  });
@@ -4350,14 +4619,13 @@
4350
4619
  vue.createElementVNode("div", {
4351
4620
  class: "m-editor-stage-container",
4352
4621
  ref: "stageContainer",
4622
+ style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`),
4353
4623
  onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args)),
4354
- style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`)
4624
+ onDrop: _cache[1] || (_cache[1] = (...args) => _ctx.dropHandler && _ctx.dropHandler(...args)),
4625
+ onDragover: _cache[2] || (_cache[2] = (...args) => _ctx.dragoverHandler && _ctx.dragoverHandler(...args))
4355
4626
  }, null, 36),
4356
4627
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
4357
- vue.createVNode(_component_viewer_menu, {
4358
- ref: "menu",
4359
- style: vue.normalizeStyle(_ctx.menuStyle)
4360
- }, null, 8, ["style"])
4628
+ vue.createVNode(_component_viewer_menu, { ref: "menu" }, null, 512)
4361
4629
  ]))
4362
4630
  ]),
4363
4631
  _: 1
@@ -4391,29 +4659,74 @@
4391
4659
  const mouseenterHandler = () => {
4392
4660
  workspace.value?.focus();
4393
4661
  };
4394
- const mouseleaveHandler = () => {
4395
- workspace.value?.blur();
4396
- };
4397
4662
  vue.onMounted(() => {
4398
4663
  workspace.value?.addEventListener("mouseenter", mouseenterHandler);
4399
- workspace.value?.addEventListener("mouseleave", mouseleaveHandler);
4400
4664
  keycon = new KeyController__default["default"](workspace.value);
4401
- keycon.keyup("delete", () => {
4402
- node.value && services?.editorService.remove(node.value);
4403
- }).keyup(["ctrl", "c"], () => {
4665
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
4666
+ const ctrl = isMac ? "meta" : "ctrl";
4667
+ keycon.keyup("delete", (e) => {
4668
+ e.inputEvent.preventDefault();
4669
+ if (!node.value || utils.isPage(node.value))
4670
+ return;
4671
+ services?.editorService.remove(node.value);
4672
+ }).keydown([ctrl, "c"], (e) => {
4673
+ e.inputEvent.preventDefault();
4404
4674
  node.value && services?.editorService.copy(node.value);
4405
- }).keyup(["ctrl", "v"], () => {
4675
+ }).keydown([ctrl, "v"], (e) => {
4676
+ e.inputEvent.preventDefault();
4406
4677
  node.value && services?.editorService.paste();
4407
- }).keyup(["ctrl", "x"], () => {
4408
- if (node.value && services) {
4409
- services.editorService.copy(node.value);
4410
- services.editorService.remove(node.value);
4411
- }
4678
+ }).keydown([ctrl, "x"], (e) => {
4679
+ e.inputEvent.preventDefault();
4680
+ if (!node.value || utils.isPage(node.value))
4681
+ return;
4682
+ services?.editorService.copy(node.value);
4683
+ services?.editorService.remove(node.value);
4684
+ }).keydown([ctrl, "z"], (e) => {
4685
+ e.inputEvent.preventDefault();
4686
+ services?.editorService.undo();
4687
+ }).keydown([ctrl, "shift", "z"], (e) => {
4688
+ e.inputEvent.preventDefault();
4689
+ services?.editorService.redo();
4690
+ }).keydown("up", (e) => {
4691
+ e.inputEvent.preventDefault();
4692
+ services?.editorService.move(0, -1);
4693
+ }).keydown("down", (e) => {
4694
+ e.inputEvent.preventDefault();
4695
+ services?.editorService.move(0, 1);
4696
+ }).keydown("left", (e) => {
4697
+ e.inputEvent.preventDefault();
4698
+ services?.editorService.move(-1, 0);
4699
+ }).keydown("right", (e) => {
4700
+ e.inputEvent.preventDefault();
4701
+ services?.editorService.move(1, 0);
4702
+ }).keydown([ctrl, "up"], (e) => {
4703
+ e.inputEvent.preventDefault();
4704
+ services?.editorService.move(0, -10);
4705
+ }).keydown([ctrl, "down"], (e) => {
4706
+ e.inputEvent.preventDefault();
4707
+ services?.editorService.move(0, 10);
4708
+ }).keydown([ctrl, "left"], (e) => {
4709
+ e.inputEvent.preventDefault();
4710
+ services?.editorService.move(-10, 0);
4711
+ }).keydown([ctrl, "right"], (e) => {
4712
+ e.inputEvent.preventDefault();
4713
+ services?.editorService.move(10, 0);
4714
+ }).keydown("tab", (e) => {
4715
+ e.inputEvent.preventDefault();
4716
+ services?.editorService.selectNextNode();
4717
+ }).keydown([ctrl, "tab"], (e) => {
4718
+ e.inputEvent.preventDefault();
4719
+ services?.editorService.selectNextPage();
4720
+ }).keydown([ctrl, "="], (e) => {
4721
+ e.inputEvent.preventDefault();
4722
+ services?.uiService.zoom(0.1);
4723
+ }).keydown([ctrl, "-"], (e) => {
4724
+ e.inputEvent.preventDefault();
4725
+ services?.uiService.zoom(-0.1);
4412
4726
  });
4413
4727
  });
4414
4728
  vue.onUnmounted(() => {
4415
4729
  workspace.value?.removeEventListener("mouseenter", mouseenterHandler);
4416
- workspace.value?.removeEventListener("mouseleave", mouseleaveHandler);
4417
4730
  keycon.destroy();
4418
4731
  });
4419
4732
  return {
@@ -4453,11 +4766,11 @@
4453
4766
  var Workspace = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
4454
4767
 
4455
4768
  class ComponentList extends BaseService {
4456
- state = vue.reactive({
4457
- list: []
4458
- });
4459
4769
  constructor() {
4460
4770
  super([]);
4771
+ this.state = vue.reactive({
4772
+ list: []
4773
+ });
4461
4774
  }
4462
4775
  setList(componentGroupList) {
4463
4776
  this.state.list = componentGroupList;
@@ -4523,6 +4836,11 @@
4523
4836
  get(name) {
4524
4837
  return state[name];
4525
4838
  }
4839
+ zoom(zoom) {
4840
+ this.set("zoom", (this.get("zoom") * 100 + zoom * 100) / 100);
4841
+ if (this.get("zoom") < 0.1)
4842
+ this.set("zoom", 0.1);
4843
+ }
4526
4844
  setColumnWidth({ left, center, right }) {
4527
4845
  const columnWidth = {
4528
4846
  ...vue.toRaw(this.get("columnWidth"))
@@ -4747,6 +5065,7 @@
4747
5065
  exports.PropsPanel = PropsPanel;
4748
5066
  exports.TMagicCodeEditor = CodeEditor;
4749
5067
  exports.TMagicEditor = Editor;
5068
+ exports.ToolButton = ToolButton;
4750
5069
  exports.change2Fixed = change2Fixed;
4751
5070
  exports.debug = debug;
4752
5071
  exports["default"] = index;
@@ -4775,8 +5094,7 @@
4775
5094
  exports.uiService = uiService;
4776
5095
  exports.warn = warn;
4777
5096
 
4778
- Object.defineProperty(exports, '__esModule', { value: true });
4779
- exports[Symbol.toStringTag] = 'Module';
5097
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
4780
5098
 
4781
5099
  }));
4782
5100
  //# sourceMappingURL=tmagic-editor.umd.js.map