vue-editify 0.2.16 → 0.2.18
Sign up to get free protection for your applications and to get access to all the features.
- package/examples/App.vue +289 -5
- package/lib/components/colors/colors.vue.d.ts +9 -0
- package/lib/components/colors/props.d.ts +4 -0
- package/lib/core/function.d.ts +120 -45
- package/lib/core/rule.d.ts +23 -17
- package/lib/core/tool.d.ts +1 -13
- package/lib/editify/editify.vue.d.ts +10 -1
- package/lib/editify/props.d.ts +1 -1
- package/lib/editify/toolbar/props.d.ts +1 -1
- package/lib/editify/toolbar/toolbar.vue.d.ts +3 -3
- package/lib/editify.es.js +13640 -13799
- package/lib/editify.umd.js +2 -2
- package/lib/feature/align.d.ts +0 -14
- package/lib/feature/heading.d.ts +0 -14
- package/lib/feature/lineHeight.d.ts +0 -14
- package/lib/feature/orderList.d.ts +1 -3
- package/lib/feature/task.d.ts +0 -14
- package/lib/feature/unorderList.d.ts +1 -3
- package/lib/index.d.ts +12 -3
- package/package.json +2 -2
- package/src/components/button/button.vue +3 -3
- package/src/components/checkbox/checkbox.vue +1 -1
- package/src/components/colors/colors.vue +4 -4
- package/src/components/colors/props.ts +6 -1
- package/src/components/insertAttachment/insertAttachment.vue +1 -1
- package/src/components/insertImage/insertImage.vue +1 -1
- package/src/components/insertLink/insertLink.vue +1 -1
- package/src/components/insertVideo/insertVideo.vue +1 -1
- package/src/components/layer/layer.vue +9 -3
- package/src/components/tooltip/tooltip.vue +1 -1
- package/src/components/updateLink/updateLink.vue +1 -1
- package/src/core/function.ts +961 -475
- package/src/core/rule.ts +85 -367
- package/src/core/tool.ts +8 -114
- package/src/editify/editify.less +88 -14
- package/src/editify/editify.vue +117 -65
- package/src/editify/props.ts +1 -1
- package/src/editify/toolbar/props.ts +2 -2
- package/src/editify/toolbar/toolbar.vue +12 -12
- package/src/feature/align.ts +1 -61
- package/src/feature/attachment.ts +13 -26
- package/src/feature/backColor.ts +1 -0
- package/src/feature/foreColor.ts +1 -0
- package/src/feature/heading.ts +2 -73
- package/src/feature/infoBlock.ts +4 -35
- package/src/feature/lineHeight.ts +1 -77
- package/src/feature/mathformula.ts +3 -50
- package/src/feature/orderList.ts +166 -35
- package/src/feature/panel.ts +4 -49
- package/src/feature/sub.ts +1 -1
- package/src/feature/super.ts +1 -1
- package/src/feature/task.ts +1 -55
- package/src/feature/unorderList.ts +106 -35
- package/src/feature/video.ts +1 -1
- package/src/icon/iconfont.css +40 -0
- package/src/icon/iconfont.ttf +0 -0
- package/src/icon/iconfont.woff +0 -0
- package/src/index.ts +14 -8
- package/src/locale/en_US.ts +112 -110
- package/src/locale/zh_CN.ts +11 -9
package/src/core/tool.ts
CHANGED
@@ -102,11 +102,6 @@ export type CodeBlockToolbarType = {
|
|
102
102
|
}
|
103
103
|
|
104
104
|
export type TextToolbarType = {
|
105
|
-
heading?: MenuDisplayButtonType
|
106
|
-
align?: MenuSelectButtonType
|
107
|
-
orderList?: MenuButtonType
|
108
|
-
unorderList?: MenuButtonType
|
109
|
-
task?: MenuButtonType
|
110
105
|
bold?: MenuButtonType
|
111
106
|
italic?: MenuButtonType
|
112
107
|
strikethrough?: MenuButtonType
|
@@ -116,7 +111,6 @@ export type TextToolbarType = {
|
|
116
111
|
sub?: MenuButtonType
|
117
112
|
fontSize?: MenuDisplayButtonType
|
118
113
|
fontFamily?: MenuDisplayButtonType
|
119
|
-
lineHeight?: MenuDisplayButtonType
|
120
114
|
foreColor?: MenuSelectButtonType
|
121
115
|
backColor?: MenuSelectButtonType
|
122
116
|
formatClear?: MenuButtonType
|
@@ -288,18 +282,6 @@ export const queryHasValue = (obj: ObjectType, name: string, value?: string | nu
|
|
288
282
|
return ownValue == value
|
289
283
|
}
|
290
284
|
|
291
|
-
/**
|
292
|
-
* 深拷贝函数
|
293
|
-
* @param data
|
294
|
-
* @returns
|
295
|
-
*/
|
296
|
-
export const cloneData = (data: any) => {
|
297
|
-
if (DapCommon.isObject(data) || Array.isArray(data)) {
|
298
|
-
return JSON.parse(JSON.stringify(data))
|
299
|
-
}
|
300
|
-
return data
|
301
|
-
}
|
302
|
-
|
303
285
|
/**
|
304
286
|
* 获取菜单按钮列表数据配置
|
305
287
|
* @param editTrans
|
@@ -506,7 +488,7 @@ export const getButtonOptionsConfig = (editTrans: (key: string) => any): ButtonO
|
|
506
488
|
* @param editLocale
|
507
489
|
* @returns
|
508
490
|
*/
|
509
|
-
export const getToolbarConfig = (editTrans: (key: string) => any
|
491
|
+
export const getToolbarConfig = (editTrans: (key: string) => any): ToolbarConfigType => {
|
510
492
|
return {
|
511
493
|
//是否使用工具条
|
512
494
|
use: true,
|
@@ -542,75 +524,6 @@ export const getToolbarConfig = (editTrans: (key: string) => any, editLocale: Lo
|
|
542
524
|
},
|
543
525
|
//文本工具条配置
|
544
526
|
text: {
|
545
|
-
//标题
|
546
|
-
heading: {
|
547
|
-
//是否显示此工具
|
548
|
-
show: false,
|
549
|
-
//是否禁用此工具
|
550
|
-
disabled: false,
|
551
|
-
//列表配置
|
552
|
-
options: getButtonOptionsConfig(editTrans).heading,
|
553
|
-
//按钮默认显示的值
|
554
|
-
defaultValue: 'p',
|
555
|
-
//浮层宽度
|
556
|
-
width: editLocale == 'zh_CN' ? 130 : 150,
|
557
|
-
//浮层最大高度
|
558
|
-
maxHeight: '',
|
559
|
-
//左侧边框是否显示
|
560
|
-
leftBorder: false,
|
561
|
-
//右侧边框是否显示
|
562
|
-
rightBorder: false
|
563
|
-
},
|
564
|
-
//对齐方式
|
565
|
-
align: {
|
566
|
-
//是否显示此工具
|
567
|
-
show: false,
|
568
|
-
//是否禁用此工具
|
569
|
-
disabled: false,
|
570
|
-
//列表配置
|
571
|
-
options: getButtonOptionsConfig(editTrans).align,
|
572
|
-
//浮层宽度
|
573
|
-
width: editLocale == 'zh_CN' ? 110 : 130,
|
574
|
-
//浮层最大高度
|
575
|
-
maxHeight: '',
|
576
|
-
//左侧边框是否显示
|
577
|
-
leftBorder: false,
|
578
|
-
//右侧边框是否显示
|
579
|
-
rightBorder: false
|
580
|
-
},
|
581
|
-
//有序列表
|
582
|
-
orderList: {
|
583
|
-
//是否显示此工具
|
584
|
-
show: false,
|
585
|
-
//是否禁用此工具
|
586
|
-
disabled: false,
|
587
|
-
//左侧边框是否显示
|
588
|
-
leftBorder: false,
|
589
|
-
//右侧边框是否显示
|
590
|
-
rightBorder: false
|
591
|
-
},
|
592
|
-
//无序列表
|
593
|
-
unorderList: {
|
594
|
-
//是否显示此工具
|
595
|
-
show: false,
|
596
|
-
//是否禁用此工具
|
597
|
-
disabled: false,
|
598
|
-
//左侧边框是否显示
|
599
|
-
leftBorder: false,
|
600
|
-
//右侧边框是否显示
|
601
|
-
rightBorder: false
|
602
|
-
},
|
603
|
-
//任务列表
|
604
|
-
task: {
|
605
|
-
//是否显示此工具
|
606
|
-
show: false,
|
607
|
-
//是否禁用此工具
|
608
|
-
disabled: false,
|
609
|
-
//左侧边框是否显示
|
610
|
-
leftBorder: false,
|
611
|
-
//右侧边框是否显示
|
612
|
-
rightBorder: false
|
613
|
-
},
|
614
527
|
//粗体
|
615
528
|
bold: {
|
616
529
|
//是否显示此工具
|
@@ -726,25 +639,6 @@ export const getToolbarConfig = (editTrans: (key: string) => any, editLocale: Lo
|
|
726
639
|
//右侧边框是否显示
|
727
640
|
rightBorder: false
|
728
641
|
},
|
729
|
-
//行高
|
730
|
-
lineHeight: {
|
731
|
-
//是否显示此工具
|
732
|
-
show: false,
|
733
|
-
//是否禁用此工具
|
734
|
-
disabled: false,
|
735
|
-
//列表配置
|
736
|
-
options: getButtonOptionsConfig(editTrans).lineHeight,
|
737
|
-
//按钮默认显示的值
|
738
|
-
defaultValue: '',
|
739
|
-
//浮层宽度
|
740
|
-
width: 90,
|
741
|
-
//浮层最大高度
|
742
|
-
maxHeight: '',
|
743
|
-
//左侧边框是否显示
|
744
|
-
leftBorder: false,
|
745
|
-
//右侧边框是否显示
|
746
|
-
rightBorder: false
|
747
|
-
},
|
748
642
|
//前景色
|
749
643
|
foreColor: {
|
750
644
|
//是否显示此工具
|
@@ -754,7 +648,7 @@ export const getToolbarConfig = (editTrans: (key: string) => any, editLocale: Lo
|
|
754
648
|
//列表配置
|
755
649
|
options: getButtonOptionsConfig(editTrans).foreColor,
|
756
650
|
//左侧边框是否显示
|
757
|
-
leftBorder:
|
651
|
+
leftBorder: true,
|
758
652
|
//右侧边框是否显示
|
759
653
|
rightBorder: false
|
760
654
|
},
|
@@ -832,12 +726,12 @@ export const getMenuConfig = (editTrans: (key: string) => any, editLocale: Local
|
|
832
726
|
video: 25,
|
833
727
|
table: 26,
|
834
728
|
codeBlock: 27,
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
729
|
+
attachment: 28,
|
730
|
+
mathformula: 29,
|
731
|
+
panel: 30,
|
732
|
+
infoBlock: 31,
|
733
|
+
sourceView: 32,
|
734
|
+
fullScreen: 33
|
841
735
|
},
|
842
736
|
//撤销按钮配置
|
843
737
|
undo: {
|
package/src/editify/editify.less
CHANGED
@@ -136,23 +136,92 @@
|
|
136
136
|
:deep(h6) {
|
137
137
|
font-size: 16px;
|
138
138
|
}
|
139
|
+
|
140
|
+
//不是有序列表元素则重置后面的有序列表序列
|
141
|
+
:deep(:not(div[data-editify-list='ol'])) + div[data-editify-list='ol'] {
|
142
|
+
counter-reset: item 0;
|
143
|
+
}
|
144
|
+
|
139
145
|
//有序列表样式
|
140
146
|
:deep(div[data-editify-list='ol']) {
|
141
147
|
margin-bottom: 15px;
|
142
148
|
|
149
|
+
//第一个元素重置序列
|
150
|
+
&:first-of-type {
|
151
|
+
counter-reset: item 0;
|
152
|
+
}
|
153
|
+
|
143
154
|
&::before {
|
144
|
-
|
155
|
+
counter-increment: item;
|
156
|
+
content: counter(item) '.';
|
145
157
|
margin-right: 10px;
|
146
158
|
}
|
159
|
+
|
160
|
+
&[data-editify-list-style='decimal'] {
|
161
|
+
&::before {
|
162
|
+
content: counter(item, decimal) '.';
|
163
|
+
}
|
164
|
+
}
|
165
|
+
&[data-editify-list-style='decimal-leading-zero'] {
|
166
|
+
&::before {
|
167
|
+
content: counter(item, decimal-leading-zero) '.';
|
168
|
+
}
|
169
|
+
}
|
170
|
+
&[data-editify-list-style='lower-roman'] {
|
171
|
+
&::before {
|
172
|
+
content: counter(item, lower-roman) '.';
|
173
|
+
}
|
174
|
+
}
|
175
|
+
&[data-editify-list-style='upper-roman'] {
|
176
|
+
&::before {
|
177
|
+
content: counter(item, upper-roman) '.';
|
178
|
+
}
|
179
|
+
}
|
180
|
+
&[data-editify-list-style='lower-alpha'] {
|
181
|
+
&::before {
|
182
|
+
content: counter(item, lower-alpha) '.';
|
183
|
+
}
|
184
|
+
}
|
185
|
+
&[data-editify-list-style='upper-alpha'] {
|
186
|
+
&::before {
|
187
|
+
content: counter(item, upper-alpha) '.';
|
188
|
+
}
|
189
|
+
}
|
190
|
+
&[data-editify-list-style='lower-greek'] {
|
191
|
+
&::before {
|
192
|
+
content: counter(item, lower-greek) '.';
|
193
|
+
}
|
194
|
+
}
|
195
|
+
&[data-editify-list-style='cjk-ideographic'] {
|
196
|
+
&::before {
|
197
|
+
content: counter(item, cjk-ideographic) '.';
|
198
|
+
}
|
199
|
+
}
|
147
200
|
}
|
148
201
|
//无序列表样式
|
149
202
|
:deep(div[data-editify-list='ul']) {
|
150
203
|
margin-bottom: 15px;
|
151
204
|
|
152
205
|
&::before {
|
153
|
-
content:
|
206
|
+
content: counter(item, disc);
|
154
207
|
margin-right: 10px;
|
155
208
|
}
|
209
|
+
|
210
|
+
&[data-editify-list-style='disc'] {
|
211
|
+
&::before {
|
212
|
+
content: counter(item, disc);
|
213
|
+
}
|
214
|
+
}
|
215
|
+
&[data-editify-list-style='circle'] {
|
216
|
+
&::before {
|
217
|
+
content: counter(item, circle);
|
218
|
+
}
|
219
|
+
}
|
220
|
+
&[data-editify-list-style='square'] {
|
221
|
+
&::before {
|
222
|
+
content: counter(item, square);
|
223
|
+
}
|
224
|
+
}
|
156
225
|
}
|
157
226
|
//代码样式
|
158
227
|
:deep([data-editify-code]) {
|
@@ -309,15 +378,13 @@
|
|
309
378
|
padding-left: 26px;
|
310
379
|
font-size: var(--editify-font-size);
|
311
380
|
color: var(--editify-font-color-dark);
|
312
|
-
transition: all 300ms;
|
313
381
|
|
314
382
|
&::before {
|
315
383
|
display: block;
|
316
|
-
width:
|
317
|
-
height:
|
384
|
+
width: 14px;
|
385
|
+
height: 14px;
|
318
386
|
border-radius: 2px;
|
319
387
|
border: 1px solid var(--editify-font-color-light);
|
320
|
-
transition: all 300ms;
|
321
388
|
box-sizing: border-box;
|
322
389
|
user-select: none;
|
323
390
|
content: '';
|
@@ -332,29 +399,32 @@
|
|
332
399
|
&::after {
|
333
400
|
display: inline-block;
|
334
401
|
width: 10px;
|
335
|
-
height:
|
402
|
+
height: 5px;
|
336
403
|
position: absolute;
|
337
404
|
content: '';
|
338
|
-
left:
|
405
|
+
left: 2px;
|
339
406
|
top: 50%;
|
340
|
-
margin-top: -
|
341
|
-
border:
|
407
|
+
margin-top: -1px;
|
408
|
+
border: 2px solid transparent;
|
342
409
|
border-top: none;
|
343
410
|
border-right: none;
|
344
411
|
transform: translateY(-50%) rotate(-45deg);
|
345
412
|
transform-origin: center;
|
346
|
-
box-sizing: border-box;
|
347
413
|
z-index: 2;
|
348
414
|
cursor: pointer;
|
349
|
-
opacity: 0;
|
350
|
-
transition: all 300ms;
|
351
415
|
}
|
352
416
|
|
353
417
|
&[data-editify-task='checked'] {
|
354
418
|
text-decoration: line-through;
|
355
419
|
color: var(--editify-font-color-light);
|
420
|
+
|
421
|
+
&::before {
|
422
|
+
background-color: var(--editify-font-color-disabled);
|
423
|
+
border-color: var(--editify-font-color-disabled);
|
424
|
+
}
|
425
|
+
|
356
426
|
&::after {
|
357
|
-
|
427
|
+
border-color: #fff;
|
358
428
|
}
|
359
429
|
}
|
360
430
|
}
|
@@ -428,6 +498,10 @@
|
|
428
498
|
font-size: 18px;
|
429
499
|
border-bottom: 1px solid var(--editify-border-color);
|
430
500
|
padding-bottom: 8px;
|
501
|
+
|
502
|
+
&:empty {
|
503
|
+
background-color: #000;
|
504
|
+
}
|
431
505
|
}
|
432
506
|
}
|
433
507
|
}
|
package/src/editify/editify.vue
CHANGED
@@ -21,10 +21,10 @@
|
|
21
21
|
<script setup lang="ts">
|
22
22
|
import { computed, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, provide, ref, watch } from 'vue'
|
23
23
|
import { AlexEditor, AlexElement, AlexElementRangeType, AlexElementsRangeType } from 'alex-editor'
|
24
|
-
import { element as DapElement, event as DapEvent, data as DapData, number as DapNumber, color as DapColor } from 'dap-util'
|
25
|
-
import { mergeObject, getToolbarConfig, getMenuConfig, MenuConfigType, ObjectType, ToolbarConfigType, clickIsOut
|
26
|
-
import {
|
27
|
-
import { elementToParagraph, getMatchElementByRange,
|
24
|
+
import { element as DapElement, event as DapEvent, data as DapData, number as DapNumber, color as DapColor, common as DapCommon } from 'dap-util'
|
25
|
+
import { mergeObject, getToolbarConfig, getMenuConfig, MenuConfigType, ObjectType, ToolbarConfigType, clickIsOut } from '@/core/tool'
|
26
|
+
import { listHandle, imageHandle, videoHandle, separatorHandle, linkHandle, codeHandle, tableHandle, preHandle, attachmentHandle, mathformulaHandle, infoBlockHandle, specialInblockHandle } from '@/core/rule'
|
27
|
+
import { elementToParagraph, getMatchElementByRange, elementIsTask, elementIsAttachment, elementIsList, elementIsMathformula, getMathformulaByElement, elementIsPanel, elementIsInfoBlock, getMatchElementByElement } from '@/core/function'
|
28
28
|
import { trans } from '@/locale'
|
29
29
|
import { LanguagesItemType } from '@/hljs'
|
30
30
|
import { extraKeepTagsForMathformula } from '@/feature/mathformula'
|
@@ -125,7 +125,7 @@ const showBorder = computed<boolean>(() => {
|
|
125
125
|
})
|
126
126
|
//最终生效的工具栏配置
|
127
127
|
const toolbarConfig = computed<ToolbarConfigType>(() => {
|
128
|
-
return mergeObject(getToolbarConfig($editTrans
|
128
|
+
return mergeObject(getToolbarConfig($editTrans), props.toolbar || {}) as ToolbarConfigType
|
129
129
|
})
|
130
130
|
//最终生效的菜单栏配置
|
131
131
|
const menuConfig = computed<MenuConfigType>(() => {
|
@@ -163,9 +163,7 @@ const handleToolbar = () => {
|
|
163
163
|
}
|
164
164
|
hideToolbar()
|
165
165
|
nextTick(() => {
|
166
|
-
const table = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'table' })
|
167
166
|
const codeBlock = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'pre' })
|
168
|
-
const link = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'a' })
|
169
167
|
const image = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'img' })
|
170
168
|
const video = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'video' })
|
171
169
|
|
@@ -189,26 +187,6 @@ const handleToolbar = () => {
|
|
189
187
|
toolbarOptions.value.show = true
|
190
188
|
}
|
191
189
|
}
|
192
|
-
//显示链接工具条
|
193
|
-
else if (link) {
|
194
|
-
toolbarOptions.value.type = 'link'
|
195
|
-
toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${link.key}"]`
|
196
|
-
if (toolbarOptions.value.show) {
|
197
|
-
toolbarRef.value!.layerRef!.setPosition()
|
198
|
-
} else {
|
199
|
-
toolbarOptions.value.show = true
|
200
|
-
}
|
201
|
-
}
|
202
|
-
//显示表格工具条
|
203
|
-
else if (table) {
|
204
|
-
toolbarOptions.value.type = 'table'
|
205
|
-
toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${table.key}"]`
|
206
|
-
if (toolbarOptions.value.show) {
|
207
|
-
toolbarRef.value!.layerRef!.setPosition()
|
208
|
-
} else {
|
209
|
-
toolbarOptions.value.show = true
|
210
|
-
}
|
211
|
-
}
|
212
190
|
//显示代码块工具条
|
213
191
|
else if (codeBlock) {
|
214
192
|
toolbarOptions.value.type = 'codeBlock'
|
@@ -219,10 +197,11 @@ const handleToolbar = () => {
|
|
219
197
|
toolbarOptions.value.show = true
|
220
198
|
}
|
221
199
|
}
|
222
|
-
|
200
|
+
//以下是选区时显示文本工具条,非选区时显示其他工具条的情况
|
223
201
|
else {
|
224
202
|
const result = dataRangeCaches.value.flatList.filter((item: AlexElementRangeType) => item.element.isText())
|
225
|
-
|
203
|
+
//显示文本工具条
|
204
|
+
if (result.length) {
|
226
205
|
toolbarOptions.value.type = 'text'
|
227
206
|
if (toolbarOptions.value.show) {
|
228
207
|
toolbarRef.value!.layerRef!.setPosition()
|
@@ -230,6 +209,63 @@ const handleToolbar = () => {
|
|
230
209
|
toolbarOptions.value.show = true
|
231
210
|
}
|
232
211
|
}
|
212
|
+
//显示其他工具条
|
213
|
+
else {
|
214
|
+
const table = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'table' })
|
215
|
+
const link = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'a' })
|
216
|
+
const orderList = getMatchElementByRange(editor.value!, dataRangeCaches.value, {
|
217
|
+
parsedom: 'div',
|
218
|
+
marks: {
|
219
|
+
'data-editify-list': 'ol'
|
220
|
+
}
|
221
|
+
})
|
222
|
+
const unorderList = getMatchElementByRange(editor.value!, dataRangeCaches.value, {
|
223
|
+
parsedom: 'div',
|
224
|
+
marks: {
|
225
|
+
'data-editify-list': 'ul'
|
226
|
+
}
|
227
|
+
})
|
228
|
+
//显示链接工具条
|
229
|
+
if (link) {
|
230
|
+
toolbarOptions.value.type = 'link'
|
231
|
+
toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${link.key}"]`
|
232
|
+
if (toolbarOptions.value.show) {
|
233
|
+
toolbarRef.value!.layerRef!.setPosition()
|
234
|
+
} else {
|
235
|
+
toolbarOptions.value.show = true
|
236
|
+
}
|
237
|
+
}
|
238
|
+
//显示表格工具条
|
239
|
+
else if (table) {
|
240
|
+
toolbarOptions.value.type = 'table'
|
241
|
+
toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${table.key}"]`
|
242
|
+
if (toolbarOptions.value.show) {
|
243
|
+
toolbarRef.value!.layerRef!.setPosition()
|
244
|
+
} else {
|
245
|
+
toolbarOptions.value.show = true
|
246
|
+
}
|
247
|
+
}
|
248
|
+
//显示有序列表工具条
|
249
|
+
else if (orderList) {
|
250
|
+
toolbarOptions.value.type = 'orderList'
|
251
|
+
toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${orderList.key}"]`
|
252
|
+
if (toolbarOptions.value.show) {
|
253
|
+
toolbarRef.value!.layerRef!.setPosition()
|
254
|
+
} else {
|
255
|
+
toolbarOptions.value.show = true
|
256
|
+
}
|
257
|
+
}
|
258
|
+
//显示无序列表工具条
|
259
|
+
else if (unorderList) {
|
260
|
+
toolbarOptions.value.type = 'unorderList'
|
261
|
+
toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${unorderList.key}"]`
|
262
|
+
if (toolbarOptions.value.show) {
|
263
|
+
toolbarRef.value!.layerRef!.setPosition()
|
264
|
+
} else {
|
265
|
+
toolbarOptions.value.show = true
|
266
|
+
}
|
267
|
+
}
|
268
|
+
}
|
233
269
|
}
|
234
270
|
})
|
235
271
|
}
|
@@ -241,28 +277,28 @@ const createEditor = () => {
|
|
241
277
|
disabled: isDisabled.value,
|
242
278
|
renderRules: [
|
243
279
|
el => {
|
244
|
-
|
280
|
+
listHandle(editor.value!, el)
|
245
281
|
},
|
246
282
|
el => {
|
247
|
-
|
283
|
+
imageHandle(editor.value!, el)
|
248
284
|
},
|
249
285
|
el => {
|
250
|
-
|
286
|
+
videoHandle(editor.value!, el)
|
251
287
|
},
|
252
288
|
el => {
|
253
|
-
|
289
|
+
separatorHandle(editor.value!, el)
|
254
290
|
},
|
255
291
|
el => {
|
256
|
-
|
292
|
+
linkHandle(editor.value!, el)
|
257
293
|
},
|
258
294
|
el => {
|
259
|
-
|
295
|
+
codeHandle(editor.value!, el)
|
260
296
|
},
|
261
297
|
el => {
|
262
|
-
|
298
|
+
tableHandle(editor.value!, el)
|
263
299
|
},
|
264
300
|
el => {
|
265
|
-
|
301
|
+
preHandle(editor.value!, el, !!(toolbarConfig.value?.use && toolbarConfig.value?.codeBlock?.languages?.show), toolbarConfig.value?.codeBlock?.languages?.options as (string | LanguagesItemType)[])
|
266
302
|
},
|
267
303
|
el => {
|
268
304
|
attachmentHandle(editor.value!, el, $editTrans)
|
@@ -273,6 +309,9 @@ const createEditor = () => {
|
|
273
309
|
el => {
|
274
310
|
infoBlockHandle(editor.value!, el, props.color)
|
275
311
|
},
|
312
|
+
el => {
|
313
|
+
specialInblockHandle(editor.value!, el)
|
314
|
+
},
|
276
315
|
...props.renderRules
|
277
316
|
],
|
278
317
|
extraKeepTags: [...extraKeepTagsForMathformula, ...props.extraKeepTags],
|
@@ -473,7 +512,7 @@ const documentClick = (e: Event) => {
|
|
473
512
|
if (key) {
|
474
513
|
const element = editor.value!.getElementByKey(key)!
|
475
514
|
//如果是任务列表元素
|
476
|
-
if (elementIsTask(element)) {
|
515
|
+
if (element && elementIsTask(element)) {
|
477
516
|
const rect = DapElement.getElementBounding(elm)
|
478
517
|
//在复选框范围内
|
479
518
|
if (event.pageX >= Math.abs(rect.left) && event.pageX <= Math.abs(rect.left + 16) && event.pageY >= Math.abs(rect.top + elm.offsetHeight / 2 - 8) && event.pageY <= Math.abs(rect.top + elm.offsetHeight / 2 + 8)) {
|
@@ -499,7 +538,8 @@ const documentClick = (e: Event) => {
|
|
499
538
|
}
|
500
539
|
//重新定义编辑器粘贴html
|
501
540
|
const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
502
|
-
AlexElement.flatElements(elements)
|
541
|
+
const flatElements = AlexElement.flatElements(elements)
|
542
|
+
flatElements.forEach(el => {
|
503
543
|
if (!el.isText()) {
|
504
544
|
let marks: ObjectType = {}
|
505
545
|
let styles: ObjectType = {}
|
@@ -552,10 +592,7 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
|
552
592
|
//有序和无序列表属性保留
|
553
593
|
if (elementIsList(el, true) || elementIsList(el, false)) {
|
554
594
|
marks['data-editify-list'] = el.marks!['data-editify-list']
|
555
|
-
|
556
|
-
if (el.marks!['data-editify-value']) {
|
557
|
-
marks['data-editify-value'] = el.marks!['data-editify-value']
|
558
|
-
}
|
595
|
+
marks['data-editify-list-style'] = el.marks!['data-editify-list-style']
|
559
596
|
}
|
560
597
|
//行内代码属性保留
|
561
598
|
if (el.parsedom == AlexElement.TEXT_NODE && el.marks!['data-editify-code']) {
|
@@ -590,7 +627,7 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
|
590
627
|
}
|
591
628
|
//数学公式内的属性全部保留
|
592
629
|
if (!!getMathformulaByElement(el)) {
|
593
|
-
marks = mergeObject(marks,
|
630
|
+
marks = mergeObject(marks, DapCommon.clone(el.marks!))!
|
594
631
|
}
|
595
632
|
//面板属性保留
|
596
633
|
if (elementIsPanel(el)) {
|
@@ -621,7 +658,7 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
|
621
658
|
}
|
622
659
|
//数学公式内的样式全部保留
|
623
660
|
if (!!getMathformulaByElement(el)) {
|
624
|
-
styles = mergeObject(styles,
|
661
|
+
styles = mergeObject(styles, DapCommon.clone(el.styles!))!
|
625
662
|
}
|
626
663
|
}
|
627
664
|
//对外的自定义属性和样式保留
|
@@ -635,7 +672,24 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
|
|
635
672
|
el.marks = marks
|
636
673
|
el.styles = styles
|
637
674
|
}
|
675
|
+
//对于不在table下的这些表格元素直接置空
|
676
|
+
if (el.parsedom && ['tbody', 'tr', 'th', 'td', 'thead', 'tfooter', 'colgroup', 'col'].includes(el.parsedom)) {
|
677
|
+
const flag = !!getMatchElementByElement(el, {
|
678
|
+
parsedom: 'table'
|
679
|
+
})
|
680
|
+
if (!flag) {
|
681
|
+
el.toEmpty()
|
682
|
+
if (el.parent) {
|
683
|
+
const index = el.parent.children!.findIndex(item => item.isEqual(el))
|
684
|
+
el.parent.children!.splice(index, 1)
|
685
|
+
}
|
686
|
+
}
|
687
|
+
}
|
638
688
|
})
|
689
|
+
elements = elements.filter(el => !el.isEmpty())
|
690
|
+
if (!elements.length) {
|
691
|
+
return
|
692
|
+
}
|
639
693
|
//如果使用了自定义粘贴html的功能
|
640
694
|
if (typeof props.customHtmlPaste == 'function') {
|
641
695
|
await props.customHtmlPaste(elements)
|
@@ -862,27 +916,25 @@ const handleAfterRender = () => {
|
|
862
916
|
//设定视频高度
|
863
917
|
setVideoHeight()
|
864
918
|
//附件元素下载事件设置
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
method: 'GET'
|
875
|
-
})
|
876
|
-
//获取blob数据
|
877
|
-
const blob = await res.blob()
|
878
|
-
//创建a标签进行下载
|
879
|
-
const a = document.createElement('a')
|
880
|
-
a.setAttribute('target', '_blank')
|
881
|
-
a.setAttribute('href', URL.createObjectURL(blob))
|
882
|
-
a.setAttribute('download', el.marks!['data-editify-attachment-name'])
|
883
|
-
a.click()
|
919
|
+
contentRef.value!.querySelectorAll('span[data-editify-attachment]').forEach(dom => {
|
920
|
+
DapEvent.off(dom as HTMLElement, 'click')
|
921
|
+
//单击下载
|
922
|
+
DapEvent.on(dom as HTMLElement, 'click', async () => {
|
923
|
+
//获取文件地址
|
924
|
+
const url = dom.getAttribute('data-editify-attachment')!
|
925
|
+
//使用fetch读取文件地址
|
926
|
+
const res = await fetch(url, {
|
927
|
+
method: 'GET'
|
884
928
|
})
|
885
|
-
|
929
|
+
//获取blob数据
|
930
|
+
const blob = await res.blob()
|
931
|
+
//创建a标签进行下载
|
932
|
+
const a = document.createElement('a')
|
933
|
+
a.setAttribute('target', '_blank')
|
934
|
+
a.setAttribute('href', URL.createObjectURL(blob))
|
935
|
+
a.setAttribute('download', dom.getAttribute('data-editify-attachment-name')!)
|
936
|
+
a.click()
|
937
|
+
})
|
886
938
|
})
|
887
939
|
emits('updateview')
|
888
940
|
}
|
package/src/editify/props.ts
CHANGED
@@ -12,7 +12,7 @@ export type EditifyResizeParamsType = {
|
|
12
12
|
export type EditifyToolbarOptionsType = {
|
13
13
|
show: boolean
|
14
14
|
node: string | null
|
15
|
-
type: 'text' | 'link' | 'image' | 'video' | 'table' | 'codeBlock'
|
15
|
+
type: 'text' | 'link' | 'image' | 'video' | 'table' | 'codeBlock' | 'orderList' | 'unorderList'
|
16
16
|
}
|
17
17
|
|
18
18
|
export const EditifyProps = {
|
@@ -19,10 +19,10 @@ export const ToolbarProps = {
|
|
19
19
|
},
|
20
20
|
//类型
|
21
21
|
type: {
|
22
|
-
type: String as PropType<'text' | 'table' | 'link' | 'codeBlock' | 'image' | 'video'>,
|
22
|
+
type: String as PropType<'text' | 'table' | 'link' | 'codeBlock' | 'image' | 'video' | 'orderList' | 'unorderList'>,
|
23
23
|
default: 'text',
|
24
24
|
validator(value: any) {
|
25
|
-
return ['text', 'table', 'link', 'codeBlock', 'image', 'video'].includes(value)
|
25
|
+
return ['text', 'table', 'link', 'codeBlock', 'image', 'video', 'orderList', 'unorderList'].includes(value)
|
26
26
|
}
|
27
27
|
},
|
28
28
|
//工具条配置
|