vue-editify 0.2.20 → 0.2.22

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 (49) hide show
  1. package/examples/App.vue +12 -3
  2. package/examples/test.html +26 -29
  3. package/lib/components/button/button.vue.d.ts +1 -0
  4. package/lib/core/tool.d.ts +1 -1
  5. package/lib/editify/menu/menu.vue.d.ts +8 -1
  6. package/lib/editify.es.js +272 -250
  7. package/lib/editify.umd.js +2 -2
  8. package/lib/index.d.ts +1 -1
  9. package/package.json +2 -2
  10. package/src/components/button/button.vue +2 -1
  11. package/src/core/shortcut.ts +48 -201
  12. package/src/core/tool.ts +1 -1
  13. package/src/editify/editify.vue +20 -4
  14. package/src/editify/menu/menu.vue +15 -6
  15. package/src/editify/toolbar/toolbar.vue +1 -1
  16. package/src/feature/align.ts +9 -2
  17. package/src/feature/attachment.ts +5 -1
  18. package/src/feature/backColor.ts +7 -1
  19. package/src/feature/bold.ts +8 -1
  20. package/src/feature/code.ts +8 -1
  21. package/src/feature/codeBlock.ts +8 -1
  22. package/src/feature/fontFamily.ts +10 -1
  23. package/src/feature/fontSize.ts +8 -1
  24. package/src/feature/foreColor.ts +5 -1
  25. package/src/feature/formatClear.ts +8 -1
  26. package/src/feature/fullScreen.ts +9 -2
  27. package/src/feature/heading.ts +9 -2
  28. package/src/feature/image.ts +5 -1
  29. package/src/feature/indent.ts +9 -2
  30. package/src/feature/infoBlock.ts +9 -2
  31. package/src/feature/italic.ts +8 -1
  32. package/src/feature/lineHeight.ts +9 -2
  33. package/src/feature/link.ts +5 -1
  34. package/src/feature/mathformula.ts +5 -1
  35. package/src/feature/orderList.ts +9 -2
  36. package/src/feature/quote.ts +9 -2
  37. package/src/feature/redo.ts +9 -2
  38. package/src/feature/separator.ts +9 -2
  39. package/src/feature/sourceView.ts +9 -2
  40. package/src/feature/strikethrough.ts +8 -1
  41. package/src/feature/sub.ts +8 -1
  42. package/src/feature/super.ts +8 -1
  43. package/src/feature/table.ts +5 -1
  44. package/src/feature/task.ts +9 -2
  45. package/src/feature/underline.ts +8 -1
  46. package/src/feature/undo.ts +9 -2
  47. package/src/feature/unorderList.ts +9 -2
  48. package/src/feature/video.ts +5 -1
  49. 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.20";
956
+ declare const version = "0.2.22";
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.20",
3
+ "version": "0.2.22",
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.34",
20
+ "alex-editor": "^1.4.35",
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,