vue-editify 0.1.17 → 0.1.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. package/README.md +3 -3
  2. package/examples/App.vue +62 -53
  3. package/examples/main.ts +4 -4
  4. package/lib/components/button/button.vue.d.ts +11 -11
  5. package/lib/components/checkbox/checkbox.vue.d.ts +8 -8
  6. package/lib/components/colors/colors.vue.d.ts +4 -4
  7. package/lib/components/icon/icon.vue.d.ts +1 -1
  8. package/lib/components/insertImage/insertImage.vue.d.ts +9 -9
  9. package/lib/components/insertLink/insertLink.vue.d.ts +2 -2
  10. package/lib/components/insertTable/insertTable.vue.d.ts +2 -2
  11. package/lib/components/insertVideo/insertVideo.vue.d.ts +9 -9
  12. package/lib/components/layer/layer.vue.d.ts +9 -9
  13. package/lib/components/menu/menu.vue.d.ts +4 -4
  14. package/lib/components/toolbar/toolbar.vue.d.ts +9 -9
  15. package/lib/components/tooltip/tooltip.vue.d.ts +1 -1
  16. package/lib/components/triangle/triangle.vue.d.ts +4 -4
  17. package/lib/editify/editify.vue.d.ts +88 -70
  18. package/lib/editify/props.d.ts +11 -3
  19. package/lib/editify.es.js +65 -46
  20. package/lib/editify.umd.js +1 -1
  21. package/lib/index.d.ts +1 -1
  22. package/lib/style.css +1 -1
  23. package/package.json +45 -45
  24. package/src/components/button/button.less +145 -145
  25. package/src/components/button/button.vue +197 -197
  26. package/src/components/button/props.ts +95 -95
  27. package/src/components/checkbox/checkbox.less +84 -84
  28. package/src/components/checkbox/checkbox.vue +68 -68
  29. package/src/components/checkbox/props.ts +49 -49
  30. package/src/components/colors/colors.less +75 -75
  31. package/src/components/colors/colors.vue +36 -36
  32. package/src/components/colors/props.ts +29 -29
  33. package/src/components/icon/icon.less +14 -14
  34. package/src/components/icon/icon.vue +12 -12
  35. package/src/components/icon/props.ts +11 -11
  36. package/src/components/insertImage/insertImage.less +135 -135
  37. package/src/components/insertImage/insertImage.vue +146 -146
  38. package/src/components/insertImage/props.ts +43 -43
  39. package/src/components/insertLink/insertLink.less +64 -64
  40. package/src/components/insertLink/insertLink.vue +58 -58
  41. package/src/components/insertLink/props.ts +16 -16
  42. package/src/components/insertTable/insertTable.less +54 -54
  43. package/src/components/insertTable/insertTable.vue +85 -85
  44. package/src/components/insertTable/props.ts +27 -27
  45. package/src/components/insertVideo/insertVideo.less +135 -135
  46. package/src/components/insertVideo/insertVideo.vue +146 -146
  47. package/src/components/insertVideo/props.ts +43 -43
  48. package/src/components/layer/layer.less +49 -49
  49. package/src/components/layer/layer.vue +598 -598
  50. package/src/components/layer/props.ts +71 -71
  51. package/src/components/menu/menu.less +63 -63
  52. package/src/components/menu/menu.vue +1569 -1569
  53. package/src/components/menu/props.ts +17 -17
  54. package/src/components/toolbar/props.ts +35 -35
  55. package/src/components/toolbar/toolbar.less +89 -89
  56. package/src/components/toolbar/toolbar.vue +1101 -1101
  57. package/src/components/tooltip/props.ts +21 -21
  58. package/src/components/tooltip/tooltip.less +23 -23
  59. package/src/components/tooltip/tooltip.vue +37 -37
  60. package/src/components/triangle/props.ts +26 -26
  61. package/src/components/triangle/triangle.less +79 -79
  62. package/src/components/triangle/triangle.vue +65 -65
  63. package/src/core/function.ts +1144 -1144
  64. package/src/core/rule.ts +259 -259
  65. package/src/core/tool.ts +1137 -1137
  66. package/src/css/base.less +30 -30
  67. package/src/css/hljs.less +54 -54
  68. package/src/editify/editify.less +404 -403
  69. package/src/editify/editify.vue +803 -792
  70. package/src/editify/props.ts +156 -146
  71. package/src/hljs/index.ts +197 -197
  72. package/src/icon/iconfont.css +219 -219
  73. package/src/index.ts +32 -32
  74. package/src/locale/en_US.ts +88 -88
  75. package/src/locale/index.ts +12 -12
  76. package/src/locale/zh_CN.ts +88 -88
  77. package/tsconfig.json +27 -27
  78. package/tsconfig.node.json +11 -11
  79. package/vite-env.d.ts +1 -1
  80. package/vite.config.ts +42 -42
@@ -1,1569 +1,1569 @@
1
- <template>
2
- <div class="editify-menu" :class="{ border: menuShowBorder, source: isSourceView && menuMode == 'inner', fullscreen: isFullScreen }" :data-editify-mode="menuMode" :style="config.style || ''">
3
- <MenuItem v-for="item in menuNames" :name="item" :disabled="menuDisabled(item)"></MenuItem>
4
- </div>
5
- </template>
6
- <script setup lang="ts">
7
- import Icon from '../icon/icon.vue'
8
- import Layer from '../layer/layer.vue'
9
- import Button from '../button/button.vue'
10
- import Colors from '../colors/colors.vue'
11
- import InsertLink from '../insertLink/insertLink.vue'
12
- import InsertImage from '../insertImage/insertImage.vue'
13
- import InsertVideo from '../insertVideo/insertVideo.vue'
14
- import InsertTable from '../insertTable/insertTable.vue'
15
- import { h, getCurrentInstance, ref, computed, inject, ComponentInternalInstance, Ref, ComputedRef, defineComponent } from 'vue'
16
- import { common as DapCommon } from 'dap-util'
17
- import { getRangeText, setHeading, setIndentIncrease, setIndentDecrease, setQuote, setAlign, setList, setTask, setTextStyle, setTextMark, removeTextStyle, removeTextMark, setLineHeight, insertLink, insertImage, insertVideo, insertTable, insertCodeBlock, hasPreInRange, hasTableInRange, hasQuoteInRange, hasLinkInRange, isRangeInQuote, isRangeInList, isRangeInTask, queryTextStyle, queryTextMark, getCurrentParsedomElement } from '../../core/function'
18
- import { MenuProps } from './props'
19
- import { MenuModeType, ObjectType } from '../../core/tool'
20
- import AlexEditor, { AlexElementsRangeType } from 'alex-editor'
21
- import { ButtonOptionsItemType } from '../button/props'
22
-
23
- defineOptions({
24
- name: 'Menu'
25
- })
26
- const props = defineProps(MenuProps)
27
-
28
- const editify = inject<ComponentInternalInstance>('editify')!
29
- const isSourceView = inject<Ref<boolean>>('isSourceView')!
30
- const isFullScreen = inject<Ref<boolean>>('isFullScreen')!
31
- const canUseMenu = inject<Ref<boolean>>('canUseMenu')!
32
- const editor = inject<Ref<AlexEditor>>('editor')!
33
- const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
34
- const showBorder = inject<ComputedRef<boolean>>('showBorder')!
35
- const $editTrans = inject<(key: string) => any>('$editTrans')!
36
-
37
- //撤销按钮配置
38
- const undoConfig = ref<ObjectType>({
39
- show: props.config.undo!.show,
40
- leftBorder: props.config.undo!.leftBorder,
41
- rightBorder: props.config.undo!.rightBorder,
42
- active: false,
43
- disabled: false
44
- })
45
- //重做按钮配置
46
- const redoConfig = ref<ObjectType>({
47
- show: props.config.redo!.show,
48
- leftBorder: props.config.redo!.leftBorder,
49
- rightBorder: props.config.redo!.rightBorder,
50
- active: false,
51
- disabled: false
52
- })
53
- //标题按钮配置
54
- const headingConfig = ref<ObjectType>({
55
- show: props.config.heading!.show,
56
- displayConfig: {
57
- options: props.config.heading!.options,
58
- value: '',
59
- width: props.config.heading!.width,
60
- maxHeight: props.config.heading!.maxHeight
61
- },
62
- defaultValue: props.config.heading!.defaultValue,
63
- leftBorder: props.config.heading!.leftBorder,
64
- rightBorder: props.config.heading!.rightBorder,
65
- active: false,
66
- disabled: false
67
- })
68
- //缩进按钮配置
69
- const indentConfig = ref<ObjectType>({
70
- show: props.config.indent!.show,
71
- selectConfig: {
72
- options: props.config.indent!.options,
73
- value: '',
74
- width: props.config.indent!.width,
75
- maxHeight: props.config.indent!.maxHeight
76
- },
77
- leftBorder: props.config.indent!.leftBorder,
78
- rightBorder: props.config.indent!.rightBorder,
79
- active: false,
80
- disabled: false
81
- })
82
- //引用按钮配置
83
- const quoteConfig = ref<ObjectType>({
84
- show: props.config.quote!.show,
85
- leftBorder: props.config.quote!.leftBorder,
86
- rightBorder: props.config.quote!.rightBorder,
87
- active: false,
88
- disabled: false
89
- })
90
- //对齐方式按钮配置
91
- const alignConfig = ref<ObjectType>({
92
- show: props.config.align!.show,
93
- selectConfig: {
94
- options: props.config.align!.options,
95
- width: props.config.align!.width,
96
- maxHeight: props.config.align!.maxHeight
97
- },
98
- leftBorder: props.config.align!.leftBorder,
99
- rightBorder: props.config.align!.rightBorder,
100
- active: false,
101
- disabled: false
102
- })
103
- //有序列表按钮配置
104
- const orderListConfig = ref<ObjectType>({
105
- show: props.config.orderList!.show,
106
- leftBorder: props.config.orderList!.leftBorder,
107
- rightBorder: props.config.orderList!.rightBorder,
108
- active: false,
109
- disabled: false
110
- })
111
- //无序列表按钮配置
112
- const unorderListConfig = ref<ObjectType>({
113
- show: props.config.unorderList!.show,
114
- leftBorder: props.config.unorderList!.leftBorder,
115
- rightBorder: props.config.unorderList!.rightBorder,
116
- active: false,
117
- disabled: false
118
- })
119
- //任务列表按钮配置
120
- const taskConfig = ref<ObjectType>({
121
- show: props.config.task!.show,
122
- leftBorder: props.config.task!.leftBorder,
123
- rightBorder: props.config.task!.rightBorder,
124
- active: false,
125
- disabled: false
126
- })
127
- //粗体按钮配置
128
- const boldConfig = ref<ObjectType>({
129
- show: props.config.bold!.show,
130
- leftBorder: props.config.bold!.leftBorder,
131
- rightBorder: props.config.bold!.rightBorder,
132
- active: false,
133
- disabled: false
134
- })
135
- //下划线按钮配置
136
- const underlineConfig = ref<ObjectType>({
137
- show: props.config.underline!.show,
138
- leftBorder: props.config.underline!.leftBorder,
139
- rightBorder: props.config.underline!.rightBorder,
140
- active: false,
141
- disabled: false
142
- })
143
- //斜体按钮配置
144
- const italicConfig = ref<ObjectType>({
145
- show: props.config.italic!.show,
146
- leftBorder: props.config.italic!.leftBorder,
147
- rightBorder: props.config.italic!.rightBorder,
148
- active: false,
149
- disabled: false
150
- })
151
- //删除线按钮配置
152
- const strikethroughConfig = ref<ObjectType>({
153
- show: props.config.strikethrough!.show,
154
- leftBorder: props.config.strikethrough!.leftBorder,
155
- rightBorder: props.config.strikethrough!.rightBorder,
156
- active: false,
157
- disabled: false
158
- })
159
- //行内代码按钮配置
160
- const codeConfig = ref<ObjectType>({
161
- show: props.config.code!.show,
162
- leftBorder: props.config.code!.leftBorder,
163
- rightBorder: props.config.code!.rightBorder,
164
- active: false,
165
- disabled: false
166
- })
167
- //上标按钮配置
168
- const superConfig = ref<ObjectType>({
169
- show: props.config.super!.show,
170
- leftBorder: props.config.super!.leftBorder,
171
- rightBorder: props.config.super!.rightBorder,
172
- active: false,
173
- disabled: false
174
- })
175
- //下标按钮配置
176
- const subConfig = ref<ObjectType>({
177
- show: props.config.sub!.show,
178
- leftBorder: props.config.sub!.leftBorder,
179
- rightBorder: props.config.sub!.rightBorder,
180
- active: false,
181
- disabled: false
182
- })
183
- //清除格式按钮配置
184
- const formatClearConfig = ref<ObjectType>({
185
- show: props.config.formatClear!.show,
186
- leftBorder: props.config.formatClear!.leftBorder,
187
- rightBorder: props.config.formatClear!.rightBorder,
188
- active: false,
189
- disabled: false
190
- })
191
- //字号按钮配置
192
- const fontSizeConfig = ref<ObjectType>({
193
- show: props.config.fontSize!.show,
194
- displayConfig: {
195
- options: props.config.fontSize!.options,
196
- value: '',
197
- width: props.config.fontSize!.width,
198
- maxHeight: props.config.fontSize!.maxHeight
199
- },
200
- defaultValue: props.config.fontSize!.defaultValue,
201
- leftBorder: props.config.fontSize!.leftBorder,
202
- rightBorder: props.config.fontSize!.rightBorder,
203
- active: false,
204
- disabled: false
205
- })
206
- //字体按钮配置
207
- const fontFamilyConfig = ref<ObjectType>({
208
- show: props.config.fontFamily!.show,
209
- displayConfig: {
210
- options: props.config.fontFamily!.options,
211
- value: '',
212
- width: props.config.fontFamily!.width,
213
- maxHeight: props.config.fontFamily!.maxHeight
214
- },
215
- defaultValue: props.config.fontFamily!.defaultValue,
216
- leftBorder: props.config.fontFamily!.leftBorder,
217
- rightBorder: props.config.fontFamily!.rightBorder,
218
- active: false,
219
- disabled: false
220
- })
221
- //行高按钮配置
222
- const lineHeightConfig = ref<ObjectType>({
223
- show: props.config.lineHeight!.show,
224
- displayConfig: {
225
- options: props.config.lineHeight!.options,
226
- value: '',
227
- width: props.config.lineHeight!.width,
228
- maxHeight: props.config.lineHeight!.maxHeight
229
- },
230
- defaultValue: props.config.lineHeight!.defaultValue,
231
- leftBorder: props.config.lineHeight!.leftBorder,
232
- rightBorder: props.config.lineHeight!.rightBorder,
233
- active: false,
234
- disabled: false
235
- })
236
- //前景颜色按钮配置
237
- const foreColorConfig = ref<ObjectType>({
238
- show: props.config.foreColor!.show,
239
- selectConfig: {
240
- options: props.config.foreColor!.options
241
- },
242
- leftBorder: props.config.foreColor!.leftBorder,
243
- rightBorder: props.config.foreColor!.rightBorder,
244
- value: '', //选择的颜色值
245
- active: false,
246
- disabled: false
247
- })
248
- //背景颜色按钮配置
249
- const backColorConfig = ref<ObjectType>({
250
- show: props.config.backColor!.show,
251
- selectConfig: {
252
- options: props.config.backColor!.options
253
- },
254
- leftBorder: props.config.backColor!.leftBorder,
255
- rightBorder: props.config.backColor!.rightBorder,
256
- value: '', //选择的颜色值
257
- active: false,
258
- disabled: false
259
- })
260
- //链接按钮配置
261
- const linkConfig = ref<ObjectType>({
262
- show: props.config.link!.show,
263
- leftBorder: props.config.link!.leftBorder,
264
- rightBorder: props.config.link!.rightBorder,
265
- active: false,
266
- disabled: false,
267
- text: '' //链接的文本
268
- })
269
- //插入图片按钮配置
270
- const imageConfig = ref<ObjectType>({
271
- show: props.config.image!.show,
272
- leftBorder: props.config.image!.leftBorder,
273
- rightBorder: props.config.image!.rightBorder,
274
- active: false,
275
- disabled: false,
276
- accept: props.config.image!.accept,
277
- multiple: props.config.image!.multiple,
278
- maxSize: props.config.image!.maxSize,
279
- minSize: props.config.image!.minSize,
280
- handleError: props.config.image!.handleError,
281
- customUpload: props.config.image!.customUpload
282
- })
283
- //插入视频按钮配置
284
- const videoConfig = ref<ObjectType>({
285
- show: props.config.video!.show,
286
- leftBorder: props.config.video!.leftBorder,
287
- rightBorder: props.config.video!.rightBorder,
288
- active: false,
289
- disabled: false,
290
- accept: props.config.video!.accept,
291
- multiple: props.config.video!.multiple,
292
- maxSize: props.config.video!.maxSize,
293
- minSize: props.config.video!.minSize,
294
- handleError: props.config.video!.handleError,
295
- customUpload: props.config.video!.customUpload
296
- })
297
- //表格按钮配置
298
- const tableConfig = ref<ObjectType>({
299
- show: props.config.table!.show,
300
- leftBorder: props.config.table!.leftBorder,
301
- rightBorder: props.config.table!.rightBorder,
302
- active: false,
303
- disabled: false,
304
- maxRows: props.config.table!.maxRows,
305
- maxColumns: props.config.table!.maxColumns
306
- })
307
- //代码块按钮配置
308
- const codeBlockConfig = ref<ObjectType>({
309
- show: props.config.codeBlock!.show,
310
- leftBorder: props.config.codeBlock!.leftBorder,
311
- rightBorder: props.config.codeBlock!.rightBorder,
312
- active: false,
313
- disabled: false
314
- })
315
- //代码视图按钮配置
316
- const sourceViewConfig = ref<ObjectType>({
317
- show: props.config.sourceView!.show,
318
- leftBorder: props.config.sourceView!.leftBorder,
319
- rightBorder: props.config.sourceView!.rightBorder,
320
- active: false,
321
- disabled: false
322
- })
323
- //全屏按钮配置
324
- const fullScreenConfig = ref<ObjectType>({
325
- show: props.config.fullScreen!.show,
326
- leftBorder: props.config.fullScreen!.leftBorder,
327
- rightBorder: props.config.fullScreen!.rightBorder,
328
- active: false,
329
- disabled: false
330
- })
331
-
332
- //整个菜单栏是否禁用
333
- const disabled = computed<boolean>(() => {
334
- return <boolean>editify.props.disabled || !canUseMenu.value
335
- })
336
- //菜单名称数组
337
- const menuNames = computed<string[]>(() => {
338
- return Object.keys(props.config.sequence!).sort((a, b) => {
339
- if (props.config.sequence![a] > props.config.sequence![b]) {
340
- return 1
341
- }
342
- return -1
343
- })
344
- })
345
- //菜单是否禁用
346
- const menuDisabled = computed<(name: string) => boolean>(() => {
347
- return (name: string) => {
348
- if (name == 'sourceView' || name == 'fullScreen') {
349
- return false
350
- }
351
- return isSourceView.value
352
- }
353
- })
354
- //菜单模式
355
- const menuMode = computed<MenuModeType>(() => {
356
- //如果是全屏状态下或者高度自适应状态下
357
- if (isFullScreen.value || editify.props.autoheight) {
358
- //fixed模式改为默认模式
359
- if (props.config.mode == 'fixed') {
360
- return 'default'
361
- }
362
- }
363
- return props.config.mode!
364
- })
365
- //菜单栏是否显示边框
366
- const menuShowBorder = computed(() => {
367
- //fixed模式下不显示边框
368
- if (menuMode.value == 'fixed') {
369
- return false
370
- }
371
- //由编辑器的border属性来决定
372
- return showBorder.value
373
- })
374
-
375
- //按钮操作触发函数
376
- const handleOperate = (name: string, val: string | number | ObjectType) => {
377
- //菜单栏禁用
378
- if (disabled.value) {
379
- return
380
- }
381
- //没有获取焦点
382
- if (!editor.value.range) {
383
- return
384
- }
385
- //撤销
386
- if (name == 'undo') {
387
- editify.exposed!.undo()
388
- }
389
- //重做
390
- else if (name == 'redo') {
391
- editify.exposed!.redo()
392
- }
393
- //设置标题
394
- else if (name == 'heading') {
395
- setHeading(editor.value, dataRangeCaches.value, $editTrans, <string>val)
396
- editor.value.formatElementStack()
397
- editor.value.domRender()
398
- editor.value.rangeRender()
399
- }
400
- //设置缩进
401
- else if (name == 'indent') {
402
- //增加缩进
403
- if (val == 'indent-increase') {
404
- setIndentIncrease(editor.value, dataRangeCaches.value)
405
- }
406
- //减少缩进
407
- else if (val == 'indent-decrease') {
408
- setIndentDecrease(editor.value, dataRangeCaches.value)
409
- }
410
- editor.value.formatElementStack()
411
- editor.value.domRender()
412
- editor.value.rangeRender()
413
- }
414
- //设置引用
415
- else if (name == 'quote') {
416
- setQuote(editor.value, dataRangeCaches.value)
417
- editor.value.formatElementStack()
418
- editor.value.domRender()
419
- editor.value.rangeRender()
420
- }
421
- //设置对齐方式
422
- else if (name == 'align') {
423
- setAlign(editor.value, dataRangeCaches.value, <string>val)
424
- editor.value.formatElementStack()
425
- editor.value.domRender()
426
- editor.value.rangeRender()
427
- }
428
- //设置有序列表
429
- else if (name == 'orderList') {
430
- setList(editor.value, dataRangeCaches.value, true)
431
- editor.value.formatElementStack()
432
- editor.value.domRender()
433
- editor.value.rangeRender()
434
- }
435
- //设置无序列表
436
- else if (name == 'unorderList') {
437
- setList(editor.value, dataRangeCaches.value, false)
438
- editor.value.formatElementStack()
439
- editor.value.domRender()
440
- editor.value.rangeRender()
441
- }
442
- //设置任务列表
443
- else if (name == 'task') {
444
- setTask(editor.value, dataRangeCaches.value)
445
- editor.value.formatElementStack()
446
- editor.value.domRender()
447
- editor.value.rangeRender()
448
- }
449
- //设置粗体
450
- else if (name == 'bold') {
451
- if (queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', 'bold') || queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', '700')) {
452
- removeTextStyle(editor.value, dataRangeCaches.value, ['font-weight'])
453
- } else {
454
- setTextStyle(editor.value, dataRangeCaches.value, {
455
- 'font-weight': 'bold'
456
- })
457
- }
458
- editor.value.formatElementStack()
459
- editor.value.domRender()
460
- editor.value.rangeRender()
461
- }
462
- //设置下划线
463
- else if (name == 'underline') {
464
- if (queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration', 'underline') || queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration-line', 'underline')) {
465
- removeTextStyle(editor.value, dataRangeCaches.value, ['text-decoration', 'text-decoration-line'])
466
- } else {
467
- setTextStyle(editor.value, dataRangeCaches.value, {
468
- 'text-decoration': 'underline'
469
- })
470
- }
471
- editor.value.formatElementStack()
472
- editor.value.domRender()
473
- editor.value.rangeRender()
474
- }
475
- //设置斜体
476
- else if (name == 'italic') {
477
- if (queryTextStyle(editor.value, dataRangeCaches.value, 'font-style', 'italic')) {
478
- removeTextStyle(editor.value, dataRangeCaches.value, ['font-style'])
479
- } else {
480
- setTextStyle(editor.value, dataRangeCaches.value, {
481
- 'font-style': 'italic'
482
- })
483
- }
484
- editor.value.formatElementStack()
485
- editor.value.domRender()
486
- editor.value.rangeRender()
487
- }
488
- //设置删除线
489
- else if (name == 'strikethrough') {
490
- if (queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration', 'line-through') || queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration-line', 'line-through')) {
491
- removeTextStyle(editor.value, dataRangeCaches.value, ['text-decoration', 'text-decoration-line'])
492
- } else {
493
- setTextStyle(editor.value, dataRangeCaches.value, {
494
- 'text-decoration': 'line-through'
495
- })
496
- }
497
- editor.value.formatElementStack()
498
- editor.value.domRender()
499
- editor.value.rangeRender()
500
- }
501
- //设置行内代码
502
- else if (name == 'code') {
503
- if (queryTextMark(editor.value, dataRangeCaches.value, 'data-editify-code')) {
504
- removeTextMark(editor.value, dataRangeCaches.value, ['data-editify-code'])
505
- } else {
506
- setTextMark(editor.value, dataRangeCaches.value, {
507
- 'data-editify-code': true
508
- })
509
- }
510
- editor.value.formatElementStack()
511
- editor.value.domRender()
512
- editor.value.rangeRender()
513
- }
514
- //设置上标
515
- else if (name == 'super') {
516
- if (queryTextStyle(editor.value, dataRangeCaches.value, 'vertical-align', 'super')) {
517
- removeTextStyle(editor.value, dataRangeCaches.value, ['vertical-align'])
518
- } else {
519
- setTextStyle(editor.value, dataRangeCaches.value, {
520
- 'vertical-align': 'super'
521
- })
522
- }
523
- editor.value.formatElementStack()
524
- editor.value.domRender()
525
- editor.value.rangeRender()
526
- }
527
- //设置下标
528
- else if (name == 'sub') {
529
- if (queryTextStyle(editor.value, dataRangeCaches.value, 'vertical-align', 'sub')) {
530
- removeTextStyle(editor.value, dataRangeCaches.value, ['vertical-align'])
531
- } else {
532
- setTextStyle(editor.value, dataRangeCaches.value, {
533
- 'vertical-align': 'sub'
534
- })
535
- }
536
- editor.value.formatElementStack()
537
- editor.value.domRender()
538
- editor.value.rangeRender()
539
- }
540
- //清除格式
541
- else if (name == 'formatClear') {
542
- removeTextStyle(editor.value, dataRangeCaches.value)
543
- removeTextMark(editor.value, dataRangeCaches.value)
544
- editor.value.formatElementStack()
545
- editor.value.domRender()
546
- editor.value.rangeRender()
547
- }
548
- //设置字号
549
- else if (name == 'fontSize') {
550
- setTextStyle(editor.value, dataRangeCaches.value, {
551
- 'font-size': val
552
- })
553
- editor.value.formatElementStack()
554
- editor.value.domRender()
555
- editor.value.rangeRender()
556
- }
557
- //设置字体
558
- else if (name == 'fontFamily') {
559
- setTextStyle(editor.value, dataRangeCaches.value, {
560
- 'font-family': val
561
- })
562
- editor.value.formatElementStack()
563
- editor.value.domRender()
564
- editor.value.rangeRender()
565
- }
566
- //设置行高
567
- else if (name == 'lineHeight') {
568
- setLineHeight(editor.value, dataRangeCaches.value, <string | number>val)
569
- editor.value.formatElementStack()
570
- editor.value.domRender()
571
- editor.value.rangeRender()
572
- }
573
- //设置前景色
574
- else if (name == 'foreColor') {
575
- setTextStyle(editor.value, dataRangeCaches.value, {
576
- color: val
577
- })
578
- editor.value.formatElementStack()
579
- editor.value.domRender()
580
- editor.value.rangeRender()
581
- }
582
- //设置背景色
583
- else if (name == 'backColor') {
584
- setTextStyle(editor.value, dataRangeCaches.value, {
585
- 'background-color': val
586
- })
587
- editor.value.formatElementStack()
588
- editor.value.domRender()
589
- editor.value.rangeRender()
590
- }
591
- //插入链接
592
- else if (name == 'link') {
593
- if (!(<ObjectType>val).url) {
594
- return
595
- }
596
- insertLink(editor.value, (<ObjectType>val).text, (<ObjectType>val).url, (<ObjectType>val).newOpen)
597
- editor.value.formatElementStack()
598
- editor.value.domRender()
599
- editor.value.rangeRender()
600
- }
601
- //插入图片
602
- else if (name == 'image') {
603
- if (!val) {
604
- return
605
- }
606
- insertImage(editor.value, <string>val)
607
- editor.value.formatElementStack()
608
- editor.value.domRender()
609
- editor.value.rangeRender()
610
- }
611
- //插入视频
612
- else if (name == 'video') {
613
- if (!val) {
614
- return
615
- }
616
- insertVideo(editor.value, <string>val)
617
- editor.value.formatElementStack()
618
- editor.value.domRender()
619
- editor.value.rangeRender()
620
- }
621
- //插入表格
622
- else if (name == 'table') {
623
- insertTable(editor.value, (<ObjectType>val).row, (<ObjectType>val).column)
624
- editor.value.formatElementStack()
625
- editor.value.domRender()
626
- editor.value.rangeRender()
627
- }
628
- //插入代码块
629
- else if (name == 'codeBlock') {
630
- insertCodeBlock(editor.value, dataRangeCaches.value)
631
- editor.value.formatElementStack()
632
- editor.value.domRender()
633
- editor.value.rangeRender()
634
- }
635
- //代码视图
636
- else if (name == 'sourceView') {
637
- isSourceView.value = !isSourceView.value
638
- sourceViewConfig.value.active = isSourceView.value
639
- if (!isSourceView.value) {
640
- editor.value.rangeRender()
641
- }
642
- }
643
- //全屏
644
- else if (name == 'fullScreen') {
645
- isFullScreen.value = !isFullScreen.value
646
- fullScreenConfig.value.active = isFullScreen.value
647
- editor.value.rangeRender()
648
- }
649
- }
650
- //处理光标更新
651
- const handleRangeUpdate = () => {
652
- //选区是否含有代码块
653
- const value_hasPreInRange = hasPreInRange(editor.value, dataRangeCaches.value)
654
- //选区是否含有表格元素
655
- const value_hasTableInRange = hasTableInRange(editor.value, dataRangeCaches.value)
656
- //选区是否含有引用元素
657
- const value_hasQuoteInRange = hasQuoteInRange(editor.value, dataRangeCaches.value)
658
- //选区是否都在引用元素内
659
- const value_isRangeInQuote = isRangeInQuote(editor.value, dataRangeCaches.value)
660
- //选区是否含有链接元素
661
- const value_hasLinkInRange = hasLinkInRange(editor.value, dataRangeCaches.value)
662
- //选区是否都在有序列表内
663
- const value_isRangeInOrderList = isRangeInList(editor.value, dataRangeCaches.value, true)
664
- //选区是否都在无序列表内
665
- const value_isRangeInUnorderList = isRangeInList(editor.value, dataRangeCaches.value, false)
666
- //选区是否都在任务列表内
667
- const value_isRangeInTask = isRangeInTask(editor.value, dataRangeCaches.value)
668
- //额外禁用判定
669
- const extraDisabled = (name: string) => {
670
- if (typeof props.config.extraDisabled == 'function') {
671
- return props.config.extraDisabled.apply(editify.proxy!, [name]) || false
672
- }
673
- return false
674
- }
675
-
676
- //撤销按钮禁用
677
- undoConfig.value.disabled = !editor.value.history.get(-1) || extraDisabled('undo')
678
-
679
- //重做按钮禁用
680
- redoConfig.value.disabled = !editor.value.history.get(1) || extraDisabled('redo')
681
-
682
- //显示已设置标题
683
- const findHeadingItem = headingConfig.value.displayConfig.options.find((item: string | number | ButtonOptionsItemType) => {
684
- let val: string | number | ButtonOptionsItemType = item
685
- if (DapCommon.isObject(item)) {
686
- val = (<ButtonOptionsItemType>item).value!
687
- }
688
- if (editor.value.range!.anchor.isEqual(editor.value.range!.focus)) {
689
- return editor.value.range!.anchor.element.getBlock().parsedom == val
690
- }
691
- return dataRangeCaches.value.list.every(el => {
692
- if (el.element.isBlock()) {
693
- return el.element.parsedom == val
694
- }
695
- return el.element.getBlock().parsedom == val
696
- })
697
- })
698
- headingConfig.value.displayConfig.value = findHeadingItem ? (DapCommon.isObject(findHeadingItem) ? findHeadingItem.value : findHeadingItem) : headingConfig.value.defaultValue
699
- //标题禁用
700
- headingConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('heading')
701
-
702
- //缩进禁用
703
- indentConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('indent')
704
-
705
- //引用按钮激活
706
- quoteConfig.value.active = value_isRangeInQuote
707
- //引用按钮禁用
708
- quoteConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('quote')
709
-
710
- //对齐方式按钮禁用
711
- alignConfig.value.disabled = value_hasPreInRange || extraDisabled('align')
712
-
713
- //有序列表按钮激活
714
- orderListConfig.value.active = value_isRangeInOrderList
715
- //有序列表禁用
716
- orderListConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('orderList')
717
-
718
- //无序列表按钮激活
719
- unorderListConfig.value.active = value_isRangeInUnorderList
720
- //无序列表禁用
721
- unorderListConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('unorderList')
722
-
723
- //任务列表按钮激活
724
- taskConfig.value.active = value_isRangeInTask
725
- //任务列表禁用
726
- taskConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('task')
727
-
728
- //粗体按钮激活
729
- boldConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', 'bold') || queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', '700')
730
- //粗体按钮禁用
731
- boldConfig.value.disabled = value_hasPreInRange || extraDisabled('bold')
732
-
733
- //下划线按钮激活
734
- underlineConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration', 'underline') || queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration-line', 'underline')
735
- //下划线按钮禁用
736
- underlineConfig.value.disabled = value_hasPreInRange || extraDisabled('underline')
737
-
738
- //斜体按钮激活
739
- italicConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'font-style', 'italic')
740
- //斜体按钮禁用
741
- italicConfig.value.disabled = value_hasPreInRange || extraDisabled('italic')
742
-
743
- //删除线按钮激活
744
- strikethroughConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration', 'line-through') || queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration-line', 'line-through')
745
- //删除线按钮禁用
746
- strikethroughConfig.value.disabled = value_hasPreInRange || extraDisabled('strikethrough')
747
-
748
- //行内代码按钮激活
749
- codeConfig.value.active = queryTextMark(editor.value, dataRangeCaches.value, 'data-editify-code')
750
- //行内代码按钮禁用
751
- codeConfig.value.disabled = value_hasPreInRange || extraDisabled('code')
752
-
753
- //上标按钮激活
754
- superConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'vertical-align', 'super')
755
- //上标按钮禁用
756
- superConfig.value.disabled = value_hasPreInRange || extraDisabled('super')
757
-
758
- //下标按钮激活
759
- subConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'vertical-align', 'sub')
760
- //下标按钮禁用
761
- subConfig.value.disabled = value_hasPreInRange || extraDisabled('sub')
762
-
763
- //清除格式按钮禁用
764
- formatClearConfig.value.disabled = value_hasPreInRange || extraDisabled('formatClear')
765
-
766
- //显示已选择字号
767
- const findFontItem = fontSizeConfig.value.displayConfig.options.find((item: string | ButtonOptionsItemType) => {
768
- if (DapCommon.isObject(item)) {
769
- return queryTextStyle(editor.value, dataRangeCaches.value, 'font-size', (<ButtonOptionsItemType>item).value)
770
- }
771
- return queryTextStyle(editor.value, dataRangeCaches.value, 'font-size', <string>item)
772
- })
773
- fontSizeConfig.value.displayConfig.value = findFontItem ? (DapCommon.isObject(findFontItem) ? findFontItem.value : findFontItem) : fontSizeConfig.value.defaultValue
774
- //字号按钮禁用
775
- fontSizeConfig.value.disabled = value_hasPreInRange || extraDisabled('fontSize')
776
-
777
- //显示已选择字体
778
- const findFamilyItem = fontFamilyConfig.value.displayConfig.options.find((item: string | ButtonOptionsItemType) => {
779
- if (DapCommon.isObject(item)) {
780
- return queryTextStyle(editor.value, dataRangeCaches.value, 'font-family', (<ButtonOptionsItemType>item).value)
781
- }
782
- return queryTextStyle(editor.value, dataRangeCaches.value, 'font-family', <string>item)
783
- })
784
- fontFamilyConfig.value.displayConfig.value = findFamilyItem ? (DapCommon.isObject(findFamilyItem) ? findFamilyItem.value : findFamilyItem) : fontFamilyConfig.value.defaultValue
785
- //字体按钮禁用
786
- fontFamilyConfig.value.disabled = value_hasPreInRange || extraDisabled('fontFamily')
787
-
788
- //显示已设置行高
789
- const findHeightItem = lineHeightConfig.value.displayConfig.options.find((item: string | number | ButtonOptionsItemType) => {
790
- let val: string | number | ButtonOptionsItemType = item
791
- if (DapCommon.isObject(item)) {
792
- val = (<ButtonOptionsItemType>item).value!
793
- }
794
- if (editor.value.range!.anchor.isEqual(editor.value.range!.focus)) {
795
- const block = editor.value.range!.anchor.element.getBlock()
796
- return block.hasStyles() && block.styles!['line-height'] == val
797
- }
798
- return dataRangeCaches.value.list.every(el => {
799
- if (el.element.isBlock() || el.element.isInblock()) {
800
- return el.element.hasStyles() && el.element.styles!['line-height'] == val
801
- }
802
- const block = el.element.getBlock()
803
- const inblock = el.element.getInblock()
804
- if (inblock) {
805
- return inblock.hasStyles() && inblock.styles!['line-height'] == val
806
- }
807
- return block.hasStyles() && block.styles!['line-height'] == val
808
- })
809
- })
810
- lineHeightConfig.value.displayConfig.value = findHeightItem ? (DapCommon.isObject(findHeightItem) ? findHeightItem.value : findHeightItem) : lineHeightConfig.value.defaultValue
811
- //行高按钮禁用
812
- lineHeightConfig.value.disabled = value_hasPreInRange || extraDisabled('lineHeight')
813
-
814
- //显示已选择的前景色
815
- const findForeColorItem = foreColorConfig.value.selectConfig.options.find((item: string | ButtonOptionsItemType) => {
816
- if (DapCommon.isObject(item)) {
817
- return queryTextStyle(editor.value, dataRangeCaches.value, 'color', (<ButtonOptionsItemType>item).value)
818
- }
819
- return queryTextStyle(editor.value, dataRangeCaches.value, 'color', <string>item)
820
- })
821
- foreColorConfig.value.value = findForeColorItem ? (DapCommon.isObject(findForeColorItem) ? findForeColorItem.value : findForeColorItem) : ''
822
- //前景色按钮禁用
823
- foreColorConfig.value.disabled = value_hasPreInRange || extraDisabled('foreColor')
824
-
825
- //显示已选择的背景色
826
- const findBackColorItem = backColorConfig.value.selectConfig.options.find((item: string | ButtonOptionsItemType) => {
827
- if (DapCommon.isObject(item)) {
828
- return queryTextStyle(editor.value, dataRangeCaches.value, 'background-color', (<ButtonOptionsItemType>item).value)
829
- }
830
- return queryTextStyle(editor.value, dataRangeCaches.value, 'background-color', <string>item)
831
- })
832
- backColorConfig.value.value = findBackColorItem ? (DapCommon.isObject(findBackColorItem) ? findBackColorItem.value : findBackColorItem) : ''
833
- //背景色按钮禁用
834
- backColorConfig.value.disabled = value_hasPreInRange || extraDisabled('backColor')
835
-
836
- //链接按钮禁用
837
- linkConfig.value.disabled = value_hasLinkInRange || value_hasPreInRange || extraDisabled('link')
838
-
839
- //插入图片按钮禁用
840
- imageConfig.value.disabled = value_hasPreInRange || extraDisabled('image')
841
-
842
- //插入视频按钮禁用
843
- videoConfig.value.disabled = value_hasPreInRange || extraDisabled('video')
844
-
845
- //表格按钮禁用
846
- tableConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || value_hasQuoteInRange || extraDisabled('table')
847
-
848
- //代码块按钮激活
849
- codeBlockConfig.value.active = !!getCurrentParsedomElement(editor.value, dataRangeCaches.value, 'pre')
850
- //代码块按钮禁用
851
- codeBlockConfig.value.disabled = value_hasTableInRange || value_hasQuoteInRange || extraDisabled('codeBlock')
852
-
853
- //代码视图按钮激活
854
- sourceViewConfig.value.active = isSourceView.value
855
-
856
- //全屏按钮激活
857
- fullScreenConfig.value.active = isFullScreen.value
858
- }
859
-
860
- //菜单项子组件
861
- const MenuItem = defineComponent(
862
- selfProps => {
863
- //获取实例
864
- const itemInstance = getCurrentInstance()!
865
- //共同设置的属性
866
- const itemProps = {
867
- tooltip: props.config.tooltip,
868
- name: selfProps.name
869
- }
870
- return () => {
871
- //撤销按钮
872
- if (itemProps.name == 'undo' && undoConfig.value.show) {
873
- return h(
874
- Button,
875
- {
876
- ...itemProps,
877
- title: $editTrans('undo'),
878
- leftBorder: undoConfig.value.leftBorder,
879
- rightBorder: undoConfig.value.rightBorder,
880
- disabled: undoConfig.value.disabled || selfProps.disabled || disabled.value,
881
- color: props.color,
882
- active: undoConfig.value.active,
883
- onOperate: handleOperate
884
- },
885
- () => h(Icon, { value: 'undo' })
886
- )
887
- }
888
- //重做按钮
889
- if (itemProps.name == 'redo' && redoConfig.value.show) {
890
- return h(
891
- Button,
892
- {
893
- ...itemProps,
894
- title: $editTrans('redo'),
895
- leftBorder: redoConfig.value.leftBorder,
896
- rightBorder: redoConfig.value.rightBorder,
897
- disabled: redoConfig.value.disabled || selfProps.disabled || disabled.value,
898
- color: props.color,
899
- active: redoConfig.value.active,
900
- onOperate: handleOperate
901
- },
902
- () => h(Icon, { value: 'redo' })
903
- )
904
- }
905
- //标题按钮
906
- if (itemProps.name == 'heading' && headingConfig.value.show) {
907
- return h(Button, {
908
- ...itemProps,
909
- type: 'display',
910
- displayConfig: headingConfig.value.displayConfig,
911
- title: $editTrans('heading'),
912
- leftBorder: headingConfig.value.leftBorder,
913
- rightBorder: headingConfig.value.rightBorder,
914
- color: props.color,
915
- disabled: headingConfig.value.disabled || selfProps.disabled || disabled.value,
916
- active: headingConfig.value.active,
917
- onOperate: handleOperate
918
- })
919
- }
920
- //缩进按钮
921
- if (itemProps.name == 'indent' && indentConfig.value.show) {
922
- return h(
923
- Button,
924
- {
925
- ...itemProps,
926
- type: 'select',
927
- selectConfig: indentConfig.value.selectConfig,
928
- title: $editTrans('indent'),
929
- leftBorder: indentConfig.value.leftBorder,
930
- rightBorder: indentConfig.value.rightBorder,
931
- color: props.color,
932
- disabled: indentConfig.value.disabled || selfProps.disabled || disabled.value,
933
- active: indentConfig.value.active,
934
- onOperate: handleOperate
935
- },
936
- () => h(Icon, { value: 'indent-increase' })
937
- )
938
- }
939
- //引用按钮
940
- if (itemProps.name == 'quote' && quoteConfig.value.show) {
941
- return h(
942
- Button,
943
- {
944
- ...itemProps,
945
- title: $editTrans('quote'),
946
- leftBorder: quoteConfig.value.leftBorder,
947
- rightBorder: quoteConfig.value.rightBorder,
948
- color: props.color,
949
- disabled: quoteConfig.value.disabled || selfProps.disabled || disabled.value,
950
- active: quoteConfig.value.active,
951
- onOperate: handleOperate
952
- },
953
- () => h(Icon, { value: 'quote' })
954
- )
955
- }
956
- //对齐方式按钮
957
- if (itemProps.name == 'align' && alignConfig.value.show) {
958
- return h(
959
- Button,
960
- {
961
- ...itemProps,
962
- type: 'select',
963
- selectConfig: alignConfig.value.selectConfig,
964
- title: $editTrans('align'),
965
- leftBorder: alignConfig.value.leftBorder,
966
- rightBorder: alignConfig.value.rightBorder,
967
- color: props.color,
968
- disabled: alignConfig.value.disabled || selfProps.disabled || disabled.value,
969
- active: alignConfig.value.active,
970
- onOperate: handleOperate
971
- },
972
- () => h(Icon, { value: 'align-left' })
973
- )
974
- }
975
- //有序列表按钮
976
- if (itemProps.name == 'orderList' && orderListConfig.value.show) {
977
- return h(
978
- Button,
979
- {
980
- ...itemProps,
981
- title: $editTrans('orderList'),
982
- leftBorder: orderListConfig.value.leftBorder,
983
- rightBorder: orderListConfig.value.rightBorder,
984
- color: props.color,
985
- disabled: orderListConfig.value.disabled || selfProps.disabled || disabled.value,
986
- active: orderListConfig.value.active,
987
- onOperate: handleOperate
988
- },
989
- () => h(Icon, { value: 'list-ordered' })
990
- )
991
- }
992
- //无序列表按钮
993
- if (itemProps.name == 'unorderList' && unorderListConfig.value.show) {
994
- return h(
995
- Button,
996
- {
997
- ...itemProps,
998
- title: $editTrans('unorderList'),
999
- leftBorder: unorderListConfig.value.leftBorder,
1000
- rightBorder: unorderListConfig.value.rightBorder,
1001
- color: props.color,
1002
- disabled: unorderListConfig.value.disabled || selfProps.disabled || disabled.value,
1003
- active: unorderListConfig.value.active,
1004
- onOperate: handleOperate
1005
- },
1006
- () => h(Icon, { value: 'list-unordered' })
1007
- )
1008
- }
1009
- //任务列表按钮
1010
- if (itemProps.name == 'task' && taskConfig.value.show) {
1011
- return h(
1012
- Button,
1013
- {
1014
- ...itemProps,
1015
- title: $editTrans('task'),
1016
- leftBorder: taskConfig.value.leftBorder,
1017
- rightBorder: taskConfig.value.rightBorder,
1018
- color: props.color,
1019
- disabled: taskConfig.value.disabled || selfProps.disabled || disabled.value,
1020
- active: taskConfig.value.active,
1021
- onOperate: handleOperate
1022
- },
1023
- () => h(Icon, { value: 'task' })
1024
- )
1025
- }
1026
- //粗体按钮
1027
- if (itemProps.name == 'bold' && boldConfig.value.show) {
1028
- return h(
1029
- Button,
1030
- {
1031
- ...itemProps,
1032
- title: $editTrans('bold'),
1033
- leftBorder: boldConfig.value.leftBorder,
1034
- rightBorder: boldConfig.value.rightBorder,
1035
- color: props.color,
1036
- disabled: boldConfig.value.disabled || selfProps.disabled || disabled.value,
1037
- active: boldConfig.value.active,
1038
- onOperate: handleOperate
1039
- },
1040
- () => h(Icon, { value: 'bold' })
1041
- )
1042
- }
1043
- //下划线按钮
1044
- if (itemProps.name == 'underline' && underlineConfig.value.show) {
1045
- return h(
1046
- Button,
1047
- {
1048
- ...itemProps,
1049
- title: $editTrans('underline'),
1050
- leftBorder: underlineConfig.value.leftBorder,
1051
- rightBorder: underlineConfig.value.rightBorder,
1052
- color: props.color,
1053
- disabled: underlineConfig.value.disabled || selfProps.disabled || disabled.value,
1054
- active: underlineConfig.value.active,
1055
- onOperate: handleOperate
1056
- },
1057
- () => h(Icon, { value: 'underline' })
1058
- )
1059
- }
1060
- //斜体按钮
1061
- if (itemProps.name == 'italic' && italicConfig.value.show) {
1062
- return h(
1063
- Button,
1064
- {
1065
- ...itemProps,
1066
- title: $editTrans('italic'),
1067
- leftBorder: italicConfig.value.leftBorder,
1068
- rightBorder: italicConfig.value.rightBorder,
1069
- color: props.color,
1070
- disabled: italicConfig.value.disabled || selfProps.disabled || disabled.value,
1071
- active: italicConfig.value.active,
1072
- onOperate: handleOperate
1073
- },
1074
- () => h(Icon, { value: 'italic' })
1075
- )
1076
- }
1077
- //删除线按钮
1078
- if (itemProps.name == 'strikethrough' && strikethroughConfig.value.show) {
1079
- return h(
1080
- Button,
1081
- {
1082
- ...itemProps,
1083
- title: $editTrans('strikethrough'),
1084
- leftBorder: strikethroughConfig.value.leftBorder,
1085
- rightBorder: strikethroughConfig.value.rightBorder,
1086
- color: props.color,
1087
- disabled: strikethroughConfig.value.disabled || selfProps.disabled || disabled.value,
1088
- active: strikethroughConfig.value.active,
1089
- onOperate: handleOperate
1090
- },
1091
- () => h(Icon, { value: 'strikethrough' })
1092
- )
1093
- }
1094
- //行内代码按钮
1095
- if (itemProps.name == 'code' && codeConfig.value.show) {
1096
- return h(
1097
- Button,
1098
- {
1099
- ...itemProps,
1100
- title: $editTrans('code'),
1101
- leftBorder: codeConfig.value.leftBorder,
1102
- rightBorder: codeConfig.value.rightBorder,
1103
- color: props.color,
1104
- disabled: codeConfig.value.disabled || selfProps.disabled || disabled.value,
1105
- active: codeConfig.value.active,
1106
- onOperate: handleOperate
1107
- },
1108
- () => h(Icon, { value: 'code' })
1109
- )
1110
- }
1111
- //上标按钮
1112
- if (itemProps.name == 'super' && superConfig.value.show) {
1113
- return h(
1114
- Button,
1115
- {
1116
- ...itemProps,
1117
- title: $editTrans('superscript'),
1118
- leftBorder: superConfig.value.leftBorder,
1119
- rightBorder: superConfig.value.rightBorder,
1120
- color: props.color,
1121
- disabled: superConfig.value.disabled || selfProps.disabled || disabled.value,
1122
- active: superConfig.value.active,
1123
- onOperate: handleOperate
1124
- },
1125
- () => h(Icon, { value: 'superscript' })
1126
- )
1127
- }
1128
- //下标按钮
1129
- if (itemProps.name == 'sub' && subConfig.value.show) {
1130
- return h(
1131
- Button,
1132
- {
1133
- ...itemProps,
1134
- title: $editTrans('subscript'),
1135
- leftBorder: subConfig.value.leftBorder,
1136
- rightBorder: subConfig.value.rightBorder,
1137
- color: props.color,
1138
- disabled: subConfig.value.disabled || selfProps.disabled || disabled.value,
1139
- active: subConfig.value.active,
1140
- onOperate: handleOperate
1141
- },
1142
- () => h(Icon, { value: 'subscript' })
1143
- )
1144
- }
1145
- //清除格式按钮
1146
- if (itemProps.name == 'formatClear' && formatClearConfig.value.show) {
1147
- return h(
1148
- Button,
1149
- {
1150
- ...itemProps,
1151
- title: $editTrans('formatClear'),
1152
- leftBorder: formatClearConfig.value.leftBorder,
1153
- rightBorder: formatClearConfig.value.rightBorder,
1154
- color: props.color,
1155
- disabled: formatClearConfig.value.disabled || selfProps.disabled || disabled.value,
1156
- active: formatClearConfig.value.active,
1157
- onOperate: handleOperate
1158
- },
1159
- () => h(Icon, { value: 'format-clear' })
1160
- )
1161
- }
1162
- //字号按钮
1163
- if (itemProps.name == 'fontSize' && fontSizeConfig.value.show) {
1164
- return h(Button, {
1165
- ...itemProps,
1166
- type: 'display',
1167
- displayConfig: fontSizeConfig.value.displayConfig,
1168
- title: $editTrans('fontSize'),
1169
- leftBorder: fontSizeConfig.value.leftBorder,
1170
- rightBorder: fontSizeConfig.value.rightBorder,
1171
- color: props.color,
1172
- disabled: fontSizeConfig.value.disabled || selfProps.disabled || disabled.value,
1173
- active: fontSizeConfig.value.active,
1174
- onOperate: handleOperate
1175
- })
1176
- }
1177
- //字体按钮
1178
- if (itemProps.name == 'fontFamily' && fontFamilyConfig.value.show) {
1179
- return h(Button, {
1180
- ...itemProps,
1181
- type: 'display',
1182
- displayConfig: fontFamilyConfig.value.displayConfig,
1183
- title: $editTrans('fontFamily'),
1184
- leftBorder: fontFamilyConfig.value.leftBorder,
1185
- rightBorder: fontFamilyConfig.value.rightBorder,
1186
- color: props.color,
1187
- disabled: fontFamilyConfig.value.disabled || selfProps.disabled || disabled.value,
1188
- active: fontFamilyConfig.value.active,
1189
- onOperate: handleOperate
1190
- })
1191
- }
1192
- //行高按钮
1193
- if (itemProps.name == 'lineHeight' && lineHeightConfig.value.show) {
1194
- return h(Button, {
1195
- ...itemProps,
1196
- type: 'display',
1197
- displayConfig: lineHeightConfig.value.displayConfig,
1198
- title: $editTrans('lineHeight'),
1199
- leftBorder: lineHeightConfig.value.leftBorder,
1200
- rightBorder: lineHeightConfig.value.rightBorder,
1201
- color: props.color,
1202
- disabled: lineHeightConfig.value.disabled || selfProps.disabled || disabled.value,
1203
- active: lineHeightConfig.value.active,
1204
- onOperate: handleOperate
1205
- })
1206
- }
1207
- //前景色按钮
1208
- if (itemProps.name == 'foreColor' && foreColorConfig.value.show) {
1209
- return h(
1210
- Button,
1211
- {
1212
- ...itemProps,
1213
- ref: 'btnRef',
1214
- type: 'select',
1215
- selectConfig: foreColorConfig.value.selectConfig,
1216
- title: $editTrans('foreColor'),
1217
- leftBorder: foreColorConfig.value.leftBorder,
1218
- rightBorder: foreColorConfig.value.rightBorder,
1219
- color: props.color,
1220
- disabled: foreColorConfig.value.disabled || selfProps.disabled || disabled.value,
1221
- active: foreColorConfig.value.active,
1222
- hideScroll: true
1223
- },
1224
- {
1225
- default: () =>
1226
- h(Icon, {
1227
- value: 'font-color'
1228
- }),
1229
- layer: (data: ObjectType) => {
1230
- return h(Colors, {
1231
- tooltip: props.config.tooltip,
1232
- value: foreColorConfig.value.value,
1233
- data: data.options,
1234
- color: props.color,
1235
- onChange: (val: string) => {
1236
- handleOperate('foreColor', val)
1237
- const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1238
- btn.show = false
1239
- }
1240
- })
1241
- }
1242
- }
1243
- )
1244
- }
1245
- //背景色按钮
1246
- if (itemProps.name == 'backColor' && backColorConfig.value.show) {
1247
- return h(
1248
- Button,
1249
- {
1250
- ...itemProps,
1251
- type: 'select',
1252
- ref: 'btnRef',
1253
- selectConfig: backColorConfig.value.selectConfig,
1254
- title: $editTrans('backColor'),
1255
- leftBorder: backColorConfig.value.leftBorder,
1256
- rightBorder: backColorConfig.value.rightBorder,
1257
- color: props.color,
1258
- disabled: backColorConfig.value.disabled || selfProps.disabled || disabled.value,
1259
- active: backColorConfig.value.active,
1260
- onOperate: handleOperate,
1261
- hideScroll: true
1262
- },
1263
- {
1264
- default: () =>
1265
- h(Icon, {
1266
- value: 'brush'
1267
- }),
1268
- layer: (data: ObjectType) =>
1269
- h(Colors, {
1270
- tooltip: props.config.tooltip,
1271
- value: backColorConfig.value.value,
1272
- data: data.options,
1273
- color: props.color,
1274
- onChange: val => {
1275
- handleOperate('backColor', val)
1276
- const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1277
- btn.show = false
1278
- }
1279
- })
1280
- }
1281
- )
1282
- }
1283
- //链接按钮
1284
- if (itemProps.name == 'link' && linkConfig.value.show) {
1285
- return h(
1286
- Button,
1287
- {
1288
- ...itemProps,
1289
- type: 'select',
1290
- ref: 'btnRef',
1291
- title: $editTrans('insertLink'),
1292
- leftBorder: linkConfig.value.leftBorder,
1293
- rightBorder: linkConfig.value.rightBorder,
1294
- color: props.color,
1295
- disabled: linkConfig.value.disabled || selfProps.disabled || disabled.value,
1296
- active: linkConfig.value.active,
1297
- hideScroll: true,
1298
- onLayerShow: () => {
1299
- //存在选区的情况下预置链接文本值
1300
- linkConfig.value.text = getRangeText(dataRangeCaches.value)
1301
- }
1302
- },
1303
- {
1304
- default: () =>
1305
- h(Icon, {
1306
- value: 'link'
1307
- }),
1308
- layer: () =>
1309
- h(InsertLink, {
1310
- color: props.color,
1311
- text: linkConfig.value.text,
1312
- onInsert: (text, url, newOpen) => {
1313
- handleOperate('link', { text, url, newOpen })
1314
- const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1315
- btn.show = false
1316
- }
1317
- })
1318
- }
1319
- )
1320
- }
1321
- //图片按钮
1322
- if (itemProps.name == 'image' && imageConfig.value.show) {
1323
- return h(
1324
- Button,
1325
- {
1326
- ...itemProps,
1327
- type: 'select',
1328
- ref: 'btnRef',
1329
- title: $editTrans('insertImage'),
1330
- leftBorder: imageConfig.value.leftBorder,
1331
- rightBorder: imageConfig.value.rightBorder,
1332
- color: props.color,
1333
- disabled: imageConfig.value.disabled || selfProps.disabled || disabled.value,
1334
- active: imageConfig.value.active,
1335
- hideScroll: true
1336
- },
1337
- {
1338
- default: () =>
1339
- h(Icon, {
1340
- value: 'image'
1341
- }),
1342
- layer: () =>
1343
- h(InsertImage, {
1344
- color: props.color,
1345
- accept: imageConfig.value.accept,
1346
- multiple: imageConfig.value.multiple,
1347
- maxSize: imageConfig.value.maxSize,
1348
- minSize: imageConfig.value.minSize,
1349
- customUpload: imageConfig.value.customUpload,
1350
- handleError: imageConfig.value.handleError,
1351
- onChange: () => {
1352
- const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1353
- const layer = <InstanceType<typeof Layer>>btn.$refs.layerRef
1354
- layer.setPosition()
1355
- },
1356
- onInsert: url => {
1357
- handleOperate('image', url)
1358
- const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1359
- btn.show = false
1360
- }
1361
- })
1362
- }
1363
- )
1364
- }
1365
- //视频按钮
1366
- if (itemProps.name == 'video' && videoConfig.value.show) {
1367
- return h(
1368
- Button,
1369
- {
1370
- ...itemProps,
1371
- type: 'select',
1372
- ref: 'btnRef',
1373
- title: $editTrans('insertVideo'),
1374
- leftBorder: videoConfig.value.leftBorder,
1375
- rightBorder: videoConfig.value.rightBorder,
1376
- color: props.color,
1377
- disabled: videoConfig.value.disabled || selfProps.disabled || disabled.value,
1378
- active: videoConfig.value.active,
1379
- hideScroll: true
1380
- },
1381
- {
1382
- default: () =>
1383
- h(Icon, {
1384
- value: 'video'
1385
- }),
1386
- layer: () =>
1387
- h(InsertVideo, {
1388
- color: props.color,
1389
- accept: videoConfig.value.accept,
1390
- multiple: videoConfig.value.multiple,
1391
- maxSize: videoConfig.value.maxSize,
1392
- minSize: videoConfig.value.minSize,
1393
- customUpload: videoConfig.value.customUpload,
1394
- handleError: videoConfig.value.handleError,
1395
- onChange: () => {
1396
- const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1397
- const layer = <InstanceType<typeof Layer>>btn.$refs.layerRef
1398
- layer.setPosition()
1399
- },
1400
- onInsert: url => {
1401
- handleOperate('video', url)
1402
- const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1403
- btn.show = false
1404
- }
1405
- })
1406
- }
1407
- )
1408
- }
1409
- //表格按钮
1410
- if (itemProps.name == 'table' && tableConfig.value.show) {
1411
- return h(
1412
- Button,
1413
- {
1414
- ...itemProps,
1415
- type: 'select',
1416
- ref: 'btnRef',
1417
- title: $editTrans('insertTable'),
1418
- leftBorder: tableConfig.value.leftBorder,
1419
- rightBorder: tableConfig.value.rightBorder,
1420
- color: props.color,
1421
- disabled: tableConfig.value.disabled || selfProps.disabled || disabled.value,
1422
- active: tableConfig.value.active,
1423
- hideScroll: true
1424
- },
1425
- {
1426
- default: () =>
1427
- h(Icon, {
1428
- value: 'table'
1429
- }),
1430
- layer: () =>
1431
- h(InsertTable, {
1432
- color: props.color,
1433
- maxRows: tableConfig.value.maxRows,
1434
- maxColumns: tableConfig.value.maxColumns,
1435
- onInsert: (row, column) => {
1436
- handleOperate('table', { row, column })
1437
- const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1438
- btn.show = false
1439
- }
1440
- })
1441
- }
1442
- )
1443
- }
1444
- //代码块按钮
1445
- if (itemProps.name == 'codeBlock' && codeBlockConfig.value.show) {
1446
- return h(
1447
- Button,
1448
- {
1449
- ...itemProps,
1450
- title: $editTrans('inserCodeBlock'),
1451
- leftBorder: codeBlockConfig.value.leftBorder,
1452
- rightBorder: codeBlockConfig.value.rightBorder,
1453
- color: props.color,
1454
- disabled: codeBlockConfig.value.disabled || selfProps.disabled || disabled.value,
1455
- active: codeBlockConfig.value.active,
1456
- onOperate: handleOperate
1457
- },
1458
- () => h(Icon, { value: 'code-block' })
1459
- )
1460
- }
1461
- //代码视图按钮
1462
- if (itemProps.name == 'sourceView' && sourceViewConfig.value.show) {
1463
- return h(
1464
- Button,
1465
- {
1466
- ...itemProps,
1467
- title: $editTrans('sourceView'),
1468
- leftBorder: sourceViewConfig.value.leftBorder,
1469
- rightBorder: sourceViewConfig.value.rightBorder,
1470
- color: props.color,
1471
- disabled: sourceViewConfig.value.disabled || selfProps.disabled || disabled.value,
1472
- active: sourceViewConfig.value.active,
1473
- onOperate: handleOperate
1474
- },
1475
- () => h(Icon, { value: 'source-view' })
1476
- )
1477
- }
1478
- //全屏按钮
1479
- if (itemProps.name == 'fullScreen' && fullScreenConfig.value.show) {
1480
- return h(
1481
- Button,
1482
- {
1483
- ...itemProps,
1484
- title: $editTrans('fullScreen'),
1485
- leftBorder: fullScreenConfig.value.leftBorder,
1486
- rightBorder: fullScreenConfig.value.rightBorder,
1487
- color: props.color,
1488
- disabled: fullScreenConfig.value.disabled || selfProps.disabled || disabled.value,
1489
- active: fullScreenConfig.value.active,
1490
- onOperate: handleOperate
1491
- },
1492
- () => h(Icon, { value: 'full-screen' })
1493
- )
1494
- }
1495
- /** 下面是拓展菜单的配置 */
1496
- if (DapCommon.isObject(props.config.extends)) {
1497
- //获取菜单按钮的配置
1498
- const configuration = props.config.extends![itemProps.name]
1499
- if (configuration) {
1500
- //渲染函数
1501
- return h(
1502
- Button,
1503
- {
1504
- ...itemProps,
1505
- ref: 'btnRef',
1506
- type: configuration.type || 'default',
1507
- title: configuration.title || '',
1508
- leftBorder: configuration.leftBorder || false,
1509
- rightBorder: configuration.rightBorder || false,
1510
- disabled: configuration.disabled || selfProps.disabled || disabled.value,
1511
- hideScroll: configuration.hideScroll || false,
1512
- active: configuration.active || false,
1513
- selectConfig: {
1514
- width: configuration.width,
1515
- maxHeight: configuration.maxHeight,
1516
- options: configuration.options
1517
- },
1518
- displayConfig: {
1519
- width: configuration.width,
1520
- maxHeight: configuration.maxHeight,
1521
- value: configuration.value,
1522
- options: configuration.options
1523
- },
1524
- color: props.color,
1525
- onLayerShow: () => {
1526
- if (typeof configuration.onLayerShow == 'function') {
1527
- configuration.onLayerShow.apply(editify.proxy!, [itemProps.name, <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef])
1528
- }
1529
- },
1530
- onLayerShown: () => {
1531
- if (typeof configuration.onLayerShown == 'function') {
1532
- configuration.onLayerShown.apply(editify.proxy!, [itemProps.name, <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef])
1533
- }
1534
- },
1535
- onLayerHidden: () => {
1536
- if (typeof configuration.onLayerHidden == 'function') {
1537
- configuration.onLayerHidden.apply(editify.proxy!, [itemProps.name, <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef])
1538
- }
1539
- },
1540
- onOperate: (name, val) => {
1541
- if (typeof configuration.onOperate == 'function') {
1542
- configuration.onOperate.apply(editify.proxy!, [name, val, <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef])
1543
- }
1544
- }
1545
- },
1546
- {
1547
- default: configuration.default || null,
1548
- layer: configuration.layer || null,
1549
- option: configuration.option || null
1550
- }
1551
- )
1552
- }
1553
- }
1554
- return null
1555
- }
1556
- },
1557
- {
1558
- props: {
1559
- name: String,
1560
- disabled: Boolean
1561
- }
1562
- }
1563
- )
1564
-
1565
- defineExpose({
1566
- handleRangeUpdate
1567
- })
1568
- </script>
1569
- <style scoped src="./menu.less"></style>
1
+ <template>
2
+ <div class="editify-menu" :class="{ border: menuShowBorder, source: isSourceView && menuMode == 'inner', fullscreen: isFullScreen }" :data-editify-mode="menuMode" :style="config.style || ''">
3
+ <MenuItem v-for="item in menuNames" :name="item" :disabled="menuDisabled(item)"></MenuItem>
4
+ </div>
5
+ </template>
6
+ <script setup lang="ts">
7
+ import Icon from '../icon/icon.vue'
8
+ import Layer from '../layer/layer.vue'
9
+ import Button from '../button/button.vue'
10
+ import Colors from '../colors/colors.vue'
11
+ import InsertLink from '../insertLink/insertLink.vue'
12
+ import InsertImage from '../insertImage/insertImage.vue'
13
+ import InsertVideo from '../insertVideo/insertVideo.vue'
14
+ import InsertTable from '../insertTable/insertTable.vue'
15
+ import { h, getCurrentInstance, ref, computed, inject, ComponentInternalInstance, Ref, ComputedRef, defineComponent } from 'vue'
16
+ import { common as DapCommon } from 'dap-util'
17
+ import { getRangeText, setHeading, setIndentIncrease, setIndentDecrease, setQuote, setAlign, setList, setTask, setTextStyle, setTextMark, removeTextStyle, removeTextMark, setLineHeight, insertLink, insertImage, insertVideo, insertTable, insertCodeBlock, hasPreInRange, hasTableInRange, hasQuoteInRange, hasLinkInRange, isRangeInQuote, isRangeInList, isRangeInTask, queryTextStyle, queryTextMark, getCurrentParsedomElement } from '../../core/function'
18
+ import { MenuProps } from './props'
19
+ import { MenuModeType, ObjectType } from '../../core/tool'
20
+ import AlexEditor, { AlexElementsRangeType } from 'alex-editor'
21
+ import { ButtonOptionsItemType } from '../button/props'
22
+
23
+ defineOptions({
24
+ name: 'Menu'
25
+ })
26
+ const props = defineProps(MenuProps)
27
+
28
+ const editify = inject<ComponentInternalInstance>('editify')!
29
+ const isSourceView = inject<Ref<boolean>>('isSourceView')!
30
+ const isFullScreen = inject<Ref<boolean>>('isFullScreen')!
31
+ const canUseMenu = inject<Ref<boolean>>('canUseMenu')!
32
+ const editor = inject<Ref<AlexEditor>>('editor')!
33
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
34
+ const showBorder = inject<ComputedRef<boolean>>('showBorder')!
35
+ const $editTrans = inject<(key: string) => any>('$editTrans')!
36
+
37
+ //撤销按钮配置
38
+ const undoConfig = ref<ObjectType>({
39
+ show: props.config.undo!.show,
40
+ leftBorder: props.config.undo!.leftBorder,
41
+ rightBorder: props.config.undo!.rightBorder,
42
+ active: false,
43
+ disabled: false
44
+ })
45
+ //重做按钮配置
46
+ const redoConfig = ref<ObjectType>({
47
+ show: props.config.redo!.show,
48
+ leftBorder: props.config.redo!.leftBorder,
49
+ rightBorder: props.config.redo!.rightBorder,
50
+ active: false,
51
+ disabled: false
52
+ })
53
+ //标题按钮配置
54
+ const headingConfig = ref<ObjectType>({
55
+ show: props.config.heading!.show,
56
+ displayConfig: {
57
+ options: props.config.heading!.options,
58
+ value: '',
59
+ width: props.config.heading!.width,
60
+ maxHeight: props.config.heading!.maxHeight
61
+ },
62
+ defaultValue: props.config.heading!.defaultValue,
63
+ leftBorder: props.config.heading!.leftBorder,
64
+ rightBorder: props.config.heading!.rightBorder,
65
+ active: false,
66
+ disabled: false
67
+ })
68
+ //缩进按钮配置
69
+ const indentConfig = ref<ObjectType>({
70
+ show: props.config.indent!.show,
71
+ selectConfig: {
72
+ options: props.config.indent!.options,
73
+ value: '',
74
+ width: props.config.indent!.width,
75
+ maxHeight: props.config.indent!.maxHeight
76
+ },
77
+ leftBorder: props.config.indent!.leftBorder,
78
+ rightBorder: props.config.indent!.rightBorder,
79
+ active: false,
80
+ disabled: false
81
+ })
82
+ //引用按钮配置
83
+ const quoteConfig = ref<ObjectType>({
84
+ show: props.config.quote!.show,
85
+ leftBorder: props.config.quote!.leftBorder,
86
+ rightBorder: props.config.quote!.rightBorder,
87
+ active: false,
88
+ disabled: false
89
+ })
90
+ //对齐方式按钮配置
91
+ const alignConfig = ref<ObjectType>({
92
+ show: props.config.align!.show,
93
+ selectConfig: {
94
+ options: props.config.align!.options,
95
+ width: props.config.align!.width,
96
+ maxHeight: props.config.align!.maxHeight
97
+ },
98
+ leftBorder: props.config.align!.leftBorder,
99
+ rightBorder: props.config.align!.rightBorder,
100
+ active: false,
101
+ disabled: false
102
+ })
103
+ //有序列表按钮配置
104
+ const orderListConfig = ref<ObjectType>({
105
+ show: props.config.orderList!.show,
106
+ leftBorder: props.config.orderList!.leftBorder,
107
+ rightBorder: props.config.orderList!.rightBorder,
108
+ active: false,
109
+ disabled: false
110
+ })
111
+ //无序列表按钮配置
112
+ const unorderListConfig = ref<ObjectType>({
113
+ show: props.config.unorderList!.show,
114
+ leftBorder: props.config.unorderList!.leftBorder,
115
+ rightBorder: props.config.unorderList!.rightBorder,
116
+ active: false,
117
+ disabled: false
118
+ })
119
+ //任务列表按钮配置
120
+ const taskConfig = ref<ObjectType>({
121
+ show: props.config.task!.show,
122
+ leftBorder: props.config.task!.leftBorder,
123
+ rightBorder: props.config.task!.rightBorder,
124
+ active: false,
125
+ disabled: false
126
+ })
127
+ //粗体按钮配置
128
+ const boldConfig = ref<ObjectType>({
129
+ show: props.config.bold!.show,
130
+ leftBorder: props.config.bold!.leftBorder,
131
+ rightBorder: props.config.bold!.rightBorder,
132
+ active: false,
133
+ disabled: false
134
+ })
135
+ //下划线按钮配置
136
+ const underlineConfig = ref<ObjectType>({
137
+ show: props.config.underline!.show,
138
+ leftBorder: props.config.underline!.leftBorder,
139
+ rightBorder: props.config.underline!.rightBorder,
140
+ active: false,
141
+ disabled: false
142
+ })
143
+ //斜体按钮配置
144
+ const italicConfig = ref<ObjectType>({
145
+ show: props.config.italic!.show,
146
+ leftBorder: props.config.italic!.leftBorder,
147
+ rightBorder: props.config.italic!.rightBorder,
148
+ active: false,
149
+ disabled: false
150
+ })
151
+ //删除线按钮配置
152
+ const strikethroughConfig = ref<ObjectType>({
153
+ show: props.config.strikethrough!.show,
154
+ leftBorder: props.config.strikethrough!.leftBorder,
155
+ rightBorder: props.config.strikethrough!.rightBorder,
156
+ active: false,
157
+ disabled: false
158
+ })
159
+ //行内代码按钮配置
160
+ const codeConfig = ref<ObjectType>({
161
+ show: props.config.code!.show,
162
+ leftBorder: props.config.code!.leftBorder,
163
+ rightBorder: props.config.code!.rightBorder,
164
+ active: false,
165
+ disabled: false
166
+ })
167
+ //上标按钮配置
168
+ const superConfig = ref<ObjectType>({
169
+ show: props.config.super!.show,
170
+ leftBorder: props.config.super!.leftBorder,
171
+ rightBorder: props.config.super!.rightBorder,
172
+ active: false,
173
+ disabled: false
174
+ })
175
+ //下标按钮配置
176
+ const subConfig = ref<ObjectType>({
177
+ show: props.config.sub!.show,
178
+ leftBorder: props.config.sub!.leftBorder,
179
+ rightBorder: props.config.sub!.rightBorder,
180
+ active: false,
181
+ disabled: false
182
+ })
183
+ //清除格式按钮配置
184
+ const formatClearConfig = ref<ObjectType>({
185
+ show: props.config.formatClear!.show,
186
+ leftBorder: props.config.formatClear!.leftBorder,
187
+ rightBorder: props.config.formatClear!.rightBorder,
188
+ active: false,
189
+ disabled: false
190
+ })
191
+ //字号按钮配置
192
+ const fontSizeConfig = ref<ObjectType>({
193
+ show: props.config.fontSize!.show,
194
+ displayConfig: {
195
+ options: props.config.fontSize!.options,
196
+ value: '',
197
+ width: props.config.fontSize!.width,
198
+ maxHeight: props.config.fontSize!.maxHeight
199
+ },
200
+ defaultValue: props.config.fontSize!.defaultValue,
201
+ leftBorder: props.config.fontSize!.leftBorder,
202
+ rightBorder: props.config.fontSize!.rightBorder,
203
+ active: false,
204
+ disabled: false
205
+ })
206
+ //字体按钮配置
207
+ const fontFamilyConfig = ref<ObjectType>({
208
+ show: props.config.fontFamily!.show,
209
+ displayConfig: {
210
+ options: props.config.fontFamily!.options,
211
+ value: '',
212
+ width: props.config.fontFamily!.width,
213
+ maxHeight: props.config.fontFamily!.maxHeight
214
+ },
215
+ defaultValue: props.config.fontFamily!.defaultValue,
216
+ leftBorder: props.config.fontFamily!.leftBorder,
217
+ rightBorder: props.config.fontFamily!.rightBorder,
218
+ active: false,
219
+ disabled: false
220
+ })
221
+ //行高按钮配置
222
+ const lineHeightConfig = ref<ObjectType>({
223
+ show: props.config.lineHeight!.show,
224
+ displayConfig: {
225
+ options: props.config.lineHeight!.options,
226
+ value: '',
227
+ width: props.config.lineHeight!.width,
228
+ maxHeight: props.config.lineHeight!.maxHeight
229
+ },
230
+ defaultValue: props.config.lineHeight!.defaultValue,
231
+ leftBorder: props.config.lineHeight!.leftBorder,
232
+ rightBorder: props.config.lineHeight!.rightBorder,
233
+ active: false,
234
+ disabled: false
235
+ })
236
+ //前景颜色按钮配置
237
+ const foreColorConfig = ref<ObjectType>({
238
+ show: props.config.foreColor!.show,
239
+ selectConfig: {
240
+ options: props.config.foreColor!.options
241
+ },
242
+ leftBorder: props.config.foreColor!.leftBorder,
243
+ rightBorder: props.config.foreColor!.rightBorder,
244
+ value: '', //选择的颜色值
245
+ active: false,
246
+ disabled: false
247
+ })
248
+ //背景颜色按钮配置
249
+ const backColorConfig = ref<ObjectType>({
250
+ show: props.config.backColor!.show,
251
+ selectConfig: {
252
+ options: props.config.backColor!.options
253
+ },
254
+ leftBorder: props.config.backColor!.leftBorder,
255
+ rightBorder: props.config.backColor!.rightBorder,
256
+ value: '', //选择的颜色值
257
+ active: false,
258
+ disabled: false
259
+ })
260
+ //链接按钮配置
261
+ const linkConfig = ref<ObjectType>({
262
+ show: props.config.link!.show,
263
+ leftBorder: props.config.link!.leftBorder,
264
+ rightBorder: props.config.link!.rightBorder,
265
+ active: false,
266
+ disabled: false,
267
+ text: '' //链接的文本
268
+ })
269
+ //插入图片按钮配置
270
+ const imageConfig = ref<ObjectType>({
271
+ show: props.config.image!.show,
272
+ leftBorder: props.config.image!.leftBorder,
273
+ rightBorder: props.config.image!.rightBorder,
274
+ active: false,
275
+ disabled: false,
276
+ accept: props.config.image!.accept,
277
+ multiple: props.config.image!.multiple,
278
+ maxSize: props.config.image!.maxSize,
279
+ minSize: props.config.image!.minSize,
280
+ handleError: props.config.image!.handleError,
281
+ customUpload: props.config.image!.customUpload
282
+ })
283
+ //插入视频按钮配置
284
+ const videoConfig = ref<ObjectType>({
285
+ show: props.config.video!.show,
286
+ leftBorder: props.config.video!.leftBorder,
287
+ rightBorder: props.config.video!.rightBorder,
288
+ active: false,
289
+ disabled: false,
290
+ accept: props.config.video!.accept,
291
+ multiple: props.config.video!.multiple,
292
+ maxSize: props.config.video!.maxSize,
293
+ minSize: props.config.video!.minSize,
294
+ handleError: props.config.video!.handleError,
295
+ customUpload: props.config.video!.customUpload
296
+ })
297
+ //表格按钮配置
298
+ const tableConfig = ref<ObjectType>({
299
+ show: props.config.table!.show,
300
+ leftBorder: props.config.table!.leftBorder,
301
+ rightBorder: props.config.table!.rightBorder,
302
+ active: false,
303
+ disabled: false,
304
+ maxRows: props.config.table!.maxRows,
305
+ maxColumns: props.config.table!.maxColumns
306
+ })
307
+ //代码块按钮配置
308
+ const codeBlockConfig = ref<ObjectType>({
309
+ show: props.config.codeBlock!.show,
310
+ leftBorder: props.config.codeBlock!.leftBorder,
311
+ rightBorder: props.config.codeBlock!.rightBorder,
312
+ active: false,
313
+ disabled: false
314
+ })
315
+ //代码视图按钮配置
316
+ const sourceViewConfig = ref<ObjectType>({
317
+ show: props.config.sourceView!.show,
318
+ leftBorder: props.config.sourceView!.leftBorder,
319
+ rightBorder: props.config.sourceView!.rightBorder,
320
+ active: false,
321
+ disabled: false
322
+ })
323
+ //全屏按钮配置
324
+ const fullScreenConfig = ref<ObjectType>({
325
+ show: props.config.fullScreen!.show,
326
+ leftBorder: props.config.fullScreen!.leftBorder,
327
+ rightBorder: props.config.fullScreen!.rightBorder,
328
+ active: false,
329
+ disabled: false
330
+ })
331
+
332
+ //整个菜单栏是否禁用
333
+ const disabled = computed<boolean>(() => {
334
+ return <boolean>editify.props.disabled || !canUseMenu.value
335
+ })
336
+ //菜单名称数组
337
+ const menuNames = computed<string[]>(() => {
338
+ return Object.keys(props.config.sequence!).sort((a, b) => {
339
+ if (props.config.sequence![a] > props.config.sequence![b]) {
340
+ return 1
341
+ }
342
+ return -1
343
+ })
344
+ })
345
+ //菜单是否禁用
346
+ const menuDisabled = computed<(name: string) => boolean>(() => {
347
+ return (name: string) => {
348
+ if (name == 'sourceView' || name == 'fullScreen') {
349
+ return false
350
+ }
351
+ return isSourceView.value
352
+ }
353
+ })
354
+ //菜单模式
355
+ const menuMode = computed<MenuModeType>(() => {
356
+ //如果是全屏状态下或者高度自适应状态下
357
+ if (isFullScreen.value || editify.props.autoheight) {
358
+ //fixed模式改为默认模式
359
+ if (props.config.mode == 'fixed') {
360
+ return 'default'
361
+ }
362
+ }
363
+ return props.config.mode!
364
+ })
365
+ //菜单栏是否显示边框
366
+ const menuShowBorder = computed(() => {
367
+ //fixed模式下不显示边框
368
+ if (menuMode.value == 'fixed') {
369
+ return false
370
+ }
371
+ //由编辑器的border属性来决定
372
+ return showBorder.value
373
+ })
374
+
375
+ //按钮操作触发函数
376
+ const handleOperate = (name: string, val: string | number | ObjectType) => {
377
+ //菜单栏禁用
378
+ if (disabled.value) {
379
+ return
380
+ }
381
+ //没有获取焦点
382
+ if (!editor.value.range) {
383
+ return
384
+ }
385
+ //撤销
386
+ if (name == 'undo') {
387
+ editify.exposed!.undo()
388
+ }
389
+ //重做
390
+ else if (name == 'redo') {
391
+ editify.exposed!.redo()
392
+ }
393
+ //设置标题
394
+ else if (name == 'heading') {
395
+ setHeading(editor.value, dataRangeCaches.value, $editTrans, <string>val)
396
+ editor.value.formatElementStack()
397
+ editor.value.domRender()
398
+ editor.value.rangeRender()
399
+ }
400
+ //设置缩进
401
+ else if (name == 'indent') {
402
+ //增加缩进
403
+ if (val == 'indent-increase') {
404
+ setIndentIncrease(editor.value, dataRangeCaches.value)
405
+ }
406
+ //减少缩进
407
+ else if (val == 'indent-decrease') {
408
+ setIndentDecrease(editor.value, dataRangeCaches.value)
409
+ }
410
+ editor.value.formatElementStack()
411
+ editor.value.domRender()
412
+ editor.value.rangeRender()
413
+ }
414
+ //设置引用
415
+ else if (name == 'quote') {
416
+ setQuote(editor.value, dataRangeCaches.value)
417
+ editor.value.formatElementStack()
418
+ editor.value.domRender()
419
+ editor.value.rangeRender()
420
+ }
421
+ //设置对齐方式
422
+ else if (name == 'align') {
423
+ setAlign(editor.value, dataRangeCaches.value, <string>val)
424
+ editor.value.formatElementStack()
425
+ editor.value.domRender()
426
+ editor.value.rangeRender()
427
+ }
428
+ //设置有序列表
429
+ else if (name == 'orderList') {
430
+ setList(editor.value, dataRangeCaches.value, true)
431
+ editor.value.formatElementStack()
432
+ editor.value.domRender()
433
+ editor.value.rangeRender()
434
+ }
435
+ //设置无序列表
436
+ else if (name == 'unorderList') {
437
+ setList(editor.value, dataRangeCaches.value, false)
438
+ editor.value.formatElementStack()
439
+ editor.value.domRender()
440
+ editor.value.rangeRender()
441
+ }
442
+ //设置任务列表
443
+ else if (name == 'task') {
444
+ setTask(editor.value, dataRangeCaches.value)
445
+ editor.value.formatElementStack()
446
+ editor.value.domRender()
447
+ editor.value.rangeRender()
448
+ }
449
+ //设置粗体
450
+ else if (name == 'bold') {
451
+ if (queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', 'bold') || queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', '700')) {
452
+ removeTextStyle(editor.value, dataRangeCaches.value, ['font-weight'])
453
+ } else {
454
+ setTextStyle(editor.value, dataRangeCaches.value, {
455
+ 'font-weight': 'bold'
456
+ })
457
+ }
458
+ editor.value.formatElementStack()
459
+ editor.value.domRender()
460
+ editor.value.rangeRender()
461
+ }
462
+ //设置下划线
463
+ else if (name == 'underline') {
464
+ if (queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration', 'underline') || queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration-line', 'underline')) {
465
+ removeTextStyle(editor.value, dataRangeCaches.value, ['text-decoration', 'text-decoration-line'])
466
+ } else {
467
+ setTextStyle(editor.value, dataRangeCaches.value, {
468
+ 'text-decoration': 'underline'
469
+ })
470
+ }
471
+ editor.value.formatElementStack()
472
+ editor.value.domRender()
473
+ editor.value.rangeRender()
474
+ }
475
+ //设置斜体
476
+ else if (name == 'italic') {
477
+ if (queryTextStyle(editor.value, dataRangeCaches.value, 'font-style', 'italic')) {
478
+ removeTextStyle(editor.value, dataRangeCaches.value, ['font-style'])
479
+ } else {
480
+ setTextStyle(editor.value, dataRangeCaches.value, {
481
+ 'font-style': 'italic'
482
+ })
483
+ }
484
+ editor.value.formatElementStack()
485
+ editor.value.domRender()
486
+ editor.value.rangeRender()
487
+ }
488
+ //设置删除线
489
+ else if (name == 'strikethrough') {
490
+ if (queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration', 'line-through') || queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration-line', 'line-through')) {
491
+ removeTextStyle(editor.value, dataRangeCaches.value, ['text-decoration', 'text-decoration-line'])
492
+ } else {
493
+ setTextStyle(editor.value, dataRangeCaches.value, {
494
+ 'text-decoration': 'line-through'
495
+ })
496
+ }
497
+ editor.value.formatElementStack()
498
+ editor.value.domRender()
499
+ editor.value.rangeRender()
500
+ }
501
+ //设置行内代码
502
+ else if (name == 'code') {
503
+ if (queryTextMark(editor.value, dataRangeCaches.value, 'data-editify-code')) {
504
+ removeTextMark(editor.value, dataRangeCaches.value, ['data-editify-code'])
505
+ } else {
506
+ setTextMark(editor.value, dataRangeCaches.value, {
507
+ 'data-editify-code': true
508
+ })
509
+ }
510
+ editor.value.formatElementStack()
511
+ editor.value.domRender()
512
+ editor.value.rangeRender()
513
+ }
514
+ //设置上标
515
+ else if (name == 'super') {
516
+ if (queryTextStyle(editor.value, dataRangeCaches.value, 'vertical-align', 'super')) {
517
+ removeTextStyle(editor.value, dataRangeCaches.value, ['vertical-align'])
518
+ } else {
519
+ setTextStyle(editor.value, dataRangeCaches.value, {
520
+ 'vertical-align': 'super'
521
+ })
522
+ }
523
+ editor.value.formatElementStack()
524
+ editor.value.domRender()
525
+ editor.value.rangeRender()
526
+ }
527
+ //设置下标
528
+ else if (name == 'sub') {
529
+ if (queryTextStyle(editor.value, dataRangeCaches.value, 'vertical-align', 'sub')) {
530
+ removeTextStyle(editor.value, dataRangeCaches.value, ['vertical-align'])
531
+ } else {
532
+ setTextStyle(editor.value, dataRangeCaches.value, {
533
+ 'vertical-align': 'sub'
534
+ })
535
+ }
536
+ editor.value.formatElementStack()
537
+ editor.value.domRender()
538
+ editor.value.rangeRender()
539
+ }
540
+ //清除格式
541
+ else if (name == 'formatClear') {
542
+ removeTextStyle(editor.value, dataRangeCaches.value)
543
+ removeTextMark(editor.value, dataRangeCaches.value)
544
+ editor.value.formatElementStack()
545
+ editor.value.domRender()
546
+ editor.value.rangeRender()
547
+ }
548
+ //设置字号
549
+ else if (name == 'fontSize') {
550
+ setTextStyle(editor.value, dataRangeCaches.value, {
551
+ 'font-size': val
552
+ })
553
+ editor.value.formatElementStack()
554
+ editor.value.domRender()
555
+ editor.value.rangeRender()
556
+ }
557
+ //设置字体
558
+ else if (name == 'fontFamily') {
559
+ setTextStyle(editor.value, dataRangeCaches.value, {
560
+ 'font-family': val
561
+ })
562
+ editor.value.formatElementStack()
563
+ editor.value.domRender()
564
+ editor.value.rangeRender()
565
+ }
566
+ //设置行高
567
+ else if (name == 'lineHeight') {
568
+ setLineHeight(editor.value, dataRangeCaches.value, <string | number>val)
569
+ editor.value.formatElementStack()
570
+ editor.value.domRender()
571
+ editor.value.rangeRender()
572
+ }
573
+ //设置前景色
574
+ else if (name == 'foreColor') {
575
+ setTextStyle(editor.value, dataRangeCaches.value, {
576
+ color: val
577
+ })
578
+ editor.value.formatElementStack()
579
+ editor.value.domRender()
580
+ editor.value.rangeRender()
581
+ }
582
+ //设置背景色
583
+ else if (name == 'backColor') {
584
+ setTextStyle(editor.value, dataRangeCaches.value, {
585
+ 'background-color': val
586
+ })
587
+ editor.value.formatElementStack()
588
+ editor.value.domRender()
589
+ editor.value.rangeRender()
590
+ }
591
+ //插入链接
592
+ else if (name == 'link') {
593
+ if (!(<ObjectType>val).url) {
594
+ return
595
+ }
596
+ insertLink(editor.value, (<ObjectType>val).text, (<ObjectType>val).url, (<ObjectType>val).newOpen)
597
+ editor.value.formatElementStack()
598
+ editor.value.domRender()
599
+ editor.value.rangeRender()
600
+ }
601
+ //插入图片
602
+ else if (name == 'image') {
603
+ if (!val) {
604
+ return
605
+ }
606
+ insertImage(editor.value, <string>val)
607
+ editor.value.formatElementStack()
608
+ editor.value.domRender()
609
+ editor.value.rangeRender()
610
+ }
611
+ //插入视频
612
+ else if (name == 'video') {
613
+ if (!val) {
614
+ return
615
+ }
616
+ insertVideo(editor.value, <string>val)
617
+ editor.value.formatElementStack()
618
+ editor.value.domRender()
619
+ editor.value.rangeRender()
620
+ }
621
+ //插入表格
622
+ else if (name == 'table') {
623
+ insertTable(editor.value, (<ObjectType>val).row, (<ObjectType>val).column)
624
+ editor.value.formatElementStack()
625
+ editor.value.domRender()
626
+ editor.value.rangeRender()
627
+ }
628
+ //插入代码块
629
+ else if (name == 'codeBlock') {
630
+ insertCodeBlock(editor.value, dataRangeCaches.value)
631
+ editor.value.formatElementStack()
632
+ editor.value.domRender()
633
+ editor.value.rangeRender()
634
+ }
635
+ //代码视图
636
+ else if (name == 'sourceView') {
637
+ isSourceView.value = !isSourceView.value
638
+ sourceViewConfig.value.active = isSourceView.value
639
+ if (!isSourceView.value) {
640
+ editor.value.rangeRender()
641
+ }
642
+ }
643
+ //全屏
644
+ else if (name == 'fullScreen') {
645
+ isFullScreen.value = !isFullScreen.value
646
+ fullScreenConfig.value.active = isFullScreen.value
647
+ editor.value.rangeRender()
648
+ }
649
+ }
650
+ //处理光标更新
651
+ const handleRangeUpdate = () => {
652
+ //选区是否含有代码块
653
+ const value_hasPreInRange = hasPreInRange(editor.value, dataRangeCaches.value)
654
+ //选区是否含有表格元素
655
+ const value_hasTableInRange = hasTableInRange(editor.value, dataRangeCaches.value)
656
+ //选区是否含有引用元素
657
+ const value_hasQuoteInRange = hasQuoteInRange(editor.value, dataRangeCaches.value)
658
+ //选区是否都在引用元素内
659
+ const value_isRangeInQuote = isRangeInQuote(editor.value, dataRangeCaches.value)
660
+ //选区是否含有链接元素
661
+ const value_hasLinkInRange = hasLinkInRange(editor.value, dataRangeCaches.value)
662
+ //选区是否都在有序列表内
663
+ const value_isRangeInOrderList = isRangeInList(editor.value, dataRangeCaches.value, true)
664
+ //选区是否都在无序列表内
665
+ const value_isRangeInUnorderList = isRangeInList(editor.value, dataRangeCaches.value, false)
666
+ //选区是否都在任务列表内
667
+ const value_isRangeInTask = isRangeInTask(editor.value, dataRangeCaches.value)
668
+ //额外禁用判定
669
+ const extraDisabled = (name: string) => {
670
+ if (typeof props.config.extraDisabled == 'function') {
671
+ return props.config.extraDisabled.apply(editify.proxy!, [name]) || false
672
+ }
673
+ return false
674
+ }
675
+
676
+ //撤销按钮禁用
677
+ undoConfig.value.disabled = !editor.value.history.get(-1) || extraDisabled('undo')
678
+
679
+ //重做按钮禁用
680
+ redoConfig.value.disabled = !editor.value.history.get(1) || extraDisabled('redo')
681
+
682
+ //显示已设置标题
683
+ const findHeadingItem = headingConfig.value.displayConfig.options.find((item: string | number | ButtonOptionsItemType) => {
684
+ let val: string | number | ButtonOptionsItemType = item
685
+ if (DapCommon.isObject(item)) {
686
+ val = (<ButtonOptionsItemType>item).value!
687
+ }
688
+ if (editor.value.range!.anchor.isEqual(editor.value.range!.focus)) {
689
+ return editor.value.range!.anchor.element.getBlock().parsedom == val
690
+ }
691
+ return dataRangeCaches.value.list.every(el => {
692
+ if (el.element.isBlock()) {
693
+ return el.element.parsedom == val
694
+ }
695
+ return el.element.getBlock().parsedom == val
696
+ })
697
+ })
698
+ headingConfig.value.displayConfig.value = findHeadingItem ? (DapCommon.isObject(findHeadingItem) ? findHeadingItem.value : findHeadingItem) : headingConfig.value.defaultValue
699
+ //标题禁用
700
+ headingConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('heading')
701
+
702
+ //缩进禁用
703
+ indentConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('indent')
704
+
705
+ //引用按钮激活
706
+ quoteConfig.value.active = value_isRangeInQuote
707
+ //引用按钮禁用
708
+ quoteConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('quote')
709
+
710
+ //对齐方式按钮禁用
711
+ alignConfig.value.disabled = value_hasPreInRange || extraDisabled('align')
712
+
713
+ //有序列表按钮激活
714
+ orderListConfig.value.active = value_isRangeInOrderList
715
+ //有序列表禁用
716
+ orderListConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('orderList')
717
+
718
+ //无序列表按钮激活
719
+ unorderListConfig.value.active = value_isRangeInUnorderList
720
+ //无序列表禁用
721
+ unorderListConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('unorderList')
722
+
723
+ //任务列表按钮激活
724
+ taskConfig.value.active = value_isRangeInTask
725
+ //任务列表禁用
726
+ taskConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || extraDisabled('task')
727
+
728
+ //粗体按钮激活
729
+ boldConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', 'bold') || queryTextStyle(editor.value, dataRangeCaches.value, 'font-weight', '700')
730
+ //粗体按钮禁用
731
+ boldConfig.value.disabled = value_hasPreInRange || extraDisabled('bold')
732
+
733
+ //下划线按钮激活
734
+ underlineConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration', 'underline') || queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration-line', 'underline')
735
+ //下划线按钮禁用
736
+ underlineConfig.value.disabled = value_hasPreInRange || extraDisabled('underline')
737
+
738
+ //斜体按钮激活
739
+ italicConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'font-style', 'italic')
740
+ //斜体按钮禁用
741
+ italicConfig.value.disabled = value_hasPreInRange || extraDisabled('italic')
742
+
743
+ //删除线按钮激活
744
+ strikethroughConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration', 'line-through') || queryTextStyle(editor.value, dataRangeCaches.value, 'text-decoration-line', 'line-through')
745
+ //删除线按钮禁用
746
+ strikethroughConfig.value.disabled = value_hasPreInRange || extraDisabled('strikethrough')
747
+
748
+ //行内代码按钮激活
749
+ codeConfig.value.active = queryTextMark(editor.value, dataRangeCaches.value, 'data-editify-code')
750
+ //行内代码按钮禁用
751
+ codeConfig.value.disabled = value_hasPreInRange || extraDisabled('code')
752
+
753
+ //上标按钮激活
754
+ superConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'vertical-align', 'super')
755
+ //上标按钮禁用
756
+ superConfig.value.disabled = value_hasPreInRange || extraDisabled('super')
757
+
758
+ //下标按钮激活
759
+ subConfig.value.active = queryTextStyle(editor.value, dataRangeCaches.value, 'vertical-align', 'sub')
760
+ //下标按钮禁用
761
+ subConfig.value.disabled = value_hasPreInRange || extraDisabled('sub')
762
+
763
+ //清除格式按钮禁用
764
+ formatClearConfig.value.disabled = value_hasPreInRange || extraDisabled('formatClear')
765
+
766
+ //显示已选择字号
767
+ const findFontItem = fontSizeConfig.value.displayConfig.options.find((item: string | ButtonOptionsItemType) => {
768
+ if (DapCommon.isObject(item)) {
769
+ return queryTextStyle(editor.value, dataRangeCaches.value, 'font-size', (<ButtonOptionsItemType>item).value)
770
+ }
771
+ return queryTextStyle(editor.value, dataRangeCaches.value, 'font-size', <string>item)
772
+ })
773
+ fontSizeConfig.value.displayConfig.value = findFontItem ? (DapCommon.isObject(findFontItem) ? findFontItem.value : findFontItem) : fontSizeConfig.value.defaultValue
774
+ //字号按钮禁用
775
+ fontSizeConfig.value.disabled = value_hasPreInRange || extraDisabled('fontSize')
776
+
777
+ //显示已选择字体
778
+ const findFamilyItem = fontFamilyConfig.value.displayConfig.options.find((item: string | ButtonOptionsItemType) => {
779
+ if (DapCommon.isObject(item)) {
780
+ return queryTextStyle(editor.value, dataRangeCaches.value, 'font-family', (<ButtonOptionsItemType>item).value)
781
+ }
782
+ return queryTextStyle(editor.value, dataRangeCaches.value, 'font-family', <string>item)
783
+ })
784
+ fontFamilyConfig.value.displayConfig.value = findFamilyItem ? (DapCommon.isObject(findFamilyItem) ? findFamilyItem.value : findFamilyItem) : fontFamilyConfig.value.defaultValue
785
+ //字体按钮禁用
786
+ fontFamilyConfig.value.disabled = value_hasPreInRange || extraDisabled('fontFamily')
787
+
788
+ //显示已设置行高
789
+ const findHeightItem = lineHeightConfig.value.displayConfig.options.find((item: string | number | ButtonOptionsItemType) => {
790
+ let val: string | number | ButtonOptionsItemType = item
791
+ if (DapCommon.isObject(item)) {
792
+ val = (<ButtonOptionsItemType>item).value!
793
+ }
794
+ if (editor.value.range!.anchor.isEqual(editor.value.range!.focus)) {
795
+ const block = editor.value.range!.anchor.element.getBlock()
796
+ return block.hasStyles() && block.styles!['line-height'] == val
797
+ }
798
+ return dataRangeCaches.value.list.every(el => {
799
+ if (el.element.isBlock() || el.element.isInblock()) {
800
+ return el.element.hasStyles() && el.element.styles!['line-height'] == val
801
+ }
802
+ const block = el.element.getBlock()
803
+ const inblock = el.element.getInblock()
804
+ if (inblock) {
805
+ return inblock.hasStyles() && inblock.styles!['line-height'] == val
806
+ }
807
+ return block.hasStyles() && block.styles!['line-height'] == val
808
+ })
809
+ })
810
+ lineHeightConfig.value.displayConfig.value = findHeightItem ? (DapCommon.isObject(findHeightItem) ? findHeightItem.value : findHeightItem) : lineHeightConfig.value.defaultValue
811
+ //行高按钮禁用
812
+ lineHeightConfig.value.disabled = value_hasPreInRange || extraDisabled('lineHeight')
813
+
814
+ //显示已选择的前景色
815
+ const findForeColorItem = foreColorConfig.value.selectConfig.options.find((item: string | ButtonOptionsItemType) => {
816
+ if (DapCommon.isObject(item)) {
817
+ return queryTextStyle(editor.value, dataRangeCaches.value, 'color', (<ButtonOptionsItemType>item).value)
818
+ }
819
+ return queryTextStyle(editor.value, dataRangeCaches.value, 'color', <string>item)
820
+ })
821
+ foreColorConfig.value.value = findForeColorItem ? (DapCommon.isObject(findForeColorItem) ? findForeColorItem.value : findForeColorItem) : ''
822
+ //前景色按钮禁用
823
+ foreColorConfig.value.disabled = value_hasPreInRange || extraDisabled('foreColor')
824
+
825
+ //显示已选择的背景色
826
+ const findBackColorItem = backColorConfig.value.selectConfig.options.find((item: string | ButtonOptionsItemType) => {
827
+ if (DapCommon.isObject(item)) {
828
+ return queryTextStyle(editor.value, dataRangeCaches.value, 'background-color', (<ButtonOptionsItemType>item).value)
829
+ }
830
+ return queryTextStyle(editor.value, dataRangeCaches.value, 'background-color', <string>item)
831
+ })
832
+ backColorConfig.value.value = findBackColorItem ? (DapCommon.isObject(findBackColorItem) ? findBackColorItem.value : findBackColorItem) : ''
833
+ //背景色按钮禁用
834
+ backColorConfig.value.disabled = value_hasPreInRange || extraDisabled('backColor')
835
+
836
+ //链接按钮禁用
837
+ linkConfig.value.disabled = value_hasLinkInRange || value_hasPreInRange || extraDisabled('link')
838
+
839
+ //插入图片按钮禁用
840
+ imageConfig.value.disabled = value_hasPreInRange || extraDisabled('image')
841
+
842
+ //插入视频按钮禁用
843
+ videoConfig.value.disabled = value_hasPreInRange || extraDisabled('video')
844
+
845
+ //表格按钮禁用
846
+ tableConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || value_hasQuoteInRange || extraDisabled('table')
847
+
848
+ //代码块按钮激活
849
+ codeBlockConfig.value.active = !!getCurrentParsedomElement(editor.value, dataRangeCaches.value, 'pre')
850
+ //代码块按钮禁用
851
+ codeBlockConfig.value.disabled = value_hasTableInRange || value_hasQuoteInRange || extraDisabled('codeBlock')
852
+
853
+ //代码视图按钮激活
854
+ sourceViewConfig.value.active = isSourceView.value
855
+
856
+ //全屏按钮激活
857
+ fullScreenConfig.value.active = isFullScreen.value
858
+ }
859
+
860
+ //菜单项子组件
861
+ const MenuItem = defineComponent(
862
+ selfProps => {
863
+ //获取实例
864
+ const itemInstance = getCurrentInstance()!
865
+ //共同设置的属性
866
+ const itemProps = {
867
+ tooltip: props.config.tooltip,
868
+ name: selfProps.name
869
+ }
870
+ return () => {
871
+ //撤销按钮
872
+ if (itemProps.name == 'undo' && undoConfig.value.show) {
873
+ return h(
874
+ Button,
875
+ {
876
+ ...itemProps,
877
+ title: $editTrans('undo'),
878
+ leftBorder: undoConfig.value.leftBorder,
879
+ rightBorder: undoConfig.value.rightBorder,
880
+ disabled: undoConfig.value.disabled || selfProps.disabled || disabled.value,
881
+ color: props.color,
882
+ active: undoConfig.value.active,
883
+ onOperate: handleOperate
884
+ },
885
+ () => h(Icon, { value: 'undo' })
886
+ )
887
+ }
888
+ //重做按钮
889
+ if (itemProps.name == 'redo' && redoConfig.value.show) {
890
+ return h(
891
+ Button,
892
+ {
893
+ ...itemProps,
894
+ title: $editTrans('redo'),
895
+ leftBorder: redoConfig.value.leftBorder,
896
+ rightBorder: redoConfig.value.rightBorder,
897
+ disabled: redoConfig.value.disabled || selfProps.disabled || disabled.value,
898
+ color: props.color,
899
+ active: redoConfig.value.active,
900
+ onOperate: handleOperate
901
+ },
902
+ () => h(Icon, { value: 'redo' })
903
+ )
904
+ }
905
+ //标题按钮
906
+ if (itemProps.name == 'heading' && headingConfig.value.show) {
907
+ return h(Button, {
908
+ ...itemProps,
909
+ type: 'display',
910
+ displayConfig: headingConfig.value.displayConfig,
911
+ title: $editTrans('heading'),
912
+ leftBorder: headingConfig.value.leftBorder,
913
+ rightBorder: headingConfig.value.rightBorder,
914
+ color: props.color,
915
+ disabled: headingConfig.value.disabled || selfProps.disabled || disabled.value,
916
+ active: headingConfig.value.active,
917
+ onOperate: handleOperate
918
+ })
919
+ }
920
+ //缩进按钮
921
+ if (itemProps.name == 'indent' && indentConfig.value.show) {
922
+ return h(
923
+ Button,
924
+ {
925
+ ...itemProps,
926
+ type: 'select',
927
+ selectConfig: indentConfig.value.selectConfig,
928
+ title: $editTrans('indent'),
929
+ leftBorder: indentConfig.value.leftBorder,
930
+ rightBorder: indentConfig.value.rightBorder,
931
+ color: props.color,
932
+ disabled: indentConfig.value.disabled || selfProps.disabled || disabled.value,
933
+ active: indentConfig.value.active,
934
+ onOperate: handleOperate
935
+ },
936
+ () => h(Icon, { value: 'indent-increase' })
937
+ )
938
+ }
939
+ //引用按钮
940
+ if (itemProps.name == 'quote' && quoteConfig.value.show) {
941
+ return h(
942
+ Button,
943
+ {
944
+ ...itemProps,
945
+ title: $editTrans('quote'),
946
+ leftBorder: quoteConfig.value.leftBorder,
947
+ rightBorder: quoteConfig.value.rightBorder,
948
+ color: props.color,
949
+ disabled: quoteConfig.value.disabled || selfProps.disabled || disabled.value,
950
+ active: quoteConfig.value.active,
951
+ onOperate: handleOperate
952
+ },
953
+ () => h(Icon, { value: 'quote' })
954
+ )
955
+ }
956
+ //对齐方式按钮
957
+ if (itemProps.name == 'align' && alignConfig.value.show) {
958
+ return h(
959
+ Button,
960
+ {
961
+ ...itemProps,
962
+ type: 'select',
963
+ selectConfig: alignConfig.value.selectConfig,
964
+ title: $editTrans('align'),
965
+ leftBorder: alignConfig.value.leftBorder,
966
+ rightBorder: alignConfig.value.rightBorder,
967
+ color: props.color,
968
+ disabled: alignConfig.value.disabled || selfProps.disabled || disabled.value,
969
+ active: alignConfig.value.active,
970
+ onOperate: handleOperate
971
+ },
972
+ () => h(Icon, { value: 'align-left' })
973
+ )
974
+ }
975
+ //有序列表按钮
976
+ if (itemProps.name == 'orderList' && orderListConfig.value.show) {
977
+ return h(
978
+ Button,
979
+ {
980
+ ...itemProps,
981
+ title: $editTrans('orderList'),
982
+ leftBorder: orderListConfig.value.leftBorder,
983
+ rightBorder: orderListConfig.value.rightBorder,
984
+ color: props.color,
985
+ disabled: orderListConfig.value.disabled || selfProps.disabled || disabled.value,
986
+ active: orderListConfig.value.active,
987
+ onOperate: handleOperate
988
+ },
989
+ () => h(Icon, { value: 'list-ordered' })
990
+ )
991
+ }
992
+ //无序列表按钮
993
+ if (itemProps.name == 'unorderList' && unorderListConfig.value.show) {
994
+ return h(
995
+ Button,
996
+ {
997
+ ...itemProps,
998
+ title: $editTrans('unorderList'),
999
+ leftBorder: unorderListConfig.value.leftBorder,
1000
+ rightBorder: unorderListConfig.value.rightBorder,
1001
+ color: props.color,
1002
+ disabled: unorderListConfig.value.disabled || selfProps.disabled || disabled.value,
1003
+ active: unorderListConfig.value.active,
1004
+ onOperate: handleOperate
1005
+ },
1006
+ () => h(Icon, { value: 'list-unordered' })
1007
+ )
1008
+ }
1009
+ //任务列表按钮
1010
+ if (itemProps.name == 'task' && taskConfig.value.show) {
1011
+ return h(
1012
+ Button,
1013
+ {
1014
+ ...itemProps,
1015
+ title: $editTrans('task'),
1016
+ leftBorder: taskConfig.value.leftBorder,
1017
+ rightBorder: taskConfig.value.rightBorder,
1018
+ color: props.color,
1019
+ disabled: taskConfig.value.disabled || selfProps.disabled || disabled.value,
1020
+ active: taskConfig.value.active,
1021
+ onOperate: handleOperate
1022
+ },
1023
+ () => h(Icon, { value: 'task' })
1024
+ )
1025
+ }
1026
+ //粗体按钮
1027
+ if (itemProps.name == 'bold' && boldConfig.value.show) {
1028
+ return h(
1029
+ Button,
1030
+ {
1031
+ ...itemProps,
1032
+ title: $editTrans('bold'),
1033
+ leftBorder: boldConfig.value.leftBorder,
1034
+ rightBorder: boldConfig.value.rightBorder,
1035
+ color: props.color,
1036
+ disabled: boldConfig.value.disabled || selfProps.disabled || disabled.value,
1037
+ active: boldConfig.value.active,
1038
+ onOperate: handleOperate
1039
+ },
1040
+ () => h(Icon, { value: 'bold' })
1041
+ )
1042
+ }
1043
+ //下划线按钮
1044
+ if (itemProps.name == 'underline' && underlineConfig.value.show) {
1045
+ return h(
1046
+ Button,
1047
+ {
1048
+ ...itemProps,
1049
+ title: $editTrans('underline'),
1050
+ leftBorder: underlineConfig.value.leftBorder,
1051
+ rightBorder: underlineConfig.value.rightBorder,
1052
+ color: props.color,
1053
+ disabled: underlineConfig.value.disabled || selfProps.disabled || disabled.value,
1054
+ active: underlineConfig.value.active,
1055
+ onOperate: handleOperate
1056
+ },
1057
+ () => h(Icon, { value: 'underline' })
1058
+ )
1059
+ }
1060
+ //斜体按钮
1061
+ if (itemProps.name == 'italic' && italicConfig.value.show) {
1062
+ return h(
1063
+ Button,
1064
+ {
1065
+ ...itemProps,
1066
+ title: $editTrans('italic'),
1067
+ leftBorder: italicConfig.value.leftBorder,
1068
+ rightBorder: italicConfig.value.rightBorder,
1069
+ color: props.color,
1070
+ disabled: italicConfig.value.disabled || selfProps.disabled || disabled.value,
1071
+ active: italicConfig.value.active,
1072
+ onOperate: handleOperate
1073
+ },
1074
+ () => h(Icon, { value: 'italic' })
1075
+ )
1076
+ }
1077
+ //删除线按钮
1078
+ if (itemProps.name == 'strikethrough' && strikethroughConfig.value.show) {
1079
+ return h(
1080
+ Button,
1081
+ {
1082
+ ...itemProps,
1083
+ title: $editTrans('strikethrough'),
1084
+ leftBorder: strikethroughConfig.value.leftBorder,
1085
+ rightBorder: strikethroughConfig.value.rightBorder,
1086
+ color: props.color,
1087
+ disabled: strikethroughConfig.value.disabled || selfProps.disabled || disabled.value,
1088
+ active: strikethroughConfig.value.active,
1089
+ onOperate: handleOperate
1090
+ },
1091
+ () => h(Icon, { value: 'strikethrough' })
1092
+ )
1093
+ }
1094
+ //行内代码按钮
1095
+ if (itemProps.name == 'code' && codeConfig.value.show) {
1096
+ return h(
1097
+ Button,
1098
+ {
1099
+ ...itemProps,
1100
+ title: $editTrans('code'),
1101
+ leftBorder: codeConfig.value.leftBorder,
1102
+ rightBorder: codeConfig.value.rightBorder,
1103
+ color: props.color,
1104
+ disabled: codeConfig.value.disabled || selfProps.disabled || disabled.value,
1105
+ active: codeConfig.value.active,
1106
+ onOperate: handleOperate
1107
+ },
1108
+ () => h(Icon, { value: 'code' })
1109
+ )
1110
+ }
1111
+ //上标按钮
1112
+ if (itemProps.name == 'super' && superConfig.value.show) {
1113
+ return h(
1114
+ Button,
1115
+ {
1116
+ ...itemProps,
1117
+ title: $editTrans('superscript'),
1118
+ leftBorder: superConfig.value.leftBorder,
1119
+ rightBorder: superConfig.value.rightBorder,
1120
+ color: props.color,
1121
+ disabled: superConfig.value.disabled || selfProps.disabled || disabled.value,
1122
+ active: superConfig.value.active,
1123
+ onOperate: handleOperate
1124
+ },
1125
+ () => h(Icon, { value: 'superscript' })
1126
+ )
1127
+ }
1128
+ //下标按钮
1129
+ if (itemProps.name == 'sub' && subConfig.value.show) {
1130
+ return h(
1131
+ Button,
1132
+ {
1133
+ ...itemProps,
1134
+ title: $editTrans('subscript'),
1135
+ leftBorder: subConfig.value.leftBorder,
1136
+ rightBorder: subConfig.value.rightBorder,
1137
+ color: props.color,
1138
+ disabled: subConfig.value.disabled || selfProps.disabled || disabled.value,
1139
+ active: subConfig.value.active,
1140
+ onOperate: handleOperate
1141
+ },
1142
+ () => h(Icon, { value: 'subscript' })
1143
+ )
1144
+ }
1145
+ //清除格式按钮
1146
+ if (itemProps.name == 'formatClear' && formatClearConfig.value.show) {
1147
+ return h(
1148
+ Button,
1149
+ {
1150
+ ...itemProps,
1151
+ title: $editTrans('formatClear'),
1152
+ leftBorder: formatClearConfig.value.leftBorder,
1153
+ rightBorder: formatClearConfig.value.rightBorder,
1154
+ color: props.color,
1155
+ disabled: formatClearConfig.value.disabled || selfProps.disabled || disabled.value,
1156
+ active: formatClearConfig.value.active,
1157
+ onOperate: handleOperate
1158
+ },
1159
+ () => h(Icon, { value: 'format-clear' })
1160
+ )
1161
+ }
1162
+ //字号按钮
1163
+ if (itemProps.name == 'fontSize' && fontSizeConfig.value.show) {
1164
+ return h(Button, {
1165
+ ...itemProps,
1166
+ type: 'display',
1167
+ displayConfig: fontSizeConfig.value.displayConfig,
1168
+ title: $editTrans('fontSize'),
1169
+ leftBorder: fontSizeConfig.value.leftBorder,
1170
+ rightBorder: fontSizeConfig.value.rightBorder,
1171
+ color: props.color,
1172
+ disabled: fontSizeConfig.value.disabled || selfProps.disabled || disabled.value,
1173
+ active: fontSizeConfig.value.active,
1174
+ onOperate: handleOperate
1175
+ })
1176
+ }
1177
+ //字体按钮
1178
+ if (itemProps.name == 'fontFamily' && fontFamilyConfig.value.show) {
1179
+ return h(Button, {
1180
+ ...itemProps,
1181
+ type: 'display',
1182
+ displayConfig: fontFamilyConfig.value.displayConfig,
1183
+ title: $editTrans('fontFamily'),
1184
+ leftBorder: fontFamilyConfig.value.leftBorder,
1185
+ rightBorder: fontFamilyConfig.value.rightBorder,
1186
+ color: props.color,
1187
+ disabled: fontFamilyConfig.value.disabled || selfProps.disabled || disabled.value,
1188
+ active: fontFamilyConfig.value.active,
1189
+ onOperate: handleOperate
1190
+ })
1191
+ }
1192
+ //行高按钮
1193
+ if (itemProps.name == 'lineHeight' && lineHeightConfig.value.show) {
1194
+ return h(Button, {
1195
+ ...itemProps,
1196
+ type: 'display',
1197
+ displayConfig: lineHeightConfig.value.displayConfig,
1198
+ title: $editTrans('lineHeight'),
1199
+ leftBorder: lineHeightConfig.value.leftBorder,
1200
+ rightBorder: lineHeightConfig.value.rightBorder,
1201
+ color: props.color,
1202
+ disabled: lineHeightConfig.value.disabled || selfProps.disabled || disabled.value,
1203
+ active: lineHeightConfig.value.active,
1204
+ onOperate: handleOperate
1205
+ })
1206
+ }
1207
+ //前景色按钮
1208
+ if (itemProps.name == 'foreColor' && foreColorConfig.value.show) {
1209
+ return h(
1210
+ Button,
1211
+ {
1212
+ ...itemProps,
1213
+ ref: 'btnRef',
1214
+ type: 'select',
1215
+ selectConfig: foreColorConfig.value.selectConfig,
1216
+ title: $editTrans('foreColor'),
1217
+ leftBorder: foreColorConfig.value.leftBorder,
1218
+ rightBorder: foreColorConfig.value.rightBorder,
1219
+ color: props.color,
1220
+ disabled: foreColorConfig.value.disabled || selfProps.disabled || disabled.value,
1221
+ active: foreColorConfig.value.active,
1222
+ hideScroll: true
1223
+ },
1224
+ {
1225
+ default: () =>
1226
+ h(Icon, {
1227
+ value: 'font-color'
1228
+ }),
1229
+ layer: (data: ObjectType) => {
1230
+ return h(Colors, {
1231
+ tooltip: props.config.tooltip,
1232
+ value: foreColorConfig.value.value,
1233
+ data: data.options,
1234
+ color: props.color,
1235
+ onChange: (val: string) => {
1236
+ handleOperate('foreColor', val)
1237
+ const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1238
+ btn.show = false
1239
+ }
1240
+ })
1241
+ }
1242
+ }
1243
+ )
1244
+ }
1245
+ //背景色按钮
1246
+ if (itemProps.name == 'backColor' && backColorConfig.value.show) {
1247
+ return h(
1248
+ Button,
1249
+ {
1250
+ ...itemProps,
1251
+ type: 'select',
1252
+ ref: 'btnRef',
1253
+ selectConfig: backColorConfig.value.selectConfig,
1254
+ title: $editTrans('backColor'),
1255
+ leftBorder: backColorConfig.value.leftBorder,
1256
+ rightBorder: backColorConfig.value.rightBorder,
1257
+ color: props.color,
1258
+ disabled: backColorConfig.value.disabled || selfProps.disabled || disabled.value,
1259
+ active: backColorConfig.value.active,
1260
+ onOperate: handleOperate,
1261
+ hideScroll: true
1262
+ },
1263
+ {
1264
+ default: () =>
1265
+ h(Icon, {
1266
+ value: 'brush'
1267
+ }),
1268
+ layer: (data: ObjectType) =>
1269
+ h(Colors, {
1270
+ tooltip: props.config.tooltip,
1271
+ value: backColorConfig.value.value,
1272
+ data: data.options,
1273
+ color: props.color,
1274
+ onChange: val => {
1275
+ handleOperate('backColor', val)
1276
+ const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1277
+ btn.show = false
1278
+ }
1279
+ })
1280
+ }
1281
+ )
1282
+ }
1283
+ //链接按钮
1284
+ if (itemProps.name == 'link' && linkConfig.value.show) {
1285
+ return h(
1286
+ Button,
1287
+ {
1288
+ ...itemProps,
1289
+ type: 'select',
1290
+ ref: 'btnRef',
1291
+ title: $editTrans('insertLink'),
1292
+ leftBorder: linkConfig.value.leftBorder,
1293
+ rightBorder: linkConfig.value.rightBorder,
1294
+ color: props.color,
1295
+ disabled: linkConfig.value.disabled || selfProps.disabled || disabled.value,
1296
+ active: linkConfig.value.active,
1297
+ hideScroll: true,
1298
+ onLayerShow: () => {
1299
+ //存在选区的情况下预置链接文本值
1300
+ linkConfig.value.text = getRangeText(dataRangeCaches.value)
1301
+ }
1302
+ },
1303
+ {
1304
+ default: () =>
1305
+ h(Icon, {
1306
+ value: 'link'
1307
+ }),
1308
+ layer: () =>
1309
+ h(InsertLink, {
1310
+ color: props.color,
1311
+ text: linkConfig.value.text,
1312
+ onInsert: (text, url, newOpen) => {
1313
+ handleOperate('link', { text, url, newOpen })
1314
+ const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1315
+ btn.show = false
1316
+ }
1317
+ })
1318
+ }
1319
+ )
1320
+ }
1321
+ //图片按钮
1322
+ if (itemProps.name == 'image' && imageConfig.value.show) {
1323
+ return h(
1324
+ Button,
1325
+ {
1326
+ ...itemProps,
1327
+ type: 'select',
1328
+ ref: 'btnRef',
1329
+ title: $editTrans('insertImage'),
1330
+ leftBorder: imageConfig.value.leftBorder,
1331
+ rightBorder: imageConfig.value.rightBorder,
1332
+ color: props.color,
1333
+ disabled: imageConfig.value.disabled || selfProps.disabled || disabled.value,
1334
+ active: imageConfig.value.active,
1335
+ hideScroll: true
1336
+ },
1337
+ {
1338
+ default: () =>
1339
+ h(Icon, {
1340
+ value: 'image'
1341
+ }),
1342
+ layer: () =>
1343
+ h(InsertImage, {
1344
+ color: props.color,
1345
+ accept: imageConfig.value.accept,
1346
+ multiple: imageConfig.value.multiple,
1347
+ maxSize: imageConfig.value.maxSize,
1348
+ minSize: imageConfig.value.minSize,
1349
+ customUpload: imageConfig.value.customUpload,
1350
+ handleError: imageConfig.value.handleError,
1351
+ onChange: () => {
1352
+ const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1353
+ const layer = <InstanceType<typeof Layer>>btn.$refs.layerRef
1354
+ layer.setPosition()
1355
+ },
1356
+ onInsert: url => {
1357
+ handleOperate('image', url)
1358
+ const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1359
+ btn.show = false
1360
+ }
1361
+ })
1362
+ }
1363
+ )
1364
+ }
1365
+ //视频按钮
1366
+ if (itemProps.name == 'video' && videoConfig.value.show) {
1367
+ return h(
1368
+ Button,
1369
+ {
1370
+ ...itemProps,
1371
+ type: 'select',
1372
+ ref: 'btnRef',
1373
+ title: $editTrans('insertVideo'),
1374
+ leftBorder: videoConfig.value.leftBorder,
1375
+ rightBorder: videoConfig.value.rightBorder,
1376
+ color: props.color,
1377
+ disabled: videoConfig.value.disabled || selfProps.disabled || disabled.value,
1378
+ active: videoConfig.value.active,
1379
+ hideScroll: true
1380
+ },
1381
+ {
1382
+ default: () =>
1383
+ h(Icon, {
1384
+ value: 'video'
1385
+ }),
1386
+ layer: () =>
1387
+ h(InsertVideo, {
1388
+ color: props.color,
1389
+ accept: videoConfig.value.accept,
1390
+ multiple: videoConfig.value.multiple,
1391
+ maxSize: videoConfig.value.maxSize,
1392
+ minSize: videoConfig.value.minSize,
1393
+ customUpload: videoConfig.value.customUpload,
1394
+ handleError: videoConfig.value.handleError,
1395
+ onChange: () => {
1396
+ const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1397
+ const layer = <InstanceType<typeof Layer>>btn.$refs.layerRef
1398
+ layer.setPosition()
1399
+ },
1400
+ onInsert: url => {
1401
+ handleOperate('video', url)
1402
+ const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1403
+ btn.show = false
1404
+ }
1405
+ })
1406
+ }
1407
+ )
1408
+ }
1409
+ //表格按钮
1410
+ if (itemProps.name == 'table' && tableConfig.value.show) {
1411
+ return h(
1412
+ Button,
1413
+ {
1414
+ ...itemProps,
1415
+ type: 'select',
1416
+ ref: 'btnRef',
1417
+ title: $editTrans('insertTable'),
1418
+ leftBorder: tableConfig.value.leftBorder,
1419
+ rightBorder: tableConfig.value.rightBorder,
1420
+ color: props.color,
1421
+ disabled: tableConfig.value.disabled || selfProps.disabled || disabled.value,
1422
+ active: tableConfig.value.active,
1423
+ hideScroll: true
1424
+ },
1425
+ {
1426
+ default: () =>
1427
+ h(Icon, {
1428
+ value: 'table'
1429
+ }),
1430
+ layer: () =>
1431
+ h(InsertTable, {
1432
+ color: props.color,
1433
+ maxRows: tableConfig.value.maxRows,
1434
+ maxColumns: tableConfig.value.maxColumns,
1435
+ onInsert: (row, column) => {
1436
+ handleOperate('table', { row, column })
1437
+ const btn = <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef
1438
+ btn.show = false
1439
+ }
1440
+ })
1441
+ }
1442
+ )
1443
+ }
1444
+ //代码块按钮
1445
+ if (itemProps.name == 'codeBlock' && codeBlockConfig.value.show) {
1446
+ return h(
1447
+ Button,
1448
+ {
1449
+ ...itemProps,
1450
+ title: $editTrans('inserCodeBlock'),
1451
+ leftBorder: codeBlockConfig.value.leftBorder,
1452
+ rightBorder: codeBlockConfig.value.rightBorder,
1453
+ color: props.color,
1454
+ disabled: codeBlockConfig.value.disabled || selfProps.disabled || disabled.value,
1455
+ active: codeBlockConfig.value.active,
1456
+ onOperate: handleOperate
1457
+ },
1458
+ () => h(Icon, { value: 'code-block' })
1459
+ )
1460
+ }
1461
+ //代码视图按钮
1462
+ if (itemProps.name == 'sourceView' && sourceViewConfig.value.show) {
1463
+ return h(
1464
+ Button,
1465
+ {
1466
+ ...itemProps,
1467
+ title: $editTrans('sourceView'),
1468
+ leftBorder: sourceViewConfig.value.leftBorder,
1469
+ rightBorder: sourceViewConfig.value.rightBorder,
1470
+ color: props.color,
1471
+ disabled: sourceViewConfig.value.disabled || selfProps.disabled || disabled.value,
1472
+ active: sourceViewConfig.value.active,
1473
+ onOperate: handleOperate
1474
+ },
1475
+ () => h(Icon, { value: 'source-view' })
1476
+ )
1477
+ }
1478
+ //全屏按钮
1479
+ if (itemProps.name == 'fullScreen' && fullScreenConfig.value.show) {
1480
+ return h(
1481
+ Button,
1482
+ {
1483
+ ...itemProps,
1484
+ title: $editTrans('fullScreen'),
1485
+ leftBorder: fullScreenConfig.value.leftBorder,
1486
+ rightBorder: fullScreenConfig.value.rightBorder,
1487
+ color: props.color,
1488
+ disabled: fullScreenConfig.value.disabled || selfProps.disabled || disabled.value,
1489
+ active: fullScreenConfig.value.active,
1490
+ onOperate: handleOperate
1491
+ },
1492
+ () => h(Icon, { value: 'full-screen' })
1493
+ )
1494
+ }
1495
+ /** 下面是拓展菜单的配置 */
1496
+ if (DapCommon.isObject(props.config.extends)) {
1497
+ //获取菜单按钮的配置
1498
+ const configuration = props.config.extends![itemProps.name]
1499
+ if (configuration) {
1500
+ //渲染函数
1501
+ return h(
1502
+ Button,
1503
+ {
1504
+ ...itemProps,
1505
+ ref: 'btnRef',
1506
+ type: configuration.type || 'default',
1507
+ title: configuration.title || '',
1508
+ leftBorder: configuration.leftBorder || false,
1509
+ rightBorder: configuration.rightBorder || false,
1510
+ disabled: configuration.disabled || selfProps.disabled || disabled.value,
1511
+ hideScroll: configuration.hideScroll || false,
1512
+ active: configuration.active || false,
1513
+ selectConfig: {
1514
+ width: configuration.width,
1515
+ maxHeight: configuration.maxHeight,
1516
+ options: configuration.options
1517
+ },
1518
+ displayConfig: {
1519
+ width: configuration.width,
1520
+ maxHeight: configuration.maxHeight,
1521
+ value: configuration.value,
1522
+ options: configuration.options
1523
+ },
1524
+ color: props.color,
1525
+ onLayerShow: () => {
1526
+ if (typeof configuration.onLayerShow == 'function') {
1527
+ configuration.onLayerShow.apply(editify.proxy!, [itemProps.name, <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef])
1528
+ }
1529
+ },
1530
+ onLayerShown: () => {
1531
+ if (typeof configuration.onLayerShown == 'function') {
1532
+ configuration.onLayerShown.apply(editify.proxy!, [itemProps.name, <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef])
1533
+ }
1534
+ },
1535
+ onLayerHidden: () => {
1536
+ if (typeof configuration.onLayerHidden == 'function') {
1537
+ configuration.onLayerHidden.apply(editify.proxy!, [itemProps.name, <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef])
1538
+ }
1539
+ },
1540
+ onOperate: (name, val) => {
1541
+ if (typeof configuration.onOperate == 'function') {
1542
+ configuration.onOperate.apply(editify.proxy!, [name, val, <InstanceType<typeof Button>>itemInstance.proxy!.$refs.btnRef])
1543
+ }
1544
+ }
1545
+ },
1546
+ {
1547
+ default: configuration.default || null,
1548
+ layer: configuration.layer || null,
1549
+ option: configuration.option || null
1550
+ }
1551
+ )
1552
+ }
1553
+ }
1554
+ return null
1555
+ }
1556
+ },
1557
+ {
1558
+ props: {
1559
+ name: String,
1560
+ disabled: Boolean
1561
+ }
1562
+ }
1563
+ )
1564
+
1565
+ defineExpose({
1566
+ handleRangeUpdate
1567
+ })
1568
+ </script>
1569
+ <style scoped src="./menu.less"></style>