vue-editify 0.2.16 → 0.2.18

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 (60) hide show
  1. package/examples/App.vue +289 -5
  2. package/lib/components/colors/colors.vue.d.ts +9 -0
  3. package/lib/components/colors/props.d.ts +4 -0
  4. package/lib/core/function.d.ts +120 -45
  5. package/lib/core/rule.d.ts +23 -17
  6. package/lib/core/tool.d.ts +1 -13
  7. package/lib/editify/editify.vue.d.ts +10 -1
  8. package/lib/editify/props.d.ts +1 -1
  9. package/lib/editify/toolbar/props.d.ts +1 -1
  10. package/lib/editify/toolbar/toolbar.vue.d.ts +3 -3
  11. package/lib/editify.es.js +13640 -13799
  12. package/lib/editify.umd.js +2 -2
  13. package/lib/feature/align.d.ts +0 -14
  14. package/lib/feature/heading.d.ts +0 -14
  15. package/lib/feature/lineHeight.d.ts +0 -14
  16. package/lib/feature/orderList.d.ts +1 -3
  17. package/lib/feature/task.d.ts +0 -14
  18. package/lib/feature/unorderList.d.ts +1 -3
  19. package/lib/index.d.ts +12 -3
  20. package/package.json +2 -2
  21. package/src/components/button/button.vue +3 -3
  22. package/src/components/checkbox/checkbox.vue +1 -1
  23. package/src/components/colors/colors.vue +4 -4
  24. package/src/components/colors/props.ts +6 -1
  25. package/src/components/insertAttachment/insertAttachment.vue +1 -1
  26. package/src/components/insertImage/insertImage.vue +1 -1
  27. package/src/components/insertLink/insertLink.vue +1 -1
  28. package/src/components/insertVideo/insertVideo.vue +1 -1
  29. package/src/components/layer/layer.vue +9 -3
  30. package/src/components/tooltip/tooltip.vue +1 -1
  31. package/src/components/updateLink/updateLink.vue +1 -1
  32. package/src/core/function.ts +961 -475
  33. package/src/core/rule.ts +85 -367
  34. package/src/core/tool.ts +8 -114
  35. package/src/editify/editify.less +88 -14
  36. package/src/editify/editify.vue +117 -65
  37. package/src/editify/props.ts +1 -1
  38. package/src/editify/toolbar/props.ts +2 -2
  39. package/src/editify/toolbar/toolbar.vue +12 -12
  40. package/src/feature/align.ts +1 -61
  41. package/src/feature/attachment.ts +13 -26
  42. package/src/feature/backColor.ts +1 -0
  43. package/src/feature/foreColor.ts +1 -0
  44. package/src/feature/heading.ts +2 -73
  45. package/src/feature/infoBlock.ts +4 -35
  46. package/src/feature/lineHeight.ts +1 -77
  47. package/src/feature/mathformula.ts +3 -50
  48. package/src/feature/orderList.ts +166 -35
  49. package/src/feature/panel.ts +4 -49
  50. package/src/feature/sub.ts +1 -1
  51. package/src/feature/super.ts +1 -1
  52. package/src/feature/task.ts +1 -55
  53. package/src/feature/unorderList.ts +106 -35
  54. package/src/feature/video.ts +1 -1
  55. package/src/icon/iconfont.css +40 -0
  56. package/src/icon/iconfont.ttf +0 -0
  57. package/src/icon/iconfont.woff +0 -0
  58. package/src/index.ts +14 -8
  59. package/src/locale/en_US.ts +112 -110
  60. 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, editLocale: LocaleType): ToolbarConfigType => {
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: false,
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
- sourceView: 28,
836
- fullScreen: 29,
837
- attachment: 30,
838
- mathformula: 31,
839
- panel: 32,
840
- infoBlock: 33
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: {
@@ -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
- content: attr(data-editify-value) '.';
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: '\2022';
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: 16px;
317
- height: 16px;
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: 6px;
402
+ height: 5px;
336
403
  position: absolute;
337
404
  content: '';
338
- left: 3px;
405
+ left: 2px;
339
406
  top: 50%;
340
- margin-top: -2px;
341
- border: 1px solid var(--editify-font-color-light);
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
- opacity: 1;
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
  }
@@ -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, cloneData } from '@/core/tool'
26
- import { parseList, orderdListHandle, commonElementHandle, tableThTdHandle, tableFormatHandle, tableRangeMergedHandle, preHandle, specialInblockHandle, attachmentHandle, mathformulaHandle, infoBlockHandle } from '@/core/rule'
27
- import { elementToParagraph, getMatchElementByRange, hasTableInRange, hasLinkInRange, hasPreInRange, hasImageInRange, hasVideoInRange, elementIsTask, elementIsAttachment, elementIsList, elementIsMathformula, getMathformulaByElement, elementIsPanel, elementIsInfoBlock } from '@/core/function'
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, props.locale), props.toolbar || {}) as ToolbarConfigType
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
- if (result.length && !hasTableInRange(editor.value!, dataRangeCaches.value) && !hasPreInRange(editor.value!, dataRangeCaches.value) && !hasLinkInRange(editor.value!, dataRangeCaches.value) && !hasImageInRange(editor.value!, dataRangeCaches.value) && !hasVideoInRange(editor.value!, dataRangeCaches.value)) {
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
- parseList(editor.value!, el)
280
+ listHandle(editor.value!, el)
245
281
  },
246
282
  el => {
247
- orderdListHandle(editor.value!, el)
283
+ imageHandle(editor.value!, el)
248
284
  },
249
285
  el => {
250
- commonElementHandle(editor.value!, el)
286
+ videoHandle(editor.value!, el)
251
287
  },
252
288
  el => {
253
- tableThTdHandle(editor.value!, el)
289
+ separatorHandle(editor.value!, el)
254
290
  },
255
291
  el => {
256
- tableFormatHandle(editor.value!, el)
292
+ linkHandle(editor.value!, el)
257
293
  },
258
294
  el => {
259
- tableRangeMergedHandle(editor.value!, el)
295
+ codeHandle(editor.value!, el)
260
296
  },
261
297
  el => {
262
- preHandle(editor.value!, el, !!(toolbarConfig.value?.use && toolbarConfig.value?.codeBlock?.languages?.show), toolbarConfig.value?.codeBlock?.languages?.options as (string | LanguagesItemType)[])
298
+ tableHandle(editor.value!, el)
263
299
  },
264
300
  el => {
265
- specialInblockHandle(editor.value!, el)
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).forEach(el => {
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, cloneData(el.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, cloneData(el.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
- AlexElement.flatElements(editor.value!.stack).forEach(el => {
866
- if (elementIsAttachment(el)) {
867
- DapEvent.off(el.elm as HTMLElement, 'click')
868
- //单击下载
869
- DapEvent.on(el.elm as HTMLElement, 'click', async () => {
870
- //获取文件地址
871
- const url = el.marks!['data-editify-attachment']
872
- //使用fetch读取文件地址
873
- const res = await fetch(url, {
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
  }
@@ -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
  //工具条配置