@tmagic/editor 1.3.0-alpha.6 → 1.3.0-alpha.8

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 (38) hide show
  1. package/dist/style.css +17 -0
  2. package/dist/tmagic-editor.js +471 -264
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +474 -265
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +12 -12
  7. package/src/Editor.vue +3 -0
  8. package/src/components/ContentMenu.vue +15 -8
  9. package/src/components/FunctionEditor.vue +6 -4
  10. package/src/components/SplitView.vue +2 -2
  11. package/src/fields/CodeLink.vue +4 -2
  12. package/src/fields/DataSourceInput.vue +11 -10
  13. package/src/index.ts +4 -2
  14. package/src/initService.ts +2 -0
  15. package/src/layouts/Framework.vue +4 -4
  16. package/src/layouts/PropsPanel.vue +2 -1
  17. package/src/layouts/sidebar/LayerMenu.vue +4 -3
  18. package/src/layouts/sidebar/LayerPanel.vue +55 -32
  19. package/src/layouts/workspace/Stage.vue +13 -3
  20. package/src/layouts/workspace/Workspace.vue +2 -2
  21. package/src/services/codeBlock.ts +3 -2
  22. package/src/services/keybinding.ts +148 -203
  23. package/src/services/storage.ts +3 -2
  24. package/src/theme/data-source-input.scss +18 -0
  25. package/src/theme/stage.scss +4 -0
  26. package/src/theme/theme.scss +1 -0
  27. package/src/type.ts +56 -0
  28. package/src/utils/config.ts +1 -1
  29. package/src/utils/keybinding-config.ts +120 -0
  30. package/src/utils/props.ts +34 -0
  31. package/types/components/ContentMenu.vue.d.ts +2 -0
  32. package/types/index.d.ts +2 -1
  33. package/types/initService.d.ts +1 -1
  34. package/types/layouts/workspace/Workspace.vue.d.ts +1 -1
  35. package/types/services/keybinding.d.ts +13 -5
  36. package/types/type.d.ts +53 -0
  37. package/types/utils/config.d.ts +1 -1
  38. package/types/utils/keybinding-config.d.ts +3 -0
@@ -1,4 +1,4 @@
1
- import { defineComponent, computed, resolveComponent, openBlock, createBlock, normalizeStyle, reactive, watch, createElementBlock, normalizeClass, createVNode, unref, withCtx, createElementVNode, resolveDynamicComponent, toRaw, inject, ref, createTextVNode, mergeProps, toDisplayString, Fragment, renderList, createCommentVNode, nextTick, watchEffect, withModifiers, onMounted, onUnmounted, renderSlot, createSlots, normalizeProps, markRaw, getCurrentInstance, createStaticVNode, withDirectives, Teleport, vShow, toHandlers, provide } from 'vue';
1
+ import { defineComponent, computed, resolveComponent, openBlock, createBlock, normalizeStyle, reactive, watch, createElementBlock, normalizeClass, createVNode, unref, withCtx, createElementVNode, resolveDynamicComponent, toRaw, inject, ref, createTextVNode, mergeProps, toDisplayString, Fragment, renderList, createCommentVNode, nextTick, watchEffect, withModifiers, onMounted, onUnmounted, renderSlot, createSlots, normalizeProps, markRaw, getCurrentInstance, createStaticVNode, provide, withDirectives, Teleport, vShow, onBeforeUnmount, toHandlers } from 'vue';
2
2
  import serialize from 'serialize-javascript';
3
3
  import { isEmpty, map, has, throttle, cloneDeep, mergeWith, isObject, uniq, forIn, difference, union, pick, keys } from 'lodash-es';
4
4
  import { TMagicCard, TMagicIcon, TMagicButton, tMagicMessageBox, getConfig as getConfig$1, TMagicTag, TMagicInput, TMagicTooltip, TMagicScrollbar, TMagicDivider, TMagicDropdown, TMagicDropdownMenu, TMagicDropdownItem, tMagicMessage, TMagicDrawer, TMagicTree, TMagicCollapse, TMagicCollapseItem, TMagicPopover } from '@tmagic/design';
@@ -9,10 +9,10 @@ import { MagicTable } from '@tmagic/table';
9
9
  import * as monaco from 'monaco-editor';
10
10
  import Gesto from 'gesto';
11
11
  import { isPop, getNodePath, isNumber, isPage, toLine, guid, datetimeFormatter, removeClassNameByClassName, getNodes } from '@tmagic/utils';
12
- import KeyController from 'keycon';
13
12
  import StageCore, { GuidesType, getOffset, calcValueByFontsize, CONTAINER_HIGHLIGHT_CLASS_NAME, ContainerHighlightType } from '@tmagic/stage';
14
13
  import { EventEmitter } from 'events';
15
14
  import { DEFAULT_EVENTS, DEFAULT_METHODS } from '@tmagic/core';
15
+ import KeyController from 'keycon';
16
16
 
17
17
  const _sfc_main$E = /* @__PURE__ */ defineComponent({
18
18
  ...{
@@ -47,6 +47,12 @@ const _sfc_main$E = /* @__PURE__ */ defineComponent({
47
47
  }
48
48
  });
49
49
 
50
+ let $TMAGIC_EDITOR = {};
51
+ const setConfig = (option) => {
52
+ $TMAGIC_EDITOR = option;
53
+ };
54
+ const getConfig = (key) => $TMAGIC_EDITOR[key];
55
+
50
56
  const _sfc_main$D = /* @__PURE__ */ defineComponent({
51
57
  ...{
52
58
  name: "MEditorCodeLink"
@@ -102,7 +108,8 @@ const _sfc_main$D = /* @__PURE__ */ defineComponent({
102
108
  if (!props.name || !props.model)
103
109
  return;
104
110
  try {
105
- props.model[props.name] = eval(`(${v[props.name]})`);
111
+ const parseDSL = getConfig("parseDSL");
112
+ props.model[props.name] = parseDSL(`(${v[props.name]})`);
106
113
  emit("change", props.model[props.name]);
107
114
  } catch (e) {
108
115
  console.error(e);
@@ -556,7 +563,7 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
556
563
  const dataSources = computed(() => dataSourceService?.get("dataSources") || []);
557
564
  const setDisplayState = () => {
558
565
  displayState.value = [];
559
- const matches = state.value.matchAll(/\{\{([\s\S]+?)\}\}/g);
566
+ const matches = state.value.matchAll(/\$\{([\s\S]+?)\}/g);
560
567
  let index = 0;
561
568
  for (const match of matches) {
562
569
  if (typeof match.index === "undefined")
@@ -629,13 +636,13 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
629
636
  }
630
637
  return selectionStart;
631
638
  };
632
- const curCharIsLeftCurlyBracket = (leftCurlyBracketIndex) => leftCurlyBracketIndex > -1 && leftCurlyBracketIndex === getSelectionStart() - 1;
639
+ const curCharIsLeftCurlyBracket = (leftCurlyBracketIndex) => leftCurlyBracketIndex > 0 && leftCurlyBracketIndex === getSelectionStart() - 1;
633
640
  const curCharIsDot = (dotIndex) => dotIndex > -1 && dotIndex === getSelectionStart() - 1;
634
641
  const dsQuerySearch = (queryString, leftCurlyBracketIndex, cb) => {
635
642
  let result = [];
636
643
  if (curCharIsLeftCurlyBracket(leftCurlyBracketIndex)) {
637
644
  result = dataSources.value;
638
- } else if (leftCurlyBracketIndex > -1) {
645
+ } else if (leftCurlyBracketIndex > 0) {
639
646
  const queryName = queryString.substring(leftCurlyBracketIndex + 1).toLowerCase();
640
647
  result = dataSources.value.filter((ds) => ds.title?.toLowerCase().includes(queryName) || ds.id.includes(queryName));
641
648
  }
@@ -687,7 +694,7 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
687
694
  const selectionStart = getSelectionStart();
688
695
  const curQueryString = queryString.substring(0, selectionStart);
689
696
  const fieldKeyStringLastIndex = curQueryString.lastIndexOf(".");
690
- const dsKeyStringLastIndex = curQueryString.lastIndexOf("{");
697
+ const dsKeyStringLastIndex = curQueryString.lastIndexOf("${") + 1;
691
698
  const isFieldTip = fieldKeyStringLastIndex > dsKeyStringLastIndex;
692
699
  if (isFieldTip) {
693
700
  fieldQuerySearch(curQueryString, dsKeyStringLastIndex, fieldKeyStringLastIndex, cb);
@@ -700,7 +707,7 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
700
707
  const selectionStart = input.value?.selectionStart || 0;
701
708
  let startText = inputText.substring(0, selectionStart);
702
709
  const dotIndex = startText.lastIndexOf(".");
703
- const leftCurlyBracketIndex = startText.lastIndexOf("{");
710
+ const leftCurlyBracketIndex = startText.lastIndexOf("${") + 1;
704
711
  const endText = inputText.substring(selectionStart);
705
712
  let suggestText = value;
706
713
  if (isDataSource) {
@@ -710,7 +717,6 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
710
717
  if (!isRightCurlyBracket(selectionStart + 1)) {
711
718
  suggestText = `${suggestText}}`;
712
719
  }
713
- suggestText = `{${suggestText}}`;
714
720
  } else if (!curCharIsDot(dotIndex)) {
715
721
  startText = startText.substring(0, dotIndex + 1);
716
722
  }
@@ -718,7 +724,7 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
718
724
  await nextTick();
719
725
  let newSelectionStart = 0;
720
726
  if (isDataSource) {
721
- newSelectionStart = leftCurlyBracketIndex + suggestText.length - 1;
727
+ newSelectionStart = leftCurlyBracketIndex + suggestText.length;
722
728
  } else {
723
729
  newSelectionStart = dotIndex + suggestText.length + 1;
724
730
  }
@@ -761,11 +767,11 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
761
767
  _: 1
762
768
  }, 16, ["modelValue"])) : (openBlock(), createElementBlock("div", {
763
769
  key: 1,
764
- class: normalizeClass(`el-input el-input--${_ctx.size}`),
770
+ class: normalizeClass(`tmagic-data-source-input-text el-input el-input--${_ctx.size}`),
765
771
  onMouseup: mouseupHandler
766
772
  }, [
767
773
  createElementVNode("div", {
768
- class: normalizeClass(`el-input__wrapper ${isFocused.value ? " is-focus" : ""}`)
774
+ class: normalizeClass(`tmagic-data-source-input-text-wrapper el-input__wrapper ${isFocused.value ? " is-focus" : ""}`)
769
775
  }, [
770
776
  createElementVNode("div", _hoisted_3$5, [
771
777
  (openBlock(true), createElementBlock(Fragment, null, renderList(displayState.value, (item, index) => {
@@ -784,7 +790,11 @@ const _sfc_main$y = /* @__PURE__ */ defineComponent({
784
790
  _: 2
785
791
  }, 1032, ["size"])) : createCommentVNode("", true)
786
792
  ], 64);
787
- }), 256))
793
+ }), 256)),
794
+ createVNode(_sfc_main$B, {
795
+ class: "tmagic-data-source-input-icon",
796
+ icon: unref(Coin)
797
+ }, null, 8, ["icon"])
788
798
  ])
789
799
  ], 2)
790
800
  ], 34));
@@ -1347,12 +1357,6 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
1347
1357
  }
1348
1358
  });
1349
1359
 
1350
- let $TMAGIC_EDITOR = {};
1351
- const setConfig = (option) => {
1352
- $TMAGIC_EDITOR = option;
1353
- };
1354
- const getConfig = (key) => $TMAGIC_EDITOR[key];
1355
-
1356
1360
  const _sfc_main$t = /* @__PURE__ */ defineComponent({
1357
1361
  ...{
1358
1362
  name: "MEditorResizer"
@@ -1500,7 +1504,7 @@ const _sfc_main$s = /* @__PURE__ */ defineComponent({
1500
1504
  ref: el,
1501
1505
  class: "m-editor-layout"
1502
1506
  }, [
1503
- hasLeft.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
1507
+ hasLeft.value && _ctx.$slots.left ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
1504
1508
  createElementVNode("div", {
1505
1509
  class: normalizeClass(["m-editor-layout-left", _ctx.leftClass]),
1506
1510
  style: normalizeStyle(`width: ${_ctx.left}px`)
@@ -1515,7 +1519,7 @@ const _sfc_main$s = /* @__PURE__ */ defineComponent({
1515
1519
  }, [
1516
1520
  renderSlot(_ctx.$slots, "center")
1517
1521
  ], 6),
1518
- hasRight.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
1522
+ hasRight.value && _ctx.$slots.right ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
1519
1523
  createVNode(_sfc_main$t, { onChange: changeRight }),
1520
1524
  createElementVNode("div", {
1521
1525
  class: normalizeClass(["m-editor-layout-right", _ctx.rightClass]),
@@ -1609,6 +1613,40 @@ const fillConfig$1 = (config = []) => [
1609
1613
  }
1610
1614
  ]
1611
1615
  },
1616
+ {
1617
+ type: "fieldset",
1618
+ legend: "边框",
1619
+ items: [
1620
+ {
1621
+ name: "borderWidth",
1622
+ text: "宽度",
1623
+ defaultValue: "0"
1624
+ },
1625
+ {
1626
+ name: "borderColor",
1627
+ text: "颜色",
1628
+ type: "colorPicker"
1629
+ },
1630
+ {
1631
+ name: "borderStyle",
1632
+ text: "样式",
1633
+ type: "select",
1634
+ defaultValue: "none",
1635
+ options: [
1636
+ { text: "none", value: "none" },
1637
+ { text: "hidden", value: "hidden" },
1638
+ { text: "dotted", value: "dotted" },
1639
+ { text: "dashed", value: "dashed" },
1640
+ { text: "solid", value: "solid" },
1641
+ { text: "double", value: "double" },
1642
+ { text: "groove", value: "groove" },
1643
+ { text: "ridge", value: "ridge" },
1644
+ { text: "inset", value: "inset" },
1645
+ { text: "outset", value: "outset" }
1646
+ ]
1647
+ }
1648
+ ]
1649
+ },
1612
1650
  {
1613
1651
  type: "fieldset",
1614
1652
  legend: "背景",
@@ -1768,6 +1806,28 @@ var CodeDeleteErrorType = /* @__PURE__ */ ((CodeDeleteErrorType2) => {
1768
1806
  return CodeDeleteErrorType2;
1769
1807
  })(CodeDeleteErrorType || {});
1770
1808
  const CODE_DRAFT_STORAGE_KEY = "magicCodeDraft";
1809
+ var KeyBindingCommand = /* @__PURE__ */ ((KeyBindingCommand2) => {
1810
+ KeyBindingCommand2["COPY_NODE"] = "tmagic-system-copy-node";
1811
+ KeyBindingCommand2["PASTE_NODE"] = "tmagic-system-paste-node";
1812
+ KeyBindingCommand2["DELETE_NODE"] = "tmagic-system-delete-node";
1813
+ KeyBindingCommand2["CUT_NODE"] = "tmagic-system-cut-node";
1814
+ KeyBindingCommand2["UNDO"] = "tmagic-system-undo";
1815
+ KeyBindingCommand2["REDO"] = "tmagic-system-redo";
1816
+ KeyBindingCommand2["ZOOM_IN"] = "tmagic-system-zoom-in";
1817
+ KeyBindingCommand2["ZOOM_OUT"] = "tmagic-system-zoom-out";
1818
+ KeyBindingCommand2["ZOOM_RESET"] = "tmagic-system-zoom-reset";
1819
+ KeyBindingCommand2["ZOOM_FIT"] = "tmagic-system-zoom-fit";
1820
+ KeyBindingCommand2["MOVE_UP_1"] = "tmagic-system-move-up-1";
1821
+ KeyBindingCommand2["MOVE_DOWN_1"] = "tmagic-system-move-down-1";
1822
+ KeyBindingCommand2["MOVE_LEFT_1"] = "tmagic-system-move-left-1";
1823
+ KeyBindingCommand2["MOVE_RIGHT_1"] = "tmagic-system-move-right-1";
1824
+ KeyBindingCommand2["MOVE_UP_10"] = "tmagic-system-move-up-10";
1825
+ KeyBindingCommand2["MOVE_DOWN_10"] = "tmagic-system-move-down-10";
1826
+ KeyBindingCommand2["MOVE_LEFT_10"] = "tmagic-system-move-left-10";
1827
+ KeyBindingCommand2["MOVE_RIGHT_10"] = "tmagic-system-move-right-10";
1828
+ KeyBindingCommand2["SWITCH_NODE"] = "tmagic-system-switch-node";
1829
+ return KeyBindingCommand2;
1830
+ })(KeyBindingCommand || {});
1771
1831
 
1772
1832
  const COPY_STORAGE_KEY = "$MagicEditorCopyData";
1773
1833
  const getPageList = (app) => {
@@ -2214,8 +2274,8 @@ class WebStorage extends BaseService {
2214
2274
  * 清理,支持storageService.usePlugin
2215
2275
  */
2216
2276
  async clear() {
2217
- const storage2 = await this.getStorage();
2218
- storage2.clear();
2277
+ const storage = await this.getStorage();
2278
+ storage.clear();
2219
2279
  }
2220
2280
  /**
2221
2281
  * 获取存储项,支持storageService.usePlugin
@@ -2229,7 +2289,7 @@ class WebStorage extends BaseService {
2229
2289
  return null;
2230
2290
  switch (protocol) {
2231
2291
  case "object" /* OBJECT */:
2232
- return eval(`(${item})`);
2292
+ return getConfig("parseDSL")(`(${item})`);
2233
2293
  case "json" /* JSON */:
2234
2294
  return JSON.parse(item);
2235
2295
  case "number" /* NUMBER */:
@@ -2244,49 +2304,49 @@ class WebStorage extends BaseService {
2244
2304
  * 获取指定索引位置的key
2245
2305
  */
2246
2306
  async key(index) {
2247
- const storage2 = await this.getStorage();
2248
- return storage2.key(index);
2307
+ const storage = await this.getStorage();
2308
+ return storage.key(index);
2249
2309
  }
2250
2310
  /**
2251
2311
  * 移除存储项,支持storageService.usePlugin
2252
2312
  */
2253
- async removeItem(key2, options2 = {}) {
2254
- const [storage2, namespace2] = await Promise.all([this.getStorage(), this.getNamespace()]);
2255
- storage2.removeItem(`${options2.namespace || namespace2}:${key2}`);
2313
+ async removeItem(key, options = {}) {
2314
+ const [storage, namespace] = await Promise.all([this.getStorage(), this.getNamespace()]);
2315
+ storage.removeItem(`${options.namespace || namespace}:${key}`);
2256
2316
  }
2257
2317
  /**
2258
2318
  * 设置存储项,支持storageService.usePlugin
2259
2319
  */
2260
- async setItem(key2, value, options2 = {}) {
2261
- const [storage2, namespace2] = await Promise.all([this.getStorage(), this.getNamespace()]);
2262
- let item2 = value;
2263
- const protocol2 = options2.protocol ? `${options2.protocol}:` : "";
2320
+ async setItem(key, value, options = {}) {
2321
+ const [storage, namespace] = await Promise.all([this.getStorage(), this.getNamespace()]);
2322
+ let item = value;
2323
+ const protocol = options.protocol ? `${options.protocol}:` : "";
2264
2324
  if (typeof value === "string" /* STRING */ || typeof value === "number" /* NUMBER */) {
2265
- item2 = `${protocol2}${value}`;
2325
+ item = `${protocol}${value}`;
2266
2326
  } else {
2267
- item2 = `${protocol2}${serialize(value)}`;
2327
+ item = `${protocol}${serialize(value)}`;
2268
2328
  }
2269
- storage2.setItem(`${options2.namespace || namespace2}:${key2}`, item2);
2329
+ storage.setItem(`${options.namespace || namespace}:${key}`, item);
2270
2330
  }
2271
2331
  destroy() {
2272
2332
  this.removeAllListeners();
2273
2333
  this.removeAllPlugins();
2274
2334
  }
2275
2335
  getValueAndProtocol(value) {
2276
- let protocol2 = "";
2336
+ let protocol = "";
2277
2337
  if (value === null) {
2278
2338
  return {
2279
2339
  item: value,
2280
- protocol: protocol2
2340
+ protocol
2281
2341
  };
2282
2342
  }
2283
- const item2 = value.replace(new RegExp(`^(${Object.values(Protocol).join("|")})(:)(.+)`), (_$0, $1, _$2, $3) => {
2284
- protocol2 = $1;
2343
+ const item = value.replace(new RegExp(`^(${Object.values(Protocol).join("|")})(:)(.+)`), (_$0, $1, _$2, $3) => {
2344
+ protocol = $1;
2285
2345
  return $3;
2286
2346
  });
2287
2347
  return {
2288
- protocol: protocol2,
2289
- item: item2
2348
+ protocol,
2349
+ item
2290
2350
  };
2291
2351
  }
2292
2352
  }
@@ -3437,7 +3497,6 @@ const _sfc_main$q = /* @__PURE__ */ defineComponent({
3437
3497
  const codeOptions = inject("codeOptions", {});
3438
3498
  const { editorService, uiService } = inject("services") || {};
3439
3499
  const root = computed(() => editorService?.get("root"));
3440
- const nodes = computed(() => editorService?.get("nodes") || []);
3441
3500
  const pageLength = computed(() => editorService?.get("pageLength") || 0);
3442
3501
  const showSrc = computed(() => uiService?.get("showSrc"));
3443
3502
  const leftColumnWidthCacheData = Number(globalThis.localStorage.getItem(LEFT_COLUMN_WIDTH_STORAGE_KEY));
@@ -3488,7 +3547,8 @@ const _sfc_main$q = /* @__PURE__ */ defineComponent({
3488
3547
  };
3489
3548
  const saveCode = (value) => {
3490
3549
  try {
3491
- editorService?.set("root", eval(value));
3550
+ const parseDSL = getConfig("parseDSL");
3551
+ editorService?.set("root", parseDSL(value));
3492
3552
  } catch (e) {
3493
3553
  console.error(e);
3494
3554
  }
@@ -3529,7 +3589,7 @@ const _sfc_main$q = /* @__PURE__ */ defineComponent({
3529
3589
  ]),
3530
3590
  _: 2
3531
3591
  }, [
3532
- pageLength.value > 0 && nodes.value.length === 1 ? {
3592
+ pageLength.value > 0 ? {
3533
3593
  name: "right",
3534
3594
  fn: withCtx(() => [
3535
3595
  createVNode(unref(TMagicScrollbar), null, {
@@ -3888,7 +3948,10 @@ const _sfc_main$o = /* @__PURE__ */ defineComponent({
3888
3948
  }
3889
3949
  });
3890
3950
 
3891
- const _hoisted_1$e = { class: "m-editor-props-panel" };
3951
+ const _hoisted_1$e = {
3952
+ key: 0,
3953
+ class: "m-editor-props-panel"
3954
+ };
3892
3955
  const _sfc_main$n = /* @__PURE__ */ defineComponent({
3893
3956
  ...{
3894
3957
  name: "MEditorPropsPanel"
@@ -3902,6 +3965,7 @@ const _sfc_main$n = /* @__PURE__ */ defineComponent({
3902
3965
  const curFormConfig = ref([]);
3903
3966
  const services = inject("services");
3904
3967
  const node = computed(() => services?.editorService.get("node"));
3968
+ const nodes = computed(() => services?.editorService.get("nodes") || []);
3905
3969
  const propsPanelSize = computed(() => services?.uiService.get("propsPanelSize") || "small");
3906
3970
  const stage = computed(() => services?.editorService.get("stage"));
3907
3971
  const init = async () => {
@@ -3938,7 +4002,7 @@ const _sfc_main$n = /* @__PURE__ */ defineComponent({
3938
4002
  };
3939
4003
  __expose({ submit });
3940
4004
  return (_ctx, _cache) => {
3941
- return openBlock(), createElementBlock("div", _hoisted_1$e, [
4005
+ return nodes.value.length === 1 ? (openBlock(), createElementBlock("div", _hoisted_1$e, [
3942
4006
  renderSlot(_ctx.$slots, "props-panel-header"),
3943
4007
  createVNode(unref(MForm), {
3944
4008
  ref_key: "configForm",
@@ -3950,7 +4014,7 @@ const _sfc_main$n = /* @__PURE__ */ defineComponent({
3950
4014
  config: curFormConfig.value,
3951
4015
  onChange: submit
3952
4016
  }, null, 8, ["class", "popper-class", "size", "init-values", "config"])
3953
- ]);
4017
+ ])) : createCommentVNode("", true);
3954
4018
  };
3955
4019
  }
3956
4020
  });
@@ -4218,6 +4282,7 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
4218
4282
  },
4219
4283
  setup(__props, { expose: __expose }) {
4220
4284
  const props = __props;
4285
+ provide("mForm", {});
4221
4286
  const defaultParamColConfig = {
4222
4287
  type: "row",
4223
4288
  label: "参数类型",
@@ -4286,29 +4351,29 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
4286
4351
  initTableModel();
4287
4352
  const beforeSave = (codeValue) => {
4288
4353
  try {
4289
- eval(codeValue);
4354
+ getConfig("parseDSL")(codeValue);
4290
4355
  return true;
4291
4356
  } catch (e) {
4292
4357
  tMagicMessage.error(e.stack);
4293
4358
  return false;
4294
4359
  }
4295
4360
  };
4296
- const saveCode = async (codeValue2) => {
4361
+ const saveCode = async (codeValue) => {
4297
4362
  if (!props.editable)
4298
4363
  return;
4299
- evalRes.value = beforeSave(codeValue2);
4364
+ evalRes.value = beforeSave(codeValue);
4300
4365
  if (evalRes.value) {
4301
4366
  await services?.codeBlockService.setCodeDslById(props.id, {
4302
4367
  name: codeName.value,
4303
- content: codeValue2,
4368
+ content: codeValue,
4304
4369
  params: tableModel.value?.params || []
4305
4370
  });
4306
4371
  tMagicMessage.success("代码成功保存到本地");
4307
4372
  services?.codeBlockService.removeCodeDraft(props.id);
4308
4373
  }
4309
4374
  };
4310
- const saveAndClose = async (codeValue2) => {
4311
- await saveCode(codeValue2);
4375
+ const saveAndClose = async (codeValue) => {
4376
+ await saveCode(codeValue);
4312
4377
  if (evalRes.value) {
4313
4378
  close();
4314
4379
  }
@@ -5077,6 +5142,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
5077
5142
  left: "0",
5078
5143
  top: "0"
5079
5144
  });
5145
+ const contains = (el) => menu.value?.contains(el) || subMenu.value?.contains(el);
5080
5146
  const hide = () => {
5081
5147
  if (!visible.value)
5082
5148
  return;
@@ -5089,7 +5155,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
5089
5155
  if (!visible.value || !target) {
5090
5156
  return;
5091
5157
  }
5092
- if (menu.value?.contains(target) || subMenu.value?.$el?.contains(target)) {
5158
+ if (contains(target)) {
5093
5159
  return;
5094
5160
  }
5095
5161
  hide();
@@ -5116,13 +5182,15 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
5116
5182
  if (typeof item !== "object" || !menuItem.items?.length) {
5117
5183
  return;
5118
5184
  }
5119
- subMenuData.value = menuItem.items;
5120
- if (menu.value) {
5121
- subMenu.value.show({
5122
- clientX: menu.value.offsetLeft + menu.value.clientWidth,
5123
- clientY: menu.value.offsetTop
5124
- });
5125
- }
5185
+ subMenuData.value = menuItem.items || [];
5186
+ setTimeout(() => {
5187
+ if (menu.value) {
5188
+ subMenu.value?.show({
5189
+ clientX: menu.value.offsetLeft + menu.value.clientWidth,
5190
+ clientY: menu.value.offsetTop
5191
+ });
5192
+ }
5193
+ }, 0);
5126
5194
  };
5127
5195
  onMounted(() => {
5128
5196
  if (props.isSubMenu)
@@ -5135,8 +5203,10 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
5135
5203
  globalThis.removeEventListener("mousedown", hideHandler, true);
5136
5204
  });
5137
5205
  __expose({
5206
+ menu,
5138
5207
  hide,
5139
- show
5208
+ show,
5209
+ contains
5140
5210
  });
5141
5211
  return (_ctx, _cache) => {
5142
5212
  const _component_content_menu = resolveComponent("content-menu", true);
@@ -5159,14 +5229,15 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
5159
5229
  }), 128))
5160
5230
  ]),
5161
5231
  (openBlock(), createBlock(Teleport, { to: "body" }, [
5162
- createVNode(_component_content_menu, {
5232
+ subMenuData.value.length ? (openBlock(), createBlock(_component_content_menu, {
5233
+ key: 0,
5163
5234
  class: "sub-menu",
5164
5235
  ref_key: "subMenu",
5165
5236
  ref: subMenu,
5166
5237
  "menu-data": subMenuData.value,
5167
5238
  "is-sub-menu": true,
5168
5239
  onHide: hide
5169
- }, null, 8, ["menu-data"])
5240
+ }, null, 8, ["menu-data"])) : createCommentVNode("", true)
5170
5241
  ]))
5171
5242
  ], 4)), [
5172
5243
  [vShow, visible.value]
@@ -5188,6 +5259,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
5188
5259
  const services = inject("services");
5189
5260
  const menu = ref();
5190
5261
  const node = computed(() => services?.editorService.get("node"));
5262
+ const nodes = computed(() => services?.editorService.get("nodes"));
5191
5263
  const isRoot = computed(() => node.value?.type === NodeType.ROOT);
5192
5264
  const isPage = computed(() => node.value?.type === NodeType.PAGE);
5193
5265
  const componentList = computed(() => services?.componentListService.getList() || []);
@@ -5239,7 +5311,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
5239
5311
  type: "button",
5240
5312
  text: "新增",
5241
5313
  icon: markRaw(Plus),
5242
- display: () => node.value?.items,
5314
+ display: () => node.value?.items && nodes.value?.length === 1,
5243
5315
  items: getSubMenuData.value
5244
5316
  },
5245
5317
  {
@@ -5248,7 +5320,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
5248
5320
  icon: markRaw(CopyDocument),
5249
5321
  display: () => !isRoot.value,
5250
5322
  handler: () => {
5251
- node.value && services?.editorService.copy(node.value);
5323
+ node.value && services?.editorService.copy(nodes.value || []);
5252
5324
  }
5253
5325
  },
5254
5326
  {
@@ -5257,7 +5329,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
5257
5329
  icon: markRaw(Delete),
5258
5330
  display: () => !isRoot.value && !isPage.value,
5259
5331
  handler: () => {
5260
- node.value && services?.editorService.remove(node.value);
5332
+ node.value && services?.editorService.remove(nodes.value || []);
5261
5333
  }
5262
5334
  },
5263
5335
  ...props.layerContentMenu
@@ -5426,38 +5498,61 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
5426
5498
  const windowBlurHandler = () => {
5427
5499
  isCtrlKeyDown.value = false;
5428
5500
  };
5429
- const globalKeyupHandler = () => {
5430
- if (document.activeElement !== tree.value?.$el) {
5501
+ keybindingService?.registeCommand("layer-panel-not-ctrl-keydown", (e) => {
5502
+ if (e.key !== keybindingService.ctrlKey) {
5431
5503
  isCtrlKeyDown.value = false;
5432
5504
  }
5433
- };
5434
- let keycon;
5435
- onMounted(() => {
5436
- editorService?.on("remove", editorServiceRemoveHandler);
5505
+ });
5506
+ keybindingService?.registeCommand("layer-panel-ctrl-keydown", () => {
5507
+ isCtrlKeyDown.value = true;
5508
+ });
5509
+ keybindingService?.registeCommand("layer-panel-ctrl-keyup", () => {
5510
+ isCtrlKeyDown.value = false;
5511
+ });
5512
+ keybindingService?.registeCommand("layer-panel-global-keydwon", () => {
5513
+ if (!tree.value?.$el.contains(document.activeElement)) {
5514
+ isCtrlKeyDown.value = false;
5515
+ }
5516
+ });
5517
+ keybindingService?.registe([
5518
+ {
5519
+ command: "layer-panel-not-ctrl-keydown",
5520
+ when: [["layer-panel", "keydown"]]
5521
+ },
5522
+ {
5523
+ command: "layer-panel-ctrl-keydown",
5524
+ keybinding: "ctrl",
5525
+ when: [["layer-panel", "keydown"]]
5526
+ },
5527
+ {
5528
+ command: "layer-panel-ctrl-keyup",
5529
+ keybinding: "ctrl",
5530
+ when: [["layer-panel", "keyup"]]
5531
+ },
5532
+ {
5533
+ command: "layer-panel-global-keydwon",
5534
+ keybinding: "ctrl",
5535
+ when: [["global", "keydown"]]
5536
+ }
5537
+ ]);
5538
+ watch(tree, () => {
5437
5539
  if (tree.value?.$el) {
5438
- keybindingService?.on("keyup", globalKeyupHandler);
5439
- keycon = new KeyController(tree.value.$el);
5440
- const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
5441
- const ctrl = isMac ? "meta" : "ctrl";
5442
- keycon.keydown((e) => {
5443
- if (e.key !== ctrl) {
5444
- isCtrlKeyDown.value = false;
5445
- }
5446
- }).keydown(ctrl, () => {
5447
- isCtrlKeyDown.value = true;
5448
- }).keyup(ctrl, () => {
5449
- isCtrlKeyDown.value = false;
5450
- });
5540
+ keybindingService?.registeEl("layer-panel", tree.value.$el);
5451
5541
  tree.value.$el.addEventListener("blur", windowBlurHandler);
5542
+ } else {
5543
+ keybindingService?.unregisteEl("layer-panel");
5452
5544
  }
5545
+ });
5546
+ onMounted(() => {
5547
+ editorService?.on("remove", editorServiceRemoveHandler);
5453
5548
  globalThis.addEventListener("blur", windowBlurHandler);
5454
5549
  });
5550
+ onBeforeUnmount(() => {
5551
+ tree.value?.$el.removeEventListener("blur", windowBlurHandler);
5552
+ });
5455
5553
  onUnmounted(() => {
5456
- keycon.destroy();
5457
5554
  editorService?.off("remove", editorServiceRemoveHandler);
5458
- keybindingService?.off("keyup", globalKeyupHandler);
5459
5555
  globalThis.removeEventListener("blur", windowBlurHandler);
5460
- tree.value?.$el.removeEventListener("blur", windowBlurHandler);
5461
5556
  });
5462
5557
  const highlightHandler = throttle((data) => {
5463
5558
  highlight(data);
@@ -5487,7 +5582,9 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
5487
5582
  };
5488
5583
  const contextmenu = async (event, data) => {
5489
5584
  event.preventDefault();
5490
- await select(data);
5585
+ if (nodes.value.length < 2) {
5586
+ await select(data);
5587
+ }
5491
5588
  menu.value?.show(event);
5492
5589
  };
5493
5590
  return (_ctx, _cache) => {
@@ -6501,6 +6598,9 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
6501
6598
  if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value)
6502
6599
  return;
6503
6600
  stage = useStage(stageOptions);
6601
+ stage.on("select", () => {
6602
+ stageWrap.value?.container?.focus();
6603
+ });
6504
6604
  services?.editorService.set("stage", markRaw(stage));
6505
6605
  stage?.mount(stageContainer.value);
6506
6606
  if (!node.value?.id)
@@ -6541,21 +6641,25 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
6541
6641
  }
6542
6642
  });
6543
6643
  onMounted(() => {
6544
- stageWrap.value?.container && resizeObserver.observe(stageWrap.value.container);
6644
+ if (stageWrap.value?.container) {
6645
+ resizeObserver.observe(stageWrap.value.container);
6646
+ services?.keybindingService.registeEl("stage", stageWrap.value.container);
6647
+ }
6545
6648
  });
6546
6649
  onUnmounted(() => {
6547
6650
  stage?.destroy();
6548
6651
  resizeObserver.disconnect();
6549
6652
  services?.editorService.set("stage", null);
6653
+ services?.keybindingService.unregisteEl("stage");
6550
6654
  });
6551
- const contextmenuHandler = (e2) => {
6552
- e2.preventDefault();
6553
- menu.value?.show(e2);
6655
+ const contextmenuHandler = (e) => {
6656
+ e.preventDefault();
6657
+ menu.value?.show(e);
6554
6658
  };
6555
- const dragoverHandler = (e2) => {
6556
- e2.preventDefault();
6557
- if (e2.dataTransfer) {
6558
- e2.dataTransfer.dropEffect = "move";
6659
+ const dragoverHandler = (e) => {
6660
+ e.preventDefault();
6661
+ if (e.dataTransfer) {
6662
+ e.dataTransfer.dropEffect = "move";
6559
6663
  }
6560
6664
  };
6561
6665
  const dropHandler = async (e) => {
@@ -6567,7 +6671,8 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
6567
6671
  parent = services?.editorService.getNodeById(parentEl.id, false);
6568
6672
  }
6569
6673
  if (e.dataTransfer && parent && stageContainer.value && stage) {
6570
- const config = eval(`(${e.dataTransfer.getData("data")})`);
6674
+ const parseDSL = getConfig("parseDSL");
6675
+ const config = parseDSL(`(${e.dataTransfer.getData("data")})`);
6571
6676
  const layout = await services?.editorService.getLayout(parent);
6572
6677
  const containerRect = stageContainer.value.getBoundingClientRect();
6573
6678
  const { scrollTop, scrollLeft } = stage.mask;
@@ -6600,6 +6705,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
6600
6705
  class: "m-editor-stage",
6601
6706
  ref_key: "stageWrap",
6602
6707
  ref: stageWrap,
6708
+ tabindex: "-1",
6603
6709
  width: stageRect.value?.width,
6604
6710
  height: stageRect.value?.height,
6605
6711
  "wrap-width": stageContainerRect.value?.width,
@@ -6635,10 +6741,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
6635
6741
  }
6636
6742
  });
6637
6743
 
6638
- const _hoisted_1 = {
6639
- class: "m-editor-workspace",
6640
- tabindex: "-1"
6641
- };
6744
+ const _hoisted_1 = { class: "m-editor-workspace" };
6642
6745
  const _sfc_main$1 = /* @__PURE__ */ defineComponent({
6643
6746
  ...{
6644
6747
  name: "MEditorWorkspace"
@@ -6698,8 +6801,8 @@ class CodeBlock extends BaseService {
6698
6801
  * @param {CodeBlockDSL} codeDsl 代码DSL
6699
6802
  * @returns {void}
6700
6803
  */
6701
- async setCodeDsl(codeDsl2) {
6702
- this.state.codeDsl = codeDsl2;
6804
+ async setCodeDsl(codeDsl) {
6805
+ this.state.codeDsl = codeDsl;
6703
6806
  this.emit("code-dsl-change", this.state.codeDsl);
6704
6807
  }
6705
6808
  /**
@@ -6716,13 +6819,13 @@ class CodeBlock extends BaseService {
6716
6819
  * @param {Id} id 代码块id
6717
6820
  * @returns {CodeBlockContent | null}
6718
6821
  */
6719
- getCodeContentById(id2) {
6720
- if (!id2)
6822
+ getCodeContentById(id) {
6823
+ if (!id)
6721
6824
  return null;
6722
6825
  const totalCodeDsl = this.getCodeDsl();
6723
6826
  if (!totalCodeDsl)
6724
6827
  return null;
6725
- return totalCodeDsl[id2] ?? null;
6828
+ return totalCodeDsl[id] ?? null;
6726
6829
  }
6727
6830
  /**
6728
6831
  * 设置代码块ID和代码内容到源dsl
@@ -6737,7 +6840,8 @@ class CodeBlock extends BaseService {
6737
6840
  }
6738
6841
  const codeConfigProcessed = codeConfig;
6739
6842
  if (codeConfig.content) {
6740
- codeConfigProcessed.content = eval(codeConfig.content);
6843
+ const parseDSL = getConfig("parseDSL");
6844
+ codeConfigProcessed.content = parseDSL(codeConfig.content);
6741
6845
  }
6742
6846
  const existContent = codeDsl[id] || {};
6743
6847
  codeDsl[id] = {
@@ -6752,8 +6856,8 @@ class CodeBlock extends BaseService {
6752
6856
  * @returns {CodeBlockDSL}
6753
6857
  */
6754
6858
  getCodeDslByIds(ids) {
6755
- const codeDsl2 = this.getCodeDsl();
6756
- return pick(codeDsl2, ids);
6859
+ const codeDsl = this.getCodeDsl();
6860
+ return pick(codeDsl, ids);
6757
6861
  }
6758
6862
  /**
6759
6863
  * 设置代码编辑面板展示状态
@@ -6776,10 +6880,10 @@ class CodeBlock extends BaseService {
6776
6880
  * @param {Id} id 代码块id
6777
6881
  * @returns {void}
6778
6882
  */
6779
- setCodeEditorContent(status, id2) {
6780
- if (!id2)
6883
+ setCodeEditorContent(status, id) {
6884
+ if (!id)
6781
6885
  return;
6782
- this.setId(id2);
6886
+ this.setId(id);
6783
6887
  this.state.isShowCodeEditor = status;
6784
6888
  }
6785
6889
  /**
@@ -6809,10 +6913,10 @@ class CodeBlock extends BaseService {
6809
6913
  * @param {Id} id 代码块id
6810
6914
  * @returns {void}
6811
6915
  */
6812
- setId(id2) {
6813
- if (!id2)
6916
+ setId(id) {
6917
+ if (!id)
6814
6918
  return;
6815
- this.state.id = id2;
6919
+ this.state.id = id;
6816
6920
  }
6817
6921
  /**
6818
6922
  * 获取当前选中的代码块ID
@@ -6877,9 +6981,9 @@ class CodeBlock extends BaseService {
6877
6981
  const currentDsl = await this.getCodeDsl();
6878
6982
  if (!currentDsl)
6879
6983
  return;
6880
- codeIds.forEach((id2) => {
6881
- delete currentDsl[id2];
6882
- this.emit("remove", id2);
6984
+ codeIds.forEach((id) => {
6985
+ delete currentDsl[id];
6986
+ this.emit("remove", id);
6883
6987
  });
6884
6988
  }
6885
6989
  /**
@@ -7394,176 +7498,274 @@ class Events extends BaseService {
7394
7498
  const eventsService = new Events();
7395
7499
 
7396
7500
  class Keybinding extends BaseService {
7397
- keycon = new KeyController();
7398
7501
  ctrlKey = /mac os x/.test(navigator.userAgent.toLowerCase()) ? "meta" : "ctrl";
7399
- constructor() {
7400
- super();
7401
- this.keycon.keyup((e) => {
7402
- this.emit("keyup", e.inputEvent);
7403
- }).keyup("delete", (e) => {
7404
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7405
- return;
7406
- }
7407
- e.inputEvent.preventDefault();
7408
- this.removeNode();
7409
- }).keyup("backspace", (e) => {
7410
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7411
- return;
7412
- }
7413
- e.inputEvent.preventDefault();
7414
- this.removeNode();
7415
- }).keydown([this.ctrlKey, "c"], (e) => {
7416
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7417
- return;
7418
- }
7419
- e.inputEvent.preventDefault();
7502
+ controllers = /* @__PURE__ */ new Map();
7503
+ bindingList = [];
7504
+ commands = {
7505
+ [KeyBindingCommand.DELETE_NODE]: () => {
7420
7506
  const nodes = editorService.get("nodes");
7421
- nodes && editorService.copy(nodes);
7422
- }).keydown([this.ctrlKey, "v"], (e) => {
7423
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7507
+ if (!nodes || isPage(nodes[0]))
7424
7508
  return;
7425
- }
7426
- e.inputEvent.preventDefault();
7509
+ editorService.remove(nodes);
7510
+ },
7511
+ [KeyBindingCommand.COPY_NODE]: () => {
7427
7512
  const nodes = editorService.get("nodes");
7428
- nodes && editorService.paste({ offsetX: 10, offsetY: 10 });
7429
- }).keydown([this.ctrlKey, "x"], (e) => {
7430
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7431
- return;
7432
- }
7433
- e.inputEvent.preventDefault();
7434
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7435
- return;
7436
- }
7513
+ nodes && editorService.copy(nodes);
7514
+ },
7515
+ [KeyBindingCommand.CUT_NODE]: () => {
7437
7516
  const nodes = editorService.get("nodes");
7438
7517
  if (!nodes || isPage(nodes[0]))
7439
7518
  return;
7440
7519
  editorService.copy(nodes);
7441
7520
  editorService.remove(nodes);
7442
- }).keydown([this.ctrlKey, "z"], (e) => {
7443
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7444
- return;
7445
- }
7446
- e.inputEvent.preventDefault();
7521
+ },
7522
+ [KeyBindingCommand.PASTE_NODE]: () => {
7523
+ const nodes = editorService.get("nodes");
7524
+ nodes && editorService.paste({ offsetX: 10, offsetY: 10 });
7525
+ },
7526
+ [KeyBindingCommand.UNDO]: () => {
7447
7527
  editorService.undo();
7448
- }).keydown([this.ctrlKey, "shift", "z"], (e) => {
7449
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7450
- return;
7451
- }
7452
- e.inputEvent.preventDefault();
7528
+ },
7529
+ [KeyBindingCommand.REDO]: () => {
7453
7530
  editorService.redo();
7454
- }).keydown("up", (e) => {
7455
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7456
- return;
7457
- }
7458
- e.inputEvent.preventDefault();
7531
+ },
7532
+ [KeyBindingCommand.ZOOM_IN]: () => {
7533
+ uiService.zoom(0.1);
7534
+ },
7535
+ [KeyBindingCommand.ZOOM_OUT]: () => {
7536
+ uiService.zoom(-0.1);
7537
+ },
7538
+ [KeyBindingCommand.ZOOM_RESET]: () => {
7539
+ uiService.set("zoom", 1);
7540
+ },
7541
+ [KeyBindingCommand.ZOOM_FIT]: async () => {
7542
+ uiService.set("zoom", await uiService.calcZoom());
7543
+ },
7544
+ [KeyBindingCommand.MOVE_UP_1]: () => {
7459
7545
  editorService.move(0, -1);
7460
- }).keydown("down", (e) => {
7461
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7462
- return;
7463
- }
7464
- e.inputEvent.preventDefault();
7546
+ },
7547
+ [KeyBindingCommand.MOVE_DOWN_1]: () => {
7465
7548
  editorService.move(0, 1);
7466
- }).keydown("left", (e) => {
7467
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7468
- return;
7469
- }
7470
- e.inputEvent.preventDefault();
7549
+ },
7550
+ [KeyBindingCommand.MOVE_LEFT_1]: () => {
7471
7551
  editorService.move(-1, 0);
7472
- }).keydown("right", (e) => {
7473
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7474
- return;
7475
- }
7476
- e.inputEvent.preventDefault();
7552
+ },
7553
+ [KeyBindingCommand.MOVE_RIGHT_1]: () => {
7477
7554
  editorService.move(1, 0);
7478
- }).keydown([this.ctrlKey, "up"], (e) => {
7479
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7480
- return;
7481
- }
7482
- e.inputEvent.preventDefault();
7555
+ },
7556
+ [KeyBindingCommand.MOVE_UP_10]: () => {
7483
7557
  editorService.move(0, -10);
7484
- }).keydown([this.ctrlKey, "down"], (e) => {
7485
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7486
- return;
7487
- }
7488
- e.inputEvent.preventDefault();
7558
+ },
7559
+ [KeyBindingCommand.MOVE_DOWN_10]: () => {
7489
7560
  editorService.move(0, 10);
7490
- }).keydown([this.ctrlKey, "left"], (e) => {
7491
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7492
- return;
7493
- }
7494
- e.inputEvent.preventDefault();
7561
+ },
7562
+ [KeyBindingCommand.MOVE_LEFT_10]: () => {
7495
7563
  editorService.move(-10, 0);
7496
- }).keydown([this.ctrlKey, "right"], (e) => {
7497
- e.inputEvent.preventDefault();
7564
+ },
7565
+ [KeyBindingCommand.MOVE_RIGHT_10]: () => {
7498
7566
  editorService.move(10, 0);
7499
- }).keydown("tab", (e) => {
7500
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7501
- return;
7502
- }
7503
- e.inputEvent.preventDefault();
7567
+ },
7568
+ [KeyBindingCommand.SWITCH_NODE]: () => {
7504
7569
  editorService.selectNextNode();
7505
- }).keydown([this.ctrlKey, "tab"], (e) => {
7506
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7507
- return;
7508
- }
7509
- e.inputEvent.preventDefault();
7510
- editorService.selectNextPage();
7511
- }).keydown([this.ctrlKey, "="], (e) => {
7512
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7513
- return;
7514
- }
7515
- e.inputEvent.preventDefault();
7516
- uiService.zoom(0.1);
7517
- }).keydown([this.ctrlKey, "numpadplus"], (e) => {
7518
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7519
- return;
7520
- }
7521
- e.inputEvent.preventDefault();
7522
- uiService.zoom(0.1);
7523
- }).keydown([this.ctrlKey, "-"], (e) => {
7524
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7525
- return;
7526
- }
7527
- e.inputEvent.preventDefault();
7528
- uiService.zoom(-0.1);
7529
- }).keydown([this.ctrlKey, "numpad-"], (e) => {
7530
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7531
- return;
7532
- }
7533
- e.inputEvent.preventDefault();
7534
- uiService.zoom(-0.1);
7535
- }).keydown([this.ctrlKey, "0"], async (e) => {
7536
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7537
- return;
7538
- }
7539
- e.inputEvent.preventDefault();
7540
- uiService.set("zoom", await uiService.calcZoom());
7541
- }).keydown([this.ctrlKey, "1"], (e) => {
7542
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7543
- return;
7570
+ }
7571
+ };
7572
+ registeCommand(command, handler) {
7573
+ this.commands[command] = handler;
7574
+ }
7575
+ unregisteCommand(command) {
7576
+ delete this.commands[command];
7577
+ }
7578
+ registeEl(name, el) {
7579
+ if (name !== "global" && !el) {
7580
+ throw new Error("只有name为global可以不传el");
7581
+ }
7582
+ const keycon = new KeyController(el);
7583
+ this.controllers.set(name, keycon);
7584
+ this.bind(name);
7585
+ }
7586
+ unregisteEl(name) {
7587
+ this.controllers.get(name)?.destroy();
7588
+ this.controllers.delete(name);
7589
+ this.bindingList.forEach((item) => {
7590
+ item.binded = false;
7591
+ });
7592
+ }
7593
+ registe(maps) {
7594
+ for (const keybindingItem of maps) {
7595
+ const { command, keybinding, when } = keybindingItem;
7596
+ for (const [type = "", eventType = "keydown"] of when) {
7597
+ const cacheItem = { type, command, keybinding, eventType, binded: false };
7598
+ this.bindingList.push(cacheItem);
7544
7599
  }
7545
- e.inputEvent.preventDefault();
7546
- uiService.set("zoom", 1);
7600
+ }
7601
+ this.bind();
7602
+ }
7603
+ reset() {
7604
+ this.controllers.forEach((keycon) => {
7605
+ keycon.destroy();
7547
7606
  });
7607
+ this.controllers.clear();
7608
+ this.bindingList = [];
7548
7609
  }
7549
7610
  destroy() {
7550
- this.keycon.destroy();
7611
+ this.reset();
7551
7612
  }
7552
- isDisabledKeyEvent(node) {
7553
- const el = node;
7554
- if (!el)
7555
- return false;
7556
- return el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable;
7613
+ bind(name) {
7614
+ for (const item of this.bindingList) {
7615
+ const { type, eventType, command, keybinding, binded } = item;
7616
+ if (name && name !== type) {
7617
+ continue;
7618
+ }
7619
+ if (binded) {
7620
+ continue;
7621
+ }
7622
+ const keycon = this.controllers.get(type);
7623
+ if (!keycon) {
7624
+ continue;
7625
+ }
7626
+ const handler = (e) => {
7627
+ e.inputEvent.preventDefault();
7628
+ this.commands[command]?.(e.inputEvent);
7629
+ };
7630
+ this.getKeyconKeys(keybinding).forEach((keys) => {
7631
+ if (keys[0]) {
7632
+ keycon[eventType](keys, handler);
7633
+ } else {
7634
+ keycon[eventType](handler);
7635
+ }
7636
+ });
7637
+ item.binded = true;
7638
+ }
7557
7639
  }
7558
- removeNode() {
7559
- const nodes = editorService.get("nodes");
7560
- if (!nodes || isPage(nodes[0]))
7561
- return;
7562
- editorService.remove(nodes);
7640
+ getKeyconKeys(keybinding = "") {
7641
+ const splitKey = (key) => key.split("+").map((k) => k === "ctrl" ? this.ctrlKey : k);
7642
+ if (Array.isArray(keybinding)) {
7643
+ return keybinding.map((key) => splitKey(key));
7644
+ }
7645
+ return [splitKey(keybinding)];
7563
7646
  }
7564
7647
  }
7565
7648
  const keybindingService = new Keybinding();
7566
7649
 
7650
+ const keybindingConfig = [
7651
+ {
7652
+ command: KeyBindingCommand.DELETE_NODE,
7653
+ keybinding: ["delete", "backspace"],
7654
+ when: [
7655
+ ["stage", "keyup"],
7656
+ ["layer-panel", "keydown"]
7657
+ ]
7658
+ },
7659
+ {
7660
+ command: KeyBindingCommand.COPY_NODE,
7661
+ keybinding: "ctrl+c",
7662
+ when: [
7663
+ ["stage", "keydown"],
7664
+ ["layer-panel", "keydown"]
7665
+ ]
7666
+ },
7667
+ {
7668
+ command: KeyBindingCommand.PASTE_NODE,
7669
+ keybinding: "ctrl+v",
7670
+ when: [
7671
+ ["stage", "keydown"],
7672
+ ["layer-panel", "keydown"]
7673
+ ]
7674
+ },
7675
+ {
7676
+ command: KeyBindingCommand.CUT_NODE,
7677
+ keybinding: "ctrl+x",
7678
+ when: [
7679
+ ["stage", "keydown"],
7680
+ ["layer-panel", "keydown"]
7681
+ ]
7682
+ },
7683
+ {
7684
+ command: KeyBindingCommand.UNDO,
7685
+ keybinding: "ctrl+z",
7686
+ when: [
7687
+ ["stage", "keydown"],
7688
+ ["layer-panel", "keydown"]
7689
+ ]
7690
+ },
7691
+ {
7692
+ command: KeyBindingCommand.REDO,
7693
+ keybinding: "ctrl+shift+z",
7694
+ when: [
7695
+ ["stage", "keydown"],
7696
+ ["layer-panel", "keydown"]
7697
+ ]
7698
+ },
7699
+ {
7700
+ command: KeyBindingCommand.MOVE_UP_1,
7701
+ keybinding: "up",
7702
+ when: [["stage", "keydown"]]
7703
+ },
7704
+ {
7705
+ command: KeyBindingCommand.MOVE_DOWN_1,
7706
+ keybinding: "down",
7707
+ when: [["stage", "keydown"]]
7708
+ },
7709
+ {
7710
+ command: KeyBindingCommand.MOVE_LEFT_1,
7711
+ keybinding: "left",
7712
+ when: [["stage", "keydown"]]
7713
+ },
7714
+ {
7715
+ command: KeyBindingCommand.MOVE_RIGHT_1,
7716
+ keybinding: "right",
7717
+ when: [["stage", "keydown"]]
7718
+ },
7719
+ {
7720
+ command: KeyBindingCommand.MOVE_UP_10,
7721
+ keybinding: "ctrl+up",
7722
+ when: [["stage", "keydown"]]
7723
+ },
7724
+ {
7725
+ command: KeyBindingCommand.MOVE_DOWN_10,
7726
+ keybinding: "ctrl+down",
7727
+ when: [["stage", "keydown"]]
7728
+ },
7729
+ {
7730
+ command: KeyBindingCommand.MOVE_LEFT_10,
7731
+ keybinding: "ctrl+left",
7732
+ when: [["stage", "keydown"]]
7733
+ },
7734
+ {
7735
+ command: KeyBindingCommand.MOVE_RIGHT_10,
7736
+ keybinding: "ctrl+right",
7737
+ when: [["stage", "keydown"]]
7738
+ },
7739
+ {
7740
+ command: KeyBindingCommand.SWITCH_NODE,
7741
+ keybinding: "tab",
7742
+ when: [
7743
+ ["stage", "keydown"],
7744
+ ["layer-panel", "keydown"]
7745
+ ]
7746
+ },
7747
+ {
7748
+ command: KeyBindingCommand.ZOOM_IN,
7749
+ keybinding: ["ctrl+=", "ctrl+numpadplus"],
7750
+ when: [["stage", "keydown"]]
7751
+ },
7752
+ {
7753
+ command: KeyBindingCommand.ZOOM_OUT,
7754
+ keybinding: ["ctrl+-", "ctrl+numpad-"],
7755
+ when: [["stage", "keydown"]]
7756
+ },
7757
+ {
7758
+ command: KeyBindingCommand.ZOOM_FIT,
7759
+ keybinding: "ctrl+0",
7760
+ when: [["stage", "keydown"]]
7761
+ },
7762
+ {
7763
+ command: KeyBindingCommand.ZOOM_RESET,
7764
+ keybinding: "ctrl+1",
7765
+ when: [["stage", "keydown"]]
7766
+ }
7767
+ ];
7768
+
7567
7769
  const editorProps = {
7568
7770
  /** 页面初始值 */
7569
7771
  modelValue: {
@@ -7691,7 +7893,8 @@ const initServiceState = (props, {
7691
7893
  propsService,
7692
7894
  eventsService,
7693
7895
  uiService,
7694
- codeBlockService
7896
+ codeBlockService,
7897
+ keybindingService
7695
7898
  }) => {
7696
7899
  watch(
7697
7900
  () => props.modelValue,
@@ -7760,6 +7963,7 @@ const initServiceState = (props, {
7760
7963
  uiService.resetState();
7761
7964
  componentListService.resetState();
7762
7965
  codeBlockService.resetState();
7966
+ keybindingService.reset();
7763
7967
  });
7764
7968
  };
7765
7969
  const initServiceEvents = (props, emit, { editorService, codeBlockService, dataSourceService, depService }) => {
@@ -7956,6 +8160,8 @@ const _sfc_main = defineComponent({
7956
8160
  };
7957
8161
  initServiceEvents(props, emit, services);
7958
8162
  initServiceState(props, services);
8163
+ keybindingService.registe(keybindingConfig);
8164
+ keybindingService.registeEl("global");
7959
8165
  provide("services", services);
7960
8166
  provide("codeOptions", props.codeOptions);
7961
8167
  provide(
@@ -8092,7 +8298,8 @@ const Editor = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]])
8092
8298
  const index$1 = '';
8093
8299
 
8094
8300
  const defaultInstallOpt = {
8095
- // @todo, 自定义图片上传方法等编辑器依赖的外部选项
8301
+ // eslint-disable-next-line no-eval
8302
+ parseDSL: (dsl) => eval(dsl)
8096
8303
  };
8097
8304
  const index = {
8098
8305
  install: (app, opt) => {
@@ -8113,5 +8320,5 @@ const index = {
8113
8320
  }
8114
8321
  };
8115
8322
 
8116
- export { CODE_DRAFT_STORAGE_KEY, COPY_STORAGE_KEY, _sfc_main$g as CodeBlockList, CodeDeleteErrorType, _sfc_main$C as CodeSelect, _sfc_main$A as CodeSelectCol, ColumnLayout, _sfc_main$d as ComponentListPanel, _sfc_main$c as ContentMenu, _sfc_main$z as DataSourceFields, _sfc_main$y as DataSourceInput, _sfc_main$x as EventSelect, Fixed2Other, H_GUIDE_LINE_STORAGE_KEY, _sfc_main$B as Icon, _sfc_main$w as KeyValue, Keys, LayerOffset, _sfc_main$a as LayerPanel, Layout, _sfc_main$s as LayoutContainer, _sfc_main$n as PropsPanel, _sfc_main$s as SplitView, _sfc_main$u as TMagicCodeEditor, Editor as TMagicEditor, _sfc_main$p as ToolButton, V_GUIDE_LINE_STORAGE_KEY, beforePaste, change2Fixed, codeBlockService, dataSourceService, debug, index as default, depService, editorService, error, eventsService, fillConfig$1 as fillConfig, fixNodeLeft, fixNodePosition, generatePageName, generatePageNameByApp, getAddParent, getConfig, getDefaultConfig, getGuideLineFromCache, getInitPositionStyle, getNodeIndex, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, historyService, info, isFixed, log, propsService, serializeConfig, setConfig, setLayout, storageService, uiService, useStage, warn };
8323
+ export { CODE_DRAFT_STORAGE_KEY, COPY_STORAGE_KEY, _sfc_main$g as CodeBlockList, CodeDeleteErrorType, _sfc_main$C as CodeSelect, _sfc_main$A as CodeSelectCol, ColumnLayout, _sfc_main$d as ComponentListPanel, _sfc_main$c as ContentMenu, _sfc_main$z as DataSourceFields, _sfc_main$y as DataSourceInput, _sfc_main$x as EventSelect, Fixed2Other, H_GUIDE_LINE_STORAGE_KEY, _sfc_main$B as Icon, KeyBindingCommand, _sfc_main$w as KeyValue, Keys, LayerOffset, _sfc_main$a as LayerPanel, Layout, _sfc_main$s as LayoutContainer, _sfc_main$n as PropsPanel, _sfc_main$t as Resizer, _sfc_main$s as SplitView, _sfc_main$u as TMagicCodeEditor, Editor as TMagicEditor, _sfc_main$p as ToolButton, V_GUIDE_LINE_STORAGE_KEY, beforePaste, change2Fixed, codeBlockService, dataSourceService, debug, index as default, depService, editorService, error, eventsService, fillConfig$1 as fillConfig, fixNodeLeft, fixNodePosition, generatePageName, generatePageNameByApp, getAddParent, getConfig, getDefaultConfig, getGuideLineFromCache, getInitPositionStyle, getNodeIndex, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, historyService, info, isFixed, log, propsService, serializeConfig, setConfig, setLayout, storageService, uiService, useStage, warn };
8117
8324
  //# sourceMappingURL=tmagic-editor.js.map