@tmagic/editor 1.0.0-beta.7 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +5432 -0
  2. package/README.md +1 -0
  3. package/coverage/clover.xml +1560 -0
  4. package/coverage/coverage-final.json +36 -0
  5. package/coverage/lcov-report/base.css +224 -0
  6. package/coverage/lcov-report/block-navigation.js +87 -0
  7. package/coverage/lcov-report/favicon.png +0 -0
  8. package/coverage/lcov-report/index.html +206 -0
  9. package/coverage/lcov-report/prettify.css +1 -0
  10. package/coverage/lcov-report/prettify.js +2 -0
  11. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  12. package/coverage/lcov-report/sorter.js +196 -0
  13. package/coverage/lcov-report/src/Editor.vue.html +787 -0
  14. package/coverage/lcov-report/src/components/ContentMenu.vue.html +406 -0
  15. package/coverage/lcov-report/src/components/Icon.vue.html +172 -0
  16. package/coverage/lcov-report/src/components/ScrollViewer.vue.html +283 -0
  17. package/coverage/lcov-report/src/components/ToolButton.vue.html +772 -0
  18. package/coverage/lcov-report/src/components/index.html +161 -0
  19. package/coverage/lcov-report/src/index.html +131 -0
  20. package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +214 -0
  21. package/coverage/lcov-report/src/layouts/Framework.vue.html +304 -0
  22. package/coverage/lcov-report/src/layouts/NavMenu.vue.html +208 -0
  23. package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +319 -0
  24. package/coverage/lcov-report/src/layouts/Resizer.vue.html +268 -0
  25. package/coverage/lcov-report/src/layouts/index.html +176 -0
  26. package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +358 -0
  27. package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +421 -0
  28. package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +775 -0
  29. package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +226 -0
  30. package/coverage/lcov-report/src/layouts/sidebar/TabPane.vue.html +289 -0
  31. package/coverage/lcov-report/src/layouts/sidebar/index.html +176 -0
  32. package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +718 -0
  33. package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +757 -0
  34. package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +532 -0
  35. package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +586 -0
  36. package/coverage/lcov-report/src/layouts/workspace/index.html +161 -0
  37. package/coverage/lcov-report/src/services/BaseService.ts.html +643 -0
  38. package/coverage/lcov-report/src/services/componentList.ts.html +229 -0
  39. package/coverage/lcov-report/src/services/editor.ts.html +2077 -0
  40. package/coverage/lcov-report/src/services/events.ts.html +331 -0
  41. package/coverage/lcov-report/src/services/history.ts.html +478 -0
  42. package/coverage/lcov-report/src/services/index.html +206 -0
  43. package/coverage/lcov-report/src/services/props.ts.html +415 -0
  44. package/coverage/lcov-report/src/services/ui.ts.html +580 -0
  45. package/coverage/lcov-report/src/type.ts.html +850 -0
  46. package/coverage/lcov-report/src/utils/compose.ts.html +184 -0
  47. package/coverage/lcov-report/src/utils/config.ts.html +172 -0
  48. package/coverage/lcov-report/src/utils/editor.ts.html +838 -0
  49. package/coverage/lcov-report/src/utils/index.html +221 -0
  50. package/coverage/lcov-report/src/utils/index.ts.html +151 -0
  51. package/coverage/lcov-report/src/utils/logger.ts.html +226 -0
  52. package/coverage/lcov-report/src/utils/props.ts.html +796 -0
  53. package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +733 -0
  54. package/coverage/lcov-report/src/utils/undo-redo.ts.html +313 -0
  55. package/coverage/lcov.info +3708 -0
  56. package/dist/style.css +94 -38
  57. package/dist/tmagic-editor.es.js +1474 -817
  58. package/dist/tmagic-editor.es.js.map +1 -1
  59. package/dist/tmagic-editor.umd.js +1475 -819
  60. package/dist/tmagic-editor.umd.js.map +1 -1
  61. package/dist/types/src/Editor.vue.d.ts +1 -1
  62. package/dist/types/src/components/ToolButton.vue.d.ts +12 -1
  63. package/dist/types/src/fields/UISelect.vue.d.ts +4 -1
  64. package/dist/types/src/index.d.ts +1 -0
  65. package/dist/types/src/layouts/CodeEditor.vue.d.ts +13 -4
  66. package/dist/types/src/layouts/PropsPanel.vue.d.ts +2 -1
  67. package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +2 -1
  68. package/dist/types/src/layouts/sidebar/Sidebar.vue.d.ts +2 -3
  69. package/dist/types/src/layouts/sidebar/TabPane.vue.d.ts +14 -0
  70. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +10 -3
  71. package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +4 -6
  72. package/dist/types/src/services/BaseService.d.ts +4 -1
  73. package/dist/types/src/services/editor.d.ts +16 -6
  74. package/dist/types/src/services/history.d.ts +1 -0
  75. package/dist/types/src/services/props.d.ts +2 -2
  76. package/dist/types/src/services/ui.d.ts +2 -0
  77. package/dist/types/src/type.d.ts +16 -9
  78. package/dist/types/src/utils/editor.d.ts +5 -4
  79. package/dist/types/src/utils/polyfills.d.ts +0 -0
  80. package/package.json +37 -12
  81. package/src/components/ContentMenu.vue +107 -0
  82. package/src/components/ScrollViewer.vue +1 -1
  83. package/src/components/ToolButton.vue +72 -31
  84. package/src/fields/UISelect.vue +14 -6
  85. package/src/index.ts +2 -0
  86. package/src/layouts/AddPageBox.vue +3 -1
  87. package/src/layouts/CodeEditor.vue +20 -10
  88. package/src/layouts/Framework.vue +6 -6
  89. package/src/layouts/PropsPanel.vue +5 -3
  90. package/src/layouts/sidebar/ComponentListPanel.vue +25 -3
  91. package/src/layouts/sidebar/LayerMenu.vue +91 -96
  92. package/src/layouts/sidebar/LayerPanel.vue +80 -59
  93. package/src/layouts/sidebar/Sidebar.vue +13 -52
  94. package/src/layouts/sidebar/TabPane.vue +68 -0
  95. package/src/layouts/workspace/PageBar.vue +145 -17
  96. package/src/layouts/workspace/Stage.vue +55 -64
  97. package/src/layouts/workspace/ViewerMenu.vue +107 -68
  98. package/src/layouts/workspace/Workspace.vue +106 -18
  99. package/src/services/BaseService.ts +70 -22
  100. package/src/services/editor.ts +198 -63
  101. package/src/services/history.ts +7 -0
  102. package/src/services/props.ts +3 -3
  103. package/src/services/ui.ts +35 -5
  104. package/src/theme/common/var.scss +3 -2
  105. package/src/theme/component-list-panel.scss +2 -0
  106. package/src/theme/content-menu.scss +33 -26
  107. package/src/theme/layer-panel.scss +10 -0
  108. package/src/theme/nav-menu.scss +6 -2
  109. package/src/theme/page-bar.scss +42 -2
  110. package/src/theme/props-panel.scss +20 -6
  111. package/src/type.ts +17 -9
  112. package/src/utils/editor.ts +35 -9
  113. package/{vite.config.ts → src/utils/polyfills.ts} +4 -12
  114. package/src/utils/props.ts +20 -1
  115. package/dist/types/src/layouts/sidebar/LayerMenu.vue.d.ts +0 -31
  116. package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +0 -973
  117. package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -192
  118. package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
  119. package/tsconfig.json +0 -9
@@ -1,14 +1,14 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('serialize-javascript'), require('monaco-editor'), require('@element-plus/icons'), require('lodash-es'), require('@tmagic/utils'), require('events'), require('@tmagic/core'), require('element-plus'), require('@tmagic/stage')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'vue', 'serialize-javascript', 'monaco-editor', '@element-plus/icons', 'lodash-es', '@tmagic/utils', 'events', '@tmagic/core', 'element-plus', '@tmagic/stage'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicEditor = {}, global.vue, global.serialize, global.monaco, global.icons, global.lodashEs, global.utils, global.events, global.core, global.elementPlus, global.StageCore));
5
- })(this, (function (exports, vue, serialize, monaco, icons, lodashEs, utils, events, core, elementPlus, StageCore) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('serialize-javascript'), require('@element-plus/icons'), require('lodash-es'), require('monaco-editor'), require('@tmagic/schema'), require('@tmagic/utils'), require('events'), require('@tmagic/core'), require('element-plus'), require('keycon'), require('@tmagic/stage')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'vue', 'serialize-javascript', '@element-plus/icons', 'lodash-es', 'monaco-editor', '@tmagic/schema', '@tmagic/utils', 'events', '@tmagic/core', 'element-plus', 'keycon', '@tmagic/stage'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicEditor = {}, global.vue, global.serialize, global.icons, global.lodashEs, global.monaco, global.schema, global.utils, global.events, global.core, global.elementPlus, global.KeyController, global.StageCore));
5
+ })(this, (function (exports, vue, serialize, icons, lodashEs, monaco, schema, utils, events, core, elementPlus, KeyController, StageCore) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
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') {
@@ -26,8 +26,13 @@
26
26
 
27
27
  var serialize__default = /*#__PURE__*/_interopDefaultLegacy(serialize);
28
28
  var monaco__namespace = /*#__PURE__*/_interopNamespace(monaco);
29
+ var KeyController__default = /*#__PURE__*/_interopDefaultLegacy(KeyController);
29
30
  var StageCore__default = /*#__PURE__*/_interopDefaultLegacy(StageCore);
30
31
 
32
+ if (typeof window.global === "undefined") {
33
+ window.global = window;
34
+ }
35
+
31
36
  var _export_sfc = (sfc, props) => {
32
37
  const target = sfc.__vccOpts || sfc;
33
38
  for (const [key, val] of props) {
@@ -36,7 +41,7 @@
36
41
  return target;
37
42
  };
38
43
 
39
- const _sfc_main$k = vue.defineComponent({
44
+ const _sfc_main$m = vue.defineComponent({
40
45
  name: "m-fields-vs-code",
41
46
  props: ["model", "name", "config", "prop"],
42
47
  emits: ["change"],
@@ -53,7 +58,7 @@
53
58
  };
54
59
  }
55
60
  });
56
- function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
61
+ function _sfc_render$m(_ctx, _cache, $props, $setup, $data, $options) {
57
62
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
58
63
  return vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
59
64
  style: vue.normalizeStyle(`height: ${_ctx.height}`),
@@ -62,9 +67,9 @@
62
67
  onSave: _ctx.save
63
68
  }, null, 8, ["style", "init-values", "language", "onSave"]);
64
69
  }
65
- var Code = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
70
+ var Code = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$m]]);
66
71
 
67
- const _sfc_main$j = vue.defineComponent({
72
+ const _sfc_main$l = vue.defineComponent({
68
73
  name: "m-fields-code-link",
69
74
  props: {
70
75
  config: {
@@ -119,7 +124,7 @@
119
124
  };
120
125
  }
121
126
  });
122
- function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
127
+ function _sfc_render$l(_ctx, _cache, $props, $setup, $data, $options) {
123
128
  const _component_m_fields_link = vue.resolveComponent("m-fields-link");
124
129
  return vue.openBlock(), vue.createBlock(_component_m_fields_link, {
125
130
  config: _ctx.formConfig,
@@ -128,11 +133,11 @@
128
133
  onChange: _ctx.changeHandler
129
134
  }, null, 8, ["config", "model", "onChange"]);
130
135
  }
131
- var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
136
+ var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$l]]);
132
137
 
133
138
  var UISelect_vue_vue_type_style_index_0_lang = '';
134
139
 
135
- const _sfc_main$i = vue.defineComponent({
140
+ const _sfc_main$k = vue.defineComponent({
136
141
  name: "m-fields-ui-select",
137
142
  props: {
138
143
  labelWidth: String,
@@ -170,6 +175,9 @@
170
175
  }
171
176
  };
172
177
  return {
178
+ Delete: vue.markRaw(icons.Delete),
179
+ Pointer: vue.markRaw(icons.Pointer),
180
+ Close: vue.markRaw(icons.Close),
173
181
  val,
174
182
  uiSelectMode,
175
183
  toName: vue.computed(() => {
@@ -194,34 +202,64 @@
194
202
  };
195
203
  }
196
204
  });
197
- const _hoisted_1$d = /* @__PURE__ */ vue.createElementVNode("i", {
198
- class: "el-icon-delete",
199
- style: { "color": "rgb(221, 75, 57)" }
200
- }, "\u53D6\u6D88", -1);
201
- const _hoisted_2$7 = [
202
- _hoisted_1$d
203
- ];
204
- const _hoisted_3$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
205
- function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
205
+ const _hoisted_1$c = /* @__PURE__ */ vue.createTextVNode("\u53D6\u6D88");
206
+ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
207
+ const _component_el_button = vue.resolveComponent("el-button");
208
+ const _component_el_tooltip = vue.resolveComponent("el-tooltip");
206
209
  return _ctx.uiSelectMode ? (vue.openBlock(), vue.createElementBlock("div", {
207
210
  key: 0,
208
211
  class: "m-fields-ui-select",
209
212
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.cancelHandler && _ctx.cancelHandler(...args))
210
- }, _hoisted_2$7)) : (vue.openBlock(), vue.createElementBlock("div", {
213
+ }, [
214
+ vue.createVNode(_component_el_button, {
215
+ type: "danger",
216
+ icon: _ctx.Delete,
217
+ text: "",
218
+ style: { "padding": "0" }
219
+ }, {
220
+ default: vue.withCtx(() => [
221
+ _hoisted_1$c
222
+ ]),
223
+ _: 1
224
+ }, 8, ["icon"])
225
+ ])) : (vue.openBlock(), vue.createElementBlock("div", {
211
226
  key: 1,
212
227
  class: "m-fields-ui-select",
213
- onClick: _cache[2] || (_cache[2] = (...args) => _ctx.startSelect && _ctx.startSelect(...args))
228
+ onClick: _cache[1] || (_cache[1] = (...args) => _ctx.startSelect && _ctx.startSelect(...args)),
229
+ style: { "display": "flex" }
214
230
  }, [
215
- _hoisted_3$5,
216
- vue.createElementVNode("span", null, vue.toDisplayString(_ctx.val ? _ctx.toName + "_" + _ctx.val : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"), 1),
217
- _ctx.val ? (vue.openBlock(), vue.createElementBlock("i", {
218
- key: 0,
219
- class: "el-icon-delete",
220
- onClick: _cache[1] || (_cache[1] = vue.withModifiers((...args) => _ctx.deleteHandler && _ctx.deleteHandler(...args), ["stop"]))
221
- })) : vue.createCommentVNode("", true)
231
+ vue.createVNode(_component_el_tooltip, { content: "\u6E05\u9664" }, {
232
+ default: vue.withCtx(() => [
233
+ _ctx.val ? (vue.openBlock(), vue.createBlock(_component_el_button, {
234
+ key: 0,
235
+ style: { "padding": "0" },
236
+ type: "danger",
237
+ icon: _ctx.Close,
238
+ text: "",
239
+ onClick: vue.withModifiers(_ctx.deleteHandler, ["stop"])
240
+ }, null, 8, ["icon", "onClick"])) : vue.createCommentVNode("", true)
241
+ ]),
242
+ _: 1
243
+ }),
244
+ vue.createVNode(_component_el_tooltip, {
245
+ content: _ctx.val ? _ctx.toName + "_" + _ctx.val : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"
246
+ }, {
247
+ default: vue.withCtx(() => [
248
+ vue.createVNode(_component_el_button, {
249
+ text: "",
250
+ style: { "padding": "0", "margin": "0" }
251
+ }, {
252
+ default: vue.withCtx(() => [
253
+ vue.createTextVNode(vue.toDisplayString(_ctx.val ? _ctx.toName + "_" + _ctx.val : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"), 1)
254
+ ]),
255
+ _: 1
256
+ })
257
+ ]),
258
+ _: 1
259
+ }, 8, ["content"])
222
260
  ]));
223
261
  }
224
- var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
262
+ var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
225
263
 
226
264
  const toString = (v, language) => {
227
265
  let value = "";
@@ -238,7 +276,7 @@
238
276
  }
239
277
  return value;
240
278
  };
241
- const _sfc_main$h = vue.defineComponent({
279
+ const _sfc_main$j = vue.defineComponent({
242
280
  name: "magic-code-editor",
243
281
  props: {
244
282
  initValues: {
@@ -248,12 +286,16 @@
248
286
  type: [String, Object]
249
287
  },
250
288
  type: {
251
- type: [String],
289
+ type: String,
252
290
  default: () => ""
253
291
  },
254
292
  language: {
255
- type: [String],
293
+ type: String,
256
294
  default: () => "javascript"
295
+ },
296
+ options: {
297
+ type: Object,
298
+ default: () => ({})
257
299
  }
258
300
  },
259
301
  emits: ["initd", "save"],
@@ -263,6 +305,10 @@
263
305
  const values = vue.ref("");
264
306
  const loading = vue.ref(false);
265
307
  const codeEditor = vue.ref();
308
+ const resizeObserver = new globalThis.ResizeObserver(lodashEs.throttle(() => {
309
+ vsEditor?.layout();
310
+ vsDiffEditor?.layout();
311
+ }, 300));
266
312
  const setEditorValue = (v, m) => {
267
313
  values.value = toString(v, props.language);
268
314
  if (props.type === "diff") {
@@ -275,10 +321,6 @@
275
321
  }
276
322
  return vsEditor?.setValue(values.value);
277
323
  };
278
- const resizeHandler = () => {
279
- vsEditor?.layout();
280
- vsDiffEditor?.layout();
281
- };
282
324
  const getEditorValue = () => props.type === "diff" ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
283
325
  const init = async () => {
284
326
  if (!codeEditor.value)
@@ -289,8 +331,9 @@
289
331
  tabSize: 2,
290
332
  theme: "vs-dark",
291
333
  fontFamily: 'dm, Menlo, Monaco, "Courier New", monospace',
292
- fontSize: 15,
293
- formatOnPaste: true
334
+ fontSize: 14,
335
+ formatOnPaste: true,
336
+ ...props.options
294
337
  };
295
338
  if (props.type === "diff") {
296
339
  vsDiffEditor = monaco__namespace.editor.createDiffEditor(codeEditor.value, options);
@@ -311,7 +354,7 @@
311
354
  emit("save", getEditorValue());
312
355
  });
313
356
  }
314
- globalThis.addEventListener("resize", resizeHandler);
357
+ resizeObserver.observe(codeEditor.value);
315
358
  };
316
359
  vue.watch(() => props.initValues, (v, preV) => {
317
360
  if (v !== preV) {
@@ -326,7 +369,7 @@
326
369
  init();
327
370
  });
328
371
  vue.onUnmounted(() => {
329
- globalThis.removeEventListener("resize", resizeHandler);
372
+ resizeObserver.disconnect();
330
373
  });
331
374
  return {
332
375
  values,
@@ -343,14 +386,14 @@
343
386
  };
344
387
  }
345
388
  });
346
- const _hoisted_1$c = {
389
+ const _hoisted_1$b = {
347
390
  ref: "codeEditor",
348
391
  class: "magic-code-editor"
349
392
  };
350
- function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
351
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, null, 512);
393
+ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
394
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, null, 512);
352
395
  }
353
- var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
396
+ var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
354
397
 
355
398
  let $TMAGIC_EDITOR = {};
356
399
  const setConfig = (option) => {
@@ -359,9 +402,6 @@
359
402
  const getConfig = (key) => $TMAGIC_EDITOR[key];
360
403
 
361
404
  class UndoRedo {
362
- elementList;
363
- listCursor;
364
- listMaxSize;
365
405
  constructor(listMaxSize = 200) {
366
406
  const minListMaxSize = 2;
367
407
  this.elementList = [];
@@ -434,11 +474,40 @@
434
474
 
435
475
  const methodName = (prefix, name) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
436
476
  const isError = (error) => Object.prototype.toString.call(error) === "[object Error]";
477
+ const doAction = async (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
478
+ try {
479
+ let beforeArgs = args;
480
+ for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
481
+ let beforeReturnValue = await beforeMethod(...beforeArgs) || [];
482
+ if (isError(beforeReturnValue))
483
+ throw beforeReturnValue;
484
+ if (!Array.isArray(beforeReturnValue)) {
485
+ beforeReturnValue = [beforeReturnValue];
486
+ }
487
+ beforeArgs = beforeArgs.map((v, index) => {
488
+ if (typeof beforeReturnValue[index] === "undefined")
489
+ return v;
490
+ return beforeReturnValue[index];
491
+ });
492
+ }
493
+ let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
494
+ for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
495
+ returnValue = await afterMethod(returnValue, ...beforeArgs);
496
+ if (isError(returnValue))
497
+ throw returnValue;
498
+ }
499
+ return returnValue;
500
+ } catch (error) {
501
+ throw error;
502
+ }
503
+ };
437
504
  class BaseService extends events.EventEmitter {
438
- pluginOptionsList = {};
439
- middleware = {};
440
- constructor(methods) {
505
+ constructor(methods = [], serialMethods = []) {
441
506
  super();
507
+ this.pluginOptionsList = {};
508
+ this.middleware = {};
509
+ this.taskList = [];
510
+ this.doingTask = false;
442
511
  methods.forEach((propertyName) => {
443
512
  const scope = this;
444
513
  const sourceMethod = scope[propertyName];
@@ -450,27 +519,23 @@
450
519
  const fn = compose(this.middleware[propertyName]);
451
520
  Object.defineProperty(scope, propertyName, {
452
521
  value: async (...args) => {
453
- let beforeArgs = args;
454
- for (const beforeMethod of this.pluginOptionsList[beforeMethodName]) {
455
- let beforeReturnValue = await beforeMethod(...beforeArgs) || [];
456
- if (isError(beforeReturnValue))
457
- throw beforeReturnValue;
458
- if (!Array.isArray(beforeReturnValue)) {
459
- beforeReturnValue = [beforeReturnValue];
460
- }
461
- beforeArgs = beforeArgs.map((v, index) => {
462
- if (typeof beforeReturnValue[index] === "undefined")
463
- return v;
464
- return beforeReturnValue[index];
465
- });
522
+ if (!serialMethods.includes(propertyName)) {
523
+ return doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
466
524
  }
467
- let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
468
- for (const afterMethod of this.pluginOptionsList[afterMethodName]) {
469
- returnValue = await afterMethod(...beforeArgs, returnValue);
470
- if (isError(returnValue))
471
- throw returnValue;
525
+ const promise = new Promise((resolve, reject) => {
526
+ this.taskList.push(async () => {
527
+ try {
528
+ const value = await doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
529
+ resolve(value);
530
+ } catch (e) {
531
+ reject(e);
532
+ }
533
+ });
534
+ });
535
+ if (!this.doingTask) {
536
+ this.doTask();
472
537
  }
473
- return returnValue;
538
+ return promise;
474
539
  }
475
540
  });
476
541
  });
@@ -487,19 +552,34 @@
487
552
  this.pluginOptionsList[methodName2].push(method);
488
553
  });
489
554
  }
555
+ async doTask() {
556
+ this.doingTask = true;
557
+ let task = this.taskList.shift();
558
+ while (task) {
559
+ await task();
560
+ task = this.taskList.shift();
561
+ }
562
+ this.doingTask = false;
563
+ }
490
564
  }
491
565
 
492
566
  class History extends BaseService {
493
- state = vue.reactive({
494
- pageSteps: {},
495
- pageId: void 0,
496
- canRedo: false,
497
- canUndo: false
498
- });
499
567
  constructor() {
500
568
  super([]);
569
+ this.state = vue.reactive({
570
+ pageSteps: {},
571
+ pageId: void 0,
572
+ canRedo: false,
573
+ canUndo: false
574
+ });
501
575
  this.on("change", this.setCanUndoRedo);
502
576
  }
577
+ reset() {
578
+ this.state.pageSteps = {};
579
+ this.state.pageId = void 0;
580
+ this.state.canRedo = false;
581
+ this.state.canUndo = false;
582
+ }
503
583
  changePage(page) {
504
584
  if (!page)
505
585
  return;
@@ -563,12 +643,12 @@
563
643
  var historyService = new History();
564
644
 
565
645
  class Props extends BaseService {
566
- state = vue.reactive({
567
- propsConfigMap: {},
568
- propsValueMap: {}
569
- });
570
646
  constructor() {
571
647
  super(["setPropsConfig", "getPropsConfig", "setPropsValue", "getPropsValue"]);
648
+ this.state = vue.reactive({
649
+ propsConfigMap: {},
650
+ propsValueMap: {}
651
+ });
572
652
  }
573
653
  setPropsConfigs(configs) {
574
654
  Object.keys(configs).forEach((type) => {
@@ -593,7 +673,7 @@
593
673
  setPropsValue(type, value) {
594
674
  this.state.propsValueMap[type] = value;
595
675
  }
596
- async getPropsValue(type) {
676
+ async getPropsValue(type, defaultValue = {}) {
597
677
  if (type === "area") {
598
678
  const value = await this.getPropsValue("button");
599
679
  value.className = "action-area";
@@ -605,7 +685,7 @@
605
685
  }
606
686
  return lodashEs.cloneDeep({
607
687
  ...getDefaultPropsValue(type),
608
- ...this.state.propsValueMap[type] || {}
688
+ ...lodashEs.mergeWith(this.state.propsValueMap[type] || {}, defaultValue)
609
689
  });
610
690
  }
611
691
  }
@@ -632,7 +712,7 @@
632
712
  const generateId = (type) => `${type}_${lodashEs.random(1e4, false)}`;
633
713
  const getPageList = (app) => {
634
714
  if (app.items && Array.isArray(app.items)) {
635
- return app.items.filter((item) => item.type === "page");
715
+ return app.items.filter((item) => item.type === schema.NodeType.PAGE);
636
716
  }
637
717
  return [];
638
718
  };
@@ -666,9 +746,9 @@
666
746
  };
667
747
  const setNewItemId = (config, parent) => {
668
748
  const oldId = config.id;
669
- config.id = generateId(config.type);
749
+ config.id = generateId(config.type || "component");
670
750
  config.name = `${config.name?.replace(/_(\d+)$/, "")}_${config.id}`;
671
- if (utils.isPop(config) && parent?.type === "page") {
751
+ if (utils.isPop(config) && parent?.type === schema.NodeType.PAGE) {
672
752
  updatePopId(oldId, config.id, parent);
673
753
  }
674
754
  if (config.items && Array.isArray(config.items)) {
@@ -689,11 +769,25 @@
689
769
  };
690
770
  return node;
691
771
  };
692
- const initPosition = (node, layout) => {
772
+ const setTop2Middle = (node, parentNode, stage) => {
773
+ const style = node.style || {};
774
+ const height = style.height || 0;
775
+ if (!stage || typeof style.top !== "undefined" || !parentNode.style || !utils.isNumber(height))
776
+ return style;
777
+ const { height: parentHeight } = parentNode.style;
778
+ if (utils.isPage(parentNode)) {
779
+ const { scrollTop = 0, wrapperHeight } = stage.mask;
780
+ style.top = (wrapperHeight - height) / 2 + scrollTop;
781
+ } else {
782
+ style.top = (parentHeight - height) / 2;
783
+ }
784
+ return style;
785
+ };
786
+ const initPosition = (node, layout, parentNode, stage) => {
693
787
  if (layout === Layout.ABSOLUTE) {
694
788
  node.style = {
695
789
  position: "absolute",
696
- ...node.style || {}
790
+ ...setTop2Middle(node, parentNode, stage)
697
791
  };
698
792
  return node;
699
793
  }
@@ -740,7 +834,9 @@
740
834
  const cur = path.pop();
741
835
  const offset = {
742
836
  left: cur?.style?.left || 0,
743
- top: cur?.style?.top || 0
837
+ top: cur?.style?.top || 0,
838
+ right: "",
839
+ bottom: ""
744
840
  };
745
841
  path.forEach((value) => {
746
842
  offset.left = offset.left - globalThis.parseFloat(value.style?.left || 0);
@@ -774,15 +870,6 @@
774
870
  };
775
871
 
776
872
  class Editor$1 extends BaseService {
777
- isHistoryStateChange = false;
778
- state = vue.reactive({
779
- root: null,
780
- page: null,
781
- parent: null,
782
- node: null,
783
- stage: null,
784
- modifiedNodeIds: /* @__PURE__ */ new Map()
785
- });
786
873
  constructor() {
787
874
  super([
788
875
  "getLayout",
@@ -795,13 +882,27 @@
795
882
  "paste",
796
883
  "alignCenter",
797
884
  "moveLayer",
885
+ "move",
798
886
  "undo",
799
- "redo"
800
- ]);
887
+ "redo",
888
+ "highlight"
889
+ ], ["select", "update", "moveLayer"]);
890
+ this.isHistoryStateChange = false;
891
+ this.state = vue.reactive({
892
+ root: null,
893
+ page: null,
894
+ parent: null,
895
+ node: null,
896
+ stage: null,
897
+ highlightNode: null,
898
+ modifiedNodeIds: /* @__PURE__ */ new Map(),
899
+ pageLength: 0
900
+ });
801
901
  }
802
902
  set(name, value) {
803
903
  this.state[name] = value;
804
904
  if (name === "root") {
905
+ this.state.pageLength = value?.items?.length || 0;
805
906
  this.emit("root-change", value);
806
907
  }
807
908
  }
@@ -809,7 +910,7 @@
809
910
  return this.state[name];
810
911
  }
811
912
  getNodeInfo(id) {
812
- const root = this.get("root");
913
+ const root = vue.toRaw(this.get("root"));
813
914
  if (!root)
814
915
  return {};
815
916
  if (id === root.id) {
@@ -823,7 +924,7 @@
823
924
  info.node = path[path.length - 1];
824
925
  info.parent = path[path.length - 2];
825
926
  path.forEach((item) => {
826
- if (item.type === "page") {
927
+ if (item.type === schema.NodeType.PAGE) {
827
928
  info.page = item;
828
929
  return;
829
930
  }
@@ -840,31 +941,19 @@
840
941
  const { parent } = this.getNodeInfo(id);
841
942
  return parent;
842
943
  }
843
- async getLayout(node) {
844
- if (node.layout) {
845
- return node.layout;
944
+ async getLayout(parent, node) {
945
+ if (node && typeof node !== "function" && isFixed(node))
946
+ return Layout.FIXED;
947
+ if (parent.layout) {
948
+ return parent.layout;
846
949
  }
847
- if (!node.style?.position) {
950
+ if (!parent.style?.position) {
848
951
  return Layout.RELATIVE;
849
952
  }
850
953
  return Layout.ABSOLUTE;
851
954
  }
852
955
  async select(config2) {
853
- let id;
854
- if (typeof config2 === "string" || typeof config2 === "number") {
855
- id = config2;
856
- } else {
857
- id = config2.id;
858
- }
859
- if (!id) {
860
- throw new Error("\u6CA1\u6709ID\uFF0C\u65E0\u6CD5\u9009\u4E2D");
861
- }
862
- const { node, parent, page } = this.getNodeInfo(id);
863
- if (!node)
864
- throw new Error("\u83B7\u53D6\u4E0D\u5230\u7EC4\u4EF6\u4FE1\u606F");
865
- if (node.id === this.state.root?.id) {
866
- throw new Error("\u4E0D\u80FD\u9009\u6839\u8282\u70B9");
867
- }
956
+ const { node, page, parent } = this.selectedConfigExceptionHandler(config2);
868
957
  this.set("node", node);
869
958
  this.set("page", page || null);
870
959
  this.set("parent", parent || null);
@@ -873,12 +962,44 @@
873
962
  } else {
874
963
  historyService.empty();
875
964
  }
965
+ this.emit("select", node);
876
966
  return node;
877
967
  }
878
- async add({ type, ...config2 }, parent) {
968
+ async selectNextNode() {
969
+ const node = vue.toRaw(this.get("node"));
970
+ if (!node || utils.isPage(node) || node.type === schema.NodeType.ROOT)
971
+ return node;
972
+ const parent = vue.toRaw(this.getParentById(node.id));
973
+ if (!parent)
974
+ return node;
975
+ const index = getNodeIndex(node, parent);
976
+ const nextNode = parent.items[index + 1] || parent.items[0];
977
+ await this.select(nextNode);
978
+ this.get("stage")?.select(nextNode.id);
979
+ return nextNode;
980
+ }
981
+ async selectNextPage() {
982
+ const root = vue.toRaw(this.get("root"));
983
+ const page = vue.toRaw(this.get("page"));
984
+ const index = getNodeIndex(page, root);
985
+ const nextPage = root.items[index + 1] || root.items[0];
986
+ await this.select(nextPage);
987
+ this.get("stage")?.select(nextPage.id);
988
+ return nextPage;
989
+ }
990
+ highlight(config2) {
991
+ const { node } = this.selectedConfigExceptionHandler(config2);
992
+ const currentHighlightNode = this.get("highlightNode");
993
+ if (currentHighlightNode === node)
994
+ return;
995
+ this.set("highlightNode", node);
996
+ }
997
+ async add(addNode, parent) {
998
+ const { type, ...config2 } = addNode;
879
999
  const curNode = this.get("node");
880
1000
  let parentNode;
881
- if (type === "page") {
1001
+ const isPage2 = type === schema.NodeType.PAGE;
1002
+ if (isPage2) {
882
1003
  parentNode = this.get("root");
883
1004
  } else if (parent && typeof parent !== "function") {
884
1005
  parentNode = parent;
@@ -889,16 +1010,24 @@
889
1010
  }
890
1011
  if (!parentNode)
891
1012
  throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
892
- const layout = await this.getLayout(parentNode);
893
- const newNode = initPosition({ ...vue.toRaw(await propsService.getPropsValue(type)), ...config2 }, layout);
894
- if ((parentNode?.type === "app" || curNode.type === "app") && newNode.type !== "page") {
1013
+ const layout = await this.getLayout(vue.toRaw(parentNode), addNode);
1014
+ const newNode = initPosition({ ...vue.toRaw(await propsService.getPropsValue(type, config2)) }, layout, parentNode, this.get("stage"));
1015
+ if ((parentNode?.type === schema.NodeType.ROOT || curNode.type === schema.NodeType.ROOT) && newNode.type !== schema.NodeType.PAGE) {
895
1016
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
896
1017
  }
897
1018
  parentNode?.items?.push(newNode);
898
- await this.get("stage")?.add({ config: lodashEs.cloneDeep(newNode), root: lodashEs.cloneDeep(this.get("root")) });
1019
+ const stage = this.get("stage");
1020
+ await stage?.add({ config: lodashEs.cloneDeep(newNode), root: lodashEs.cloneDeep(this.get("root")) });
899
1021
  await this.select(newNode);
900
1022
  this.addModifiedNodeId(newNode.id);
901
- this.pushHistoryState();
1023
+ if (!isPage2) {
1024
+ this.pushHistoryState();
1025
+ }
1026
+ stage?.select(newNode.id);
1027
+ if (isPage2) {
1028
+ this.state.pageLength += 1;
1029
+ }
1030
+ this.emit("add", newNode);
902
1031
  return newNode;
903
1032
  }
904
1033
  async remove(node) {
@@ -914,14 +1043,31 @@
914
1043
  if (typeof index !== "number" || index === -1)
915
1044
  throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
916
1045
  parent.items?.splice(index, 1);
917
- this.get("stage")?.remove({ id: node.id, root: this.get("root") });
918
- if (node.type === "page") {
919
- await this.select(root.items[0] || root);
1046
+ const stage = this.get("stage");
1047
+ stage?.remove({ id: node.id, root: this.get("root") });
1048
+ if (node.type === schema.NodeType.PAGE) {
1049
+ this.state.pageLength -= 1;
1050
+ if (root.items[0]) {
1051
+ await this.select(root.items[0]);
1052
+ stage?.select(root.items[0].id);
1053
+ } else {
1054
+ this.set("node", null);
1055
+ this.set("parent", null);
1056
+ this.set("page", null);
1057
+ this.set("stage", null);
1058
+ this.set("highlightNode", null);
1059
+ this.resetModifiedNodeId();
1060
+ historyService.reset();
1061
+ this.emit("remove", node);
1062
+ return node;
1063
+ }
920
1064
  } else {
921
1065
  await this.select(parent);
1066
+ stage?.select(parent.id);
922
1067
  }
923
1068
  this.addModifiedNodeId(parent.id);
924
1069
  this.pushHistoryState();
1070
+ this.emit("remove", node);
925
1071
  return node;
926
1072
  }
927
1073
  async update(config2) {
@@ -939,7 +1085,7 @@
939
1085
  });
940
1086
  if (!newConfig.type)
941
1087
  throw new Error("\u914D\u7F6E\u7F3A\u5C11type\u503C");
942
- if (newConfig.type === "app") {
1088
+ if (newConfig.type === schema.NodeType.ROOT) {
943
1089
  this.set("root", newConfig);
944
1090
  return newConfig;
945
1091
  }
@@ -956,15 +1102,16 @@
956
1102
  newConfig = setLayout(newConfig, newLayout);
957
1103
  }
958
1104
  parentNodeItems[index] = newConfig;
959
- if (newConfig.id === this.get("node").id) {
1105
+ if (`${newConfig.id}` === `${this.get("node").id}`) {
960
1106
  this.set("node", newConfig);
961
1107
  }
962
1108
  this.get("stage")?.update({ config: lodashEs.cloneDeep(newConfig), root: this.get("root") });
963
- if (newConfig.type === "page") {
1109
+ if (newConfig.type === schema.NodeType.PAGE) {
964
1110
  this.set("page", newConfig);
965
1111
  }
966
1112
  this.addModifiedNodeId(newConfig.id);
967
1113
  this.pushHistoryState();
1114
+ this.emit("update", newConfig);
968
1115
  return newConfig;
969
1116
  }
970
1117
  async sort(id1, id2) {
@@ -977,6 +1124,7 @@
977
1124
  parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
978
1125
  await this.update(parent);
979
1126
  await this.select(node);
1127
+ this.get("stage")?.update({ config: lodashEs.cloneDeep(node), root: this.get("root") });
980
1128
  this.addModifiedNodeId(parent.id);
981
1129
  this.pushHistoryState();
982
1130
  }
@@ -1007,7 +1155,7 @@
1007
1155
  async alignCenter(config2) {
1008
1156
  const parent = this.get("parent");
1009
1157
  const node = this.get("node");
1010
- const layout = await this.getLayout(parent);
1158
+ const layout = await this.getLayout(vue.toRaw(parent), vue.toRaw(node));
1011
1159
  if (layout === Layout.RELATIVE) {
1012
1160
  return;
1013
1161
  }
@@ -1044,6 +1192,26 @@
1044
1192
  await this.changeHistoryState(value);
1045
1193
  return value;
1046
1194
  }
1195
+ async move(left, top) {
1196
+ const node = vue.toRaw(this.get("node"));
1197
+ if (!node || utils.isPage(node))
1198
+ return;
1199
+ const { style, id } = node;
1200
+ if (!style || style.position !== "absolute")
1201
+ return;
1202
+ if (top && !utils.isNumber(style.top))
1203
+ return;
1204
+ if (left && !utils.isNumber(style.left))
1205
+ return;
1206
+ this.update({
1207
+ id,
1208
+ style: {
1209
+ ...style,
1210
+ left: Number(style.left) + left,
1211
+ top: Number(style.top) + top
1212
+ }
1213
+ });
1214
+ }
1047
1215
  destroy() {
1048
1216
  this.removeAllListeners();
1049
1217
  this.set("root", null);
@@ -1076,7 +1244,12 @@
1076
1244
  this.isHistoryStateChange = true;
1077
1245
  await this.update(value.data);
1078
1246
  this.set("modifiedNodeIds", value.modifiedNodeIds);
1079
- setTimeout(() => value.nodeId && this.select(value.nodeId), 0);
1247
+ setTimeout(async () => {
1248
+ if (!value.nodeId)
1249
+ return;
1250
+ await this.select(value.nodeId);
1251
+ this.get("stage")?.select(value.nodeId);
1252
+ }, 0);
1080
1253
  }
1081
1254
  async toggleFixedPosition(dist, src, root) {
1082
1255
  let newConfig = lodashEs.cloneDeep(dist);
@@ -1089,6 +1262,28 @@
1089
1262
  }
1090
1263
  return newConfig;
1091
1264
  }
1265
+ selectedConfigExceptionHandler(config2) {
1266
+ let id;
1267
+ if (typeof config2 === "string" || typeof config2 === "number") {
1268
+ id = config2;
1269
+ } else {
1270
+ id = config2.id;
1271
+ }
1272
+ if (!id) {
1273
+ throw new Error("\u6CA1\u6709ID\uFF0C\u65E0\u6CD5\u9009\u4E2D");
1274
+ }
1275
+ const { node, parent, page } = this.getNodeInfo(id);
1276
+ if (!node)
1277
+ throw new Error("\u83B7\u53D6\u4E0D\u5230\u7EC4\u4EF6\u4FE1\u606F");
1278
+ if (node.id === this.state.root?.id) {
1279
+ throw new Error("\u4E0D\u80FD\u9009\u6839\u8282\u70B9");
1280
+ }
1281
+ return {
1282
+ node,
1283
+ parent,
1284
+ page
1285
+ };
1286
+ }
1092
1287
  }
1093
1288
  var editorService = new Editor$1();
1094
1289
 
@@ -1246,6 +1441,25 @@
1246
1441
  defaultValue: "100% 100%"
1247
1442
  }
1248
1443
  ]
1444
+ },
1445
+ {
1446
+ type: "fieldset",
1447
+ legend: "\u5B57\u4F53",
1448
+ items: [
1449
+ {
1450
+ name: "color",
1451
+ text: "\u989C\u8272",
1452
+ type: "colorPicker"
1453
+ },
1454
+ {
1455
+ name: "fontSize",
1456
+ text: "\u5927\u5C0F"
1457
+ },
1458
+ {
1459
+ name: "fontWeight",
1460
+ text: "\u7C97\u7EC6"
1461
+ }
1462
+ ]
1249
1463
  }
1250
1464
  ]
1251
1465
  }
@@ -1278,7 +1492,7 @@
1278
1492
  type: "select",
1279
1493
  options: (mForm, { model }) => {
1280
1494
  const node = editorService.getNodeById(model.to);
1281
- if (!node)
1495
+ if (!node?.type)
1282
1496
  return [];
1283
1497
  return eventsService.getMethod(node.type).map((option) => ({
1284
1498
  text: option.label,
@@ -1313,7 +1527,7 @@
1313
1527
  name: type
1314
1528
  });
1315
1529
 
1316
- const _sfc_main$g = vue.defineComponent({
1530
+ const _sfc_main$i = vue.defineComponent({
1317
1531
  components: { Plus: icons.Plus },
1318
1532
  setup() {
1319
1533
  const services = vue.inject("services");
@@ -1323,21 +1537,21 @@
1323
1537
  if (!editorService)
1324
1538
  return;
1325
1539
  editorService.add({
1326
- type: "page",
1540
+ type: schema.NodeType.PAGE,
1327
1541
  name: generatePageNameByApp(vue.toRaw(editorService.get("root")))
1328
1542
  });
1329
1543
  }
1330
1544
  };
1331
1545
  }
1332
1546
  });
1333
- const _hoisted_1$b = { class: "m-editor-empty-panel" };
1334
- const _hoisted_2$6 = { class: "m-editor-empty-content" };
1335
- const _hoisted_3$4 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1336
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
1547
+ const _hoisted_1$a = { class: "m-editor-empty-panel" };
1548
+ const _hoisted_2$4 = { class: "m-editor-empty-content" };
1549
+ const _hoisted_3$2 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1550
+ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
1337
1551
  const _component_plus = vue.resolveComponent("plus");
1338
1552
  const _component_el_icon = vue.resolveComponent("el-icon");
1339
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, [
1340
- vue.createElementVNode("div", _hoisted_2$6, [
1553
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
1554
+ vue.createElementVNode("div", _hoisted_2$4, [
1341
1555
  vue.createElementVNode("div", {
1342
1556
  class: "m-editor-empty-button",
1343
1557
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.clickHandler && _ctx.clickHandler(...args))
@@ -1350,12 +1564,12 @@
1350
1564
  _: 1
1351
1565
  })
1352
1566
  ]),
1353
- _hoisted_3$4
1567
+ _hoisted_3$2
1354
1568
  ])
1355
1569
  ])
1356
1570
  ]);
1357
1571
  }
1358
- var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
1572
+ var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
1359
1573
 
1360
1574
  /*
1361
1575
  Copyright (c) 2018 Daybrush
@@ -1759,8 +1973,8 @@
1759
1973
  name: gesto
1760
1974
  license: MIT
1761
1975
  author: Daybrush
1762
- repository: git+https://github.com/daybrush/gesture.git
1763
- version: 1.5.0
1976
+ repository: git+https://github.com/daybrush/gesto.git
1977
+ version: 1.7.0
1764
1978
  */
1765
1979
 
1766
1980
  /*! *****************************************************************************
@@ -1929,19 +2143,6 @@
1929
2143
 
1930
2144
  var __proto = ClientStore.prototype;
1931
2145
 
1932
- __proto.addClients = function (clients) {
1933
- if (clients === void 0) {
1934
- clients = this.prevClients;
1935
- }
1936
-
1937
- var position = this.getPosition(clients);
1938
- var deltaX = position.deltaX,
1939
- deltaY = position.deltaY;
1940
- this.movement += Math.sqrt(deltaX * deltaX + deltaY * deltaY);
1941
- this.prevClients = clients;
1942
- return position;
1943
- };
1944
-
1945
2146
  __proto.getAngle = function (clients) {
1946
2147
  if (clients === void 0) {
1947
2148
  clients = this.prevClients;
@@ -1958,8 +2159,17 @@
1958
2159
  return getRotatiion(clients) - getRotatiion(this.startClients);
1959
2160
  };
1960
2161
 
1961
- __proto.getPosition = function (clients) {
1962
- return getPosition(clients || this.prevClients, this.prevClients, this.startClients);
2162
+ __proto.getPosition = function (clients, isAdd) {
2163
+ if (clients === void 0) {
2164
+ clients = this.prevClients;
2165
+ }
2166
+
2167
+ var position = getPosition(clients || this.prevClients, this.prevClients, this.startClients);
2168
+ var deltaX = position.deltaX,
2169
+ deltaY = position.deltaY;
2170
+ this.movement += Math.sqrt(deltaX * deltaX + deltaY * deltaY);
2171
+ this.prevClients = clients;
2172
+ return position;
1963
2173
  };
1964
2174
 
1965
2175
  __proto.getPositions = function (clients) {
@@ -2008,10 +2218,6 @@
2008
2218
  client.clientX -= deltaX;
2009
2219
  client.clientY -= deltaY;
2010
2220
  });
2011
- this.prevClients.forEach(function (client) {
2012
- client.clientX -= deltaX;
2013
- client.clientY -= deltaY;
2014
- });
2015
2221
  };
2016
2222
 
2017
2223
  return ClientStore;
@@ -2050,6 +2256,7 @@
2050
2256
  _this.targets = [];
2051
2257
  _this.prevTime = 0;
2052
2258
  _this.doubleFlag = false;
2259
+ _this._dragFlag = false;
2053
2260
 
2054
2261
  _this.onDragStart = function (e, isTrusted) {
2055
2262
  if (isTrusted === void 0) {
@@ -2080,7 +2287,8 @@
2080
2287
  if (checkInput || activeElement === target) {
2081
2288
  // force false or already focused.
2082
2289
  return false;
2083
- }
2290
+ } // no focus
2291
+
2084
2292
 
2085
2293
  if (activeElement && hasContentEditable && activeElement.isContentEditable && activeElement.contains(target)) {
2086
2294
  return false;
@@ -2096,6 +2304,7 @@
2096
2304
  _this.clientStores = [new ClientStore(getEventClients(e))];
2097
2305
  _this.flag = true;
2098
2306
  _this.isDrag = false;
2307
+ _this._dragFlag = true;
2099
2308
  _this.datas = {};
2100
2309
 
2101
2310
  if (preventRightClick && (e.which === 3 || e.button === 2)) {
@@ -2111,7 +2320,14 @@
2111
2320
  inputEvent: e,
2112
2321
  isTrusted: isTrusted,
2113
2322
  isDouble: _this.doubleFlag
2114
- }, _this.getCurrentStore().getPosition()));
2323
+ }, _this.getCurrentStore().getPosition(), {
2324
+ preventDefault: function () {
2325
+ e.preventDefault();
2326
+ },
2327
+ preventDrag: function () {
2328
+ _this._dragFlag = false;
2329
+ }
2330
+ }));
2115
2331
 
2116
2332
  if (result === false) {
2117
2333
  _this.initDrag();
@@ -2160,24 +2376,26 @@
2160
2376
 
2161
2377
  var result = _this.moveClients(clients, e, false);
2162
2378
 
2163
- if (_this.pinchFlag || result.deltaX || result.deltaY) {
2164
- var dragResult = _this.emit("drag", __assign({}, result, {
2165
- isScroll: !!isScroll,
2166
- inputEvent: e
2167
- }));
2379
+ if (_this._dragFlag) {
2380
+ if (_this.pinchFlag || result.deltaX || result.deltaY) {
2381
+ var dragResult = _this.emit("drag", __assign({}, result, {
2382
+ isScroll: !!isScroll,
2383
+ inputEvent: e
2384
+ }));
2168
2385
 
2169
- if (dragResult === false) {
2170
- _this.stop();
2386
+ if (dragResult === false) {
2387
+ _this.stop();
2171
2388
 
2172
- return;
2389
+ return;
2390
+ }
2173
2391
  }
2174
- }
2175
2392
 
2176
- if (_this.pinchFlag) {
2177
- _this.onPinch(e, clients);
2393
+ if (_this.pinchFlag) {
2394
+ _this.onPinch(e, clients);
2395
+ }
2178
2396
  }
2179
2397
 
2180
- _this.getCurrentStore().addClients(clients);
2398
+ _this.getCurrentStore().getPosition(clients, true);
2181
2399
  };
2182
2400
 
2183
2401
  _this.onDragEnd = function (e) {
@@ -2195,7 +2413,7 @@
2195
2413
 
2196
2414
  _this.flag = false;
2197
2415
 
2198
- var position = _this.getCurrentStore().getPosition();
2416
+ var position = _this._getPosition();
2199
2417
 
2200
2418
  var currentTime = now();
2201
2419
  var isDouble = !_this.isDrag && _this.doubleFlag;
@@ -2389,7 +2607,23 @@
2389
2607
  return this;
2390
2608
  };
2391
2609
  /**
2392
- * Set the event data while dragging.
2610
+ * Get the current event state while dragging.
2611
+ */
2612
+
2613
+
2614
+ __proto.getCurrentEvent = function (inputEvent) {
2615
+ return __assign({
2616
+ datas: this.datas
2617
+ }, this._getPosition(), {
2618
+ movement: this.getMovement(),
2619
+ isDrag: this.isDrag,
2620
+ isPinch: this.isPinch,
2621
+ isScroll: false,
2622
+ inputEvent: inputEvent
2623
+ });
2624
+ };
2625
+ /**
2626
+ * Get & Set the event data while dragging.
2393
2627
  */
2394
2628
 
2395
2629
 
@@ -2505,9 +2739,12 @@
2505
2739
  };
2506
2740
 
2507
2741
  __proto.moveClients = function (clients, inputEvent, isAdd) {
2508
- var store = this.getCurrentStore();
2509
- var position = store[isAdd ? "addClients" : "getPosition"](clients);
2510
- this.isDrag = true;
2742
+ var position = this._getPosition(clients, isAdd);
2743
+
2744
+ if (position.deltaX || position.deltaY) {
2745
+ this.isDrag = true;
2746
+ }
2747
+
2511
2748
  return __assign({
2512
2749
  datas: this.datas
2513
2750
  }, position, {
@@ -2519,12 +2756,31 @@
2519
2756
  });
2520
2757
  };
2521
2758
 
2759
+ __proto._getPosition = function (clients, isAdd) {
2760
+ var store = this.getCurrentStore();
2761
+ var position = store.getPosition(clients, isAdd);
2762
+
2763
+ var _a = this.clientStores.slice(1).reduce(function (prev, cur) {
2764
+ var storePosition = cur.getPosition();
2765
+ prev.distX += storePosition.distX;
2766
+ prev.distY += storePosition.distY;
2767
+ return prev;
2768
+ }, position),
2769
+ distX = _a.distX,
2770
+ distY = _a.distY;
2771
+
2772
+ return __assign({}, position, {
2773
+ distX: distX,
2774
+ distY: distY
2775
+ });
2776
+ };
2777
+
2522
2778
  return Gesto;
2523
2779
  }(EventEmitter$1);
2524
2780
 
2525
2781
  var Gesto$1 = Gesto;
2526
2782
 
2527
- const _sfc_main$f = vue.defineComponent({
2783
+ const _sfc_main$h = vue.defineComponent({
2528
2784
  name: "m-editor-resize",
2529
2785
  props: {
2530
2786
  type: {
@@ -2566,33 +2822,33 @@
2566
2822
  };
2567
2823
  }
2568
2824
  });
2569
- const _hoisted_1$a = {
2825
+ const _hoisted_1$9 = {
2570
2826
  ref: "target",
2571
2827
  class: "m-editor-resizer"
2572
2828
  };
2573
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2574
- return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$a, [
2829
+ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
2830
+ return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$9, [
2575
2831
  vue.renderSlot(_ctx.$slots, "default")
2576
2832
  ], 512);
2577
2833
  }
2578
- var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2834
+ var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
2579
2835
 
2580
- const _sfc_main$e = vue.defineComponent({
2836
+ const _sfc_main$g = vue.defineComponent({
2581
2837
  components: {
2582
2838
  AddPageBox,
2583
2839
  Resizer
2584
2840
  },
2585
2841
  setup() {
2586
- const services = vue.inject("services");
2587
- const root = vue.computed(() => services?.editorService.get("root"));
2842
+ const { editorService, uiService } = vue.inject("services") || {};
2843
+ const root = vue.computed(() => editorService?.get("root"));
2588
2844
  return {
2589
2845
  root,
2590
- pageLength: vue.computed(() => root.value?.items?.length || 0),
2591
- showSrc: vue.computed(() => services?.uiService.get("showSrc")),
2592
- columnWidth: vue.computed(() => services?.uiService.get("columnWidth")),
2846
+ pageLength: vue.computed(() => editorService?.get("pageLength") || 0),
2847
+ showSrc: vue.computed(() => uiService?.get("showSrc")),
2848
+ columnWidth: vue.computed(() => uiService?.get("columnWidth")),
2593
2849
  saveCode(value) {
2594
2850
  try {
2595
- services?.editorService.set("root", eval(value));
2851
+ editorService?.set("root", eval(value));
2596
2852
  } catch (e) {
2597
2853
  console.error(e);
2598
2854
  }
@@ -2600,24 +2856,24 @@
2600
2856
  };
2601
2857
  }
2602
2858
  });
2603
- const _hoisted_1$9 = { class: "m-editor" };
2604
- const _hoisted_2$5 = {
2859
+ const _hoisted_1$8 = { class: "m-editor" };
2860
+ const _hoisted_2$3 = {
2605
2861
  key: 1,
2606
2862
  class: "m-editor-content"
2607
2863
  };
2608
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2864
+ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
2609
2865
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
2610
2866
  const _component_resizer = vue.resolveComponent("resizer");
2611
2867
  const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
2612
2868
  const _component_add_page_box = vue.resolveComponent("add-page-box");
2613
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$9, [
2869
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
2614
2870
  vue.renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
2615
2871
  _ctx.showSrc ? (vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
2616
2872
  key: 0,
2617
2873
  class: "m-editor-content",
2618
2874
  "init-values": _ctx.root,
2619
2875
  onSave: _ctx.saveCode
2620
- }, null, 8, ["init-values", "onSave"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$5, [
2876
+ }, null, 8, ["init-values", "onSave"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$3, [
2621
2877
  vue.createElementVNode("div", {
2622
2878
  class: "m-editor-framework-left",
2623
2879
  style: vue.normalizeStyle(`width: ${_ctx.columnWidth?.left}px`)
@@ -2650,9 +2906,9 @@
2650
2906
  ]))
2651
2907
  ]);
2652
2908
  }
2653
- var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2909
+ var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
2654
2910
 
2655
- const _sfc_main$d = vue.defineComponent({
2911
+ const _sfc_main$f = vue.defineComponent({
2656
2912
  name: "m-icon",
2657
2913
  components: { Edit: icons.Edit },
2658
2914
  props: {
@@ -2666,8 +2922,8 @@
2666
2922
  };
2667
2923
  }
2668
2924
  });
2669
- const _hoisted_1$8 = ["src"];
2670
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2925
+ const _hoisted_1$7 = ["src"];
2926
+ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2671
2927
  const _component_edit = vue.resolveComponent("edit");
2672
2928
  const _component_el_icon = vue.resolveComponent("el-icon");
2673
2929
  return !_ctx.icon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
@@ -2678,7 +2934,7 @@
2678
2934
  })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (vue.openBlock(), vue.createElementBlock("img", {
2679
2935
  key: 1,
2680
2936
  src: _ctx.icon
2681
- }, null, 8, _hoisted_1$8)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2937
+ }, null, 8, _hoisted_1$7)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2682
2938
  key: 2,
2683
2939
  class: vue.normalizeClass(_ctx.icon)
2684
2940
  }, null, 2)) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 3 }, {
@@ -2688,9 +2944,9 @@
2688
2944
  _: 1
2689
2945
  }));
2690
2946
  }
2691
- var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2947
+ var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2692
2948
 
2693
- const _sfc_main$c = vue.defineComponent({
2949
+ const _sfc_main$e = vue.defineComponent({
2694
2950
  components: { MIcon, ArrowDown: icons.ArrowDown },
2695
2951
  props: {
2696
2952
  data: {
@@ -2700,16 +2956,20 @@
2700
2956
  type: "text",
2701
2957
  display: false
2702
2958
  })
2959
+ },
2960
+ eventType: {
2961
+ type: String,
2962
+ default: "click"
2703
2963
  }
2704
2964
  },
2705
2965
  setup(props) {
2706
2966
  const services = vue.inject("services");
2707
2967
  const uiService = services?.uiService;
2708
- const zoomInHandler = () => uiService?.set("zoom", zoom.value + 0.1);
2709
- const zoomOutHandler = () => uiService?.set("zoom", zoom.value - 0.1);
2710
2968
  const zoom = vue.computed(() => uiService?.get("zoom") ?? 1);
2711
2969
  const showGuides = vue.computed(() => uiService?.get("showGuides") ?? true);
2712
2970
  const showRule = vue.computed(() => uiService?.get("showRule") ?? true);
2971
+ const zoomInHandler = () => uiService?.zoom(0.1);
2972
+ const zoomOutHandler = () => uiService?.zoom(-0.1);
2713
2973
  const item = vue.computed(() => {
2714
2974
  if (typeof props.data !== "string") {
2715
2975
  return props.data;
@@ -2726,15 +2986,15 @@
2726
2986
  case "delete":
2727
2987
  return {
2728
2988
  type: "button",
2729
- icon: icons.Delete,
2989
+ icon: vue.markRaw(icons.Delete),
2730
2990
  tooltip: "\u522A\u9664",
2731
- disabled: () => services?.editorService.get("node")?.type === "page",
2991
+ disabled: () => services?.editorService.get("node")?.type === schema.NodeType.PAGE,
2732
2992
  handler: () => services?.editorService.remove(services?.editorService.get("node"))
2733
2993
  };
2734
2994
  case "undo":
2735
2995
  return {
2736
2996
  type: "button",
2737
- icon: icons.Back,
2997
+ icon: vue.markRaw(icons.Back),
2738
2998
  tooltip: "\u540E\u9000",
2739
2999
  disabled: () => !services?.historyService.state.canUndo,
2740
3000
  handler: () => services?.editorService.undo()
@@ -2742,7 +3002,7 @@
2742
3002
  case "redo":
2743
3003
  return {
2744
3004
  type: "button",
2745
- icon: icons.Right,
3005
+ icon: vue.markRaw(icons.Right),
2746
3006
  tooltip: "\u524D\u8FDB",
2747
3007
  disabled: () => !services?.historyService.state.canRedo,
2748
3008
  handler: () => services?.editorService.redo()
@@ -2750,28 +3010,28 @@
2750
3010
  case "zoom-in":
2751
3011
  return {
2752
3012
  type: "button",
2753
- icon: icons.ZoomIn,
3013
+ icon: vue.markRaw(icons.ZoomIn),
2754
3014
  tooltip: "\u653E\u5927",
2755
3015
  handler: zoomInHandler
2756
3016
  };
2757
3017
  case "zoom-out":
2758
3018
  return {
2759
3019
  type: "button",
2760
- icon: icons.ZoomOut,
3020
+ icon: vue.markRaw(icons.ZoomOut),
2761
3021
  tooltip: "\u7E2E\u5C0F",
2762
3022
  handler: zoomOutHandler
2763
3023
  };
2764
3024
  case "rule":
2765
3025
  return {
2766
3026
  type: "button",
2767
- icon: icons.ScaleToOriginal,
3027
+ icon: vue.markRaw(icons.ScaleToOriginal),
2768
3028
  tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2769
3029
  handler: () => uiService?.set("showRule", !showRule.value)
2770
3030
  };
2771
3031
  case "guides":
2772
3032
  return {
2773
3033
  type: "button",
2774
- icon: icons.Grid,
3034
+ icon: vue.markRaw(icons.Grid),
2775
3035
  tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2776
3036
  handler: () => uiService?.set("showGuides", !showGuides.value)
2777
3037
  };
@@ -2792,9 +3052,16 @@
2792
3052
  }
2793
3053
  return item.value.disabled;
2794
3054
  });
3055
+ const buttonHandler = (item2, event) => {
3056
+ if (disabled.value)
3057
+ return;
3058
+ if (typeof item2.handler === "function" && services) {
3059
+ item2.handler?.(services, event);
3060
+ }
3061
+ };
2795
3062
  return {
2796
- ZoomIn: icons.ZoomIn,
2797
- ZoomOut: icons.ZoomOut,
3063
+ ZoomIn: vue.markRaw(icons.ZoomIn),
3064
+ ZoomOut: vue.markRaw(icons.ZoomOut),
2798
3065
  item,
2799
3066
  zoom,
2800
3067
  disabled,
@@ -2815,31 +3082,42 @@
2815
3082
  command.item.handler(services);
2816
3083
  }
2817
3084
  },
2818
- buttonHandler(item2) {
2819
- if (disabled.value)
3085
+ clickHandler(item2, event) {
3086
+ if (props.eventType !== "click")
3087
+ return;
3088
+ if (item2.type === "button") {
3089
+ buttonHandler(item2, event);
3090
+ }
3091
+ },
3092
+ mousedownHandler(item2, event) {
3093
+ if (props.eventType !== "mousedown")
2820
3094
  return;
2821
- if (typeof item2.handler === "function") {
2822
- item2.handler?.(services);
3095
+ if (item2.type === "button") {
3096
+ buttonHandler(item2, event);
3097
+ }
3098
+ },
3099
+ mouseupHandler(item2, event) {
3100
+ if (props.eventType !== "mouseup")
3101
+ return;
3102
+ if (item2.type === "button") {
3103
+ buttonHandler(item2, event);
2823
3104
  }
2824
3105
  }
2825
3106
  };
2826
3107
  }
2827
3108
  });
2828
- const _hoisted_1$7 = {
2829
- key: 0,
2830
- class: "menu-item"
2831
- };
2832
- const _hoisted_2$4 = {
3109
+ const _hoisted_1$6 = {
2833
3110
  key: 1,
2834
3111
  class: "menu-item-text"
2835
3112
  };
2836
- const _hoisted_3$3 = {
3113
+ const _hoisted_2$2 = {
2837
3114
  class: "menu-item-text",
2838
3115
  style: { "margin": "0 5px" }
2839
3116
  };
2840
- const _hoisted_4$3 = { class: "el-dropdown-link menubar-menu-button" };
2841
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
3117
+ const _hoisted_3$1 = { class: "el-dropdown-link menubar-menu-button" };
3118
+ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2842
3119
  const _component_el_divider = vue.resolveComponent("el-divider");
3120
+ const _component_tool_button = vue.resolveComponent("tool-button", true);
2843
3121
  const _component_m_icon = vue.resolveComponent("m-icon");
2844
3122
  const _component_el_button = vue.resolveComponent("el-button");
2845
3123
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -2848,48 +3126,70 @@
2848
3126
  const _component_el_dropdown_item = vue.resolveComponent("el-dropdown-item");
2849
3127
  const _component_el_dropdown_menu = vue.resolveComponent("el-dropdown-menu");
2850
3128
  const _component_el_dropdown = vue.resolveComponent("el-dropdown");
2851
- return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$7, [
3129
+ return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", {
3130
+ key: 0,
3131
+ class: vue.normalizeClass(["menu-item", _ctx.item.type]),
3132
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.clickHandler(_ctx.item, $event)),
3133
+ onMousedown: _cache[1] || (_cache[1] = ($event) => _ctx.mousedownHandler(_ctx.item, $event)),
3134
+ onMouseup: _cache[2] || (_cache[2] = ($event) => _ctx.mouseupHandler(_ctx.item, $event))
3135
+ }, [
2852
3136
  _ctx.item.type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
2853
3137
  key: 0,
2854
- direction: "vertical"
2855
- })) : _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 }, [
2856
- vue.createVNode(_component_m_icon, {
2857
- icon: _ctx.ZoomIn,
2858
- onClick: _ctx.zoomInHandler
2859
- }, null, 8, ["icon", "onClick"]),
2860
- vue.createElementVNode("span", _hoisted_3$3, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
2861
- vue.createVNode(_component_m_icon, {
2862
- icon: _ctx.ZoomOut,
2863
- onClick: _ctx.zoomOutHandler
2864
- }, null, 8, ["icon", "onClick"])
2865
- ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
2866
- key: 3,
2867
- effect: "dark",
2868
- placement: "bottom-start",
2869
- content: _ctx.item.tooltip || _ctx.item.text
2870
- }, {
2871
- default: vue.withCtx(() => [
2872
- vue.createVNode(_component_el_button, {
2873
- size: "small",
2874
- type: "text",
2875
- disabled: _ctx.disabled,
2876
- onClick: _cache[0] || (_cache[0] = ($event) => _ctx.buttonHandler(_ctx.item))
2877
- }, {
2878
- default: vue.withCtx(() => [
2879
- vue.createVNode(_component_m_icon, {
2880
- icon: _ctx.item.icon
2881
- }, null, 8, ["icon"]),
2882
- vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
2883
- ]),
2884
- _: 1
2885
- }, 8, ["disabled"])
2886
- ]),
2887
- _: 1
2888
- }, 8, ["content"])) : _ctx.item.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
2889
- key: 4,
2890
- trigger: "click",
2891
- disabled: _ctx.disabled,
2892
- onCommand: _ctx.dropdownHandler
3138
+ direction: _ctx.item.direction || "vertical"
3139
+ }, 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 }, [
3140
+ vue.createVNode(_component_tool_button, {
3141
+ data: { type: "button", icon: _ctx.ZoomOut, handler: _ctx.zoomOutHandler, tooltip: "\u7F29\u5C0F" },
3142
+ "event-type": _ctx.eventType
3143
+ }, null, 8, ["data", "event-type"]),
3144
+ vue.createElementVNode("span", _hoisted_2$2, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
3145
+ vue.createVNode(_component_tool_button, {
3146
+ data: { type: "button", icon: _ctx.ZoomIn, handler: _ctx.zoomInHandler, tooltip: "\u653E\u5927" },
3147
+ "event-type": _ctx.eventType
3148
+ }, null, 8, ["data", "event-type"])
3149
+ ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
3150
+ _ctx.item.tooltip ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
3151
+ key: 0,
3152
+ effect: "dark",
3153
+ placement: "bottom-start",
3154
+ content: _ctx.item.tooltip
3155
+ }, {
3156
+ default: vue.withCtx(() => [
3157
+ vue.createVNode(_component_el_button, {
3158
+ size: "small",
3159
+ text: "",
3160
+ disabled: _ctx.disabled
3161
+ }, {
3162
+ default: vue.withCtx(() => [
3163
+ _ctx.item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3164
+ key: 0,
3165
+ icon: _ctx.item.icon
3166
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3167
+ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
3168
+ ]),
3169
+ _: 1
3170
+ }, 8, ["disabled"])
3171
+ ]),
3172
+ _: 1
3173
+ }, 8, ["content"])) : (vue.openBlock(), vue.createBlock(_component_el_button, {
3174
+ key: 1,
3175
+ size: "small",
3176
+ text: "",
3177
+ disabled: _ctx.disabled
3178
+ }, {
3179
+ default: vue.withCtx(() => [
3180
+ _ctx.item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3181
+ key: 0,
3182
+ icon: _ctx.item.icon
3183
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3184
+ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
3185
+ ]),
3186
+ _: 1
3187
+ }, 8, ["disabled"]))
3188
+ ], 64)) : _ctx.item.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
3189
+ key: 4,
3190
+ trigger: "click",
3191
+ disabled: _ctx.disabled,
3192
+ onCommand: _ctx.dropdownHandler
2893
3193
  }, {
2894
3194
  dropdown: vue.withCtx(() => [
2895
3195
  _ctx.item.items && _ctx.item.items.length ? (vue.openBlock(), vue.createBlock(_component_el_dropdown_menu, { key: 0 }, {
@@ -2910,7 +3210,7 @@
2910
3210
  })) : vue.createCommentVNode("", true)
2911
3211
  ]),
2912
3212
  default: vue.withCtx(() => [
2913
- vue.createElementVNode("span", _hoisted_4$3, [
3213
+ vue.createElementVNode("span", _hoisted_3$1, [
2914
3214
  vue.createTextVNode(vue.toDisplayString(_ctx.item.text), 1),
2915
3215
  vue.createVNode(_component_el_icon, { class: "el-icon--right" }, {
2916
3216
  default: vue.withCtx(() => [
@@ -2922,11 +3222,11 @@
2922
3222
  ]),
2923
3223
  _: 1
2924
3224
  }, 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)
2925
- ])) : vue.createCommentVNode("", true);
3225
+ ], 34)) : vue.createCommentVNode("", true);
2926
3226
  }
2927
- var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
3227
+ var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2928
3228
 
2929
- const _sfc_main$b = vue.defineComponent({
3229
+ const _sfc_main$d = vue.defineComponent({
2930
3230
  name: "nav-menu",
2931
3231
  components: { ToolButton },
2932
3232
  props: {
@@ -2946,7 +3246,7 @@
2946
3246
  };
2947
3247
  }
2948
3248
  });
2949
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
3249
+ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2950
3250
  const _component_tool_button = vue.resolveComponent("tool-button");
2951
3251
  return vue.openBlock(), vue.createElementBlock("div", {
2952
3252
  class: "m-editor-nav-menu",
@@ -2968,9 +3268,9 @@
2968
3268
  }), 128))
2969
3269
  ], 4);
2970
3270
  }
2971
- var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3271
+ var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2972
3272
 
2973
- const _sfc_main$a = vue.defineComponent({
3273
+ const _sfc_main$c = vue.defineComponent({
2974
3274
  name: "m-editor-props-panel",
2975
3275
  emits: ["mounted"],
2976
3276
  setup(props, { emit }) {
@@ -2985,9 +3285,9 @@
2985
3285
  curFormConfig.value = [];
2986
3286
  return;
2987
3287
  }
2988
- values.value = node.value;
2989
3288
  const type = node.value.type || (node.value.items ? "container" : "text");
2990
3289
  curFormConfig.value = await services?.propsService.getPropsConfig(type) || [];
3290
+ values.value = node.value;
2991
3291
  };
2992
3292
  vue.watchEffect(init);
2993
3293
  services?.propsService.on("props-configs-change", init);
@@ -2998,6 +3298,7 @@
2998
3298
  values,
2999
3299
  configForm,
3000
3300
  curFormConfig,
3301
+ propsPanelSize: vue.computed(() => services?.uiService.get("propsPanelSize") || "small"),
3001
3302
  async submit() {
3002
3303
  try {
3003
3304
  const values2 = await configForm.value?.submitForm();
@@ -3016,20 +3317,21 @@
3016
3317
  };
3017
3318
  }
3018
3319
  });
3019
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3320
+ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
3020
3321
  const _component_m_form = vue.resolveComponent("m-form");
3021
3322
  return vue.openBlock(), vue.createBlock(_component_m_form, {
3022
- class: "m-editor-props-panel",
3323
+ class: vue.normalizeClass(`m-editor-props-panel ${_ctx.propsPanelSize}`),
3324
+ "popper-class": "m-editor-props-panel-popper",
3023
3325
  ref: "configForm",
3024
- size: "small",
3326
+ size: _ctx.propsPanelSize,
3025
3327
  "init-values": _ctx.values,
3026
3328
  config: _ctx.curFormConfig,
3027
3329
  onChange: _ctx.submit
3028
- }, null, 8, ["init-values", "config", "onChange"]);
3330
+ }, null, 8, ["class", "size", "init-values", "config", "onChange"]);
3029
3331
  }
3030
- var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3332
+ var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
3031
3333
 
3032
- const _sfc_main$9 = vue.defineComponent({
3334
+ const _sfc_main$b = vue.defineComponent({
3033
3335
  name: "ui-component-panel",
3034
3336
  components: { MIcon },
3035
3337
  setup() {
@@ -3044,19 +3346,29 @@
3044
3346
  searchText,
3045
3347
  collapseValue,
3046
3348
  list,
3047
- appendComponent({ text, type, ...config }) {
3349
+ appendComponent({ text, type, data = {} }) {
3048
3350
  services?.editorService.add({
3049
3351
  name: text,
3050
3352
  type,
3051
- ...config
3353
+ ...data
3052
3354
  });
3355
+ },
3356
+ dragstartHandler({ text, type, data = {} }, e) {
3357
+ if (e.dataTransfer) {
3358
+ e.dataTransfer.effectAllowed = "move";
3359
+ e.dataTransfer.setData("data", serialize__default["default"]({
3360
+ name: text,
3361
+ type,
3362
+ ...data
3363
+ }).replace(/"(\w+)":\s/g, "$1: "));
3364
+ }
3053
3365
  }
3054
3366
  };
3055
3367
  }
3056
3368
  });
3057
- const _hoisted_1$6 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3058
- const _hoisted_2$3 = ["onClick"];
3059
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3369
+ const _hoisted_1$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3370
+ const _hoisted_2$1 = ["onClick", "onDragstart"];
3371
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
3060
3372
  const _component_el_input = vue.resolveComponent("el-input");
3061
3373
  const _component_m_icon = vue.resolveComponent("m-icon");
3062
3374
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -3086,15 +3398,17 @@
3086
3398
  name: index
3087
3399
  }, {
3088
3400
  title: vue.withCtx(() => [
3089
- _hoisted_1$6,
3401
+ _hoisted_1$5,
3090
3402
  vue.createTextVNode(vue.toDisplayString(group.title), 1)
3091
3403
  ]),
3092
3404
  default: vue.withCtx(() => [
3093
3405
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(group.items, (item) => {
3094
3406
  return vue.openBlock(), vue.createElementBlock("div", {
3095
3407
  class: "component-item",
3408
+ draggable: "true",
3096
3409
  key: item.type,
3097
- onClick: ($event) => _ctx.appendComponent(item)
3410
+ onClick: ($event) => _ctx.appendComponent(item),
3411
+ onDragstart: ($event) => _ctx.dragstartHandler(item, $event)
3098
3412
  }, [
3099
3413
  vue.createVNode(_component_m_icon, {
3100
3414
  icon: item.icon
@@ -3109,7 +3423,7 @@
3109
3423
  ]),
3110
3424
  _: 2
3111
3425
  }, 1032, ["content"])
3112
- ], 8, _hoisted_2$3);
3426
+ ], 40, _hoisted_2$1);
3113
3427
  }), 128))
3114
3428
  ]),
3115
3429
  _: 2
@@ -3123,135 +3437,220 @@
3123
3437
  _: 1
3124
3438
  });
3125
3439
  }
3126
- var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3440
+ var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3127
3441
 
3128
- const _sfc_main$8 = vue.defineComponent({
3129
- name: "magic-editor-content-menu",
3442
+ const _sfc_main$a = vue.defineComponent({
3443
+ components: { ToolButton },
3130
3444
  props: {
3131
- componentGroupList: {
3445
+ menuData: {
3132
3446
  type: Array,
3133
3447
  default: () => []
3134
3448
  }
3135
3449
  },
3136
- setup(props) {
3137
- const services = vue.inject("services");
3138
- const subVisible = vue.ref(false);
3139
- const node = vue.computed(() => services?.editorService.get("node"));
3450
+ setup() {
3451
+ const menu = vue.ref();
3452
+ const subMenu = vue.ref();
3453
+ const visible = vue.ref(false);
3454
+ const subMenuData = vue.ref([]);
3455
+ const menuStyle = vue.ref({
3456
+ left: "0",
3457
+ top: "0"
3458
+ });
3459
+ const hide = () => {
3460
+ visible.value = false;
3461
+ };
3462
+ vue.onMounted(() => {
3463
+ globalThis.addEventListener("mousedown", (e) => {
3464
+ if (!visible.value || e.target && menu.value?.contains(e.target)) {
3465
+ return;
3466
+ }
3467
+ hide();
3468
+ }, true);
3469
+ });
3140
3470
  return {
3141
- subVisible,
3142
- node,
3143
- menu: vue.computed(() => ({
3144
- app: [
3145
- {
3146
- type: "page",
3147
- text: "\u9875\u9762"
3471
+ menu,
3472
+ subMenu,
3473
+ visible,
3474
+ menuStyle,
3475
+ subMenuData,
3476
+ hide,
3477
+ show(e) {
3478
+ visible.value = true;
3479
+ vue.nextTick(() => {
3480
+ const menuHeight = menu.value?.clientHeight || 0;
3481
+ let top = e.clientY;
3482
+ if (menuHeight + e.clientY > document.body.clientHeight) {
3483
+ top = document.body.clientHeight - menuHeight;
3148
3484
  }
3149
- ],
3150
- component: props.componentGroupList
3151
- })),
3152
- append(config) {
3153
- services?.editorService.add({
3154
- name: config.text,
3155
- type: config.type
3485
+ menuStyle.value = {
3486
+ top: `${top}px`,
3487
+ left: `${e.clientX}px`
3488
+ };
3156
3489
  });
3157
3490
  },
3158
- remove() {
3159
- node.value && services?.editorService.remove(node.value);
3160
- },
3161
- copy(node2) {
3162
- services?.editorService.copy(node2);
3163
- },
3164
- setSubVisiable(v) {
3165
- subVisible.value = v;
3491
+ showSubMenu(item) {
3492
+ const menuItem = item;
3493
+ if (typeof item !== "object" || !menuItem.items?.length) {
3494
+ return;
3495
+ }
3496
+ subMenuData.value = menuItem.items;
3497
+ if (menu.value) {
3498
+ subMenu.value.show({
3499
+ clientX: menu.value.offsetLeft + menu.value.clientWidth,
3500
+ clientY: menu.value.offsetTop
3501
+ });
3502
+ }
3166
3503
  }
3167
3504
  };
3168
3505
  }
3169
3506
  });
3170
- const _hoisted_1$5 = {
3171
- key: 0,
3172
- class: "magic-editor-content-menu"
3173
- };
3174
- const _hoisted_2$2 = ["onClick"];
3175
- const _hoisted_3$2 = ["onClick"];
3176
- const _hoisted_4$2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3177
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3178
- const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
3179
- return _ctx.node ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$5, [
3180
- _ctx.node.items ? (vue.openBlock(), vue.createElementBlock("div", {
3181
- key: 0,
3182
- class: "magic-editor-content-menu-item",
3183
- onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisiable(true)),
3184
- onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisiable(false))
3185
- }, " \u65B0\u589E ", 32)) : vue.createCommentVNode("", true),
3186
- _ctx.node.type !== "app" ? (vue.openBlock(), vue.createElementBlock("div", {
3187
- key: 1,
3188
- class: "magic-editor-content-menu-item",
3189
- onClick: _cache[2] || (_cache[2] = () => _ctx.copy(_ctx.node))
3190
- }, "\u590D\u5236")) : vue.createCommentVNode("", true),
3191
- _ctx.node.type !== "app" && _ctx.node.type !== "page" ? (vue.openBlock(), vue.createElementBlock("div", {
3192
- key: 2,
3193
- class: "magic-editor-content-menu-item",
3194
- onClick: _cache[3] || (_cache[3] = () => _ctx.remove())
3195
- }, " \u5220\u9664 ")) : vue.createCommentVNode("", true),
3196
- vue.withDirectives(vue.createElementVNode("div", {
3197
- class: "subMenu",
3198
- onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisiable(true)),
3199
- onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisiable(false))
3200
- }, [
3201
- vue.createVNode(_component_el_scrollbar, null, {
3202
- default: vue.withCtx(() => [
3203
- _ctx.node.type === "tabs" ? (vue.openBlock(), vue.createElementBlock("div", {
3204
- key: 0,
3205
- class: "magic-editor-content-menu-item",
3206
- onClick: _cache[4] || (_cache[4] = () => _ctx.append({
3207
- type: "tab-pane"
3208
- }))
3209
- }, " \u6807\u7B7E ")) : _ctx.node.type === "app" ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(_ctx.menu.app, (item) => {
3210
- return vue.openBlock(), vue.createElementBlock("div", {
3211
- class: "magic-editor-content-menu-item",
3212
- key: item.type,
3213
- onClick: () => _ctx.append(item)
3214
- }, vue.toDisplayString(item.text), 9, _hoisted_2$2);
3215
- }), 128)) : _ctx.node.items ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 2 }, vue.renderList(_ctx.menu.component, (list) => {
3216
- return vue.openBlock(), vue.createElementBlock("div", {
3217
- key: list.title
3218
- }, [
3219
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(list.items, (item) => {
3220
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
3221
- item ? (vue.openBlock(), vue.createElementBlock("div", {
3222
- class: "magic-editor-content-menu-item",
3223
- key: item.type,
3224
- onClick: () => _ctx.append(item)
3225
- }, vue.toDisplayString(item.text), 9, _hoisted_3$2)) : vue.createCommentVNode("", true)
3226
- ], 64);
3227
- }), 256)),
3228
- _hoisted_4$2
3229
- ]);
3230
- }), 128)) : vue.createCommentVNode("", true)
3231
- ]),
3232
- _: 1
3233
- })
3234
- ], 544), [
3235
- [vue.vShow, _ctx.subVisible]
3236
- ])
3237
- ])) : vue.createCommentVNode("", true);
3507
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3508
+ const _component_tool_button = vue.resolveComponent("tool-button");
3509
+ const _component_content_menu = vue.resolveComponent("content-menu", true);
3510
+ return _ctx.menuData.length ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", {
3511
+ key: 0,
3512
+ class: "magic-editor-content-menu",
3513
+ ref: "menu",
3514
+ style: vue.normalizeStyle(_ctx.menuStyle)
3515
+ }, [
3516
+ vue.createElementVNode("div", null, [
3517
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.menuData, (item, index) => {
3518
+ return vue.openBlock(), vue.createBlock(_component_tool_button, {
3519
+ "event-type": "mouseup",
3520
+ data: item,
3521
+ key: index,
3522
+ onMouseup: _ctx.hide,
3523
+ onMouseenter: ($event) => _ctx.showSubMenu(item)
3524
+ }, null, 8, ["data", "onMouseup", "onMouseenter"]);
3525
+ }), 128))
3526
+ ]),
3527
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3528
+ vue.createVNode(_component_content_menu, {
3529
+ class: "sub-menu",
3530
+ ref: "subMenu",
3531
+ "menu-data": _ctx.subMenuData
3532
+ }, null, 8, ["menu-data"])
3533
+ ]))
3534
+ ], 4)), [
3535
+ [vue.vShow, _ctx.visible]
3536
+ ]) : vue.createCommentVNode("", true);
3238
3537
  }
3239
- var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3538
+ var ContentMenu = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3240
3539
 
3241
- const select = (data, editorService) => {
3540
+ const _sfc_main$9 = vue.defineComponent({
3541
+ components: { ContentMenu },
3542
+ setup() {
3543
+ const services = vue.inject("services");
3544
+ const menu = vue.ref();
3545
+ const node = vue.computed(() => services?.editorService.get("node"));
3546
+ const isRoot = vue.computed(() => node.value?.type === schema.NodeType.ROOT);
3547
+ const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
3548
+ const componentList = vue.computed(() => services?.componentListService.getList() || []);
3549
+ const createMenuItems = (group) => group.items.map((component) => ({
3550
+ text: component.text,
3551
+ type: "button",
3552
+ icon: component.icon,
3553
+ handler: () => {
3554
+ services?.editorService.add({
3555
+ name: component.text,
3556
+ type: component.type,
3557
+ ...component.data || {}
3558
+ });
3559
+ }
3560
+ }));
3561
+ const getSubMenuData = vue.computed(() => {
3562
+ if (node.value?.type === "tabs") {
3563
+ return [
3564
+ {
3565
+ text: "\u6807\u7B7E\u9875",
3566
+ type: "button",
3567
+ icon: icons.Files,
3568
+ handler: () => {
3569
+ services?.editorService.add({
3570
+ type: "tab-pane"
3571
+ });
3572
+ }
3573
+ }
3574
+ ];
3575
+ }
3576
+ if (node.value?.items) {
3577
+ return componentList.value.reduce((subMenuData, group, index) => subMenuData.concat(createMenuItems(group), index < componentList.value.length - 1 ? [
3578
+ {
3579
+ type: "divider",
3580
+ direction: "horizontal"
3581
+ }
3582
+ ] : []), []) || [];
3583
+ }
3584
+ return [];
3585
+ });
3586
+ return {
3587
+ menu,
3588
+ menuData: vue.computed(() => [
3589
+ {
3590
+ type: "button",
3591
+ text: "\u65B0\u589E",
3592
+ icon: vue.markRaw(icons.Plus),
3593
+ display: () => node.value?.items,
3594
+ items: getSubMenuData.value
3595
+ },
3596
+ {
3597
+ type: "button",
3598
+ text: "\u590D\u5236",
3599
+ icon: vue.markRaw(icons.DocumentCopy),
3600
+ display: () => !isRoot.value,
3601
+ handler: () => {
3602
+ node.value && services?.editorService.copy(node.value);
3603
+ }
3604
+ },
3605
+ {
3606
+ type: "button",
3607
+ text: "\u5220\u9664",
3608
+ icon: vue.markRaw(icons.Delete),
3609
+ display: () => !isRoot.value && !isPage.value,
3610
+ handler: () => {
3611
+ node.value && services?.editorService.remove(node.value);
3612
+ }
3613
+ }
3614
+ ]),
3615
+ show(e) {
3616
+ menu.value?.show(e);
3617
+ }
3618
+ };
3619
+ }
3620
+ });
3621
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3622
+ const _component_content_menu = vue.resolveComponent("content-menu");
3623
+ return vue.openBlock(), vue.createBlock(_component_content_menu, {
3624
+ "menu-data": _ctx.menuData,
3625
+ ref: "menu",
3626
+ style: { "overflow": "initial" }
3627
+ }, null, 8, ["menu-data"]);
3628
+ }
3629
+ var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3630
+
3631
+ const throttleTime = 150;
3632
+ const select = async (data, editorService) => {
3242
3633
  if (!data.id) {
3243
3634
  throw new Error("\u6CA1\u6709id");
3244
3635
  }
3245
- editorService?.select(data);
3636
+ await editorService?.select(data);
3637
+ editorService?.get("stage")?.select(data.id);
3638
+ };
3639
+ const highlight = (data, editorService) => {
3640
+ if (!data?.id) {
3641
+ throw new Error("\u6CA1\u6709id");
3642
+ }
3643
+ editorService?.highlight(data);
3644
+ editorService?.get("stage")?.highlight(data.id);
3246
3645
  };
3247
3646
  const useDrop = (tree, editorService) => ({
3248
3647
  allowDrop: (draggingNode, dropNode, type) => {
3249
3648
  const { data } = dropNode || {};
3250
3649
  const { data: ingData } = draggingNode;
3251
3650
  const { type: ingType } = ingData;
3252
- if (ingType !== "page" && data.type === "page")
3651
+ if (ingType !== schema.NodeType.PAGE && data.type === schema.NodeType.PAGE)
3253
3652
  return false;
3254
- if (ingType === "page" && data.type !== "page")
3653
+ if (ingType === schema.NodeType.PAGE && data.type !== schema.NodeType.PAGE)
3255
3654
  return false;
3256
3655
  if (!data || !data.type)
3257
3656
  return false;
@@ -3270,29 +3669,35 @@
3270
3669
  }
3271
3670
  });
3272
3671
  const useStatus = (tree, editorService) => {
3672
+ const highlightNode = vue.ref();
3673
+ const node = vue.ref();
3273
3674
  const page = vue.computed(() => editorService?.get("page"));
3274
3675
  vue.watchEffect(() => {
3275
3676
  if (!tree.value)
3276
3677
  return;
3277
- const node = editorService?.get("node");
3278
- node && tree.value.setCurrentKey(node.id, true);
3678
+ node.value = editorService?.get("node");
3679
+ node.value && tree.value.setCurrentKey(node.value.id, true);
3279
3680
  const parent = editorService?.get("parent");
3280
3681
  if (!parent?.id)
3281
3682
  return;
3282
3683
  const treeNode = tree.value.getNode(parent.id);
3283
3684
  treeNode?.updateChildren();
3685
+ highlightNode.value = editorService?.get("highlightNode");
3284
3686
  });
3285
3687
  return {
3286
3688
  values: vue.computed(() => page.value ? [page.value] : []),
3287
- loadItems: (node, resolve) => {
3288
- if (Array.isArray(node.data)) {
3289
- return resolve(node.data);
3689
+ loadItems: (node2, resolve) => {
3690
+ if (Array.isArray(node2.data)) {
3691
+ return resolve(node2.data);
3290
3692
  }
3291
- if (Array.isArray(node.data?.items)) {
3292
- return resolve(node.data?.items);
3693
+ if (Array.isArray(node2.data?.items)) {
3694
+ return resolve(node2.data?.items);
3293
3695
  }
3294
3696
  resolve([]);
3295
- }
3697
+ },
3698
+ highlightNode,
3699
+ clickNode: node,
3700
+ expandedKeys: vue.computed(() => node.value ? [node.value.id] : [])
3296
3701
  };
3297
3702
  };
3298
3703
  const useFilter = (tree) => ({
@@ -3304,69 +3709,64 @@
3304
3709
  let name = "";
3305
3710
  if (data.name) {
3306
3711
  name = data.name;
3307
- } else if (data.type) {
3308
- name = data.type;
3309
3712
  } else if (data.items) {
3310
3713
  name = "container";
3311
3714
  }
3312
- return name.indexOf(value) !== -1;
3715
+ return `${data.id}${name}${data.type}`.indexOf(value) !== -1;
3313
3716
  },
3314
3717
  filterTextChangeHandler(val) {
3315
3718
  tree.value?.filter(val);
3316
3719
  }
3317
3720
  });
3318
- const useContentMenu = (editorService) => {
3319
- const menuStyle = vue.ref({
3320
- position: "absolute",
3321
- left: "0",
3322
- top: "0",
3323
- display: "none"
3324
- });
3325
- vue.onMounted(() => {
3326
- document.addEventListener("click", () => {
3327
- menuStyle.value.display = "none";
3328
- }, true);
3329
- });
3330
- return {
3331
- menuStyle,
3332
- contextmenu(event, data) {
3333
- const bodyHeight = globalThis.document.body.clientHeight;
3334
- const left = `${event.clientX + 20}px`;
3335
- let top = `${event.clientY - 10}px`;
3336
- if (event.clientY + 300 > bodyHeight) {
3337
- top = `${bodyHeight - 300}px`;
3338
- }
3339
- menuStyle.value.left = left;
3340
- menuStyle.value.top = top;
3341
- menuStyle.value.display = "";
3342
- select(data, editorService);
3343
- }
3344
- };
3345
- };
3346
- const _sfc_main$7 = vue.defineComponent({
3721
+ const _sfc_main$8 = vue.defineComponent({
3347
3722
  name: "magic-editor-layer-panel",
3348
3723
  components: { LayerMenu },
3349
3724
  setup() {
3350
3725
  const services = vue.inject("services");
3351
3726
  const tree = vue.ref();
3727
+ const menu = vue.ref();
3728
+ const clicked = vue.ref(false);
3352
3729
  const editorService = services?.editorService;
3730
+ const highlightHandler = lodashEs.throttle((data) => {
3731
+ highlight(data, editorService);
3732
+ }, throttleTime);
3733
+ const toggleClickFlag = () => {
3734
+ clicked.value = !clicked.value;
3735
+ };
3736
+ const statusData = useStatus(tree, editorService);
3737
+ const canHighlight = vue.computed(() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value);
3738
+ editorService?.on("remove", () => {
3739
+ setTimeout(() => {
3740
+ tree.value?.getNode(editorService.get("node").id)?.updateChildren();
3741
+ }, 0);
3742
+ });
3353
3743
  return {
3354
3744
  tree,
3745
+ menu,
3746
+ ...statusData,
3355
3747
  ...useDrop(tree, editorService),
3356
- ...useStatus(tree, editorService),
3357
3748
  ...useFilter(tree),
3358
- ...useContentMenu(editorService),
3749
+ highlightHandler,
3750
+ toggleClickFlag,
3751
+ canHighlight,
3359
3752
  clickHandler(data) {
3360
3753
  if (services?.uiService.get("uiSelectMode")) {
3361
3754
  document.dispatchEvent(new CustomEvent("ui-select", { detail: data }));
3362
3755
  return;
3363
3756
  }
3757
+ tree.value?.setCurrentKey(data.id);
3364
3758
  select(data, editorService);
3759
+ },
3760
+ async contextmenu(event, data) {
3761
+ event.preventDefault();
3762
+ await select(data, editorService);
3763
+ menu.value?.show(event);
3365
3764
  }
3366
3765
  };
3367
3766
  }
3368
3767
  });
3369
- function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3768
+ const _hoisted_1$4 = ["id", "onMouseenter"];
3769
+ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3370
3770
  const _component_el_input = vue.resolveComponent("el-input");
3371
3771
  const _component_el_tree = vue.resolveComponent("el-tree");
3372
3772
  const _component_layer_menu = vue.resolveComponent("layer-menu");
@@ -3387,6 +3787,7 @@
3387
3787
  ref: "tree",
3388
3788
  "node-key": "id",
3389
3789
  draggable: "",
3790
+ "default-expanded-keys": _ctx.expandedKeys,
3390
3791
  load: _ctx.loadItems,
3391
3792
  data: _ctx.values,
3392
3793
  "expand-on-click-node": false,
@@ -3402,47 +3803,46 @@
3402
3803
  "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684"
3403
3804
  }, {
3404
3805
  default: vue.withCtx(({ node, data }) => [
3405
- vue.renderSlot(_ctx.$slots, "layer-node-content", {
3406
- node,
3407
- data
3408
- }, () => [
3409
- vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
3410
- ])
3806
+ vue.createElementVNode("div", {
3807
+ id: data.id,
3808
+ class: vue.normalizeClass(["cus-tree-node", { "cus-tree-node-hover": _ctx.canHighlight && data.id === _ctx.highlightNode?.id }]),
3809
+ onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toggleClickFlag && _ctx.toggleClickFlag(...args)),
3810
+ onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toggleClickFlag && _ctx.toggleClickFlag(...args)),
3811
+ onMouseenter: ($event) => _ctx.highlightHandler(data)
3812
+ }, [
3813
+ vue.renderSlot(_ctx.$slots, "layer-node-content", {
3814
+ node,
3815
+ data
3816
+ }, () => [
3817
+ vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
3818
+ ])
3819
+ ], 42, _hoisted_1$4)
3411
3820
  ]),
3412
3821
  _: 3
3413
- }, 8, ["load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : vue.createCommentVNode("", true),
3822
+ }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : vue.createCommentVNode("", true),
3414
3823
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3415
- vue.createVNode(_component_layer_menu, {
3416
- style: vue.normalizeStyle(_ctx.menuStyle)
3417
- }, null, 8, ["style"])
3824
+ vue.createVNode(_component_layer_menu, { ref: "menu" }, null, 512)
3418
3825
  ]))
3419
3826
  ]),
3420
3827
  _: 3
3421
3828
  });
3422
3829
  }
3423
- var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3830
+ var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3424
3831
 
3425
- const _sfc_main$6 = vue.defineComponent({
3426
- name: "m-sidebar",
3832
+ const _sfc_main$7 = vue.defineComponent({
3427
3833
  components: { MIcon },
3428
3834
  props: {
3429
3835
  data: {
3430
- type: Object,
3431
- default: () => ({ type: "tabs", status: "\u7EC4\u4EF6", items: ["component-list", "layer"] })
3836
+ type: Object
3432
3837
  }
3433
3838
  },
3434
3839
  setup(props) {
3435
- const activeTabName = vue.ref(props.data?.status);
3436
- vue.watch(() => props.data?.status, (status) => {
3437
- activeTabName.value = status || "0";
3438
- });
3439
3840
  return {
3440
- activeTabName,
3441
- items: vue.computed(() => props.data?.items.map((item) => {
3442
- if (typeof item !== "string") {
3443
- return item;
3841
+ config: vue.computed(() => {
3842
+ if (typeof props.data !== "string") {
3843
+ return props.data;
3444
3844
  }
3445
- switch (item) {
3845
+ switch (props.data) {
3446
3846
  case "component-list":
3447
3847
  return {
3448
3848
  type: "component",
@@ -3460,21 +3860,75 @@
3460
3860
  slots: {}
3461
3861
  };
3462
3862
  default:
3463
- return {};
3863
+ return void 0;
3464
3864
  }
3465
- }))
3865
+ })
3466
3866
  };
3467
3867
  }
3468
3868
  });
3469
- const _hoisted_1$4 = {
3869
+ const _hoisted_1$3 = {
3470
3870
  key: 1,
3471
3871
  class: "magic-editor-tab-panel-title"
3472
3872
  };
3473
- function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3873
+ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3474
3874
  const _component_m_icon = vue.resolveComponent("m-icon");
3475
3875
  const _component_el_tab_pane = vue.resolveComponent("el-tab-pane");
3876
+ return _ctx.config ? (vue.openBlock(), vue.createBlock(_component_el_tab_pane, {
3877
+ key: 0,
3878
+ name: _ctx.config.text
3879
+ }, {
3880
+ label: vue.withCtx(() => [
3881
+ (vue.openBlock(), vue.createElementBlock("div", {
3882
+ key: _ctx.config.text
3883
+ }, [
3884
+ _ctx.config.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3885
+ key: 0,
3886
+ icon: _ctx.config.icon
3887
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3888
+ _ctx.config.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, vue.toDisplayString(_ctx.config.text), 1)) : vue.createCommentVNode("", true)
3889
+ ]))
3890
+ ]),
3891
+ default: vue.withCtx(() => [
3892
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.config.component), vue.mergeProps(_ctx.config.props || {}, vue.toHandlers(_ctx.config?.listeners || {})), vue.createSlots({ _: 2 }, [
3893
+ _ctx.config.slots?.layerNodeContent ? {
3894
+ name: "layer-node-content",
3895
+ fn: vue.withCtx(({ data, node }) => [
3896
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.config.slots?.layerNodeContent), {
3897
+ data,
3898
+ node
3899
+ }, null, 8, ["data", "node"]))
3900
+ ])
3901
+ } : void 0
3902
+ ]), 1040))
3903
+ ]),
3904
+ _: 1
3905
+ }, 8, ["name"])) : vue.createCommentVNode("", true);
3906
+ }
3907
+ var TabPane = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3908
+
3909
+ const _sfc_main$6 = vue.defineComponent({
3910
+ components: { TabPane },
3911
+ name: "m-sidebar",
3912
+ props: {
3913
+ data: {
3914
+ type: Object,
3915
+ default: () => ({ type: "tabs", status: "\u7EC4\u4EF6", items: ["component-list", "layer"] })
3916
+ }
3917
+ },
3918
+ setup(props) {
3919
+ const activeTabName = vue.ref(props.data?.status);
3920
+ vue.watch(() => props.data?.status, (status) => {
3921
+ activeTabName.value = status || "0";
3922
+ });
3923
+ return {
3924
+ activeTabName
3925
+ };
3926
+ }
3927
+ });
3928
+ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3929
+ const _component_tab_pane = vue.resolveComponent("tab-pane");
3476
3930
  const _component_el_tabs = vue.resolveComponent("el-tabs");
3477
- return _ctx.data.type === "tabs" ? (vue.openBlock(), vue.createBlock(_component_el_tabs, {
3931
+ return _ctx.data.type === "tabs" && _ctx.data.items.length ? (vue.openBlock(), vue.createBlock(_component_el_tabs, {
3478
3932
  key: 0,
3479
3933
  class: "m-editor-sidebar",
3480
3934
  modelValue: _ctx.activeTabName,
@@ -3483,35 +3937,11 @@
3483
3937
  "tab-position": "left"
3484
3938
  }, {
3485
3939
  default: vue.withCtx(() => [
3486
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.items, (item) => {
3487
- return vue.openBlock(), vue.createBlock(_component_el_tab_pane, {
3488
- key: item.text,
3489
- name: item.text
3490
- }, {
3491
- label: vue.withCtx(() => [
3492
- vue.createElementVNode("span", null, [
3493
- item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3494
- key: 0,
3495
- icon: item.icon
3496
- }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3497
- item.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$4, vue.toDisplayString(item.text), 1)) : vue.createCommentVNode("", true)
3498
- ])
3499
- ]),
3500
- default: vue.withCtx(() => [
3501
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.component), vue.mergeProps(item.props || {}, vue.toHandlers(item.listeners || {})), vue.createSlots({ _: 2 }, [
3502
- item.slots?.layerNodeContent ? {
3503
- name: "layer-node-content",
3504
- fn: vue.withCtx(({ data, node }) => [
3505
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.slots.layerNodeContent), {
3506
- data,
3507
- node
3508
- }, null, 8, ["data", "node"]))
3509
- ])
3510
- } : void 0
3511
- ]), 1040))
3512
- ]),
3513
- _: 2
3514
- }, 1032, ["name"]);
3940
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.data.items, (item, index) => {
3941
+ return vue.openBlock(), vue.createBlock(_component_tab_pane, {
3942
+ key: index,
3943
+ data: item
3944
+ }, null, 8, ["data"]);
3515
3945
  }), 128))
3516
3946
  ]),
3517
3947
  _: 1
@@ -3519,13 +3949,81 @@
3519
3949
  }
3520
3950
  var Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6]]);
3521
3951
 
3952
+ const useScroll = (root) => {
3953
+ const pageBar = vue.ref();
3954
+ const itemsContainer = vue.ref();
3955
+ const pageBarWidth = vue.ref(0);
3956
+ const canScroll = vue.ref(false);
3957
+ const itemsContainerWidth = vue.computed(() => pageBarWidth.value - 105);
3958
+ let translateLeft = 0;
3959
+ const resizeObserver = new ResizeObserver((entries) => {
3960
+ for (const { contentRect } of entries) {
3961
+ const { width } = contentRect;
3962
+ pageBarWidth.value = width || 0;
3963
+ setCanScroll();
3964
+ }
3965
+ });
3966
+ const setCanScroll = () => {
3967
+ if (itemsContainer.value) {
3968
+ canScroll.value = itemsContainer.value.scrollWidth > pageBarWidth.value - 105;
3969
+ }
3970
+ };
3971
+ const scroll = (type) => {
3972
+ if (!itemsContainer.value)
3973
+ return;
3974
+ const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
3975
+ if (type === "left") {
3976
+ translateLeft += 100;
3977
+ if (translateLeft > 0) {
3978
+ translateLeft = 0;
3979
+ }
3980
+ } else if (type === "right") {
3981
+ translateLeft -= 100;
3982
+ if (-translateLeft > maxScrollLeft) {
3983
+ translateLeft = -maxScrollLeft;
3984
+ }
3985
+ } else if (type === "start") {
3986
+ translateLeft = 0;
3987
+ } else if (type === "end") {
3988
+ translateLeft = -maxScrollLeft;
3989
+ }
3990
+ itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
3991
+ };
3992
+ vue.onMounted(() => {
3993
+ pageBar.value && resizeObserver.observe(pageBar.value);
3994
+ });
3995
+ vue.onUnmounted(() => {
3996
+ resizeObserver.disconnect();
3997
+ });
3998
+ vue.watch(() => root.value?.items.length, (length = 0, preLength = 0) => {
3999
+ setTimeout(() => {
4000
+ setCanScroll();
4001
+ if (length < preLength) {
4002
+ scroll("start");
4003
+ } else {
4004
+ scroll("end");
4005
+ }
4006
+ });
4007
+ });
4008
+ return {
4009
+ pageBar,
4010
+ itemsContainer,
4011
+ canScroll,
4012
+ itemsContainerWidth,
4013
+ scroll
4014
+ };
4015
+ };
3522
4016
  const _sfc_main$5 = vue.defineComponent({
3523
- components: { CaretBottom: icons.CaretBottom, Plus: icons.Plus },
4017
+ components: { ArrowLeftBold: icons.ArrowLeftBold, ArrowRightBold: icons.ArrowRightBold, CaretBottom: icons.CaretBottom, Plus: icons.Plus, ToolButton },
3524
4018
  setup() {
3525
4019
  const services = vue.inject("services");
3526
4020
  const editorService = services?.editorService;
4021
+ const root = vue.computed(() => editorService?.get("root"));
3527
4022
  return {
3528
- root: vue.computed(() => editorService?.get("root")),
4023
+ Delete: vue.markRaw(icons.Delete),
4024
+ DocumentCopy: vue.markRaw(icons.DocumentCopy),
4025
+ ...useScroll(root),
4026
+ root,
3529
4027
  page: vue.computed(() => editorService?.get("page")),
3530
4028
  switchPage(page) {
3531
4029
  editorService?.select(page);
@@ -3534,7 +4032,7 @@
3534
4032
  if (!editorService)
3535
4033
  return;
3536
4034
  const pageConfig = {
3537
- type: "page",
4035
+ type: schema.NodeType.PAGE,
3538
4036
  name: generatePageNameByApp(vue.toRaw(editorService.get("root")))
3539
4037
  };
3540
4038
  editorService.add(pageConfig);
@@ -3552,99 +4050,228 @@
3552
4050
  };
3553
4051
  }
3554
4052
  });
3555
- const _hoisted_1$3 = { class: "m-editor-page-bar" };
3556
- const _hoisted_2$1 = ["onClick"];
3557
- const _hoisted_3$1 = ["onClick"];
3558
- const _hoisted_4$1 = ["onClick"];
4053
+ const _hoisted_1$2 = {
4054
+ class: "m-editor-page-bar",
4055
+ ref: "pageBar"
4056
+ };
4057
+ const _hoisted_2 = ["onClick"];
4058
+ const _hoisted_3 = { class: "m-editor-page-bar-title" };
3559
4059
  function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3560
4060
  const _component_plus = vue.resolveComponent("plus");
3561
4061
  const _component_el_icon = vue.resolveComponent("el-icon");
4062
+ const _component_arrow_left_bold = vue.resolveComponent("arrow-left-bold");
4063
+ const _component_el_tooltip = vue.resolveComponent("el-tooltip");
4064
+ const _component_tool_button = vue.resolveComponent("tool-button");
3562
4065
  const _component_caret_bottom = vue.resolveComponent("caret-bottom");
3563
4066
  const _component_el_popover = vue.resolveComponent("el-popover");
3564
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [
4067
+ const _component_arrow_right_bold = vue.resolveComponent("arrow-right-bold");
4068
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
3565
4069
  vue.createElementVNode("div", {
3566
- class: "m-editor-page-bar-item",
4070
+ id: "m-editor-page-bar-add-icon",
4071
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3567
4072
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.addPage && _ctx.addPage(...args))
3568
4073
  }, [
3569
- vue.createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-add-icon" }, {
4074
+ vue.createVNode(_component_el_icon, null, {
3570
4075
  default: vue.withCtx(() => [
3571
4076
  vue.createVNode(_component_plus)
3572
4077
  ]),
3573
4078
  _: 1
3574
4079
  })
3575
4080
  ]),
3576
- _ctx.root ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(_ctx.root.items, (item) => {
3577
- return vue.openBlock(), vue.createElementBlock("div", {
3578
- key: item.key,
3579
- class: vue.normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3580
- onClick: ($event) => _ctx.switchPage(item)
3581
- }, [
3582
- vue.renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3583
- vue.createElementVNode("span", null, vue.toDisplayString(item.name), 1)
4081
+ _ctx.canScroll ? (vue.openBlock(), vue.createElementBlock("div", {
4082
+ key: 0,
4083
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
4084
+ onClick: _cache[1] || (_cache[1] = ($event) => _ctx.scroll("left"))
4085
+ }, [
4086
+ vue.createVNode(_component_el_icon, null, {
4087
+ default: vue.withCtx(() => [
4088
+ vue.createVNode(_component_arrow_left_bold)
3584
4089
  ]),
3585
- vue.createVNode(_component_el_popover, {
3586
- placement: "top",
3587
- width: 160,
3588
- trigger: "hover"
3589
- }, {
3590
- reference: vue.withCtx(() => [
3591
- vue.createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-icon" }, {
3592
- default: vue.withCtx(() => [
3593
- vue.createVNode(_component_caret_bottom)
3594
- ]),
3595
- _: 1
3596
- })
3597
- ]),
3598
- default: vue.withCtx(() => [
3599
- vue.createElementVNode("div", null, [
3600
- vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3601
- vue.createElementVNode("div", {
3602
- class: "magic-editor-content-menu-item",
3603
- onClick: () => _ctx.copy(item)
3604
- }, "\u590D\u5236", 8, _hoisted_3$1),
3605
- vue.createElementVNode("div", {
3606
- class: "magic-editor-content-menu-item",
3607
- onClick: () => _ctx.remove(item)
3608
- }, "\u5220\u9664", 8, _hoisted_4$1)
3609
- ])
4090
+ _: 1
4091
+ })
4092
+ ])) : vue.createCommentVNode("", true),
4093
+ _ctx.root ? (vue.openBlock(), vue.createElementBlock("div", {
4094
+ key: 1,
4095
+ class: "m-editor-page-bar-items",
4096
+ ref: "itemsContainer",
4097
+ style: vue.normalizeStyle(`width: ${_ctx.itemsContainerWidth}px`)
4098
+ }, [
4099
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.root.items, (item) => {
4100
+ return vue.openBlock(), vue.createElementBlock("div", {
4101
+ key: item.key,
4102
+ class: vue.normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
4103
+ onClick: ($event) => _ctx.switchPage(item)
4104
+ }, [
4105
+ vue.createElementVNode("div", _hoisted_3, [
4106
+ vue.renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
4107
+ vue.createVNode(_component_el_tooltip, {
4108
+ effect: "dark",
4109
+ placement: "top-start",
4110
+ content: item.name
4111
+ }, {
4112
+ default: vue.withCtx(() => [
4113
+ vue.createElementVNode("span", null, vue.toDisplayString(item.name), 1)
4114
+ ]),
4115
+ _: 2
4116
+ }, 1032, ["content"])
3610
4117
  ])
3611
4118
  ]),
3612
- _: 2
3613
- }, 1024)
3614
- ], 10, _hoisted_2$1);
3615
- }), 128)) : vue.createCommentVNode("", true)
3616
- ]);
4119
+ vue.createVNode(_component_el_popover, {
4120
+ "popper-class": "page-bar-popover",
4121
+ placement: "top",
4122
+ width: 160,
4123
+ trigger: "hover"
4124
+ }, {
4125
+ reference: vue.withCtx(() => [
4126
+ vue.createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-icon" }, {
4127
+ default: vue.withCtx(() => [
4128
+ vue.createVNode(_component_caret_bottom)
4129
+ ]),
4130
+ _: 1
4131
+ })
4132
+ ]),
4133
+ default: vue.withCtx(() => [
4134
+ vue.createElementVNode("div", null, [
4135
+ vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
4136
+ vue.createVNode(_component_tool_button, {
4137
+ data: {
4138
+ type: "button",
4139
+ text: "\u590D\u5236",
4140
+ icon: _ctx.DocumentCopy,
4141
+ handler: () => _ctx.copy(item)
4142
+ }
4143
+ }, null, 8, ["data"]),
4144
+ vue.createVNode(_component_tool_button, {
4145
+ data: {
4146
+ type: "button",
4147
+ text: "\u5220\u9664",
4148
+ icon: _ctx.Delete,
4149
+ handler: () => _ctx.remove(item)
4150
+ }
4151
+ }, null, 8, ["data"])
4152
+ ])
4153
+ ])
4154
+ ]),
4155
+ _: 2
4156
+ }, 1024)
4157
+ ], 10, _hoisted_2);
4158
+ }), 128))
4159
+ ], 4)) : vue.createCommentVNode("", true),
4160
+ _ctx.canScroll ? (vue.openBlock(), vue.createElementBlock("div", {
4161
+ key: 2,
4162
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
4163
+ onClick: _cache[2] || (_cache[2] = ($event) => _ctx.scroll("right"))
4164
+ }, [
4165
+ vue.createVNode(_component_el_icon, null, {
4166
+ default: vue.withCtx(() => [
4167
+ vue.createVNode(_component_arrow_right_bold)
4168
+ ]),
4169
+ _: 1
4170
+ })
4171
+ ])) : vue.createCommentVNode("", true)
4172
+ ], 512);
3617
4173
  }
3618
4174
  var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3619
4175
 
3620
4176
  class ScrollViewer$1 {
3621
- enter = false;
3622
- targetEnter = false;
3623
- keydown = false;
3624
- container;
3625
- target;
3626
- zoom = 1;
3627
- scrollLeft = 0;
3628
- scrollTop = 0;
3629
- x = 0;
3630
- y = 0;
3631
- resizeObserver = new ResizeObserver((entries) => {
3632
- for (const { contentRect } of entries) {
3633
- const { width, height } = contentRect;
3634
- const targetRect = this.target.getBoundingClientRect();
3635
- const targetWidth = targetRect.width * this.zoom;
3636
- const targetMarginTop = Number(this.target.style.marginTop) || 0;
3637
- const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3638
- if (targetWidth < width) {
3639
- this.target._left = 0;
3640
- }
3641
- if (targetHeight < height) {
3642
- this.target._top = 0;
4177
+ constructor(options) {
4178
+ this.enter = false;
4179
+ this.targetEnter = false;
4180
+ this.keydown = false;
4181
+ this.zoom = 1;
4182
+ this.scrollLeft = 0;
4183
+ this.scrollTop = 0;
4184
+ this.x = 0;
4185
+ this.y = 0;
4186
+ this.resizeObserver = new ResizeObserver((entries) => {
4187
+ for (const { contentRect } of entries) {
4188
+ const { width, height } = contentRect;
4189
+ const targetRect = this.target.getBoundingClientRect();
4190
+ const targetWidth = targetRect.width * this.zoom;
4191
+ const targetMarginTop = Number(this.target.style.marginTop) || 0;
4192
+ const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
4193
+ if (targetWidth < width) {
4194
+ this.target._left = 0;
4195
+ }
4196
+ if (targetHeight < height) {
4197
+ this.target._top = 0;
4198
+ }
4199
+ this.scroll();
3643
4200
  }
4201
+ });
4202
+ this.wheelHandler = (event) => {
4203
+ if (this.targetEnter)
4204
+ return;
4205
+ const { deltaX, deltaY, currentTarget } = event;
4206
+ if (currentTarget !== this.container)
4207
+ return;
4208
+ this.setScrollOffset(deltaX, deltaY);
3644
4209
  this.scroll();
3645
- }
3646
- });
3647
- constructor(options) {
4210
+ this.scrollLeft = this.target._left;
4211
+ this.scrollTop = this.target._top;
4212
+ };
4213
+ this.mouseEnterHandler = () => {
4214
+ this.enter = true;
4215
+ };
4216
+ this.mouseLeaveHandler = () => {
4217
+ this.enter = false;
4218
+ };
4219
+ this.targetMouseEnterHandler = () => {
4220
+ this.targetEnter = true;
4221
+ };
4222
+ this.targetMouseLeaveHandler = () => {
4223
+ this.targetEnter = false;
4224
+ };
4225
+ this.mousedownHandler = (event) => {
4226
+ if (!this.keydown)
4227
+ return;
4228
+ event.stopImmediatePropagation();
4229
+ event.stopPropagation();
4230
+ this.target.style.cursor = "grabbing";
4231
+ this.x = event.clientX;
4232
+ this.y = event.clientY;
4233
+ document.addEventListener("mousemove", this.mousemoveHandler);
4234
+ document.addEventListener("mouseup", this.mouseupHandler);
4235
+ };
4236
+ this.mouseupHandler = () => {
4237
+ this.x = 0;
4238
+ this.y = 0;
4239
+ this.scrollLeft = this.target._left;
4240
+ this.scrollTop = this.target._top;
4241
+ this.removeHandler();
4242
+ };
4243
+ this.mousemoveHandler = (event) => {
4244
+ event.stopImmediatePropagation();
4245
+ event.stopPropagation();
4246
+ const deltaX = event.clientX - this.x;
4247
+ const deltaY = event.clientY - this.y;
4248
+ this.setScrollOffset(deltaX, deltaY);
4249
+ this.scroll();
4250
+ };
4251
+ this.keydownHandler = (event) => {
4252
+ if (event.code === Keys.ESCAPE && this.enter) {
4253
+ event.preventDefault();
4254
+ event.stopImmediatePropagation();
4255
+ event.stopPropagation();
4256
+ }
4257
+ if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
4258
+ return;
4259
+ }
4260
+ this.keydown = true;
4261
+ this.target.style.cursor = "grab";
4262
+ this.container.addEventListener("mousedown", this.mousedownHandler);
4263
+ };
4264
+ this.keyupHandler = (event) => {
4265
+ if (event.code !== Keys.ESCAPE || !this.keydown) {
4266
+ return;
4267
+ }
4268
+ event.preventDefault();
4269
+ event.stopImmediatePropagation();
4270
+ event.stopPropagation();
4271
+ this.keydown = false;
4272
+ event.preventDefault();
4273
+ this.removeHandler();
4274
+ };
3648
4275
  this.container = options.container;
3649
4276
  this.target = options.target;
3650
4277
  this.zoom = options.zoom;
@@ -3680,79 +4307,6 @@
3680
4307
  document.removeEventListener("mousemove", this.mousemoveHandler);
3681
4308
  document.removeEventListener("mouseup", this.mouseupHandler);
3682
4309
  }
3683
- wheelHandler = (event) => {
3684
- if (this.targetEnter)
3685
- return;
3686
- const { deltaX, deltaY, currentTarget } = event;
3687
- if (currentTarget !== this.container)
3688
- return;
3689
- this.setScrollOffset(deltaX, deltaY);
3690
- this.scroll();
3691
- this.scrollLeft = this.target._left;
3692
- this.scrollTop = this.target._top;
3693
- };
3694
- mouseEnterHandler = () => {
3695
- this.enter = true;
3696
- };
3697
- mouseLeaveHandler = () => {
3698
- this.enter = false;
3699
- };
3700
- targetMouseEnterHandler = () => {
3701
- this.targetEnter = true;
3702
- };
3703
- targetMouseLeaveHandler = () => {
3704
- this.targetEnter = false;
3705
- };
3706
- mousedownHandler = (event) => {
3707
- if (!this.keydown)
3708
- return;
3709
- event.stopImmediatePropagation();
3710
- event.stopPropagation();
3711
- this.target.style.cursor = "grabbing";
3712
- this.x = event.clientX;
3713
- this.y = event.clientY;
3714
- document.addEventListener("mousemove", this.mousemoveHandler);
3715
- document.addEventListener("mouseup", this.mouseupHandler);
3716
- };
3717
- mouseupHandler = () => {
3718
- this.x = 0;
3719
- this.y = 0;
3720
- this.scrollLeft = this.target._left;
3721
- this.scrollTop = this.target._top;
3722
- this.removeHandler();
3723
- };
3724
- mousemoveHandler = (event) => {
3725
- event.stopImmediatePropagation();
3726
- event.stopPropagation();
3727
- const deltaX = event.clientX - this.x;
3728
- const deltaY = event.clientY - this.y;
3729
- this.setScrollOffset(deltaX, deltaY);
3730
- this.scroll();
3731
- };
3732
- keydownHandler = (event) => {
3733
- if (event.code === Keys.ESCAPE && this.enter) {
3734
- event.preventDefault();
3735
- event.stopImmediatePropagation();
3736
- event.stopPropagation();
3737
- }
3738
- if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3739
- return;
3740
- }
3741
- this.keydown = true;
3742
- this.target.style.cursor = "grab";
3743
- this.container.addEventListener("mousedown", this.mousedownHandler);
3744
- };
3745
- keyupHandler = (event) => {
3746
- if (event.code !== Keys.ESCAPE || !this.keydown) {
3747
- return;
3748
- }
3749
- event.preventDefault();
3750
- event.stopImmediatePropagation();
3751
- event.stopPropagation();
3752
- this.keydown = false;
3753
- event.preventDefault();
3754
- this.removeHandler();
3755
- };
3756
4310
  setScrollOffset(deltaX, deltaY) {
3757
4311
  const { width, height } = this.container.getBoundingClientRect();
3758
4312
  const targetRect = this.target.getBoundingClientRect();
@@ -3813,19 +4367,19 @@
3813
4367
  el,
3814
4368
  style: vue.computed(() => `
3815
4369
  width: ${props.width}px;
3816
- height: ${props.height}px;
4370
+ height: ${(props.height || 0) - 40}px;
3817
4371
  position: absolute;
3818
4372
  margin-top: 30px;
3819
4373
  `)
3820
4374
  };
3821
4375
  }
3822
4376
  });
3823
- const _hoisted_1$2 = {
4377
+ const _hoisted_1$1 = {
3824
4378
  class: "m-editor-scroll-viewer-container",
3825
4379
  ref: "container"
3826
4380
  };
3827
4381
  function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3828
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
4382
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
3829
4383
  vue.createElementVNode("div", {
3830
4384
  ref: "el",
3831
4385
  style: vue.normalizeStyle(_ctx.style)
@@ -3837,7 +4391,7 @@
3837
4391
  var ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
3838
4392
 
3839
4393
  const _sfc_main$3 = vue.defineComponent({
3840
- name: "magic-editor-ui-viewer-menu",
4394
+ components: { ContentMenu },
3841
4395
  setup() {
3842
4396
  const services = vue.inject("services");
3843
4397
  const editorService = services?.editorService;
@@ -3846,6 +4400,7 @@
3846
4400
  const canCenter = vue.ref(false);
3847
4401
  const node = vue.computed(() => editorService?.get("node"));
3848
4402
  const parent = vue.computed(() => editorService?.get("parent"));
4403
+ const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
3849
4404
  vue.onMounted(() => {
3850
4405
  const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY);
3851
4406
  canPaste.value = data !== "undefined" && !!data;
@@ -3854,137 +4409,118 @@
3854
4409
  if (!parent.value || !editorService)
3855
4410
  return canCenter.value = false;
3856
4411
  const layout = await editorService.getLayout(parent.value);
3857
- canCenter.value = [Layout.ABSOLUTE, Layout.FIXED].includes(layout) && !["app", "page", "pop"].includes(`${node.value?.type}`);
4412
+ canCenter.value = [Layout.ABSOLUTE, Layout.FIXED].includes(layout) && ![schema.NodeType.ROOT, schema.NodeType.PAGE, "pop"].includes(`${node.value?.type}`);
3858
4413
  }, { immediate: true });
3859
4414
  return {
3860
4415
  menu,
3861
- canPaste,
3862
- canDelete: vue.computed(() => node.value?.type !== "page"),
3863
- canMoveZPos: vue.computed(() => node.value?.type !== "page"),
3864
- canCenter,
3865
- center() {
3866
- node.value && editorService?.alignCenter(node.value);
3867
- },
3868
- copy() {
3869
- node.value && editorService?.copy(node.value);
3870
- canPaste.value = true;
3871
- },
3872
- paste() {
3873
- const top = menu.value?.offsetTop || 0;
3874
- const left = menu.value?.offsetLeft || 0;
3875
- editorService?.paste({ left, top });
3876
- },
3877
- remove() {
3878
- node.value && editorService?.remove(node.value);
3879
- },
3880
- top() {
3881
- editorService?.moveLayer(LayerOffset.TOP);
3882
- },
3883
- bottom() {
3884
- editorService?.moveLayer(LayerOffset.BOTTOM);
3885
- },
3886
- topItem() {
3887
- editorService?.moveLayer(1);
3888
- },
3889
- bottomItem() {
3890
- editorService?.moveLayer(-1);
3891
- },
3892
- clearGuides() {
3893
- editorService?.get("stage").clearGuides();
4416
+ menuData: vue.reactive([
4417
+ {
4418
+ type: "button",
4419
+ text: "\u6C34\u5E73\u5C45\u4E2D",
4420
+ display: () => canCenter.value,
4421
+ handler: () => {
4422
+ node.value && editorService?.alignCenter(node.value);
4423
+ }
4424
+ },
4425
+ {
4426
+ type: "button",
4427
+ text: "\u590D\u5236",
4428
+ icon: vue.markRaw(icons.DocumentCopy),
4429
+ handler: () => {
4430
+ node.value && editorService?.copy(node.value);
4431
+ canPaste.value = true;
4432
+ }
4433
+ },
4434
+ {
4435
+ type: "button",
4436
+ text: "\u7C98\u8D34",
4437
+ display: () => canPaste.value,
4438
+ handler: () => {
4439
+ const top = menu.value?.$el.offsetTop || 0;
4440
+ const left = menu.value?.$el.offsetLeft || 0;
4441
+ editorService?.paste({ left, top });
4442
+ }
4443
+ },
4444
+ {
4445
+ type: "divider",
4446
+ direction: "horizontal",
4447
+ display: () => !isPage.value
4448
+ },
4449
+ {
4450
+ type: "button",
4451
+ text: "\u4E0A\u79FB\u4E00\u5C42",
4452
+ icon: vue.markRaw(icons.Top),
4453
+ display: () => !isPage.value,
4454
+ handler: () => {
4455
+ editorService?.moveLayer(1);
4456
+ }
4457
+ },
4458
+ {
4459
+ type: "button",
4460
+ text: "\u4E0B\u79FB\u4E00\u5C42",
4461
+ icon: vue.markRaw(icons.Bottom),
4462
+ display: () => !isPage.value,
4463
+ handler: () => {
4464
+ editorService?.moveLayer(-1);
4465
+ }
4466
+ },
4467
+ {
4468
+ type: "button",
4469
+ text: "\u7F6E\u9876",
4470
+ display: () => !isPage.value,
4471
+ handler: () => {
4472
+ editorService?.moveLayer(LayerOffset.TOP);
4473
+ }
4474
+ },
4475
+ {
4476
+ type: "button",
4477
+ text: "\u7F6E\u5E95",
4478
+ display: () => !isPage.value,
4479
+ handler: () => {
4480
+ editorService?.moveLayer(LayerOffset.BOTTOM);
4481
+ }
4482
+ },
4483
+ {
4484
+ type: "divider",
4485
+ direction: "horizontal",
4486
+ display: () => !isPage.value
4487
+ },
4488
+ {
4489
+ type: "button",
4490
+ text: "\u5220\u9664",
4491
+ icon: icons.Delete,
4492
+ display: () => !isPage.value,
4493
+ handler: () => {
4494
+ node.value && editorService?.remove(node.value);
4495
+ }
4496
+ },
4497
+ {
4498
+ type: "divider",
4499
+ direction: "horizontal"
4500
+ },
4501
+ {
4502
+ type: "button",
4503
+ text: "\u6E05\u7A7A\u53C2\u8003\u7EBF",
4504
+ handler: () => {
4505
+ editorService?.get("stage").clearGuides();
4506
+ }
4507
+ }
4508
+ ]),
4509
+ show(e) {
4510
+ menu.value?.show(e);
3894
4511
  }
3895
4512
  };
3896
4513
  }
3897
4514
  });
3898
- const _hoisted_1$1 = {
3899
- class: "magic-editor-content-menu",
3900
- ref: "menu"
3901
- };
3902
- const _hoisted_2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3903
- const _hoisted_3 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3904
- const _hoisted_4 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3905
4515
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
3906
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
3907
- vue.createElementVNode("div", null, [
3908
- _ctx.canCenter ? (vue.openBlock(), vue.createElementBlock("div", {
3909
- key: 0,
3910
- class: "magic-editor-content-menu-item",
3911
- onClick: _cache[0] || (_cache[0] = () => _ctx.center())
3912
- }, "\u6C34\u5E73\u5C45\u4E2D")) : vue.createCommentVNode("", true),
3913
- vue.createElementVNode("div", {
3914
- class: "magic-editor-content-menu-item",
3915
- onClick: _cache[1] || (_cache[1] = () => _ctx.copy())
3916
- }, "\u590D\u5236"),
3917
- _ctx.canPaste ? (vue.openBlock(), vue.createElementBlock("div", {
3918
- key: 1,
3919
- class: "magic-editor-content-menu-item",
3920
- onClick: _cache[2] || (_cache[2] = (...args) => _ctx.paste && _ctx.paste(...args))
3921
- }, "\u7C98\u8D34")) : vue.createCommentVNode("", true),
3922
- _ctx.canMoveZPos ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
3923
- _hoisted_2,
3924
- vue.createElementVNode("div", {
3925
- class: "magic-editor-content-menu-item",
3926
- onClick: _cache[3] || (_cache[3] = (...args) => _ctx.topItem && _ctx.topItem(...args))
3927
- }, "\u4E0A\u79FB\u4E00\u5C42"),
3928
- vue.createElementVNode("div", {
3929
- class: "magic-editor-content-menu-item",
3930
- onClick: _cache[4] || (_cache[4] = (...args) => _ctx.bottomItem && _ctx.bottomItem(...args))
3931
- }, "\u4E0B\u79FB\u4E00\u5C42"),
3932
- vue.createElementVNode("div", {
3933
- class: "magic-editor-content-menu-item",
3934
- onClick: _cache[5] || (_cache[5] = (...args) => _ctx.top && _ctx.top(...args))
3935
- }, "\u7F6E\u9876"),
3936
- vue.createElementVNode("div", {
3937
- class: "magic-editor-content-menu-item",
3938
- onClick: _cache[6] || (_cache[6] = (...args) => _ctx.bottom && _ctx.bottom(...args))
3939
- }, "\u7F6E\u5E95")
3940
- ], 64)) : vue.createCommentVNode("", true),
3941
- _ctx.canDelete ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
3942
- _hoisted_3,
3943
- vue.createElementVNode("div", {
3944
- class: "magic-editor-content-menu-item",
3945
- onClick: _cache[7] || (_cache[7] = () => _ctx.remove())
3946
- }, "\u5220\u9664")
3947
- ], 64)) : vue.createCommentVNode("", true),
3948
- _hoisted_4,
3949
- vue.createElementVNode("div", {
3950
- class: "magic-editor-content-menu-item",
3951
- onClick: _cache[8] || (_cache[8] = (...args) => _ctx.clearGuides && _ctx.clearGuides(...args))
3952
- }, "\u6E05\u7A7A\u53C2\u8003\u7EBF")
3953
- ])
3954
- ], 512);
4516
+ const _component_content_menu = vue.resolveComponent("content-menu");
4517
+ return vue.openBlock(), vue.createBlock(_component_content_menu, {
4518
+ "menu-data": _ctx.menuData,
4519
+ ref: "menu"
4520
+ }, null, 8, ["menu-data"]);
3955
4521
  }
3956
4522
  var ViewerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3]]);
3957
4523
 
3958
- const useMenu = () => {
3959
- const menu = vue.ref();
3960
- const menuStyle = vue.ref({
3961
- display: "none",
3962
- left: "0",
3963
- top: "0"
3964
- });
3965
- vue.onMounted(() => {
3966
- document.addEventListener("click", () => {
3967
- menuStyle.value.display = "none";
3968
- }, true);
3969
- });
3970
- return {
3971
- menu,
3972
- menuStyle,
3973
- contextmenuHandler(e) {
3974
- e.preventDefault();
3975
- const menuHeight = menu.value?.$el.clientHeight;
3976
- let top = e.clientY;
3977
- if (menuHeight + e.clientY > document.body.clientHeight) {
3978
- top = document.body.clientHeight - menuHeight;
3979
- }
3980
- menuStyle.value = {
3981
- display: "block",
3982
- top: `${top}px`,
3983
- left: `${e.clientX}px`
3984
- };
3985
- }
3986
- };
3987
- };
3988
4524
  const _sfc_main$2 = vue.defineComponent({
3989
4525
  name: "magic-stage",
3990
4526
  components: {
@@ -4007,16 +4543,16 @@
4007
4543
  })
4008
4544
  }
4009
4545
  },
4010
- emits: ["select", "update", "sort"],
4011
- setup(props, { emit }) {
4546
+ setup(props) {
4012
4547
  const services = vue.inject("services");
4013
4548
  const stageWrap = vue.ref();
4014
4549
  const stageContainer = vue.ref();
4550
+ const menu = vue.ref();
4015
4551
  const stageRect = vue.computed(() => services?.uiService.get("stageRect"));
4016
4552
  const uiSelectMode = vue.computed(() => services?.uiService.get("uiSelectMode"));
4017
4553
  const root = vue.computed(() => services?.editorService.get("root"));
4018
4554
  const page = vue.computed(() => services?.editorService.get("page"));
4019
- const zoom = vue.computed(() => services?.uiService.get("zoom"));
4555
+ const zoom = vue.computed(() => services?.uiService.get("zoom") || 1);
4020
4556
  const node = vue.computed(() => services?.editorService.get("node"));
4021
4557
  let stage = null;
4022
4558
  let runtime = null;
@@ -4031,9 +4567,9 @@
4031
4567
  render: props.render,
4032
4568
  runtimeUrl: props.runtimeUrl,
4033
4569
  zoom: zoom.value,
4034
- canSelect: (el, stop) => {
4570
+ canSelect: (el, event, stop) => {
4035
4571
  const elCanSelect = props.canSelect(el);
4036
- if (uiSelectMode.value && elCanSelect) {
4572
+ if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
4037
4573
  document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
4038
4574
  return stop();
4039
4575
  }
@@ -4041,14 +4577,19 @@
4041
4577
  },
4042
4578
  moveableOptions: props.moveableOptions
4043
4579
  });
4044
- services?.editorService.set("stage", stage);
4580
+ services?.editorService.set("stage", vue.markRaw(stage));
4045
4581
  stage?.mount(stageContainer.value);
4046
- stage?.on("select", (el) => emit("select", el));
4582
+ stage?.on("select", (el) => {
4583
+ services?.editorService.select(el.id);
4584
+ });
4585
+ stage?.on("highlight", (el) => {
4586
+ services?.editorService.highlight(el.id);
4587
+ });
4047
4588
  stage?.on("update", (ev) => {
4048
- emit("update", { id: ev.el.id, style: ev.style });
4589
+ services?.editorService.update({ id: ev.el.id, style: ev.style });
4049
4590
  });
4050
4591
  stage?.on("sort", (ev) => {
4051
- emit("sort", ev);
4592
+ services?.editorService.sort(ev.src, ev.dist);
4052
4593
  });
4053
4594
  stage?.on("changeGuides", () => {
4054
4595
  services?.uiService.set("showGuides", true);
@@ -4074,11 +4615,6 @@
4074
4615
  runtime.updateRootConfig(lodashEs.cloneDeep(vue.toRaw(root2)));
4075
4616
  }
4076
4617
  });
4077
- vue.watch(() => node.value?.id, (id) => {
4078
- vue.nextTick(() => {
4079
- id && stage?.select(id);
4080
- });
4081
- });
4082
4618
  const resizeObserver = new ResizeObserver((entries) => {
4083
4619
  for (const { contentRect } of entries) {
4084
4620
  services?.uiService.set("stageContainerRect", {
@@ -4098,9 +4634,36 @@
4098
4634
  return {
4099
4635
  stageWrap,
4100
4636
  stageContainer,
4637
+ menu,
4101
4638
  stageRect,
4102
4639
  zoom,
4103
- ...useMenu()
4640
+ contextmenuHandler(e2) {
4641
+ e2.preventDefault();
4642
+ menu.value?.show(e2);
4643
+ },
4644
+ dragoverHandler(e2) {
4645
+ e2.preventDefault();
4646
+ if (e2.dataTransfer) {
4647
+ e2.dataTransfer.dropEffect = "move";
4648
+ }
4649
+ },
4650
+ async dropHandler(e) {
4651
+ e.preventDefault();
4652
+ if (e.dataTransfer && page.value && stageContainer.value && stage) {
4653
+ const config = eval(`(${e.dataTransfer.getData("data")})`);
4654
+ const layout = await services?.editorService.getLayout(page.value);
4655
+ const containerRect = stageContainer.value.getBoundingClientRect();
4656
+ const { scrollTop, scrollLeft } = stage.mask;
4657
+ if (layout === Layout.ABSOLUTE) {
4658
+ config.style = {
4659
+ position: "absolute",
4660
+ top: e.clientY - containerRect.top + scrollTop,
4661
+ left: e.clientX - containerRect.left + scrollLeft
4662
+ };
4663
+ }
4664
+ services?.editorService.add(config, page.value);
4665
+ }
4666
+ }
4104
4667
  };
4105
4668
  }
4106
4669
  });
@@ -4118,14 +4681,13 @@
4118
4681
  vue.createElementVNode("div", {
4119
4682
  class: "m-editor-stage-container",
4120
4683
  ref: "stageContainer",
4684
+ style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`),
4121
4685
  onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args)),
4122
- style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`)
4686
+ onDrop: _cache[1] || (_cache[1] = (...args) => _ctx.dropHandler && _ctx.dropHandler(...args)),
4687
+ onDragover: _cache[2] || (_cache[2] = (...args) => _ctx.dragoverHandler && _ctx.dragoverHandler(...args))
4123
4688
  }, null, 36),
4124
4689
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
4125
- vue.createVNode(_component_viewer_menu, {
4126
- ref: "menu",
4127
- style: vue.normalizeStyle(_ctx.menuStyle)
4128
- }, null, 8, ["style"])
4690
+ vue.createVNode(_component_viewer_menu, { ref: "menu" }, null, 512)
4129
4691
  ]))
4130
4692
  ]),
4131
4693
  _: 1
@@ -4153,21 +4715,93 @@
4153
4715
  },
4154
4716
  setup() {
4155
4717
  const services = vue.inject("services");
4718
+ const workspace = vue.ref();
4719
+ const node = vue.computed(() => services?.editorService.get("node"));
4720
+ let keycon;
4721
+ const mouseenterHandler = () => {
4722
+ workspace.value?.focus();
4723
+ };
4724
+ vue.onMounted(() => {
4725
+ workspace.value?.addEventListener("mouseenter", mouseenterHandler);
4726
+ keycon = new KeyController__default["default"](workspace.value);
4727
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
4728
+ const ctrl = isMac ? "meta" : "ctrl";
4729
+ keycon.keyup("delete", (e) => {
4730
+ e.inputEvent.preventDefault();
4731
+ if (!node.value || utils.isPage(node.value))
4732
+ return;
4733
+ services?.editorService.remove(node.value);
4734
+ }).keydown([ctrl, "c"], (e) => {
4735
+ e.inputEvent.preventDefault();
4736
+ node.value && services?.editorService.copy(node.value);
4737
+ }).keydown([ctrl, "v"], (e) => {
4738
+ e.inputEvent.preventDefault();
4739
+ node.value && services?.editorService.paste();
4740
+ }).keydown([ctrl, "x"], (e) => {
4741
+ e.inputEvent.preventDefault();
4742
+ if (!node.value || utils.isPage(node.value))
4743
+ return;
4744
+ services?.editorService.copy(node.value);
4745
+ services?.editorService.remove(node.value);
4746
+ }).keydown([ctrl, "z"], (e) => {
4747
+ e.inputEvent.preventDefault();
4748
+ services?.editorService.undo();
4749
+ }).keydown([ctrl, "shift", "z"], (e) => {
4750
+ e.inputEvent.preventDefault();
4751
+ services?.editorService.redo();
4752
+ }).keydown("up", (e) => {
4753
+ e.inputEvent.preventDefault();
4754
+ services?.editorService.move(0, -1);
4755
+ }).keydown("down", (e) => {
4756
+ e.inputEvent.preventDefault();
4757
+ services?.editorService.move(0, 1);
4758
+ }).keydown("left", (e) => {
4759
+ e.inputEvent.preventDefault();
4760
+ services?.editorService.move(-1, 0);
4761
+ }).keydown("right", (e) => {
4762
+ e.inputEvent.preventDefault();
4763
+ services?.editorService.move(1, 0);
4764
+ }).keydown([ctrl, "up"], (e) => {
4765
+ e.inputEvent.preventDefault();
4766
+ services?.editorService.move(0, -10);
4767
+ }).keydown([ctrl, "down"], (e) => {
4768
+ e.inputEvent.preventDefault();
4769
+ services?.editorService.move(0, 10);
4770
+ }).keydown([ctrl, "left"], (e) => {
4771
+ e.inputEvent.preventDefault();
4772
+ services?.editorService.move(-10, 0);
4773
+ }).keydown([ctrl, "right"], (e) => {
4774
+ e.inputEvent.preventDefault();
4775
+ services?.editorService.move(10, 0);
4776
+ }).keydown("tab", (e) => {
4777
+ e.inputEvent.preventDefault();
4778
+ services?.editorService.selectNextNode();
4779
+ }).keydown([ctrl, "tab"], (e) => {
4780
+ e.inputEvent.preventDefault();
4781
+ services?.editorService.selectNextPage();
4782
+ }).keydown([ctrl, "="], (e) => {
4783
+ e.inputEvent.preventDefault();
4784
+ services?.uiService.zoom(0.1);
4785
+ }).keydown([ctrl, "-"], (e) => {
4786
+ e.inputEvent.preventDefault();
4787
+ services?.uiService.zoom(-0.1);
4788
+ });
4789
+ });
4790
+ vue.onUnmounted(() => {
4791
+ workspace.value?.removeEventListener("mouseenter", mouseenterHandler);
4792
+ keycon.destroy();
4793
+ });
4156
4794
  return {
4157
- page: vue.computed(() => services?.editorService.get("page")),
4158
- selectHandler(el) {
4159
- services?.editorService.select(el.id);
4160
- },
4161
- updateNodeHandler(node) {
4162
- services?.editorService.update(node);
4163
- },
4164
- sortNodeHandler(ev) {
4165
- services?.editorService.sort(ev.src, ev.dist);
4166
- }
4795
+ workspace,
4796
+ page: vue.computed(() => services?.editorService.get("page"))
4167
4797
  };
4168
4798
  }
4169
4799
  });
4170
- const _hoisted_1 = { class: "m-editor-workspace" };
4800
+ const _hoisted_1 = {
4801
+ class: "m-editor-workspace",
4802
+ tabindex: "1",
4803
+ ref: "workspace"
4804
+ };
4171
4805
  function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
4172
4806
  const _component_magic_stage = vue.resolveComponent("magic-stage");
4173
4807
  const _component_page_bar = vue.resolveComponent("page-bar");
@@ -4177,11 +4811,8 @@
4177
4811
  "runtime-url": _ctx.runtimeUrl,
4178
4812
  render: _ctx.render,
4179
4813
  "moveable-options": _ctx.moveableOptions,
4180
- "can-select": _ctx.canSelect,
4181
- onSelect: _ctx.selectHandler,
4182
- onUpdate: _ctx.updateNodeHandler,
4183
- onSort: _ctx.sortNodeHandler
4184
- }, null, 8, ["runtime-url", "render", "moveable-options", "can-select", "onSelect", "onUpdate", "onSort"])),
4814
+ "can-select": _ctx.canSelect
4815
+ }, null, 8, ["runtime-url", "render", "moveable-options", "can-select"])),
4185
4816
  vue.renderSlot(_ctx.$slots, "workspace-content"),
4186
4817
  vue.createVNode(_component_page_bar, null, {
4187
4818
  "page-bar-title": vue.withCtx(({ page }) => [
@@ -4192,16 +4823,16 @@
4192
4823
  ]),
4193
4824
  _: 3
4194
4825
  })
4195
- ]);
4826
+ ], 512);
4196
4827
  }
4197
4828
  var Workspace = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
4198
4829
 
4199
4830
  class ComponentList extends BaseService {
4200
- state = vue.reactive({
4201
- list: []
4202
- });
4203
4831
  constructor() {
4204
4832
  super([]);
4833
+ this.state = vue.reactive({
4834
+ list: []
4835
+ });
4205
4836
  }
4206
4837
  setList(componentGroupList) {
4207
4838
  this.state.list = componentGroupList;
@@ -4212,6 +4843,14 @@
4212
4843
  }
4213
4844
  var componentListService = new ComponentList();
4214
4845
 
4846
+ const DEFAULT_LEFT_COLUMN_WIDTH = 310;
4847
+ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
4848
+ const COLUMN_WIDTH_STORAGE_KEY = "$MagicEditorColumnWidthData";
4849
+ const defaultColumnWidth = {
4850
+ left: DEFAULT_LEFT_COLUMN_WIDTH,
4851
+ center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
4852
+ right: DEFAULT_RIGHT_COLUMN_WIDTH
4853
+ };
4215
4854
  const state = vue.reactive({
4216
4855
  uiSelectMode: false,
4217
4856
  showSrc: false,
@@ -4224,13 +4863,10 @@
4224
4863
  width: 375,
4225
4864
  height: 817
4226
4865
  },
4227
- columnWidth: {
4228
- left: 310,
4229
- center: globalThis.document.body.clientWidth - 310 - 400,
4230
- right: 400
4231
- },
4866
+ columnWidth: defaultColumnWidth,
4232
4867
  showGuides: true,
4233
- showRule: true
4868
+ showRule: true,
4869
+ propsPanelSize: "small"
4234
4870
  });
4235
4871
  class Ui extends BaseService {
4236
4872
  constructor() {
@@ -4240,6 +4876,15 @@
4240
4876
  center: "auto"
4241
4877
  });
4242
4878
  });
4879
+ const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
4880
+ if (columnWidthCacheData) {
4881
+ try {
4882
+ const columnWidthCache = JSON.parse(columnWidthCacheData);
4883
+ this.setColumnWidth(columnWidthCache);
4884
+ } catch (e) {
4885
+ console.error(e);
4886
+ }
4887
+ }
4243
4888
  }
4244
4889
  set(name, value) {
4245
4890
  const mask = editorService.get("stage")?.mask;
@@ -4265,6 +4910,11 @@
4265
4910
  get(name) {
4266
4911
  return state[name];
4267
4912
  }
4913
+ zoom(zoom) {
4914
+ this.set("zoom", (this.get("zoom") * 100 + zoom * 100) / 100);
4915
+ if (this.get("zoom") < 0.1)
4916
+ this.set("zoom", 0.1);
4917
+ }
4268
4918
  setColumnWidth({ left, center, right }) {
4269
4919
  const columnWidth = {
4270
4920
  ...vue.toRaw(this.get("columnWidth"))
@@ -4278,9 +4928,15 @@
4278
4928
  if (!center || center === "auto") {
4279
4929
  const bodyWidth = globalThis.document.body.clientWidth;
4280
4930
  columnWidth.center = bodyWidth - (columnWidth?.left || 0) - (columnWidth?.right || 0);
4931
+ if (columnWidth.center <= 0) {
4932
+ columnWidth.left = defaultColumnWidth.left;
4933
+ columnWidth.center = defaultColumnWidth.center;
4934
+ columnWidth.right = defaultColumnWidth.right;
4935
+ }
4281
4936
  } else {
4282
4937
  columnWidth.center = center;
4283
4938
  }
4939
+ globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth));
4284
4940
  state.columnWidth = columnWidth;
4285
4941
  }
4286
4942
  setStageRect(value) {
@@ -4489,6 +5145,7 @@
4489
5145
  exports.PropsPanel = PropsPanel;
4490
5146
  exports.TMagicCodeEditor = CodeEditor;
4491
5147
  exports.TMagicEditor = Editor;
5148
+ exports.ToolButton = ToolButton;
4492
5149
  exports.change2Fixed = change2Fixed;
4493
5150
  exports.debug = debug;
4494
5151
  exports["default"] = index;
@@ -4517,8 +5174,7 @@
4517
5174
  exports.uiService = uiService;
4518
5175
  exports.warn = warn;
4519
5176
 
4520
- Object.defineProperty(exports, '__esModule', { value: true });
4521
- exports[Symbol.toStringTag] = 'Module';
5177
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
4522
5178
 
4523
5179
  }));
4524
5180
  //# sourceMappingURL=tmagic-editor.umd.js.map