@tmagic/editor 1.0.0-beta.8 → 1.0.0-rc.2

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 (121) hide show
  1. package/README.md +1 -0
  2. package/coverage/clover.xml +1556 -0
  3. package/coverage/coverage-final.json +36 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +87 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +206 -0
  8. package/coverage/lcov-report/prettify.css +1 -0
  9. package/coverage/lcov-report/prettify.js +2 -0
  10. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  11. package/coverage/lcov-report/sorter.js +196 -0
  12. package/coverage/lcov-report/src/Editor.vue.html +802 -0
  13. package/coverage/lcov-report/src/components/ContentMenu.vue.html +406 -0
  14. package/coverage/lcov-report/src/components/Icon.vue.html +172 -0
  15. package/coverage/lcov-report/src/components/ScrollViewer.vue.html +283 -0
  16. package/coverage/lcov-report/src/components/ToolButton.vue.html +772 -0
  17. package/coverage/lcov-report/src/components/index.html +161 -0
  18. package/coverage/lcov-report/src/index.html +131 -0
  19. package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +214 -0
  20. package/coverage/lcov-report/src/layouts/Framework.vue.html +343 -0
  21. package/coverage/lcov-report/src/layouts/NavMenu.vue.html +208 -0
  22. package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +319 -0
  23. package/coverage/lcov-report/src/layouts/Resizer.vue.html +268 -0
  24. package/coverage/lcov-report/src/layouts/index.html +176 -0
  25. package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +358 -0
  26. package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +421 -0
  27. package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +775 -0
  28. package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +226 -0
  29. package/coverage/lcov-report/src/layouts/sidebar/TabPane.vue.html +289 -0
  30. package/coverage/lcov-report/src/layouts/sidebar/index.html +176 -0
  31. package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +718 -0
  32. package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +760 -0
  33. package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +532 -0
  34. package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +598 -0
  35. package/coverage/lcov-report/src/layouts/workspace/index.html +161 -0
  36. package/coverage/lcov-report/src/services/BaseService.ts.html +643 -0
  37. package/coverage/lcov-report/src/services/componentList.ts.html +229 -0
  38. package/coverage/lcov-report/src/services/editor.ts.html +2077 -0
  39. package/coverage/lcov-report/src/services/events.ts.html +331 -0
  40. package/coverage/lcov-report/src/services/history.ts.html +478 -0
  41. package/coverage/lcov-report/src/services/index.html +206 -0
  42. package/coverage/lcov-report/src/services/props.ts.html +415 -0
  43. package/coverage/lcov-report/src/services/ui.ts.html +580 -0
  44. package/coverage/lcov-report/src/type.ts.html +850 -0
  45. package/coverage/lcov-report/src/utils/compose.ts.html +184 -0
  46. package/coverage/lcov-report/src/utils/config.ts.html +172 -0
  47. package/coverage/lcov-report/src/utils/editor.ts.html +838 -0
  48. package/coverage/lcov-report/src/utils/index.html +221 -0
  49. package/coverage/lcov-report/src/utils/index.ts.html +151 -0
  50. package/coverage/lcov-report/src/utils/logger.ts.html +226 -0
  51. package/coverage/lcov-report/src/utils/props.ts.html +796 -0
  52. package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +733 -0
  53. package/coverage/lcov-report/src/utils/undo-redo.ts.html +313 -0
  54. package/coverage/lcov.info +3747 -0
  55. package/dist/style.css +91 -45
  56. package/dist/tmagic-editor.es.js +1462 -2003
  57. package/dist/tmagic-editor.es.js.map +1 -1
  58. package/dist/tmagic-editor.umd.js +1461 -2003
  59. package/dist/tmagic-editor.umd.js.map +1 -1
  60. package/dist/types/src/Editor.vue.d.ts +10 -1
  61. package/dist/types/src/components/ToolButton.vue.d.ts +12 -1
  62. package/dist/types/src/fields/UISelect.vue.d.ts +4 -1
  63. package/dist/types/src/index.d.ts +1 -0
  64. package/dist/types/src/layouts/CodeEditor.vue.d.ts +13 -4
  65. package/dist/types/src/layouts/Framework.vue.d.ts +15 -3
  66. package/dist/types/src/layouts/PropsPanel.vue.d.ts +2 -1
  67. package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +2 -1
  68. package/dist/types/src/layouts/sidebar/Sidebar.vue.d.ts +2 -3
  69. package/dist/types/src/layouts/sidebar/TabPane.vue.d.ts +14 -0
  70. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +10 -3
  71. package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +4 -6
  72. package/dist/types/src/services/BaseService.d.ts +4 -1
  73. package/dist/types/src/services/editor.d.ts +16 -6
  74. package/dist/types/src/services/history.d.ts +1 -0
  75. package/dist/types/src/services/props.d.ts +2 -2
  76. package/dist/types/src/services/ui.d.ts +2 -0
  77. package/dist/types/src/type.d.ts +16 -9
  78. package/dist/types/src/utils/editor.d.ts +5 -4
  79. package/dist/types/src/utils/polyfills.d.ts +0 -0
  80. package/package.json +44 -12
  81. package/src/Editor.vue +6 -1
  82. package/src/components/ContentMenu.vue +107 -0
  83. package/src/components/ScrollViewer.vue +1 -1
  84. package/src/components/ToolButton.vue +72 -31
  85. package/src/fields/UISelect.vue +14 -6
  86. package/src/index.ts +2 -0
  87. package/src/layouts/AddPageBox.vue +3 -1
  88. package/src/layouts/CodeEditor.vue +20 -13
  89. package/src/layouts/Framework.vue +20 -7
  90. package/src/layouts/PropsPanel.vue +5 -4
  91. package/src/layouts/sidebar/ComponentListPanel.vue +25 -3
  92. package/src/layouts/sidebar/LayerMenu.vue +91 -96
  93. package/src/layouts/sidebar/LayerPanel.vue +80 -59
  94. package/src/layouts/sidebar/Sidebar.vue +13 -52
  95. package/src/layouts/sidebar/TabPane.vue +68 -0
  96. package/src/layouts/workspace/PageBar.vue +145 -17
  97. package/src/layouts/workspace/Stage.vue +56 -64
  98. package/src/layouts/workspace/ViewerMenu.vue +107 -68
  99. package/src/layouts/workspace/Workspace.vue +110 -18
  100. package/src/services/BaseService.ts +70 -22
  101. package/src/services/editor.ts +197 -64
  102. package/src/services/history.ts +7 -0
  103. package/src/services/props.ts +3 -3
  104. package/src/services/ui.ts +35 -5
  105. package/src/theme/common/var.scss +3 -2
  106. package/src/theme/component-list-panel.scss +2 -0
  107. package/src/theme/content-menu.scss +33 -26
  108. package/src/theme/layer-panel.scss +10 -0
  109. package/src/theme/nav-menu.scss +6 -2
  110. package/src/theme/page-bar.scss +42 -2
  111. package/src/theme/props-panel.scss +19 -17
  112. package/src/type.ts +17 -9
  113. package/src/utils/editor.ts +35 -9
  114. package/src/utils/polyfills.ts +8 -0
  115. package/src/utils/props.ts +20 -1
  116. package/dist/types/src/layouts/sidebar/LayerMenu.vue.d.ts +0 -31
  117. package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +0 -973
  118. package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -192
  119. package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
  120. package/tsconfig.json +0 -9
  121. package/vite.config.ts +0 -30
@@ -1,14 +1,11 @@
1
1
  <template>
2
- <div class="m-editor-workspace">
2
+ <div class="m-editor-workspace" tabindex="1" ref="workspace">
3
3
  <magic-stage
4
4
  :key="page?.id"
5
5
  :runtime-url="runtimeUrl"
6
6
  :render="render"
7
7
  :moveable-options="moveableOptions"
8
8
  :can-select="canSelect"
9
- @select="selectHandler"
10
- @update="updateNodeHandler"
11
- @sort="sortNodeHandler"
12
9
  ></magic-stage>
13
10
 
14
11
  <slot name="workspace-content"></slot>
@@ -21,11 +18,13 @@
21
18
  </template>
22
19
 
23
20
  <script lang="ts">
24
- import { computed, defineComponent, inject, PropType } from 'vue';
21
+ import { computed, defineComponent, inject, onMounted, onUnmounted, PropType, ref } from 'vue';
22
+ import KeyController from 'keycon';
25
23
 
26
- import type { MComponent, MContainer, MPage } from '@tmagic/schema';
27
- import type { MoveableOptions, SortEventData } from '@tmagic/stage';
24
+ import type { MNode, MPage } from '@tmagic/schema';
25
+ import type { MoveableOptions } from '@tmagic/stage';
28
26
  import StageCore from '@tmagic/stage';
27
+ import { isPage } from '@tmagic/utils';
29
28
 
30
29
  import type { Services } from '@editor/type';
31
30
 
@@ -58,21 +57,114 @@ export default defineComponent({
58
57
 
59
58
  setup() {
60
59
  const services = inject<Services>('services');
60
+ const workspace = ref<HTMLDivElement>();
61
+ const node = computed(() => services?.editorService.get<MNode>('node'));
62
+ let keycon: KeyController;
61
63
 
62
- return {
63
- page: computed(() => services?.editorService.get<MPage>('page')),
64
+ const mouseenterHandler = () => {
65
+ workspace.value?.focus();
66
+ };
64
67
 
65
- selectHandler(el: HTMLElement) {
66
- services?.editorService.select(el.id);
67
- },
68
+ const mouseleaveHandler = () => {
69
+ workspace.value?.blur();
70
+ };
68
71
 
69
- updateNodeHandler(node: MComponent | MContainer | MPage) {
70
- services?.editorService.update(node);
71
- },
72
+ onMounted(() => {
73
+ workspace.value?.addEventListener('mouseenter', mouseenterHandler);
74
+ workspace.value?.addEventListener('mouseleave', mouseleaveHandler);
75
+
76
+ keycon = new KeyController(workspace.value);
77
+
78
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
79
+
80
+ const ctrl = isMac ? 'meta' : 'ctrl';
81
+
82
+ keycon
83
+ .keydown((e) => {
84
+ console.log(e);
85
+ e.inputEvent.preventDefault();
86
+ })
87
+ .keyup('delete', (e) => {
88
+ e.inputEvent.preventDefault();
89
+ if (!node.value || isPage(node.value)) return;
90
+ services?.editorService.remove(node.value);
91
+ })
92
+ .keyup('backspace', (e) => {
93
+ e.inputEvent.preventDefault();
94
+ if (!node.value || isPage(node.value)) return;
95
+ services?.editorService.remove(node.value);
96
+ })
97
+ .keydown([ctrl, 'c'], () => {
98
+ node.value && services?.editorService.copy(node.value);
99
+ })
100
+ .keydown([ctrl, 'v'], () => {
101
+ node.value && services?.editorService.paste();
102
+ })
103
+ .keydown([ctrl, 'x'], () => {
104
+ if (!node.value || isPage(node.value)) return;
105
+ services?.editorService.copy(node.value);
106
+ services?.editorService.remove(node.value);
107
+ })
108
+ .keydown([ctrl, 'z'], () => {
109
+ services?.editorService.undo();
110
+ })
111
+ .keydown([ctrl, 'shift', 'z'], () => {
112
+ services?.editorService.redo();
113
+ })
114
+ .keydown('up', () => {
115
+ services?.editorService.move(0, -1);
116
+ })
117
+ .keydown('down', () => {
118
+ services?.editorService.move(0, 1);
119
+ })
120
+ .keydown('left', () => {
121
+ services?.editorService.move(-1, 0);
122
+ })
123
+ .keydown('right', () => {
124
+ services?.editorService.move(1, 0);
125
+ })
126
+ .keydown([ctrl, 'up'], () => {
127
+ services?.editorService.move(0, -10);
128
+ })
129
+ .keydown([ctrl, 'down'], () => {
130
+ services?.editorService.move(0, 10);
131
+ })
132
+ .keydown([ctrl, 'left'], () => {
133
+ services?.editorService.move(-10, 0);
134
+ })
135
+ .keydown([ctrl, 'right'], () => {
136
+ services?.editorService.move(10, 0);
137
+ })
138
+ .keydown('tab', () => {
139
+ services?.editorService.selectNextNode();
140
+ })
141
+ .keydown([ctrl, 'tab'], () => {
142
+ services?.editorService.selectNextPage();
143
+ })
144
+ .keydown([ctrl, '='], () => {
145
+ services?.uiService.zoom(0.1);
146
+ })
147
+ .keydown([ctrl, 'numpadplus'], () => {
148
+ services?.uiService.zoom(0.1);
149
+ })
150
+ .keydown([ctrl, '-'], () => {
151
+ services?.uiService.zoom(-0.1);
152
+ })
153
+ .keydown([ctrl, 'numpad-'], () => {
154
+ services?.uiService.zoom(-0.1);
155
+ });
156
+ });
157
+
158
+ onUnmounted(() => {
159
+ workspace.value?.removeEventListener('mouseenter', mouseenterHandler);
160
+ workspace.value?.removeEventListener('mouseleave', mouseleaveHandler);
161
+ keycon.destroy();
162
+ });
72
163
 
73
- sortNodeHandler(ev: SortEventData) {
74
- services?.editorService.sort(ev.src, ev.dist);
75
- },
164
+ return {
165
+ workspace,
166
+
167
+ page: computed(() => services?.editorService.get<MPage>('page')),
76
168
  };
77
169
  },
78
170
  });
@@ -24,6 +24,46 @@ const methodName = (prefix: string, name: string) => `${prefix}${name[0].toUpper
24
24
 
25
25
  const isError = (error: any): boolean => Object.prototype.toString.call(error) === '[object Error]';
26
26
 
27
+ const doAction = async (
28
+ args: any[],
29
+ scope: any,
30
+ sourceMethod: any,
31
+ beforeMethodName: string,
32
+ afterMethodName: string,
33
+ fn: (args: any[], next?: Function | undefined) => Promise<void>,
34
+ ) => {
35
+ try {
36
+ let beforeArgs = args;
37
+
38
+ for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
39
+ let beforeReturnValue = (await beforeMethod(...beforeArgs)) || [];
40
+
41
+ if (isError(beforeReturnValue)) throw beforeReturnValue;
42
+
43
+ if (!Array.isArray(beforeReturnValue)) {
44
+ beforeReturnValue = [beforeReturnValue];
45
+ }
46
+
47
+ beforeArgs = beforeArgs.map((v: any, index: number) => {
48
+ if (typeof beforeReturnValue[index] === 'undefined') return v;
49
+ return beforeReturnValue[index];
50
+ });
51
+ }
52
+
53
+ let returnValue: any = await fn(beforeArgs, sourceMethod.bind(scope));
54
+
55
+ for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
56
+ returnValue = await afterMethod(returnValue, ...beforeArgs);
57
+
58
+ if (isError(returnValue)) throw returnValue;
59
+ }
60
+
61
+ return returnValue;
62
+ } catch (error) {
63
+ throw error;
64
+ }
65
+ };
66
+
27
67
  /**
28
68
  * 提供两种方式对Class进行扩展
29
69
  * 方法1:
@@ -74,8 +114,10 @@ const isError = (error: any): boolean => Object.prototype.toString.call(error) =
74
114
  export default class extends EventEmitter {
75
115
  private pluginOptionsList: Record<string, Function[]> = {};
76
116
  private middleware: Record<string, Function[]> = {};
117
+ private taskList: (() => Promise<void>)[] = [];
118
+ private doingTask = false;
77
119
 
78
- constructor(methods: string[]) {
120
+ constructor(methods: string[] = [], serialMethods: string[] = []) {
79
121
  super();
80
122
 
81
123
  methods.forEach((propertyName: string) => {
@@ -93,32 +135,28 @@ export default class extends EventEmitter {
93
135
  const fn = compose(this.middleware[propertyName]);
94
136
  Object.defineProperty(scope, propertyName, {
95
137
  value: async (...args: any[]) => {
96
- let beforeArgs = args;
97
-
98
- for (const beforeMethod of this.pluginOptionsList[beforeMethodName]) {
99
- let beforeReturnValue = (await beforeMethod(...beforeArgs)) || [];
100
-
101
- if (isError(beforeReturnValue)) throw beforeReturnValue;
102
-
103
- if (!Array.isArray(beforeReturnValue)) {
104
- beforeReturnValue = [beforeReturnValue];
105
- }
106
-
107
- beforeArgs = beforeArgs.map((v: any, index: number) => {
108
- if (typeof beforeReturnValue[index] === 'undefined') return v;
109
- return beforeReturnValue[index];
110
- });
138
+ if (!serialMethods.includes(propertyName)) {
139
+ return doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
111
140
  }
112
141
 
113
- let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
114
-
115
- for (const afterMethod of this.pluginOptionsList[afterMethodName]) {
116
- returnValue = await afterMethod(...beforeArgs, returnValue);
142
+ // 由于async await,所以会出现函数执行到await时让出线程,导致执行顺序出错,例如调用了select(1) -> update -> select(2),这个时候就有可能出现update了2;
143
+ // 这里保证函数调用严格按顺序执行;
144
+ const promise = new Promise<any>((resolve, reject) => {
145
+ this.taskList.push(async () => {
146
+ try {
147
+ const value = await doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
148
+ resolve(value);
149
+ } catch (e) {
150
+ reject(e);
151
+ }
152
+ });
153
+ });
117
154
 
118
- if (isError(returnValue)) throw returnValue;
155
+ if (!this.doingTask) {
156
+ this.doTask();
119
157
  }
120
158
 
121
- return returnValue;
159
+ return promise;
122
160
  },
123
161
  });
124
162
  });
@@ -135,4 +173,14 @@ export default class extends EventEmitter {
135
173
  if (typeof method === 'function') this.pluginOptionsList[methodName].push(method);
136
174
  });
137
175
  }
176
+
177
+ private async doTask() {
178
+ this.doingTask = true;
179
+ let task = this.taskList.shift();
180
+ while (task) {
181
+ await task();
182
+ task = this.taskList.shift();
183
+ }
184
+ this.doingTask = false;
185
+ }
138
186
  }