vue-editify 0.2.19 → 0.2.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. package/examples/App.vue +10 -1
  2. package/lib/components/button/button.vue.d.ts +1 -0
  3. package/lib/core/tool.d.ts +1 -1
  4. package/lib/editify/menu/menu.vue.d.ts +8 -1
  5. package/lib/editify.es.js +274 -252
  6. package/lib/editify.umd.js +2 -2
  7. package/lib/index.d.ts +1 -1
  8. package/package.json +2 -2
  9. package/src/components/button/button.vue +2 -1
  10. package/src/core/shortcut.ts +48 -201
  11. package/src/core/tool.ts +1 -1
  12. package/src/editify/editify.vue +20 -4
  13. package/src/editify/menu/menu.vue +15 -6
  14. package/src/editify/toolbar/toolbar.vue +1 -1
  15. package/src/feature/align.ts +9 -2
  16. package/src/feature/attachment.ts +5 -1
  17. package/src/feature/backColor.ts +7 -1
  18. package/src/feature/bold.ts +8 -1
  19. package/src/feature/code.ts +8 -1
  20. package/src/feature/codeBlock.ts +8 -1
  21. package/src/feature/fontFamily.ts +10 -1
  22. package/src/feature/fontSize.ts +8 -1
  23. package/src/feature/foreColor.ts +5 -1
  24. package/src/feature/formatClear.ts +8 -1
  25. package/src/feature/fullScreen.ts +9 -2
  26. package/src/feature/heading.ts +9 -2
  27. package/src/feature/image.ts +5 -1
  28. package/src/feature/indent.ts +9 -2
  29. package/src/feature/infoBlock.ts +9 -2
  30. package/src/feature/italic.ts +8 -1
  31. package/src/feature/lineHeight.ts +9 -2
  32. package/src/feature/link.ts +5 -1
  33. package/src/feature/mathformula.ts +5 -1
  34. package/src/feature/orderList.ts +9 -2
  35. package/src/feature/quote.ts +9 -2
  36. package/src/feature/redo.ts +9 -2
  37. package/src/feature/separator.ts +9 -2
  38. package/src/feature/sourceView.ts +9 -2
  39. package/src/feature/strikethrough.ts +8 -1
  40. package/src/feature/sub.ts +8 -1
  41. package/src/feature/super.ts +8 -1
  42. package/src/feature/table.ts +5 -1
  43. package/src/feature/task.ts +9 -2
  44. package/src/feature/underline.ts +8 -1
  45. package/src/feature/undo.ts +9 -2
  46. package/src/feature/unorderList.ts +9 -2
  47. package/src/feature/video.ts +5 -1
  48. package/src/index.ts +1 -1
package/lib/index.d.ts CHANGED
@@ -953,5 +953,5 @@ export type * from './editify/menu';
953
953
  export type * from './editify/toolbar';
954
954
  export { elementIsMatch, getMatchElementByElement, getMatchElementByRange, elementIsList, getListByElement, hasListInRange, rangeIsInList, elementIsTask, getTaskByElement, hasTaskInRange, rangeIsInTask, elementIsAttachment, hasAttachmentInRange, elementIsMathformula, getMathformulaByElement, hasMathformulaInRange, elementIsInfoBlock, getInfoBlockByElement, hasInfoBlockInRange, rangeIsInInfoBlock, hasPreInRange, hasTableInRange, hasQuoteInRange, rangeIsInQuote, hasLinkInRange, hasImageInRange, hasVideoInRange, queryTextStyle, setTextStyle, removeTextStyle, queryTextMark, setTextMark, removeTextMark, getRangeText, addSpaceTextToBothSides, setHeading, setIndentIncrease, setIndentDecrease, setQuote, setAlign, setList, setTask, setLineHeight, insertLink, insertImage, insertVideo, insertTable, insertCodeBlock, insertSeparator, insertAttachment, insertMathformula, insertInfoBlock } from './core/function';
955
955
  declare const install: (app: App) => void;
956
- declare const version = "0.2.19";
956
+ declare const version = "0.2.21";
957
957
  export { Editify as default, Editify, install, AlexElement, version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-editify",
3
- "version": "0.2.19",
3
+ "version": "0.2.21",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "*.css"
@@ -17,7 +17,7 @@
17
17
  "lib": "vue-tsc && vite build"
18
18
  },
19
19
  "dependencies": {
20
- "alex-editor": "^1.4.33",
20
+ "alex-editor": "^1.4.34",
21
21
  "dap-util": "^1.5.8",
22
22
  "highlight.js": "^11.8.0",
23
23
  "katex": "^0.16.10",
@@ -192,7 +192,8 @@ const handleClick = () => {
192
192
  defineExpose({
193
193
  show,
194
194
  status,
195
- layerRef
195
+ layerRef,
196
+ handleClick
196
197
  })
197
198
  </script>
198
199
  <style scoped src="./button.less"></style>
@@ -1,5 +1,5 @@
1
1
  import { platform } from 'dap-util'
2
- import { hasAttachmentInRange, hasImageInRange, hasMathformulaInRange, hasPreInRange, hasTableInRange, hasVideoInRange, insertCodeBlock, insertInfoBlock, queryTextMark, queryTextStyle, removeTextMark, removeTextStyle, setHeading, setIndentDecrease, setIndentIncrease, setList, setQuote, setTask, setTextMark, setTextStyle } from './function'
2
+ import { hasPreInRange, hasTableInRange, setHeading, setIndentDecrease, setIndentIncrease } from './function'
3
3
  import { ShortcutType } from './tool'
4
4
 
5
5
  const { Mac } = platform.os()
@@ -88,299 +88,146 @@ export const config: ShortcutConfigType = {
88
88
  quote: {
89
89
  title: `${Mac ? 'Command' : 'Ctrl'} + E`,
90
90
  define: event => event.key.toLocaleLowerCase() == 'e' && (Mac ? event.metaKey : event.ctrlKey),
91
- operation: (editor, dataRangeCaches, isSourceView) => {
92
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches) || hasTableInRange(editor, dataRangeCaches)) {
93
- return
94
- }
95
- setQuote(editor, dataRangeCaches)
96
- editor.domRender()
97
- editor.rangeRender()
98
- }
91
+ operation: null
99
92
  },
100
93
  separator: {
101
94
  title: '',
102
- define: null
95
+ define: null,
96
+ operation: null
103
97
  },
104
98
  align: {
105
99
  title: '',
106
- define: null
100
+ define: null,
101
+ operation: null
107
102
  },
108
103
  orderList: {
109
104
  title: `${Mac ? 'Command' : 'Ctrl'} + O`,
110
105
  define: event => event.key.toLocaleLowerCase() == 'o' && (Mac ? event.metaKey : event.ctrlKey),
111
- operation: (editor, dataRangeCaches, isSourceView) => {
112
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches) || hasTableInRange(editor, dataRangeCaches)) {
113
- return
114
- }
115
- setList(editor, dataRangeCaches, true)
116
- editor.domRender()
117
- editor.rangeRender()
118
- }
106
+ operation: null
119
107
  },
120
108
  unorderList: {
121
109
  title: `${Mac ? 'Command' : 'Ctrl'} + U`,
122
110
  define: event => event.key.toLocaleLowerCase() == 'u' && (Mac ? event.metaKey : event.ctrlKey),
123
- operation: (editor, dataRangeCaches, isSourceView) => {
124
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches) || hasTableInRange(editor, dataRangeCaches)) {
125
- return
126
- }
127
- setList(editor, dataRangeCaches, false)
128
- editor.domRender()
129
- editor.rangeRender()
130
- }
111
+ operation: null
131
112
  },
132
113
  task: {
133
114
  title: `${Mac ? 'Command' : 'Ctrl'} + I`,
134
115
  define: event => event.key.toLocaleLowerCase() == 'i' && (Mac ? event.metaKey : event.ctrlKey),
135
- operation: (editor, dataRangeCaches, isSourceView) => {
136
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches) || hasTableInRange(editor, dataRangeCaches)) {
137
- return
138
- }
139
- setTask(editor, dataRangeCaches)
140
- editor.domRender()
141
- editor.rangeRender()
142
- }
116
+ operation: null
143
117
  },
144
118
  bold: {
145
119
  title: `${Mac ? 'Command' : 'Ctrl'} + B`,
146
120
  define: event => event.key.toLocaleLowerCase() == 'b' && (Mac ? event.metaKey : event.ctrlKey),
147
- operation: (editor, dataRangeCaches, isSourceView) => {
148
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches)) {
149
- return
150
- }
151
- const active = queryTextStyle(editor, dataRangeCaches, 'font-weight', 'bold') || queryTextStyle(editor, dataRangeCaches, 'font-weight', '700')
152
- if (active) {
153
- removeTextStyle(editor, dataRangeCaches, ['font-weight'])
154
- } else {
155
- setTextStyle(editor, dataRangeCaches, {
156
- 'font-weight': 'bold'
157
- })
158
- }
159
- editor.domRender()
160
- editor.rangeRender()
161
- }
121
+ operation: null
162
122
  },
163
123
  underline: {
164
124
  title: `${Mac ? 'Command' : 'Ctrl'} + G`,
165
125
  define: event => event.key.toLocaleLowerCase() == 'g' && (Mac ? event.metaKey : event.ctrlKey),
166
- operation: (editor, dataRangeCaches, isSourceView) => {
167
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches)) {
168
- return
169
- }
170
- const active = queryTextStyle(editor, dataRangeCaches, 'text-decoration', 'underline') || queryTextStyle(editor, dataRangeCaches, 'text-decoration-line', 'underline')
171
- if (active) {
172
- removeTextStyle(editor, dataRangeCaches, ['text-decoration', 'text-decoration-line'])
173
- } else {
174
- setTextStyle(editor, dataRangeCaches, {
175
- 'text-decoration': 'underline'
176
- })
177
- }
178
- editor.domRender()
179
- editor.rangeRender()
180
- }
126
+ operation: null
181
127
  },
182
128
  italic: {
183
129
  title: `${Mac ? 'Command' : 'Ctrl'} + H`,
184
130
  define: event => event.key.toLocaleLowerCase() == 'h' && (Mac ? event.metaKey : event.ctrlKey),
185
- operation: (editor, dataRangeCaches, isSourceView) => {
186
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches)) {
187
- return
188
- }
189
- const active = queryTextStyle(editor, dataRangeCaches, 'font-style', 'italic')
190
- if (active) {
191
- removeTextStyle(editor, dataRangeCaches, ['font-style'])
192
- } else {
193
- setTextStyle(editor, dataRangeCaches, {
194
- 'font-style': 'italic'
195
- })
196
- }
197
- editor.domRender()
198
- editor.rangeRender()
199
- }
131
+ operation: null
200
132
  },
201
133
  strikethrough: {
202
134
  title: `${Mac ? 'Command' : 'Ctrl'} + J`,
203
- define: event => {
204
- return event.key.toLocaleLowerCase() == 'j' && (Mac ? event.metaKey : event.ctrlKey)
205
- },
206
- operation: (editor, dataRangeCaches, isSourceView) => {
207
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches)) {
208
- return
209
- }
210
- const active = queryTextStyle(editor, dataRangeCaches, 'text-decoration', 'line-through') || queryTextStyle(editor, dataRangeCaches, 'text-decoration-line', 'line-through')
211
- if (active) {
212
- removeTextStyle(editor, dataRangeCaches, ['text-decoration', 'text-decoration-line'])
213
- } else {
214
- setTextStyle(editor, dataRangeCaches, {
215
- 'text-decoration': 'line-through'
216
- })
217
- }
218
- editor.domRender()
219
- editor.rangeRender()
220
- }
135
+ define: event => event.key.toLocaleLowerCase() == 'j' && (Mac ? event.metaKey : event.ctrlKey),
136
+ operation: null
221
137
  },
222
138
  code: {
223
139
  title: `${Mac ? 'Command' : 'Ctrl'} + K`,
224
- define: event => {
225
- return event.key.toLocaleLowerCase() == 'k' && (Mac ? event.metaKey : event.ctrlKey)
226
- },
227
- operation: (editor, dataRangeCaches, isSourceView) => {
228
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches)) {
229
- return
230
- }
231
- const active = queryTextMark(editor, dataRangeCaches, 'data-editify-code')
232
- if (active) {
233
- removeTextMark(editor, dataRangeCaches, ['data-editify-code'])
234
- } else {
235
- setTextMark(editor, dataRangeCaches, {
236
- 'data-editify-code': true
237
- })
238
- }
239
- editor.domRender()
240
- editor.rangeRender()
241
- }
140
+ define: event => event.key.toLocaleLowerCase() == 'k' && (Mac ? event.metaKey : event.ctrlKey),
141
+ operation: null
242
142
  },
243
143
  super: {
244
144
  title: `${Mac ? 'Command' : 'Ctrl'} + L`,
245
- define: event => {
246
- return event.key.toLocaleLowerCase() == 'l' && (Mac ? event.metaKey : event.ctrlKey)
247
- },
248
- operation: (editor, dataRangeCaches, isSourceView) => {
249
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches)) {
250
- return
251
- }
252
- const active = queryTextStyle(editor, dataRangeCaches, 'vertical-align', 'super')
253
- if (active) {
254
- removeTextStyle(editor, dataRangeCaches, ['vertical-align'])
255
- } else {
256
- setTextStyle(editor, dataRangeCaches, {
257
- 'vertical-align': 'super'
258
- })
259
- }
260
- editor.domRender()
261
- editor.rangeRender()
262
- }
145
+ define: event => event.key.toLocaleLowerCase() == 'l' && (Mac ? event.metaKey : event.ctrlKey),
146
+ operation: null
263
147
  },
264
148
  sub: {
265
149
  title: `${Mac ? 'Command' : 'Ctrl'} + M`,
266
- define: event => {
267
- return event.key.toLocaleLowerCase() == 'm' && (Mac ? event.metaKey : event.ctrlKey)
268
- },
269
- operation: (editor, dataRangeCaches, isSourceView) => {
270
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches)) {
271
- return
272
- }
273
- const active = queryTextStyle(editor, dataRangeCaches, 'vertical-align', 'sub')
274
- if (active) {
275
- removeTextStyle(editor, dataRangeCaches, ['vertical-align'])
276
- } else {
277
- setTextStyle(editor, dataRangeCaches, {
278
- 'vertical-align': 'sub'
279
- })
280
- }
281
- editor.domRender()
282
- editor.rangeRender()
283
- }
150
+ define: event => event.key.toLocaleLowerCase() == 'm' && (Mac ? event.metaKey : event.ctrlKey),
151
+ operation: null
284
152
  },
285
153
  formatClear: {
286
154
  title: `${Mac ? 'Command' : 'Ctrl'} + Enter`,
287
- define: event => {
288
- return event.key.toLocaleLowerCase() == 'enter' && (Mac ? event.metaKey : event.ctrlKey)
289
- },
290
- operation: (editor, dataRangeCaches, isSourceView) => {
291
- if (isSourceView.value || hasPreInRange(editor, dataRangeCaches)) {
292
- return
293
- }
294
- removeTextStyle(editor, dataRangeCaches)
295
- removeTextMark(editor, dataRangeCaches)
296
- editor.domRender()
297
- editor.rangeRender()
298
- }
155
+ define: event => event.key.toLocaleLowerCase() == 'enter' && (Mac ? event.metaKey : event.ctrlKey),
156
+ operation: null
299
157
  },
300
158
  fontSize: {
301
159
  title: '',
302
- define: null
160
+ define: null,
161
+ operation: null
303
162
  },
304
163
  fontFamily: {
305
164
  title: '',
306
- define: null
165
+ define: null,
166
+ operation: null
307
167
  },
308
168
  lineHeight: {
309
169
  title: '',
310
- define: null
170
+ define: null,
171
+ operation: null
311
172
  },
312
173
  foreColor: {
313
174
  title: '',
314
- define: null
175
+ define: null,
176
+ operation: null
315
177
  },
316
178
  backColor: {
317
179
  title: '',
318
- define: null
180
+ define: null,
181
+ operation: null
319
182
  },
320
183
  link: {
321
184
  title: '',
322
- define: null
185
+ define: null,
186
+ operation: null
323
187
  },
324
188
  image: {
325
189
  title: '',
326
- define: null
190
+ define: null,
191
+ operation: null
327
192
  },
328
193
  video: {
329
194
  title: '',
330
- define: null
195
+ define: null,
196
+ operation: null
331
197
  },
332
198
  table: {
333
199
  title: '',
334
- define: null
200
+ define: null,
201
+ operation: null
335
202
  },
336
203
  codeBlock: {
337
204
  title: `${Mac ? 'Command' : 'Ctrl'} + P`,
338
205
  define: event => event.key.toLocaleLowerCase() == 'p' && (Mac ? event.metaKey : event.ctrlKey),
339
- operation: (editor, dataRangeCaches, isSourceView) => {
340
- if (isSourceView.value || hasTableInRange(editor, dataRangeCaches) || hasImageInRange(editor, dataRangeCaches) || hasVideoInRange(editor, dataRangeCaches) || hasAttachmentInRange(editor, dataRangeCaches) || hasMathformulaInRange(editor, dataRangeCaches)) {
341
- return
342
- }
343
- insertCodeBlock(editor, dataRangeCaches)
344
- editor.domRender()
345
- editor.rangeRender()
346
- }
206
+ operation: null
347
207
  },
348
208
  sourceView: {
349
209
  title: `${Mac ? 'Command' : 'Ctrl'} + 8`,
350
210
  define: event => event.key.toLocaleLowerCase() == '8' && (Mac ? event.metaKey : event.ctrlKey),
351
- operation: (editor, _dataRangeCaches, isSourceView) => {
352
- isSourceView.value = !isSourceView.value
353
- if (!isSourceView.value) {
354
- editor.rangeRender()
355
- }
356
- }
211
+ operation: null
357
212
  },
358
213
  fullScreen: {
359
214
  title: `${Mac ? 'Command' : 'Ctrl'} + 9`,
360
215
  define: event => event.key.toLocaleLowerCase() == '9' && (Mac ? event.metaKey : event.ctrlKey),
361
- operation: (editor, _dataRangeCaches, _isSourceView, isFullScreen) => {
362
- isFullScreen.value = !isFullScreen.value
363
- editor.rangeRender()
364
- }
216
+ operation: null
365
217
  },
366
218
  attachment: {
367
219
  title: '',
368
- define: null
220
+ define: null,
221
+ operation: null
369
222
  },
370
223
  mathformula: {
371
224
  title: '',
372
- define: null
225
+ define: null,
226
+ operation: null
373
227
  },
374
228
  infoBlock: {
375
229
  title: `${Mac ? 'Command' : 'Ctrl'} + 0`,
376
230
  define: event => event.key.toLocaleLowerCase() == '0' && (Mac ? event.metaKey : event.ctrlKey),
377
- operation: (editor, dataRangeCaches, isSourceView) => {
378
- if (isSourceView.value || hasTableInRange(editor, dataRangeCaches) || hasPreInRange(editor, dataRangeCaches)) {
379
- return
380
- }
381
- insertInfoBlock(editor, dataRangeCaches)
382
- editor.domRender()
383
- editor.rangeRender()
384
- }
231
+ operation: null
385
232
  }
386
233
  }
package/src/core/tool.ts CHANGED
@@ -26,7 +26,7 @@ export type ButtonOptionsConfigType = {
26
26
  export type ShortcutType = {
27
27
  title: string
28
28
  define: ((event: KeyboardEvent) => boolean | { [code: string]: boolean }) | null
29
- operation?: (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, isSourceView: Ref<boolean>, isFullScreen: Ref<boolean>, code?: string) => void
29
+ operation: ((editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, isSourceView: Ref<boolean>, isFullScreen: Ref<boolean>, code?: string) => void) | null
30
30
  }
31
31
 
32
32
  export interface MenuButtonType {
@@ -763,7 +763,11 @@ const handleEditorKeydown = (val: string, e: KeyboardEvent) => {
763
763
  e.preventDefault()
764
764
  //没有被禁用则执行对应的操作
765
765
  if (!item.disabled) {
766
- shortcut.operation?.(editor.value!, dataRangeCaches.value, isSourceView, isFullScreen)
766
+ if (typeof shortcut.operation == 'function') {
767
+ shortcut.operation(editor.value!, dataRangeCaches.value, isSourceView, isFullScreen)
768
+ } else {
769
+ menuRef.value?.menuItemRefs[extendKey].btnRef.handleClick()
770
+ }
767
771
  }
768
772
  }
769
773
  //如果是对象,则表示有多个快捷键操作
@@ -776,7 +780,11 @@ const handleEditorKeydown = (val: string, e: KeyboardEvent) => {
776
780
  e.preventDefault()
777
781
  //没有被禁用则执行对应的操作
778
782
  if (!item.disabled) {
779
- shortcut.operation?.(editor.value!, dataRangeCaches.value, isSourceView, isFullScreen, code)
783
+ if (typeof shortcut.operation == 'function') {
784
+ shortcut.operation(editor.value!, dataRangeCaches.value, isSourceView, isFullScreen, code)
785
+ } else {
786
+ menuRef.value?.menuItemRefs[extendKey].btnRef.handleClick()
787
+ }
780
788
  }
781
789
  }
782
790
  })
@@ -801,7 +809,11 @@ const handleEditorKeydown = (val: string, e: KeyboardEvent) => {
801
809
  e.preventDefault()
802
810
  //没有被禁用则执行对应的操作
803
811
  if (!item.disabled) {
804
- shortcut.operation?.(editor.value!, dataRangeCaches.value, isSourceView, isFullScreen)
812
+ if (typeof shortcut.operation == 'function') {
813
+ shortcut.operation(editor.value!, dataRangeCaches.value, isSourceView, isFullScreen)
814
+ } else {
815
+ menuRef.value?.menuItemRefs[key].btnRef.handleClick()
816
+ }
805
817
  }
806
818
  }
807
819
  //如果是对象,则表示有多个快捷键操作
@@ -814,7 +826,11 @@ const handleEditorKeydown = (val: string, e: KeyboardEvent) => {
814
826
  e.preventDefault()
815
827
  //没有被禁用则执行对应的操作
816
828
  if (!item.disabled) {
817
- shortcut.operation?.(editor.value!, dataRangeCaches.value, isSourceView, isFullScreen, code)
829
+ if (typeof shortcut.operation == 'function') {
830
+ shortcut.operation(editor.value!, dataRangeCaches.value, isSourceView, isFullScreen, code)
831
+ } else {
832
+ menuRef.value?.menuItemRefs[key].btnRef.handleClick()
833
+ }
818
834
  }
819
835
  }
820
836
  })
@@ -2,14 +2,14 @@
2
2
  <div ref="menuRef" class="editify-menu" :class="{ 'editify-border': menuShowBorder, 'editify-source': isSourceView && menuMode == 'inner', 'editify-fullscreen': isFullScreen }" :data-editify-mode="menuMode" :style="{ zIndex: zIndex, ...(config.style || {}) }">
3
3
  <template v-for="item in menuNames">
4
4
  <!-- 内置菜单按钮 -->
5
- <component v-if="!!currentDefaultMenu(item)" :is="currentDefaultMenu(item)" :color="color" :z-index="zIndex + 1" :config="(config as any)[item]" :disabled="isDisabled || !rangeKey" :tooltip="config.tooltip!"></component>
5
+ <component :ref="(el:MenuItemComponentPublicInstance) => (menuItemRefs[item] = el)" v-if="!!currentDefaultMenu(item)" :is="currentDefaultMenu(item)" :color="color" :z-index="zIndex + 1" :config="(config as any)[item]" :disabled="isDisabled || !rangeKey" :tooltip="config.tooltip!"></component>
6
6
  <!-- 拓展菜单按钮 -->
7
- <ExtendMenuButton v-else :name="item" />
7
+ <ExtendMenuButton v-else :ref="el => (menuItemRefs[item] = (el as MenuItemComponentPublicInstance))" :name="item" />
8
8
  </template>
9
9
  </div>
10
10
  </template>
11
11
  <script setup lang="ts">
12
- import { ref, computed, inject, Ref, ComputedRef, onMounted, getCurrentInstance, onBeforeUnmount, shallowRef, defineComponent, h } from 'vue'
12
+ import { ref, computed, inject, Ref, ComputedRef, onMounted, getCurrentInstance, onBeforeUnmount, shallowRef, defineComponent, h, ComponentPublicInstance } from 'vue'
13
13
  import { event as DapEvent } from 'dap-util'
14
14
  import { MenuModeType } from '@/core/tool'
15
15
  import { Button } from '@/components/button'
@@ -72,6 +72,9 @@ const isAutoHeight = inject<ComputedRef<boolean>>('isAutoHeight')!
72
72
  const menuRef = ref<HTMLElement | null>(null)
73
73
  //菜单高度
74
74
  const height = ref<number>(0)
75
+ //菜单实例数组
76
+ type MenuItemComponentPublicInstance = ComponentPublicInstance & { btnRef: InstanceType<typeof Button> }
77
+ const menuItemRefs = ref<{ [name: string]: MenuItemComponentPublicInstance }>({})
75
78
 
76
79
  //菜单名称数组(包括内置的和拓展的)
77
80
  const menuNames = computed<string[]>(() => {
@@ -111,21 +114,26 @@ const menuShowBorder = computed<boolean>(() => {
111
114
 
112
115
  //拓展菜单组件
113
116
  const ExtendMenuButton = defineComponent(
114
- extendProps => {
117
+ (extendProps, { expose }) => {
115
118
  //按钮实例
116
119
  const btnRef = ref<InstanceType<typeof Button> | null>(null)
117
120
  //拓展菜单配置
118
121
  const configuration = props.config.extends![extendProps.name]
122
+
123
+ expose({
124
+ btnRef
125
+ })
126
+
119
127
  return () => {
120
128
  return configuration
121
129
  ? h(
122
130
  Button,
123
131
  {
132
+ ref: btnRef,
124
133
  name: extendProps.name,
125
134
  tooltip: props.config.tooltip,
126
135
  color: props.color,
127
136
  zIndex: props.zIndex + 1,
128
- ref: btnRef,
129
137
  type: configuration.type || 'default',
130
138
  title: `${configuration.title || ''}${configuration.shortcut?.title ? `【${configuration.shortcut?.title}】` : ''}`,
131
139
  leftBorder: configuration.leftBorder || false,
@@ -208,7 +216,8 @@ onBeforeUnmount(() => {
208
216
  })
209
217
 
210
218
  defineExpose({
211
- height
219
+ height,
220
+ menuItemRefs
212
221
  })
213
222
  </script>
214
223
  <style scoped src="./menu.less"></style>
@@ -57,7 +57,7 @@ const emits = defineEmits(['update:modelValue'])
57
57
 
58
58
  //工具条浮层组件实例
59
59
  const layerRef = ref<InstanceType<typeof Layer> | null>(null)
60
- //文本按钮实例类型
60
+ //按钮实例类型
61
61
  type BtnComponentPublicInstance = ComponentPublicInstance & { btnRef: InstanceType<typeof Button> }
62
62
  //代码块语言选择按钮实例
63
63
  const codeBlockToolbarRef = ref<BtnComponentPublicInstance | null>(null)
@@ -1,4 +1,4 @@
1
- import { defineComponent, h, inject, PropType, Ref } from 'vue'
1
+ import { defineComponent, h, inject, PropType, ref, Ref } from 'vue'
2
2
  import { AlexElementsRangeType, AlexEditor } from 'alex-editor'
3
3
  import { MenuSelectButtonType } from '@/core/tool'
4
4
  import { hasPreInRange, setAlign } from '@/core/function'
@@ -14,17 +14,24 @@ const FEATURE_NAME = 'align'
14
14
  * 菜单栏 - 对齐方式
15
15
  */
16
16
  export const AlignMenuButton = defineComponent(
17
- props => {
17
+ (props, { expose }) => {
18
18
  const editor = inject<Ref<AlexEditor>>('editor')!
19
19
  const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
20
20
  const $editTrans = inject<(key: string) => any>('$editTrans')!
21
21
  const isSourceView = inject<Ref<boolean>>('isSourceView')!
22
22
 
23
+ const btnRef = ref<InstanceType<typeof Button> | null>(null)
24
+
25
+ expose({
26
+ btnRef
27
+ })
28
+
23
29
  return () => {
24
30
  return props.config.show
25
31
  ? h(
26
32
  Button,
27
33
  {
34
+ ref: btnRef,
28
35
  name: FEATURE_NAME,
29
36
  tooltip: props.tooltip,
30
37
  color: props.color,
@@ -15,7 +15,7 @@ const FEATURE_NAME = 'attachment'
15
15
  * 菜单栏 - 插入附件
16
16
  */
17
17
  export const AttachmentMenuButton = defineComponent(
18
- props => {
18
+ (props, { expose }) => {
19
19
  const editor = inject<Ref<AlexEditor>>('editor')!
20
20
  const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
21
21
  const $editTrans = inject<(key: string) => any>('$editTrans')!
@@ -23,6 +23,10 @@ export const AttachmentMenuButton = defineComponent(
23
23
 
24
24
  const btnRef = ref<InstanceType<typeof Button> | null>(null)
25
25
 
26
+ expose({
27
+ btnRef
28
+ })
29
+
26
30
  return () => {
27
31
  return props.config.show
28
32
  ? h(
@@ -32,9 +32,11 @@ export const BackColorToolbarButton = defineComponent(
32
32
  })
33
33
  return findBackColorItem ? (DapCommon.isObject(findBackColorItem) ? ((findBackColorItem as ButtonOptionsItemType).value as string) : (findBackColorItem as string)) : ''
34
34
  })
35
+
35
36
  expose({
36
37
  btnRef
37
38
  })
39
+
38
40
  return () => {
39
41
  return props.config.show
40
42
  ? h(
@@ -94,7 +96,7 @@ export const BackColorToolbarButton = defineComponent(
94
96
  * 菜单栏 - 背景色
95
97
  */
96
98
  export const BackColorMenuButton = defineComponent(
97
- props => {
99
+ (props, { expose }) => {
98
100
  const editor = inject<Ref<AlexEditor>>('editor')!
99
101
  const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
100
102
  const $editTrans = inject<(key: string) => any>('$editTrans')!
@@ -112,6 +114,10 @@ export const BackColorMenuButton = defineComponent(
112
114
  return findBackColorItem ? (DapCommon.isObject(findBackColorItem) ? ((findBackColorItem as ButtonOptionsItemType).value as string) : (findBackColorItem as string)) : ''
113
115
  })
114
116
 
117
+ expose({
118
+ btnRef
119
+ })
120
+
115
121
  return () => {
116
122
  return props.config.show
117
123
  ? h(
@@ -78,21 +78,28 @@ export const BoldToolbarButton = defineComponent(
78
78
  * 菜单栏 - 加粗
79
79
  */
80
80
  export const BoldMenuButton = defineComponent(
81
- props => {
81
+ (props, { expose }) => {
82
82
  const editor = inject<Ref<AlexEditor>>('editor')!
83
83
  const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
84
84
  const $editTrans = inject<(key: string) => any>('$editTrans')!
85
85
  const isSourceView = inject<Ref<boolean>>('isSourceView')!
86
86
 
87
+ const btnRef = ref<InstanceType<typeof Button> | null>(null)
88
+
87
89
  const active = computed<boolean>(() => {
88
90
  return queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', 'bold') || queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', '700')
89
91
  })
90
92
 
93
+ expose({
94
+ btnRef
95
+ })
96
+
91
97
  return () => {
92
98
  return props.config.show
93
99
  ? h(
94
100
  Button,
95
101
  {
102
+ ref: btnRef,
96
103
  name: FEATURE_NAME,
97
104
  tooltip: props.tooltip,
98
105
  color: props.color,
@@ -78,21 +78,28 @@ export const CodeToolbarButton = defineComponent(
78
78
  * 菜单栏 - 行内代码
79
79
  */
80
80
  export const CodeMenuButton = defineComponent(
81
- props => {
81
+ (props, { expose }) => {
82
82
  const editor = inject<Ref<AlexEditor>>('editor')!
83
83
  const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
84
84
  const $editTrans = inject<(key: string) => any>('$editTrans')!
85
85
  const isSourceView = inject<Ref<boolean>>('isSourceView')!
86
86
 
87
+ const btnRef = ref<InstanceType<typeof Button> | null>(null)
88
+
87
89
  const active = computed<boolean>(() => {
88
90
  return queryTextMark(editor.value, dataRangeCaches.value, 'data-editify-code')
89
91
  })
90
92
 
93
+ expose({
94
+ btnRef
95
+ })
96
+
91
97
  return () => {
92
98
  return props.config.show
93
99
  ? h(
94
100
  Button,
95
101
  {
102
+ ref: btnRef,
96
103
  name: FEATURE_NAME,
97
104
  tooltip: props.tooltip,
98
105
  color: props.color,