@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,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('serialize-javascript'), require('lodash-es'), require('@tmagic/design'), require('@tmagic/schema'), require('@element-plus/icons-vue'), require('@tmagic/form'), require('@tmagic/table'), require('monaco-editor'), require('gesto'), require('@tmagic/utils'), require('keycon'), require('@tmagic/stage'), require('events'), require('@tmagic/core')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'vue', 'serialize-javascript', 'lodash-es', '@tmagic/design', '@tmagic/schema', '@element-plus/icons-vue', '@tmagic/form', '@tmagic/table', 'monaco-editor', 'gesto', '@tmagic/utils', 'keycon', '@tmagic/stage', 'events', '@tmagic/core'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicEditor = {}, global.Vue, global.serialize, global.lodashEs, global.design, global.schema, global.iconsVue, global.form, global.table, global.monaco, global.Gesto, global.utils, global.KeyController, global.StageCore, global.events, global.core));
5
- })(this, (function (exports, vue, serialize, lodashEs, design, schema, iconsVue, form, table, monaco, Gesto, utils, KeyController, StageCore, events, core) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('serialize-javascript'), require('lodash-es'), require('@tmagic/design'), require('@tmagic/schema'), require('@element-plus/icons-vue'), require('@tmagic/form'), require('@tmagic/table'), require('monaco-editor'), require('gesto'), require('@tmagic/utils'), require('@tmagic/stage'), require('events'), require('@tmagic/core'), require('keycon')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'vue', 'serialize-javascript', 'lodash-es', '@tmagic/design', '@tmagic/schema', '@element-plus/icons-vue', '@tmagic/form', '@tmagic/table', 'monaco-editor', 'gesto', '@tmagic/utils', '@tmagic/stage', 'events', '@tmagic/core', 'keycon'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicEditor = {}, global.Vue, global.serialize, global.lodashEs, global.design, global.schema, global.iconsVue, global.form, global.table, global.monaco, global.Gesto, global.utils, global.StageCore, global.events, global.core, global.KeyController));
5
+ })(this, (function (exports, vue, serialize, lodashEs, design, schema, iconsVue, form, table, monaco, Gesto, utils, StageCore, events, core, KeyController) { 'use strict';
6
6
 
7
7
  function _interopNamespaceDefault(e) {
8
8
  const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
@@ -56,6 +56,12 @@
56
56
  }
57
57
  });
58
58
 
59
+ let $TMAGIC_EDITOR = {};
60
+ const setConfig = (option) => {
61
+ $TMAGIC_EDITOR = option;
62
+ };
63
+ const getConfig = (key) => $TMAGIC_EDITOR[key];
64
+
59
65
  const _sfc_main$D = /* @__PURE__ */ vue.defineComponent({
60
66
  ...{
61
67
  name: "MEditorCodeLink"
@@ -111,7 +117,8 @@
111
117
  if (!props.name || !props.model)
112
118
  return;
113
119
  try {
114
- props.model[props.name] = eval(`(${v[props.name]})`);
120
+ const parseDSL = getConfig("parseDSL");
121
+ props.model[props.name] = parseDSL(`(${v[props.name]})`);
115
122
  emit("change", props.model[props.name]);
116
123
  } catch (e) {
117
124
  console.error(e);
@@ -565,7 +572,7 @@
565
572
  const dataSources = vue.computed(() => dataSourceService?.get("dataSources") || []);
566
573
  const setDisplayState = () => {
567
574
  displayState.value = [];
568
- const matches = state.value.matchAll(/\{\{([\s\S]+?)\}\}/g);
575
+ const matches = state.value.matchAll(/\$\{([\s\S]+?)\}/g);
569
576
  let index = 0;
570
577
  for (const match of matches) {
571
578
  if (typeof match.index === "undefined")
@@ -638,13 +645,13 @@
638
645
  }
639
646
  return selectionStart;
640
647
  };
641
- const curCharIsLeftCurlyBracket = (leftCurlyBracketIndex) => leftCurlyBracketIndex > -1 && leftCurlyBracketIndex === getSelectionStart() - 1;
648
+ const curCharIsLeftCurlyBracket = (leftCurlyBracketIndex) => leftCurlyBracketIndex > 0 && leftCurlyBracketIndex === getSelectionStart() - 1;
642
649
  const curCharIsDot = (dotIndex) => dotIndex > -1 && dotIndex === getSelectionStart() - 1;
643
650
  const dsQuerySearch = (queryString, leftCurlyBracketIndex, cb) => {
644
651
  let result = [];
645
652
  if (curCharIsLeftCurlyBracket(leftCurlyBracketIndex)) {
646
653
  result = dataSources.value;
647
- } else if (leftCurlyBracketIndex > -1) {
654
+ } else if (leftCurlyBracketIndex > 0) {
648
655
  const queryName = queryString.substring(leftCurlyBracketIndex + 1).toLowerCase();
649
656
  result = dataSources.value.filter((ds) => ds.title?.toLowerCase().includes(queryName) || ds.id.includes(queryName));
650
657
  }
@@ -696,7 +703,7 @@
696
703
  const selectionStart = getSelectionStart();
697
704
  const curQueryString = queryString.substring(0, selectionStart);
698
705
  const fieldKeyStringLastIndex = curQueryString.lastIndexOf(".");
699
- const dsKeyStringLastIndex = curQueryString.lastIndexOf("{");
706
+ const dsKeyStringLastIndex = curQueryString.lastIndexOf("${") + 1;
700
707
  const isFieldTip = fieldKeyStringLastIndex > dsKeyStringLastIndex;
701
708
  if (isFieldTip) {
702
709
  fieldQuerySearch(curQueryString, dsKeyStringLastIndex, fieldKeyStringLastIndex, cb);
@@ -709,7 +716,7 @@
709
716
  const selectionStart = input.value?.selectionStart || 0;
710
717
  let startText = inputText.substring(0, selectionStart);
711
718
  const dotIndex = startText.lastIndexOf(".");
712
- const leftCurlyBracketIndex = startText.lastIndexOf("{");
719
+ const leftCurlyBracketIndex = startText.lastIndexOf("${") + 1;
713
720
  const endText = inputText.substring(selectionStart);
714
721
  let suggestText = value;
715
722
  if (isDataSource) {
@@ -719,7 +726,6 @@
719
726
  if (!isRightCurlyBracket(selectionStart + 1)) {
720
727
  suggestText = `${suggestText}}`;
721
728
  }
722
- suggestText = `{${suggestText}}`;
723
729
  } else if (!curCharIsDot(dotIndex)) {
724
730
  startText = startText.substring(0, dotIndex + 1);
725
731
  }
@@ -727,7 +733,7 @@
727
733
  await vue.nextTick();
728
734
  let newSelectionStart = 0;
729
735
  if (isDataSource) {
730
- newSelectionStart = leftCurlyBracketIndex + suggestText.length - 1;
736
+ newSelectionStart = leftCurlyBracketIndex + suggestText.length;
731
737
  } else {
732
738
  newSelectionStart = dotIndex + suggestText.length + 1;
733
739
  }
@@ -770,11 +776,11 @@
770
776
  _: 1
771
777
  }, 16, ["modelValue"])) : (vue.openBlock(), vue.createElementBlock("div", {
772
778
  key: 1,
773
- class: vue.normalizeClass(`el-input el-input--${_ctx.size}`),
779
+ class: vue.normalizeClass(`tmagic-data-source-input-text el-input el-input--${_ctx.size}`),
774
780
  onMouseup: mouseupHandler
775
781
  }, [
776
782
  vue.createElementVNode("div", {
777
- class: vue.normalizeClass(`el-input__wrapper ${isFocused.value ? " is-focus" : ""}`)
783
+ class: vue.normalizeClass(`tmagic-data-source-input-text-wrapper el-input__wrapper ${isFocused.value ? " is-focus" : ""}`)
778
784
  }, [
779
785
  vue.createElementVNode("div", _hoisted_3$5, [
780
786
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(displayState.value, (item, index) => {
@@ -793,7 +799,11 @@
793
799
  _: 2
794
800
  }, 1032, ["size"])) : vue.createCommentVNode("", true)
795
801
  ], 64);
796
- }), 256))
802
+ }), 256)),
803
+ vue.createVNode(_sfc_main$B, {
804
+ class: "tmagic-data-source-input-icon",
805
+ icon: vue.unref(iconsVue.Coin)
806
+ }, null, 8, ["icon"])
797
807
  ])
798
808
  ], 2)
799
809
  ], 34));
@@ -1356,12 +1366,6 @@
1356
1366
  }
1357
1367
  });
1358
1368
 
1359
- let $TMAGIC_EDITOR = {};
1360
- const setConfig = (option) => {
1361
- $TMAGIC_EDITOR = option;
1362
- };
1363
- const getConfig = (key) => $TMAGIC_EDITOR[key];
1364
-
1365
1369
  const _sfc_main$t = /* @__PURE__ */ vue.defineComponent({
1366
1370
  ...{
1367
1371
  name: "MEditorResizer"
@@ -1509,7 +1513,7 @@
1509
1513
  ref: el,
1510
1514
  class: "m-editor-layout"
1511
1515
  }, [
1512
- hasLeft.value ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
1516
+ hasLeft.value && _ctx.$slots.left ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
1513
1517
  vue.createElementVNode("div", {
1514
1518
  class: vue.normalizeClass(["m-editor-layout-left", _ctx.leftClass]),
1515
1519
  style: vue.normalizeStyle(`width: ${_ctx.left}px`)
@@ -1524,7 +1528,7 @@
1524
1528
  }, [
1525
1529
  vue.renderSlot(_ctx.$slots, "center")
1526
1530
  ], 6),
1527
- hasRight.value ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
1531
+ hasRight.value && _ctx.$slots.right ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
1528
1532
  vue.createVNode(_sfc_main$t, { onChange: changeRight }),
1529
1533
  vue.createElementVNode("div", {
1530
1534
  class: vue.normalizeClass(["m-editor-layout-right", _ctx.rightClass]),
@@ -1618,6 +1622,40 @@
1618
1622
  }
1619
1623
  ]
1620
1624
  },
1625
+ {
1626
+ type: "fieldset",
1627
+ legend: "边框",
1628
+ items: [
1629
+ {
1630
+ name: "borderWidth",
1631
+ text: "宽度",
1632
+ defaultValue: "0"
1633
+ },
1634
+ {
1635
+ name: "borderColor",
1636
+ text: "颜色",
1637
+ type: "colorPicker"
1638
+ },
1639
+ {
1640
+ name: "borderStyle",
1641
+ text: "样式",
1642
+ type: "select",
1643
+ defaultValue: "none",
1644
+ options: [
1645
+ { text: "none", value: "none" },
1646
+ { text: "hidden", value: "hidden" },
1647
+ { text: "dotted", value: "dotted" },
1648
+ { text: "dashed", value: "dashed" },
1649
+ { text: "solid", value: "solid" },
1650
+ { text: "double", value: "double" },
1651
+ { text: "groove", value: "groove" },
1652
+ { text: "ridge", value: "ridge" },
1653
+ { text: "inset", value: "inset" },
1654
+ { text: "outset", value: "outset" }
1655
+ ]
1656
+ }
1657
+ ]
1658
+ },
1621
1659
  {
1622
1660
  type: "fieldset",
1623
1661
  legend: "背景",
@@ -1777,6 +1815,28 @@
1777
1815
  return CodeDeleteErrorType2;
1778
1816
  })(CodeDeleteErrorType || {});
1779
1817
  const CODE_DRAFT_STORAGE_KEY = "magicCodeDraft";
1818
+ var KeyBindingCommand = /* @__PURE__ */ ((KeyBindingCommand2) => {
1819
+ KeyBindingCommand2["COPY_NODE"] = "tmagic-system-copy-node";
1820
+ KeyBindingCommand2["PASTE_NODE"] = "tmagic-system-paste-node";
1821
+ KeyBindingCommand2["DELETE_NODE"] = "tmagic-system-delete-node";
1822
+ KeyBindingCommand2["CUT_NODE"] = "tmagic-system-cut-node";
1823
+ KeyBindingCommand2["UNDO"] = "tmagic-system-undo";
1824
+ KeyBindingCommand2["REDO"] = "tmagic-system-redo";
1825
+ KeyBindingCommand2["ZOOM_IN"] = "tmagic-system-zoom-in";
1826
+ KeyBindingCommand2["ZOOM_OUT"] = "tmagic-system-zoom-out";
1827
+ KeyBindingCommand2["ZOOM_RESET"] = "tmagic-system-zoom-reset";
1828
+ KeyBindingCommand2["ZOOM_FIT"] = "tmagic-system-zoom-fit";
1829
+ KeyBindingCommand2["MOVE_UP_1"] = "tmagic-system-move-up-1";
1830
+ KeyBindingCommand2["MOVE_DOWN_1"] = "tmagic-system-move-down-1";
1831
+ KeyBindingCommand2["MOVE_LEFT_1"] = "tmagic-system-move-left-1";
1832
+ KeyBindingCommand2["MOVE_RIGHT_1"] = "tmagic-system-move-right-1";
1833
+ KeyBindingCommand2["MOVE_UP_10"] = "tmagic-system-move-up-10";
1834
+ KeyBindingCommand2["MOVE_DOWN_10"] = "tmagic-system-move-down-10";
1835
+ KeyBindingCommand2["MOVE_LEFT_10"] = "tmagic-system-move-left-10";
1836
+ KeyBindingCommand2["MOVE_RIGHT_10"] = "tmagic-system-move-right-10";
1837
+ KeyBindingCommand2["SWITCH_NODE"] = "tmagic-system-switch-node";
1838
+ return KeyBindingCommand2;
1839
+ })(KeyBindingCommand || {});
1780
1840
 
1781
1841
  const COPY_STORAGE_KEY = "$MagicEditorCopyData";
1782
1842
  const getPageList = (app) => {
@@ -2223,8 +2283,8 @@
2223
2283
  * 清理,支持storageService.usePlugin
2224
2284
  */
2225
2285
  async clear() {
2226
- const storage2 = await this.getStorage();
2227
- storage2.clear();
2286
+ const storage = await this.getStorage();
2287
+ storage.clear();
2228
2288
  }
2229
2289
  /**
2230
2290
  * 获取存储项,支持storageService.usePlugin
@@ -2238,7 +2298,7 @@
2238
2298
  return null;
2239
2299
  switch (protocol) {
2240
2300
  case "object" /* OBJECT */:
2241
- return eval(`(${item})`);
2301
+ return getConfig("parseDSL")(`(${item})`);
2242
2302
  case "json" /* JSON */:
2243
2303
  return JSON.parse(item);
2244
2304
  case "number" /* NUMBER */:
@@ -2253,49 +2313,49 @@
2253
2313
  * 获取指定索引位置的key
2254
2314
  */
2255
2315
  async key(index) {
2256
- const storage2 = await this.getStorage();
2257
- return storage2.key(index);
2316
+ const storage = await this.getStorage();
2317
+ return storage.key(index);
2258
2318
  }
2259
2319
  /**
2260
2320
  * 移除存储项,支持storageService.usePlugin
2261
2321
  */
2262
- async removeItem(key2, options2 = {}) {
2263
- const [storage2, namespace2] = await Promise.all([this.getStorage(), this.getNamespace()]);
2264
- storage2.removeItem(`${options2.namespace || namespace2}:${key2}`);
2322
+ async removeItem(key, options = {}) {
2323
+ const [storage, namespace] = await Promise.all([this.getStorage(), this.getNamespace()]);
2324
+ storage.removeItem(`${options.namespace || namespace}:${key}`);
2265
2325
  }
2266
2326
  /**
2267
2327
  * 设置存储项,支持storageService.usePlugin
2268
2328
  */
2269
- async setItem(key2, value, options2 = {}) {
2270
- const [storage2, namespace2] = await Promise.all([this.getStorage(), this.getNamespace()]);
2271
- let item2 = value;
2272
- const protocol2 = options2.protocol ? `${options2.protocol}:` : "";
2329
+ async setItem(key, value, options = {}) {
2330
+ const [storage, namespace] = await Promise.all([this.getStorage(), this.getNamespace()]);
2331
+ let item = value;
2332
+ const protocol = options.protocol ? `${options.protocol}:` : "";
2273
2333
  if (typeof value === "string" /* STRING */ || typeof value === "number" /* NUMBER */) {
2274
- item2 = `${protocol2}${value}`;
2334
+ item = `${protocol}${value}`;
2275
2335
  } else {
2276
- item2 = `${protocol2}${serialize(value)}`;
2336
+ item = `${protocol}${serialize(value)}`;
2277
2337
  }
2278
- storage2.setItem(`${options2.namespace || namespace2}:${key2}`, item2);
2338
+ storage.setItem(`${options.namespace || namespace}:${key}`, item);
2279
2339
  }
2280
2340
  destroy() {
2281
2341
  this.removeAllListeners();
2282
2342
  this.removeAllPlugins();
2283
2343
  }
2284
2344
  getValueAndProtocol(value) {
2285
- let protocol2 = "";
2345
+ let protocol = "";
2286
2346
  if (value === null) {
2287
2347
  return {
2288
2348
  item: value,
2289
- protocol: protocol2
2349
+ protocol
2290
2350
  };
2291
2351
  }
2292
- const item2 = value.replace(new RegExp(`^(${Object.values(Protocol).join("|")})(:)(.+)`), (_$0, $1, _$2, $3) => {
2293
- protocol2 = $1;
2352
+ const item = value.replace(new RegExp(`^(${Object.values(Protocol).join("|")})(:)(.+)`), (_$0, $1, _$2, $3) => {
2353
+ protocol = $1;
2294
2354
  return $3;
2295
2355
  });
2296
2356
  return {
2297
- protocol: protocol2,
2298
- item: item2
2357
+ protocol,
2358
+ item
2299
2359
  };
2300
2360
  }
2301
2361
  }
@@ -3446,7 +3506,6 @@
3446
3506
  const codeOptions = vue.inject("codeOptions", {});
3447
3507
  const { editorService, uiService } = vue.inject("services") || {};
3448
3508
  const root = vue.computed(() => editorService?.get("root"));
3449
- const nodes = vue.computed(() => editorService?.get("nodes") || []);
3450
3509
  const pageLength = vue.computed(() => editorService?.get("pageLength") || 0);
3451
3510
  const showSrc = vue.computed(() => uiService?.get("showSrc"));
3452
3511
  const leftColumnWidthCacheData = Number(globalThis.localStorage.getItem(LEFT_COLUMN_WIDTH_STORAGE_KEY));
@@ -3497,7 +3556,8 @@
3497
3556
  };
3498
3557
  const saveCode = (value) => {
3499
3558
  try {
3500
- editorService?.set("root", eval(value));
3559
+ const parseDSL = getConfig("parseDSL");
3560
+ editorService?.set("root", parseDSL(value));
3501
3561
  } catch (e) {
3502
3562
  console.error(e);
3503
3563
  }
@@ -3538,7 +3598,7 @@
3538
3598
  ]),
3539
3599
  _: 2
3540
3600
  }, [
3541
- pageLength.value > 0 && nodes.value.length === 1 ? {
3601
+ pageLength.value > 0 ? {
3542
3602
  name: "right",
3543
3603
  fn: vue.withCtx(() => [
3544
3604
  vue.createVNode(vue.unref(design.TMagicScrollbar), null, {
@@ -3897,7 +3957,10 @@
3897
3957
  }
3898
3958
  });
3899
3959
 
3900
- const _hoisted_1$e = { class: "m-editor-props-panel" };
3960
+ const _hoisted_1$e = {
3961
+ key: 0,
3962
+ class: "m-editor-props-panel"
3963
+ };
3901
3964
  const _sfc_main$n = /* @__PURE__ */ vue.defineComponent({
3902
3965
  ...{
3903
3966
  name: "MEditorPropsPanel"
@@ -3911,6 +3974,7 @@
3911
3974
  const curFormConfig = vue.ref([]);
3912
3975
  const services = vue.inject("services");
3913
3976
  const node = vue.computed(() => services?.editorService.get("node"));
3977
+ const nodes = vue.computed(() => services?.editorService.get("nodes") || []);
3914
3978
  const propsPanelSize = vue.computed(() => services?.uiService.get("propsPanelSize") || "small");
3915
3979
  const stage = vue.computed(() => services?.editorService.get("stage"));
3916
3980
  const init = async () => {
@@ -3947,7 +4011,7 @@
3947
4011
  };
3948
4012
  __expose({ submit });
3949
4013
  return (_ctx, _cache) => {
3950
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$e, [
4014
+ return nodes.value.length === 1 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$e, [
3951
4015
  vue.renderSlot(_ctx.$slots, "props-panel-header"),
3952
4016
  vue.createVNode(vue.unref(form.MForm), {
3953
4017
  ref_key: "configForm",
@@ -3959,7 +4023,7 @@
3959
4023
  config: curFormConfig.value,
3960
4024
  onChange: submit
3961
4025
  }, null, 8, ["class", "popper-class", "size", "init-values", "config"])
3962
- ]);
4026
+ ])) : vue.createCommentVNode("", true);
3963
4027
  };
3964
4028
  }
3965
4029
  });
@@ -4227,6 +4291,7 @@
4227
4291
  },
4228
4292
  setup(__props, { expose: __expose }) {
4229
4293
  const props = __props;
4294
+ vue.provide("mForm", {});
4230
4295
  const defaultParamColConfig = {
4231
4296
  type: "row",
4232
4297
  label: "参数类型",
@@ -4295,29 +4360,29 @@
4295
4360
  initTableModel();
4296
4361
  const beforeSave = (codeValue) => {
4297
4362
  try {
4298
- eval(codeValue);
4363
+ getConfig("parseDSL")(codeValue);
4299
4364
  return true;
4300
4365
  } catch (e) {
4301
4366
  design.tMagicMessage.error(e.stack);
4302
4367
  return false;
4303
4368
  }
4304
4369
  };
4305
- const saveCode = async (codeValue2) => {
4370
+ const saveCode = async (codeValue) => {
4306
4371
  if (!props.editable)
4307
4372
  return;
4308
- evalRes.value = beforeSave(codeValue2);
4373
+ evalRes.value = beforeSave(codeValue);
4309
4374
  if (evalRes.value) {
4310
4375
  await services?.codeBlockService.setCodeDslById(props.id, {
4311
4376
  name: codeName.value,
4312
- content: codeValue2,
4377
+ content: codeValue,
4313
4378
  params: tableModel.value?.params || []
4314
4379
  });
4315
4380
  design.tMagicMessage.success("代码成功保存到本地");
4316
4381
  services?.codeBlockService.removeCodeDraft(props.id);
4317
4382
  }
4318
4383
  };
4319
- const saveAndClose = async (codeValue2) => {
4320
- await saveCode(codeValue2);
4384
+ const saveAndClose = async (codeValue) => {
4385
+ await saveCode(codeValue);
4321
4386
  if (evalRes.value) {
4322
4387
  close();
4323
4388
  }
@@ -5086,6 +5151,7 @@
5086
5151
  left: "0",
5087
5152
  top: "0"
5088
5153
  });
5154
+ const contains = (el) => menu.value?.contains(el) || subMenu.value?.contains(el);
5089
5155
  const hide = () => {
5090
5156
  if (!visible.value)
5091
5157
  return;
@@ -5098,7 +5164,7 @@
5098
5164
  if (!visible.value || !target) {
5099
5165
  return;
5100
5166
  }
5101
- if (menu.value?.contains(target) || subMenu.value?.$el?.contains(target)) {
5167
+ if (contains(target)) {
5102
5168
  return;
5103
5169
  }
5104
5170
  hide();
@@ -5125,13 +5191,15 @@
5125
5191
  if (typeof item !== "object" || !menuItem.items?.length) {
5126
5192
  return;
5127
5193
  }
5128
- subMenuData.value = menuItem.items;
5129
- if (menu.value) {
5130
- subMenu.value.show({
5131
- clientX: menu.value.offsetLeft + menu.value.clientWidth,
5132
- clientY: menu.value.offsetTop
5133
- });
5134
- }
5194
+ subMenuData.value = menuItem.items || [];
5195
+ setTimeout(() => {
5196
+ if (menu.value) {
5197
+ subMenu.value?.show({
5198
+ clientX: menu.value.offsetLeft + menu.value.clientWidth,
5199
+ clientY: menu.value.offsetTop
5200
+ });
5201
+ }
5202
+ }, 0);
5135
5203
  };
5136
5204
  vue.onMounted(() => {
5137
5205
  if (props.isSubMenu)
@@ -5144,8 +5212,10 @@
5144
5212
  globalThis.removeEventListener("mousedown", hideHandler, true);
5145
5213
  });
5146
5214
  __expose({
5215
+ menu,
5147
5216
  hide,
5148
- show
5217
+ show,
5218
+ contains
5149
5219
  });
5150
5220
  return (_ctx, _cache) => {
5151
5221
  const _component_content_menu = vue.resolveComponent("content-menu", true);
@@ -5168,14 +5238,15 @@
5168
5238
  }), 128))
5169
5239
  ]),
5170
5240
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
5171
- vue.createVNode(_component_content_menu, {
5241
+ subMenuData.value.length ? (vue.openBlock(), vue.createBlock(_component_content_menu, {
5242
+ key: 0,
5172
5243
  class: "sub-menu",
5173
5244
  ref_key: "subMenu",
5174
5245
  ref: subMenu,
5175
5246
  "menu-data": subMenuData.value,
5176
5247
  "is-sub-menu": true,
5177
5248
  onHide: hide
5178
- }, null, 8, ["menu-data"])
5249
+ }, null, 8, ["menu-data"])) : vue.createCommentVNode("", true)
5179
5250
  ]))
5180
5251
  ], 4)), [
5181
5252
  [vue.vShow, visible.value]
@@ -5197,6 +5268,7 @@
5197
5268
  const services = vue.inject("services");
5198
5269
  const menu = vue.ref();
5199
5270
  const node = vue.computed(() => services?.editorService.get("node"));
5271
+ const nodes = vue.computed(() => services?.editorService.get("nodes"));
5200
5272
  const isRoot = vue.computed(() => node.value?.type === schema.NodeType.ROOT);
5201
5273
  const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
5202
5274
  const componentList = vue.computed(() => services?.componentListService.getList() || []);
@@ -5248,7 +5320,7 @@
5248
5320
  type: "button",
5249
5321
  text: "新增",
5250
5322
  icon: vue.markRaw(iconsVue.Plus),
5251
- display: () => node.value?.items,
5323
+ display: () => node.value?.items && nodes.value?.length === 1,
5252
5324
  items: getSubMenuData.value
5253
5325
  },
5254
5326
  {
@@ -5257,7 +5329,7 @@
5257
5329
  icon: vue.markRaw(iconsVue.CopyDocument),
5258
5330
  display: () => !isRoot.value,
5259
5331
  handler: () => {
5260
- node.value && services?.editorService.copy(node.value);
5332
+ node.value && services?.editorService.copy(nodes.value || []);
5261
5333
  }
5262
5334
  },
5263
5335
  {
@@ -5266,7 +5338,7 @@
5266
5338
  icon: vue.markRaw(iconsVue.Delete),
5267
5339
  display: () => !isRoot.value && !isPage.value,
5268
5340
  handler: () => {
5269
- node.value && services?.editorService.remove(node.value);
5341
+ node.value && services?.editorService.remove(nodes.value || []);
5270
5342
  }
5271
5343
  },
5272
5344
  ...props.layerContentMenu
@@ -5435,38 +5507,61 @@
5435
5507
  const windowBlurHandler = () => {
5436
5508
  isCtrlKeyDown.value = false;
5437
5509
  };
5438
- const globalKeyupHandler = () => {
5439
- if (document.activeElement !== tree.value?.$el) {
5510
+ keybindingService?.registeCommand("layer-panel-not-ctrl-keydown", (e) => {
5511
+ if (e.key !== keybindingService.ctrlKey) {
5440
5512
  isCtrlKeyDown.value = false;
5441
5513
  }
5442
- };
5443
- let keycon;
5444
- vue.onMounted(() => {
5445
- editorService?.on("remove", editorServiceRemoveHandler);
5514
+ });
5515
+ keybindingService?.registeCommand("layer-panel-ctrl-keydown", () => {
5516
+ isCtrlKeyDown.value = true;
5517
+ });
5518
+ keybindingService?.registeCommand("layer-panel-ctrl-keyup", () => {
5519
+ isCtrlKeyDown.value = false;
5520
+ });
5521
+ keybindingService?.registeCommand("layer-panel-global-keydwon", () => {
5522
+ if (!tree.value?.$el.contains(document.activeElement)) {
5523
+ isCtrlKeyDown.value = false;
5524
+ }
5525
+ });
5526
+ keybindingService?.registe([
5527
+ {
5528
+ command: "layer-panel-not-ctrl-keydown",
5529
+ when: [["layer-panel", "keydown"]]
5530
+ },
5531
+ {
5532
+ command: "layer-panel-ctrl-keydown",
5533
+ keybinding: "ctrl",
5534
+ when: [["layer-panel", "keydown"]]
5535
+ },
5536
+ {
5537
+ command: "layer-panel-ctrl-keyup",
5538
+ keybinding: "ctrl",
5539
+ when: [["layer-panel", "keyup"]]
5540
+ },
5541
+ {
5542
+ command: "layer-panel-global-keydwon",
5543
+ keybinding: "ctrl",
5544
+ when: [["global", "keydown"]]
5545
+ }
5546
+ ]);
5547
+ vue.watch(tree, () => {
5446
5548
  if (tree.value?.$el) {
5447
- keybindingService?.on("keyup", globalKeyupHandler);
5448
- keycon = new KeyController(tree.value.$el);
5449
- const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
5450
- const ctrl = isMac ? "meta" : "ctrl";
5451
- keycon.keydown((e) => {
5452
- if (e.key !== ctrl) {
5453
- isCtrlKeyDown.value = false;
5454
- }
5455
- }).keydown(ctrl, () => {
5456
- isCtrlKeyDown.value = true;
5457
- }).keyup(ctrl, () => {
5458
- isCtrlKeyDown.value = false;
5459
- });
5549
+ keybindingService?.registeEl("layer-panel", tree.value.$el);
5460
5550
  tree.value.$el.addEventListener("blur", windowBlurHandler);
5551
+ } else {
5552
+ keybindingService?.unregisteEl("layer-panel");
5461
5553
  }
5554
+ });
5555
+ vue.onMounted(() => {
5556
+ editorService?.on("remove", editorServiceRemoveHandler);
5462
5557
  globalThis.addEventListener("blur", windowBlurHandler);
5463
5558
  });
5559
+ vue.onBeforeUnmount(() => {
5560
+ tree.value?.$el.removeEventListener("blur", windowBlurHandler);
5561
+ });
5464
5562
  vue.onUnmounted(() => {
5465
- keycon.destroy();
5466
5563
  editorService?.off("remove", editorServiceRemoveHandler);
5467
- keybindingService?.off("keyup", globalKeyupHandler);
5468
5564
  globalThis.removeEventListener("blur", windowBlurHandler);
5469
- tree.value?.$el.removeEventListener("blur", windowBlurHandler);
5470
5565
  });
5471
5566
  const highlightHandler = lodashEs.throttle((data) => {
5472
5567
  highlight(data);
@@ -5496,7 +5591,9 @@
5496
5591
  };
5497
5592
  const contextmenu = async (event, data) => {
5498
5593
  event.preventDefault();
5499
- await select(data);
5594
+ if (nodes.value.length < 2) {
5595
+ await select(data);
5596
+ }
5500
5597
  menu.value?.show(event);
5501
5598
  };
5502
5599
  return (_ctx, _cache) => {
@@ -6510,6 +6607,9 @@
6510
6607
  if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value)
6511
6608
  return;
6512
6609
  stage = useStage(stageOptions);
6610
+ stage.on("select", () => {
6611
+ stageWrap.value?.container?.focus();
6612
+ });
6513
6613
  services?.editorService.set("stage", vue.markRaw(stage));
6514
6614
  stage?.mount(stageContainer.value);
6515
6615
  if (!node.value?.id)
@@ -6550,21 +6650,25 @@
6550
6650
  }
6551
6651
  });
6552
6652
  vue.onMounted(() => {
6553
- stageWrap.value?.container && resizeObserver.observe(stageWrap.value.container);
6653
+ if (stageWrap.value?.container) {
6654
+ resizeObserver.observe(stageWrap.value.container);
6655
+ services?.keybindingService.registeEl("stage", stageWrap.value.container);
6656
+ }
6554
6657
  });
6555
6658
  vue.onUnmounted(() => {
6556
6659
  stage?.destroy();
6557
6660
  resizeObserver.disconnect();
6558
6661
  services?.editorService.set("stage", null);
6662
+ services?.keybindingService.unregisteEl("stage");
6559
6663
  });
6560
- const contextmenuHandler = (e2) => {
6561
- e2.preventDefault();
6562
- menu.value?.show(e2);
6664
+ const contextmenuHandler = (e) => {
6665
+ e.preventDefault();
6666
+ menu.value?.show(e);
6563
6667
  };
6564
- const dragoverHandler = (e2) => {
6565
- e2.preventDefault();
6566
- if (e2.dataTransfer) {
6567
- e2.dataTransfer.dropEffect = "move";
6668
+ const dragoverHandler = (e) => {
6669
+ e.preventDefault();
6670
+ if (e.dataTransfer) {
6671
+ e.dataTransfer.dropEffect = "move";
6568
6672
  }
6569
6673
  };
6570
6674
  const dropHandler = async (e) => {
@@ -6576,7 +6680,8 @@
6576
6680
  parent = services?.editorService.getNodeById(parentEl.id, false);
6577
6681
  }
6578
6682
  if (e.dataTransfer && parent && stageContainer.value && stage) {
6579
- const config = eval(`(${e.dataTransfer.getData("data")})`);
6683
+ const parseDSL = getConfig("parseDSL");
6684
+ const config = parseDSL(`(${e.dataTransfer.getData("data")})`);
6580
6685
  const layout = await services?.editorService.getLayout(parent);
6581
6686
  const containerRect = stageContainer.value.getBoundingClientRect();
6582
6687
  const { scrollTop, scrollLeft } = stage.mask;
@@ -6609,6 +6714,7 @@
6609
6714
  class: "m-editor-stage",
6610
6715
  ref_key: "stageWrap",
6611
6716
  ref: stageWrap,
6717
+ tabindex: "-1",
6612
6718
  width: stageRect.value?.width,
6613
6719
  height: stageRect.value?.height,
6614
6720
  "wrap-width": stageContainerRect.value?.width,
@@ -6644,10 +6750,7 @@
6644
6750
  }
6645
6751
  });
6646
6752
 
6647
- const _hoisted_1 = {
6648
- class: "m-editor-workspace",
6649
- tabindex: "-1"
6650
- };
6753
+ const _hoisted_1 = { class: "m-editor-workspace" };
6651
6754
  const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
6652
6755
  ...{
6653
6756
  name: "MEditorWorkspace"
@@ -6707,8 +6810,8 @@
6707
6810
  * @param {CodeBlockDSL} codeDsl 代码DSL
6708
6811
  * @returns {void}
6709
6812
  */
6710
- async setCodeDsl(codeDsl2) {
6711
- this.state.codeDsl = codeDsl2;
6813
+ async setCodeDsl(codeDsl) {
6814
+ this.state.codeDsl = codeDsl;
6712
6815
  this.emit("code-dsl-change", this.state.codeDsl);
6713
6816
  }
6714
6817
  /**
@@ -6725,13 +6828,13 @@
6725
6828
  * @param {Id} id 代码块id
6726
6829
  * @returns {CodeBlockContent | null}
6727
6830
  */
6728
- getCodeContentById(id2) {
6729
- if (!id2)
6831
+ getCodeContentById(id) {
6832
+ if (!id)
6730
6833
  return null;
6731
6834
  const totalCodeDsl = this.getCodeDsl();
6732
6835
  if (!totalCodeDsl)
6733
6836
  return null;
6734
- return totalCodeDsl[id2] ?? null;
6837
+ return totalCodeDsl[id] ?? null;
6735
6838
  }
6736
6839
  /**
6737
6840
  * 设置代码块ID和代码内容到源dsl
@@ -6746,7 +6849,8 @@
6746
6849
  }
6747
6850
  const codeConfigProcessed = codeConfig;
6748
6851
  if (codeConfig.content) {
6749
- codeConfigProcessed.content = eval(codeConfig.content);
6852
+ const parseDSL = getConfig("parseDSL");
6853
+ codeConfigProcessed.content = parseDSL(codeConfig.content);
6750
6854
  }
6751
6855
  const existContent = codeDsl[id] || {};
6752
6856
  codeDsl[id] = {
@@ -6761,8 +6865,8 @@
6761
6865
  * @returns {CodeBlockDSL}
6762
6866
  */
6763
6867
  getCodeDslByIds(ids) {
6764
- const codeDsl2 = this.getCodeDsl();
6765
- return lodashEs.pick(codeDsl2, ids);
6868
+ const codeDsl = this.getCodeDsl();
6869
+ return lodashEs.pick(codeDsl, ids);
6766
6870
  }
6767
6871
  /**
6768
6872
  * 设置代码编辑面板展示状态
@@ -6785,10 +6889,10 @@
6785
6889
  * @param {Id} id 代码块id
6786
6890
  * @returns {void}
6787
6891
  */
6788
- setCodeEditorContent(status, id2) {
6789
- if (!id2)
6892
+ setCodeEditorContent(status, id) {
6893
+ if (!id)
6790
6894
  return;
6791
- this.setId(id2);
6895
+ this.setId(id);
6792
6896
  this.state.isShowCodeEditor = status;
6793
6897
  }
6794
6898
  /**
@@ -6818,10 +6922,10 @@
6818
6922
  * @param {Id} id 代码块id
6819
6923
  * @returns {void}
6820
6924
  */
6821
- setId(id2) {
6822
- if (!id2)
6925
+ setId(id) {
6926
+ if (!id)
6823
6927
  return;
6824
- this.state.id = id2;
6928
+ this.state.id = id;
6825
6929
  }
6826
6930
  /**
6827
6931
  * 获取当前选中的代码块ID
@@ -6886,9 +6990,9 @@
6886
6990
  const currentDsl = await this.getCodeDsl();
6887
6991
  if (!currentDsl)
6888
6992
  return;
6889
- codeIds.forEach((id2) => {
6890
- delete currentDsl[id2];
6891
- this.emit("remove", id2);
6993
+ codeIds.forEach((id) => {
6994
+ delete currentDsl[id];
6995
+ this.emit("remove", id);
6892
6996
  });
6893
6997
  }
6894
6998
  /**
@@ -7403,176 +7507,274 @@
7403
7507
  const eventsService = new Events();
7404
7508
 
7405
7509
  class Keybinding extends BaseService {
7406
- keycon = new KeyController();
7407
7510
  ctrlKey = /mac os x/.test(navigator.userAgent.toLowerCase()) ? "meta" : "ctrl";
7408
- constructor() {
7409
- super();
7410
- this.keycon.keyup((e) => {
7411
- this.emit("keyup", e.inputEvent);
7412
- }).keyup("delete", (e) => {
7413
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7414
- return;
7415
- }
7416
- e.inputEvent.preventDefault();
7417
- this.removeNode();
7418
- }).keyup("backspace", (e) => {
7419
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7420
- return;
7421
- }
7422
- e.inputEvent.preventDefault();
7423
- this.removeNode();
7424
- }).keydown([this.ctrlKey, "c"], (e) => {
7425
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7426
- return;
7427
- }
7428
- e.inputEvent.preventDefault();
7511
+ controllers = /* @__PURE__ */ new Map();
7512
+ bindingList = [];
7513
+ commands = {
7514
+ [KeyBindingCommand.DELETE_NODE]: () => {
7429
7515
  const nodes = editorService.get("nodes");
7430
- nodes && editorService.copy(nodes);
7431
- }).keydown([this.ctrlKey, "v"], (e) => {
7432
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7516
+ if (!nodes || utils.isPage(nodes[0]))
7433
7517
  return;
7434
- }
7435
- e.inputEvent.preventDefault();
7518
+ editorService.remove(nodes);
7519
+ },
7520
+ [KeyBindingCommand.COPY_NODE]: () => {
7436
7521
  const nodes = editorService.get("nodes");
7437
- nodes && editorService.paste({ offsetX: 10, offsetY: 10 });
7438
- }).keydown([this.ctrlKey, "x"], (e) => {
7439
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7440
- return;
7441
- }
7442
- e.inputEvent.preventDefault();
7443
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7444
- return;
7445
- }
7522
+ nodes && editorService.copy(nodes);
7523
+ },
7524
+ [KeyBindingCommand.CUT_NODE]: () => {
7446
7525
  const nodes = editorService.get("nodes");
7447
7526
  if (!nodes || utils.isPage(nodes[0]))
7448
7527
  return;
7449
7528
  editorService.copy(nodes);
7450
7529
  editorService.remove(nodes);
7451
- }).keydown([this.ctrlKey, "z"], (e) => {
7452
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7453
- return;
7454
- }
7455
- e.inputEvent.preventDefault();
7530
+ },
7531
+ [KeyBindingCommand.PASTE_NODE]: () => {
7532
+ const nodes = editorService.get("nodes");
7533
+ nodes && editorService.paste({ offsetX: 10, offsetY: 10 });
7534
+ },
7535
+ [KeyBindingCommand.UNDO]: () => {
7456
7536
  editorService.undo();
7457
- }).keydown([this.ctrlKey, "shift", "z"], (e) => {
7458
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7459
- return;
7460
- }
7461
- e.inputEvent.preventDefault();
7537
+ },
7538
+ [KeyBindingCommand.REDO]: () => {
7462
7539
  editorService.redo();
7463
- }).keydown("up", (e) => {
7464
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7465
- return;
7466
- }
7467
- e.inputEvent.preventDefault();
7540
+ },
7541
+ [KeyBindingCommand.ZOOM_IN]: () => {
7542
+ uiService.zoom(0.1);
7543
+ },
7544
+ [KeyBindingCommand.ZOOM_OUT]: () => {
7545
+ uiService.zoom(-0.1);
7546
+ },
7547
+ [KeyBindingCommand.ZOOM_RESET]: () => {
7548
+ uiService.set("zoom", 1);
7549
+ },
7550
+ [KeyBindingCommand.ZOOM_FIT]: async () => {
7551
+ uiService.set("zoom", await uiService.calcZoom());
7552
+ },
7553
+ [KeyBindingCommand.MOVE_UP_1]: () => {
7468
7554
  editorService.move(0, -1);
7469
- }).keydown("down", (e) => {
7470
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7471
- return;
7472
- }
7473
- e.inputEvent.preventDefault();
7555
+ },
7556
+ [KeyBindingCommand.MOVE_DOWN_1]: () => {
7474
7557
  editorService.move(0, 1);
7475
- }).keydown("left", (e) => {
7476
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7477
- return;
7478
- }
7479
- e.inputEvent.preventDefault();
7558
+ },
7559
+ [KeyBindingCommand.MOVE_LEFT_1]: () => {
7480
7560
  editorService.move(-1, 0);
7481
- }).keydown("right", (e) => {
7482
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7483
- return;
7484
- }
7485
- e.inputEvent.preventDefault();
7561
+ },
7562
+ [KeyBindingCommand.MOVE_RIGHT_1]: () => {
7486
7563
  editorService.move(1, 0);
7487
- }).keydown([this.ctrlKey, "up"], (e) => {
7488
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7489
- return;
7490
- }
7491
- e.inputEvent.preventDefault();
7564
+ },
7565
+ [KeyBindingCommand.MOVE_UP_10]: () => {
7492
7566
  editorService.move(0, -10);
7493
- }).keydown([this.ctrlKey, "down"], (e) => {
7494
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7495
- return;
7496
- }
7497
- e.inputEvent.preventDefault();
7567
+ },
7568
+ [KeyBindingCommand.MOVE_DOWN_10]: () => {
7498
7569
  editorService.move(0, 10);
7499
- }).keydown([this.ctrlKey, "left"], (e) => {
7500
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7501
- return;
7502
- }
7503
- e.inputEvent.preventDefault();
7570
+ },
7571
+ [KeyBindingCommand.MOVE_LEFT_10]: () => {
7504
7572
  editorService.move(-10, 0);
7505
- }).keydown([this.ctrlKey, "right"], (e) => {
7506
- e.inputEvent.preventDefault();
7573
+ },
7574
+ [KeyBindingCommand.MOVE_RIGHT_10]: () => {
7507
7575
  editorService.move(10, 0);
7508
- }).keydown("tab", (e) => {
7509
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7510
- return;
7511
- }
7512
- e.inputEvent.preventDefault();
7576
+ },
7577
+ [KeyBindingCommand.SWITCH_NODE]: () => {
7513
7578
  editorService.selectNextNode();
7514
- }).keydown([this.ctrlKey, "tab"], (e) => {
7515
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7516
- return;
7517
- }
7518
- e.inputEvent.preventDefault();
7519
- editorService.selectNextPage();
7520
- }).keydown([this.ctrlKey, "="], (e) => {
7521
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7522
- return;
7523
- }
7524
- e.inputEvent.preventDefault();
7525
- uiService.zoom(0.1);
7526
- }).keydown([this.ctrlKey, "numpadplus"], (e) => {
7527
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7528
- return;
7529
- }
7530
- e.inputEvent.preventDefault();
7531
- uiService.zoom(0.1);
7532
- }).keydown([this.ctrlKey, "-"], (e) => {
7533
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7534
- return;
7535
- }
7536
- e.inputEvent.preventDefault();
7537
- uiService.zoom(-0.1);
7538
- }).keydown([this.ctrlKey, "numpad-"], (e) => {
7539
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7540
- return;
7541
- }
7542
- e.inputEvent.preventDefault();
7543
- uiService.zoom(-0.1);
7544
- }).keydown([this.ctrlKey, "0"], async (e) => {
7545
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7546
- return;
7547
- }
7548
- e.inputEvent.preventDefault();
7549
- uiService.set("zoom", await uiService.calcZoom());
7550
- }).keydown([this.ctrlKey, "1"], (e) => {
7551
- if (this.isDisabledKeyEvent(e.inputEvent.target)) {
7552
- return;
7579
+ }
7580
+ };
7581
+ registeCommand(command, handler) {
7582
+ this.commands[command] = handler;
7583
+ }
7584
+ unregisteCommand(command) {
7585
+ delete this.commands[command];
7586
+ }
7587
+ registeEl(name, el) {
7588
+ if (name !== "global" && !el) {
7589
+ throw new Error("只有name为global可以不传el");
7590
+ }
7591
+ const keycon = new KeyController(el);
7592
+ this.controllers.set(name, keycon);
7593
+ this.bind(name);
7594
+ }
7595
+ unregisteEl(name) {
7596
+ this.controllers.get(name)?.destroy();
7597
+ this.controllers.delete(name);
7598
+ this.bindingList.forEach((item) => {
7599
+ item.binded = false;
7600
+ });
7601
+ }
7602
+ registe(maps) {
7603
+ for (const keybindingItem of maps) {
7604
+ const { command, keybinding, when } = keybindingItem;
7605
+ for (const [type = "", eventType = "keydown"] of when) {
7606
+ const cacheItem = { type, command, keybinding, eventType, binded: false };
7607
+ this.bindingList.push(cacheItem);
7553
7608
  }
7554
- e.inputEvent.preventDefault();
7555
- uiService.set("zoom", 1);
7609
+ }
7610
+ this.bind();
7611
+ }
7612
+ reset() {
7613
+ this.controllers.forEach((keycon) => {
7614
+ keycon.destroy();
7556
7615
  });
7616
+ this.controllers.clear();
7617
+ this.bindingList = [];
7557
7618
  }
7558
7619
  destroy() {
7559
- this.keycon.destroy();
7620
+ this.reset();
7560
7621
  }
7561
- isDisabledKeyEvent(node) {
7562
- const el = node;
7563
- if (!el)
7564
- return false;
7565
- return el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable;
7622
+ bind(name) {
7623
+ for (const item of this.bindingList) {
7624
+ const { type, eventType, command, keybinding, binded } = item;
7625
+ if (name && name !== type) {
7626
+ continue;
7627
+ }
7628
+ if (binded) {
7629
+ continue;
7630
+ }
7631
+ const keycon = this.controllers.get(type);
7632
+ if (!keycon) {
7633
+ continue;
7634
+ }
7635
+ const handler = (e) => {
7636
+ e.inputEvent.preventDefault();
7637
+ this.commands[command]?.(e.inputEvent);
7638
+ };
7639
+ this.getKeyconKeys(keybinding).forEach((keys) => {
7640
+ if (keys[0]) {
7641
+ keycon[eventType](keys, handler);
7642
+ } else {
7643
+ keycon[eventType](handler);
7644
+ }
7645
+ });
7646
+ item.binded = true;
7647
+ }
7566
7648
  }
7567
- removeNode() {
7568
- const nodes = editorService.get("nodes");
7569
- if (!nodes || utils.isPage(nodes[0]))
7570
- return;
7571
- editorService.remove(nodes);
7649
+ getKeyconKeys(keybinding = "") {
7650
+ const splitKey = (key) => key.split("+").map((k) => k === "ctrl" ? this.ctrlKey : k);
7651
+ if (Array.isArray(keybinding)) {
7652
+ return keybinding.map((key) => splitKey(key));
7653
+ }
7654
+ return [splitKey(keybinding)];
7572
7655
  }
7573
7656
  }
7574
7657
  const keybindingService = new Keybinding();
7575
7658
 
7659
+ const keybindingConfig = [
7660
+ {
7661
+ command: KeyBindingCommand.DELETE_NODE,
7662
+ keybinding: ["delete", "backspace"],
7663
+ when: [
7664
+ ["stage", "keyup"],
7665
+ ["layer-panel", "keydown"]
7666
+ ]
7667
+ },
7668
+ {
7669
+ command: KeyBindingCommand.COPY_NODE,
7670
+ keybinding: "ctrl+c",
7671
+ when: [
7672
+ ["stage", "keydown"],
7673
+ ["layer-panel", "keydown"]
7674
+ ]
7675
+ },
7676
+ {
7677
+ command: KeyBindingCommand.PASTE_NODE,
7678
+ keybinding: "ctrl+v",
7679
+ when: [
7680
+ ["stage", "keydown"],
7681
+ ["layer-panel", "keydown"]
7682
+ ]
7683
+ },
7684
+ {
7685
+ command: KeyBindingCommand.CUT_NODE,
7686
+ keybinding: "ctrl+x",
7687
+ when: [
7688
+ ["stage", "keydown"],
7689
+ ["layer-panel", "keydown"]
7690
+ ]
7691
+ },
7692
+ {
7693
+ command: KeyBindingCommand.UNDO,
7694
+ keybinding: "ctrl+z",
7695
+ when: [
7696
+ ["stage", "keydown"],
7697
+ ["layer-panel", "keydown"]
7698
+ ]
7699
+ },
7700
+ {
7701
+ command: KeyBindingCommand.REDO,
7702
+ keybinding: "ctrl+shift+z",
7703
+ when: [
7704
+ ["stage", "keydown"],
7705
+ ["layer-panel", "keydown"]
7706
+ ]
7707
+ },
7708
+ {
7709
+ command: KeyBindingCommand.MOVE_UP_1,
7710
+ keybinding: "up",
7711
+ when: [["stage", "keydown"]]
7712
+ },
7713
+ {
7714
+ command: KeyBindingCommand.MOVE_DOWN_1,
7715
+ keybinding: "down",
7716
+ when: [["stage", "keydown"]]
7717
+ },
7718
+ {
7719
+ command: KeyBindingCommand.MOVE_LEFT_1,
7720
+ keybinding: "left",
7721
+ when: [["stage", "keydown"]]
7722
+ },
7723
+ {
7724
+ command: KeyBindingCommand.MOVE_RIGHT_1,
7725
+ keybinding: "right",
7726
+ when: [["stage", "keydown"]]
7727
+ },
7728
+ {
7729
+ command: KeyBindingCommand.MOVE_UP_10,
7730
+ keybinding: "ctrl+up",
7731
+ when: [["stage", "keydown"]]
7732
+ },
7733
+ {
7734
+ command: KeyBindingCommand.MOVE_DOWN_10,
7735
+ keybinding: "ctrl+down",
7736
+ when: [["stage", "keydown"]]
7737
+ },
7738
+ {
7739
+ command: KeyBindingCommand.MOVE_LEFT_10,
7740
+ keybinding: "ctrl+left",
7741
+ when: [["stage", "keydown"]]
7742
+ },
7743
+ {
7744
+ command: KeyBindingCommand.MOVE_RIGHT_10,
7745
+ keybinding: "ctrl+right",
7746
+ when: [["stage", "keydown"]]
7747
+ },
7748
+ {
7749
+ command: KeyBindingCommand.SWITCH_NODE,
7750
+ keybinding: "tab",
7751
+ when: [
7752
+ ["stage", "keydown"],
7753
+ ["layer-panel", "keydown"]
7754
+ ]
7755
+ },
7756
+ {
7757
+ command: KeyBindingCommand.ZOOM_IN,
7758
+ keybinding: ["ctrl+=", "ctrl+numpadplus"],
7759
+ when: [["stage", "keydown"]]
7760
+ },
7761
+ {
7762
+ command: KeyBindingCommand.ZOOM_OUT,
7763
+ keybinding: ["ctrl+-", "ctrl+numpad-"],
7764
+ when: [["stage", "keydown"]]
7765
+ },
7766
+ {
7767
+ command: KeyBindingCommand.ZOOM_FIT,
7768
+ keybinding: "ctrl+0",
7769
+ when: [["stage", "keydown"]]
7770
+ },
7771
+ {
7772
+ command: KeyBindingCommand.ZOOM_RESET,
7773
+ keybinding: "ctrl+1",
7774
+ when: [["stage", "keydown"]]
7775
+ }
7776
+ ];
7777
+
7576
7778
  const editorProps = {
7577
7779
  /** 页面初始值 */
7578
7780
  modelValue: {
@@ -7700,7 +7902,8 @@
7700
7902
  propsService,
7701
7903
  eventsService,
7702
7904
  uiService,
7703
- codeBlockService
7905
+ codeBlockService,
7906
+ keybindingService
7704
7907
  }) => {
7705
7908
  vue.watch(
7706
7909
  () => props.modelValue,
@@ -7769,6 +7972,7 @@
7769
7972
  uiService.resetState();
7770
7973
  componentListService.resetState();
7771
7974
  codeBlockService.resetState();
7975
+ keybindingService.reset();
7772
7976
  });
7773
7977
  };
7774
7978
  const initServiceEvents = (props, emit, { editorService, codeBlockService, dataSourceService, depService }) => {
@@ -7965,6 +8169,8 @@
7965
8169
  };
7966
8170
  initServiceEvents(props, emit, services);
7967
8171
  initServiceState(props, services);
8172
+ keybindingService.registe(keybindingConfig);
8173
+ keybindingService.registeEl("global");
7968
8174
  vue.provide("services", services);
7969
8175
  vue.provide("codeOptions", props.codeOptions);
7970
8176
  vue.provide(
@@ -8101,7 +8307,8 @@
8101
8307
  const index$1 = '';
8102
8308
 
8103
8309
  const defaultInstallOpt = {
8104
- // @todo, 自定义图片上传方法等编辑器依赖的外部选项
8310
+ // eslint-disable-next-line no-eval
8311
+ parseDSL: (dsl) => eval(dsl)
8105
8312
  };
8106
8313
  const index = {
8107
8314
  install: (app, opt) => {
@@ -8137,6 +8344,7 @@
8137
8344
  exports.Fixed2Other = Fixed2Other;
8138
8345
  exports.H_GUIDE_LINE_STORAGE_KEY = H_GUIDE_LINE_STORAGE_KEY;
8139
8346
  exports.Icon = _sfc_main$B;
8347
+ exports.KeyBindingCommand = KeyBindingCommand;
8140
8348
  exports.KeyValue = _sfc_main$w;
8141
8349
  exports.Keys = Keys;
8142
8350
  exports.LayerOffset = LayerOffset;
@@ -8144,6 +8352,7 @@
8144
8352
  exports.Layout = Layout;
8145
8353
  exports.LayoutContainer = _sfc_main$s;
8146
8354
  exports.PropsPanel = _sfc_main$n;
8355
+ exports.Resizer = _sfc_main$t;
8147
8356
  exports.SplitView = _sfc_main$s;
8148
8357
  exports.TMagicCodeEditor = _sfc_main$u;
8149
8358
  exports.TMagicEditor = Editor;