vue-editify 0.1.19 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +3 -3
  2. package/examples/App.vue +62 -62
  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 +68 -68
  18. package/lib/editify.es.js +35 -24
  19. package/lib/editify.umd.js +1 -1
  20. package/lib/index.d.ts +1 -1
  21. package/lib/style.css +1 -1
  22. package/package.json +45 -45
  23. package/src/components/button/button.less +145 -145
  24. package/src/components/button/button.vue +197 -197
  25. package/src/components/button/props.ts +95 -95
  26. package/src/components/checkbox/checkbox.less +84 -84
  27. package/src/components/checkbox/checkbox.vue +68 -68
  28. package/src/components/checkbox/props.ts +49 -49
  29. package/src/components/colors/colors.less +75 -75
  30. package/src/components/colors/colors.vue +36 -36
  31. package/src/components/colors/props.ts +29 -29
  32. package/src/components/icon/icon.less +14 -14
  33. package/src/components/icon/icon.vue +12 -12
  34. package/src/components/icon/props.ts +11 -11
  35. package/src/components/insertImage/insertImage.less +135 -135
  36. package/src/components/insertImage/insertImage.vue +146 -146
  37. package/src/components/insertImage/props.ts +43 -43
  38. package/src/components/insertLink/insertLink.less +64 -64
  39. package/src/components/insertLink/insertLink.vue +58 -58
  40. package/src/components/insertLink/props.ts +16 -16
  41. package/src/components/insertTable/insertTable.less +54 -54
  42. package/src/components/insertTable/insertTable.vue +85 -85
  43. package/src/components/insertTable/props.ts +27 -27
  44. package/src/components/insertVideo/insertVideo.less +135 -135
  45. package/src/components/insertVideo/insertVideo.vue +146 -146
  46. package/src/components/insertVideo/props.ts +43 -43
  47. package/src/components/layer/layer.less +49 -49
  48. package/src/components/layer/layer.vue +598 -598
  49. package/src/components/layer/props.ts +71 -71
  50. package/src/components/menu/menu.less +63 -63
  51. package/src/components/menu/menu.vue +1569 -1569
  52. package/src/components/menu/props.ts +17 -17
  53. package/src/components/toolbar/props.ts +35 -35
  54. package/src/components/toolbar/toolbar.less +89 -89
  55. package/src/components/toolbar/toolbar.vue +1101 -1101
  56. package/src/components/tooltip/props.ts +21 -21
  57. package/src/components/tooltip/tooltip.less +23 -23
  58. package/src/components/tooltip/tooltip.vue +37 -37
  59. package/src/components/triangle/props.ts +26 -26
  60. package/src/components/triangle/triangle.less +79 -79
  61. package/src/components/triangle/triangle.vue +65 -65
  62. package/src/core/function.ts +1150 -1144
  63. package/src/core/rule.ts +259 -259
  64. package/src/core/tool.ts +1137 -1137
  65. package/src/css/base.less +30 -30
  66. package/src/css/hljs.less +54 -54
  67. package/src/editify/editify.less +404 -404
  68. package/src/editify/editify.vue +810 -803
  69. package/src/editify/props.ts +156 -156
  70. package/src/hljs/index.ts +197 -197
  71. package/src/icon/iconfont.css +219 -219
  72. package/src/index.ts +32 -32
  73. package/src/locale/en_US.ts +88 -88
  74. package/src/locale/index.ts +12 -12
  75. package/src/locale/zh_CN.ts +88 -88
  76. package/tsconfig.json +27 -27
  77. package/tsconfig.node.json +11 -11
  78. package/vite-env.d.ts +1 -1
  79. 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>