vue-editify 0.1.37 → 0.1.39

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 (55) hide show
  1. package/examples/App.vue +6 -10
  2. package/lib/components/button/button.vue.d.ts +13 -13
  3. package/lib/components/button/props.d.ts +1 -1
  4. package/lib/components/checkbox/checkbox.vue.d.ts +10 -10
  5. package/lib/components/checkbox/props.d.ts +1 -1
  6. package/lib/components/colors/colors.vue.d.ts +6 -6
  7. package/lib/components/colors/props.d.ts +1 -1
  8. package/lib/components/icon/icon.vue.d.ts +1 -1
  9. package/lib/components/insertImage/insertImage.vue.d.ts +11 -11
  10. package/lib/components/insertLink/insertLink.vue.d.ts +4 -4
  11. package/lib/components/insertTable/insertTable.vue.d.ts +4 -4
  12. package/lib/components/insertVideo/insertVideo.vue.d.ts +11 -11
  13. package/lib/components/layer/layer.vue.d.ts +9 -9
  14. package/lib/components/menu/menu.vue.d.ts +6 -6
  15. package/lib/components/menu/props.d.ts +1 -1
  16. package/lib/components/toolbar/props.d.ts +1 -1
  17. package/lib/components/toolbar/toolbar.vue.d.ts +11 -11
  18. package/lib/components/tooltip/tooltip.vue.d.ts +1 -1
  19. package/lib/components/triangle/triangle.vue.d.ts +4 -4
  20. package/lib/core/function.d.ts +1 -1
  21. package/lib/core/rule.d.ts +1 -1
  22. package/lib/core/tool.d.ts +8 -11
  23. package/lib/editify/editify.vue.d.ts +110 -84
  24. package/lib/editify/props.d.ts +9 -5
  25. package/lib/editify.es.js +15154 -404
  26. package/lib/editify.umd.js +1 -1
  27. package/lib/index.d.ts +4 -2
  28. package/lib/plugins/attachment/index.d.ts +3 -2
  29. package/lib/plugins/attachment/insertAttachment/insertAttachment.vue.d.ts +11 -11
  30. package/lib/plugins/mathformula/index.d.ts +31 -0
  31. package/lib/plugins/mathformula/insertMathformula/insertMathformula.vue.d.ts +18 -0
  32. package/lib/plugins/mathformula/insertMathformula/props.d.ts +9 -0
  33. package/lib/style.css +1 -1
  34. package/package.json +4 -2
  35. package/src/components/insertImage/insertImage.less +1 -0
  36. package/src/components/insertLink/insertLink.less +1 -0
  37. package/src/components/insertVideo/insertVideo.less +1 -0
  38. package/src/core/function.ts +4 -12
  39. package/src/core/rule.ts +7 -0
  40. package/src/core/tool.ts +3 -33
  41. package/src/editify/editify.less +1 -1
  42. package/src/editify/editify.vue +111 -26
  43. package/src/editify/props.ts +11 -4
  44. package/src/icon/iconfont.css +4 -0
  45. package/src/icon/iconfont.ttf +0 -0
  46. package/src/icon/iconfont.woff +0 -0
  47. package/src/index.ts +4 -1
  48. package/src/locale/en_US.ts +6 -1
  49. package/src/locale/zh_CN.ts +7 -2
  50. package/src/plugins/attachment/index.ts +26 -15
  51. package/src/plugins/attachment/insertAttachment/insertAttachment.less +1 -0
  52. package/src/plugins/mathformula/index.ts +210 -0
  53. package/src/plugins/mathformula/insertMathformula/insertMathformula.less +64 -0
  54. package/src/plugins/mathformula/insertMathformula/insertMathformula.vue +40 -0
  55. package/src/plugins/mathformula/insertMathformula/props.ts +11 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-editify",
3
- "version": "0.1.37",
3
+ "version": "0.1.39",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "*.css"
@@ -17,12 +17,14 @@
17
17
  "lib": "vue-tsc && vite build"
18
18
  },
19
19
  "dependencies": {
20
- "alex-editor": "^1.3.37",
20
+ "alex-editor": "^1.4.6",
21
21
  "dap-util": "^1.5.4",
22
22
  "highlight.js": "^11.8.0",
23
+ "katex": "^0.16.10",
23
24
  "vue": "^3.4.19"
24
25
  },
25
26
  "devDependencies": {
27
+ "@types/katex": "^0.16.7",
26
28
  "@types/node": "^20.11.24",
27
29
  "@vitejs/plugin-vue": "^5.0.4",
28
30
  "less": "^3.0.4",
@@ -80,6 +80,7 @@
80
80
  background-color: transparent;
81
81
  outline: none;
82
82
  box-sizing: border-box;
83
+ font-family: inherit;
83
84
 
84
85
  &::-webkit-input-placeholder,
85
86
  &::placeholder {
@@ -28,6 +28,7 @@
28
28
  background-color: transparent;
29
29
  outline: none;
30
30
  box-sizing: border-box;
31
+ font-family: inherit;
31
32
 
32
33
  &::-webkit-input-placeholder,
33
34
  &::placeholder {
@@ -80,6 +80,7 @@
80
80
  background-color: transparent;
81
81
  outline: none;
82
82
  box-sizing: border-box;
83
+ font-family: inherit;
83
84
 
84
85
  &::-webkit-input-placeholder,
85
86
  &::placeholder {
@@ -1250,12 +1250,8 @@ export const insertVideo = (editor: AlexEditor, value: string) => {
1250
1250
  null
1251
1251
  )
1252
1252
  editor.insertElement(video)
1253
- const leftSpace = AlexElement.getSpaceElement()
1254
- const rightSpace = AlexElement.getSpaceElement()
1255
- editor.addElementAfter(rightSpace, video)
1256
- editor.addElementBefore(leftSpace, video)
1257
- editor.range.anchor.moveToEnd(rightSpace)
1258
- editor.range.focus.moveToEnd(rightSpace)
1253
+ editor.range.anchor.moveToEnd(video)
1254
+ editor.range.focus.moveToEnd(video)
1259
1255
  }
1260
1256
 
1261
1257
  /**
@@ -1384,10 +1380,6 @@ export const insertSeparator = (editor: AlexEditor) => {
1384
1380
  }
1385
1381
  const separator = new AlexElement('closed', 'hr', null, null, null)
1386
1382
  editor.insertElement(separator)
1387
- const leftSpace = AlexElement.getSpaceElement()
1388
- const rightSpace = AlexElement.getSpaceElement()
1389
- editor.addElementAfter(rightSpace, separator)
1390
- editor.addElementBefore(leftSpace, separator)
1391
- editor.range.anchor.moveToEnd(rightSpace)
1392
- editor.range.focus.moveToEnd(rightSpace)
1383
+ editor.range.anchor.moveToEnd(separator)
1384
+ editor.range.focus.moveToEnd(separator)
1393
1385
  }
package/src/core/rule.ts CHANGED
@@ -144,6 +144,13 @@ export const commonElementHandle = function (editor: AlexEditor, element: AlexEl
144
144
  const spaceText = AlexElement.getSpaceElement()
145
145
  editor.addElementAfter(spaceText, element)
146
146
  }
147
+ //如果光标在视频上则更新光标位置
148
+ if (editor.range && element.isContains(editor.range.anchor.element)) {
149
+ editor.range.anchor.moveToEnd(editor.getNextElement(element)!)
150
+ }
151
+ if (editor.range && element.isContains(editor.range.focus.element)) {
152
+ editor.range.focus.moveToEnd(editor.getNextElement(element)!)
153
+ }
147
154
  }
148
155
 
149
156
  //将code转为span[data-editify-code]
package/src/core/tool.ts CHANGED
@@ -210,44 +210,14 @@ export type PluginResultType = {
210
210
  menu?: PluginMenuConfigType
211
211
  updateView?: () => void
212
212
  customParseNode?: (element: AlexElement) => AlexElement
213
+ extraKeepTags?: string[]
213
214
  renderRule?: (el: AlexElement) => void
214
- pasteKeepStyles?: ObjectType
215
- pasteKeepMarks?: ObjectType
215
+ pasteKeepMarks?: (el: AlexElement) => ObjectType
216
+ pasteKeepStyles?: (el: AlexElement) => ObjectType
216
217
  }
217
218
 
218
219
  export type PluginType = (editifyInstance: ComponentInternalInstance, editTrans: (key: string) => any) => PluginResultType
219
220
 
220
- /**
221
- * 粘贴html时保留的数据
222
- */
223
- export const pasteKeepData: ObjectType = {
224
- //粘贴html时元素保留的样式(全部元素)
225
- marks: {
226
- 'data-editify-list': ['div'],
227
- 'data-editify-value': ['div'],
228
- 'data-editify-code': ['span'],
229
- 'data-editify-task': ['div'],
230
- contenteditable: '*',
231
- src: ['img', 'video'],
232
- autoplay: ['video'],
233
- loop: ['video'],
234
- muted: ['video'],
235
- href: ['a'],
236
- target: ['a'],
237
- alt: ['img'],
238
- controls: ['video'],
239
- name: '*',
240
- disabled: '*',
241
- colspan: ['td']
242
- },
243
- //粘贴html时非文本元素保留的样式
244
- styles: {
245
- 'text-indent': '*',
246
- 'text-align': '*',
247
- 'line-height': '*'
248
- }
249
- }
250
-
251
221
  /**
252
222
  * 对象平替值方法
253
223
  * @param o1
@@ -156,7 +156,7 @@
156
156
  }
157
157
  }
158
158
  //代码样式
159
- :deep(span[data-editify-code]) {
159
+ :deep([data-editify-code]) {
160
160
  display: inline-block;
161
161
  padding: 3px 6px;
162
162
  margin: 0 4px;
@@ -22,7 +22,7 @@
22
22
  import { computed, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, provide, ref, watch } from 'vue'
23
23
  import { AlexEditor, AlexElement, AlexElementRangeType, AlexElementsRangeType } from 'alex-editor'
24
24
  import { element as DapElement, event as DapEvent, data as DapData, number as DapNumber, color as DapColor } from 'dap-util'
25
- import { pasteKeepData, mergeObject, getToolbarConfig, getMenuConfig, MenuConfigType, ObjectType, ToolbarConfigType, PluginResultType } from '../core/tool'
25
+ import { mergeObject, getToolbarConfig, getMenuConfig, MenuConfigType, ObjectType, ToolbarConfigType, PluginResultType } from '../core/tool'
26
26
  import { parseList, orderdListHandle, commonElementHandle, tableHandle, preHandle, specialInblockHandle } from '../core/rule'
27
27
  import { isTask, elementToParagraph, getCurrentParsedomElement, hasTableInRange, hasLinkInRange, hasPreInRange, hasImageInRange, hasVideoInRange } from '../core/function'
28
28
  import Toolbar from '../components/toolbar/toolbar.vue'
@@ -249,6 +249,18 @@ const createEditor = () => {
249
249
  pluginRules.push(pluginResult.renderRule)
250
250
  }
251
251
  })
252
+ //注册插件:将插件定义的额外保留的标签数组与配置合并
253
+ let extraKeepTags: string[] = [...props.extraKeepTags]
254
+ pluginResultList.value.forEach(pluginResult => {
255
+ if (pluginResult.extraKeepTags && Array.isArray(pluginResult.extraKeepTags)) {
256
+ pluginResult.extraKeepTags.forEach(tag => {
257
+ //如果不包含则加入数组
258
+ if (!extraKeepTags.includes(tag)) {
259
+ extraKeepTags.push(tag)
260
+ }
261
+ })
262
+ }
263
+ })
252
264
  //创建编辑器
253
265
  editor.value = new AlexEditor(contentRef.value!, {
254
266
  value: value.value,
@@ -285,7 +297,8 @@ const createEditor = () => {
285
297
  customFilePaste: props.customFilePaste,
286
298
  customHtmlPaste: handleCustomHtmlPaste,
287
299
  customMerge: handleCustomMerge,
288
- customParseNode: handleCustomParseNode
300
+ customParseNode: handleCustomParseNode,
301
+ extraKeepTags: extraKeepTags
289
302
  })
290
303
  //编辑器渲染后会有一个渲染过程,会改变内容,因此重新获取内容的值来设置value
291
304
  internalModify(editor.value.value)
@@ -435,39 +448,111 @@ const documentClick = (e: Event) => {
435
448
  }
436
449
  //重新定义编辑器粘贴html
437
450
  const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
438
- let keepStyles = pasteKeepData.styles
439
- let keepMarks = pasteKeepData.marks
440
- //注册插件:自定义html粘贴保留
441
- pluginResultList.value.forEach(pluginResult => {
442
- keepStyles = Object.assign(keepStyles, pluginResult.pasteKeepStyles || {})
443
- keepMarks = Object.assign(keepMarks, pluginResult.pasteKeepMarks || {})
444
- })
445
- keepStyles = Object.assign(keepStyles, props.pasteKeepStyles || {})
446
- keepMarks = Object.assign(keepMarks, props.pasteKeepMarks || {})
447
- //粘贴html时过滤元素的样式和属性
448
451
  AlexElement.flatElements(elements).forEach(el => {
449
- let marks: ObjectType = {}
450
- let styles: ObjectType = {}
451
- //非文本元素
452
452
  if (!el.isText()) {
453
- //对标记进行处理
453
+ let marks: ObjectType = {}
454
+ let styles: ObjectType = {}
455
+ //处理需要保留的标记
454
456
  if (el.hasMarks()) {
455
- for (let key in keepMarks) {
456
- if (el.marks!.hasOwnProperty(key) && ((Array.isArray(keepMarks[key]) && keepMarks[key].includes(el.parsedom)) || keepMarks[key] == '*')) {
457
- marks[key] = el.marks![key]
457
+ //contenteditable属性保留
458
+ if (el.marks!['contenteditable']) {
459
+ marks['contenteditable'] = el.marks!['contenteditable']
460
+ }
461
+ //name属性保留
462
+ if (el.marks!['name']) {
463
+ marks['name'] = el.marks!['name']
464
+ }
465
+ //disabled属性保留
466
+ if (el.marks!['disabled']) {
467
+ marks['disabled'] = el.marks!['disabled']
468
+ }
469
+ //td的colspan属性保留
470
+ if (el.parsedom == 'td' && el.marks!['colspan']) {
471
+ marks['colspan'] = el.marks!['colspan']
472
+ }
473
+ //图片和视频的src属性保留
474
+ if (['img', 'video'].includes(el.parsedom!) && el.marks!['src']) {
475
+ marks['src'] = el.marks!['src']
476
+ }
477
+ //视频的autoplay属性保留
478
+ if (el.parsedom == 'video' && el.marks!['autoplay']) {
479
+ marks['autoplay'] = el.marks!['autoplay']
480
+ }
481
+ //视频的loop属性保留
482
+ if (el.parsedom == 'video' && el.marks!['loop']) {
483
+ marks['loop'] = el.marks!['loop']
484
+ }
485
+ //视频的muted属性保留
486
+ if (el.parsedom == 'video' && el.marks!['muted']) {
487
+ marks['muted'] = el.marks!['muted']
488
+ }
489
+ //视频的controls属性保留
490
+ if (el.parsedom == 'video' && el.marks!['controls']) {
491
+ marks['controls'] = el.marks!['controls']
492
+ }
493
+ //链接的href属性保留
494
+ if (el.parsedom == 'a' && el.marks!['href']) {
495
+ marks['href'] = el.marks!['href']
496
+ }
497
+ //链接的target属性保留
498
+ if (el.parsedom == 'a' && el.marks!['target']) {
499
+ marks['target'] = el.marks!['target']
500
+ }
501
+ //有序和无序列表属性保留
502
+ if (el.parsedom == 'div' && el.marks!['data-editify-list']) {
503
+ marks['data-editify-list'] = el.marks!['data-editify-list']
504
+ //有序列表保留序列号标记
505
+ if (el.marks!['data-editify-value']) {
506
+ marks['data-editify-value'] = el.marks!['data-editify-value']
458
507
  }
459
508
  }
460
- el.marks = marks
509
+ //行内代码属性保留
510
+ if (el.parsedom == AlexElement.TEXT_NODE && el.marks!['data-editify-code']) {
511
+ marks['data-editify-code'] = el.marks!['data-editify-code']
512
+ }
513
+ //任务列表属性保留
514
+ if (el.parsedom == 'div' && el.marks!['data-editify-task']) {
515
+ marks['data-editify-task'] = el.marks!['data-editify-task']
516
+ }
461
517
  }
462
- //对样式进行处理
518
+ //处理需要保留的样式
463
519
  if (el.hasStyles()) {
464
- for (let key in keepStyles) {
465
- if (el.styles!.hasOwnProperty(key) && ((Array.isArray(keepStyles[key]) && keepStyles[key].includes(el.parsedom)) || keepStyles[key] == '*')) {
466
- styles[key] = el.styles![key]
467
- }
520
+ //块元素保留text-indent样式
521
+ if ((el.isBlock() || el.isInblock()) && el.styles!['text-indent']) {
522
+ styles['text-indent'] = el.styles!['text-indent']
468
523
  }
469
- el.styles = styles
524
+ //块元素保留text-align样式
525
+ if ((el.isBlock() || el.isInblock()) && el.styles!['text-align']) {
526
+ styles['text-align'] = el.styles!['text-align']
527
+ }
528
+ //块元素保留line-height样式
529
+ if ((el.isBlock() || el.isInblock()) && el.styles!['line-height']) {
530
+ styles['line-height'] = el.styles!['line-height']
531
+ }
532
+ }
533
+ //注册插件:自定义属性和样式的保留
534
+ pluginResultList.value.forEach(pluginResult => {
535
+ if (typeof pluginResult.pasteKeepMarks == 'function') {
536
+ const keepMarks = pluginResult.pasteKeepMarks(el)
537
+ marks = mergeObject(marks, keepMarks)!
538
+ }
539
+ if (typeof pluginResult.pasteKeepStyles == 'function') {
540
+ const keepStyles = pluginResult.pasteKeepStyles(el)
541
+ styles = mergeObject(styles, keepStyles)!
542
+ }
543
+ })
544
+ //对外的自定义属性和样式保留
545
+ if (typeof props.pasteKeepMarks == 'function') {
546
+ const keepMarks = props.pasteKeepMarks(el)
547
+ marks = mergeObject(marks, keepMarks)!
548
+ }
549
+ if (typeof props.pasteKeepStyles == 'function') {
550
+ const keepStyles = props.pasteKeepStyles(el)
551
+ styles = mergeObject(styles, keepStyles)!
470
552
  }
553
+ //将处理后的样式和标记给元素
554
+ el.marks = marks
555
+ el.styles = styles
471
556
  }
472
557
  })
473
558
  //如果使用了自定义粘贴html的功能
@@ -119,14 +119,14 @@ export const EditifyProps = {
119
119
  type: Object as PropType<MenuConfigType>,
120
120
  default: null
121
121
  },
122
- //粘贴html时额外保留的标记(全部元素生效)
122
+ //粘贴html时对非文本元素额外保留标记的自定义处理
123
123
  pasteKeepMarks: {
124
- type: Object as PropType<ObjectType>,
124
+ type: Function as PropType<(el: AlexElement) => ObjectType>,
125
125
  default: null
126
126
  },
127
- //粘贴html时额外保留的样式(仅在非文本元素生效)
127
+ //粘贴html时对非文本元素额外保留样式的自定义处理
128
128
  pasteKeepStyles: {
129
- type: Object as PropType<ObjectType>,
129
+ type: Function as PropType<(el: AlexElement) => ObjectType>,
130
130
  default: null
131
131
  },
132
132
  //自定义node转元素时的处理
@@ -134,6 +134,13 @@ export const EditifyProps = {
134
134
  type: Function as PropType<(el: AlexElement) => AlexElement>,
135
135
  default: null
136
136
  },
137
+ //node转为元素时需要额外保留的标签数组
138
+ extraKeepTags: {
139
+ type: Array as PropType<string[]>,
140
+ default: function () {
141
+ return []
142
+ }
143
+ },
137
144
  //自定义额外的渲染规范
138
145
  renderRules: {
139
146
  type: Array as PropType<((el: AlexElement) => void)[]>,
@@ -1,3 +1,7 @@
1
+ .editify-icon-mathformula:before {
2
+ content: '\e616';
3
+ }
4
+
1
5
  .editify-icon-separator:before {
2
6
  content: '\e6e5';
3
7
  }
Binary file
Binary file
package/src/index.ts CHANGED
@@ -18,7 +18,7 @@ const install: FunctionPlugin = (app: App) => {
18
18
  app.component(Editify.name!, Editify)
19
19
  }
20
20
  //版本号
21
- const version = '0.1.37'
21
+ const version = '0.1.39'
22
22
 
23
23
  //导出AlexElement元素
24
24
  export { AlexElement } from 'alex-editor'
@@ -27,6 +27,9 @@ export { AlexElement } from 'alex-editor'
27
27
  export type { AttachmentOptionsType } from './plugins/attachment'
28
28
  export type { InsertAttachmentUploadErrorType } from './plugins/attachment/insertAttachment/props'
29
29
  export { attachment, isAttachment, hasAttachmentInRange } from './plugins/attachment'
30
+ //导出mathformula插件相关的方法和类型
31
+ export type { MathformulaOptionsType } from './plugins/mathformula'
32
+ export { mathformula, isMathformula, isUnderMathformula, getMathformulaElement } from './plugins/mathformula'
30
33
 
31
34
  //导出组件和安装函数
32
35
  export { install as default, install, Editify, version }
@@ -86,6 +86,7 @@ export const en_US: ObjectType = {
86
86
  defaultLineHeight: 'Default',
87
87
  auto: 'auto',
88
88
  fullScreen: 'Full screen',
89
+ confirm: 'Confirm',
89
90
 
90
91
  //插件语言配置
91
92
  insertAttachment: 'Insert attachment',
@@ -94,5 +95,9 @@ export const en_US: ObjectType = {
94
95
  attachmentNamePlaceholder: 'Please enter the attachment name',
95
96
  attachmentUrlPlaceholder: 'Please enter the attachment address',
96
97
  attachmentDownloadTitle: 'Click to download attachment',
97
- attachmentDefaultName: 'attachment'
98
+ attachmentDefaultName: 'attachment',
99
+
100
+ //数学公式插件语言配置
101
+ insertMathformula: 'Insert mathematical formula',
102
+ mathformulaPlaceholder: 'Please enter LaTex syntax'
98
103
  }
@@ -86,13 +86,18 @@ export const zh_CN: ObjectType = {
86
86
  defaultLineHeight: '默认行高',
87
87
  auto: '自适应',
88
88
  fullScreen: '全屏',
89
+ confirm: '确定',
89
90
 
90
- //插件语言配置
91
+ //附件插件语言配置
91
92
  insertAttachment: '插入附件',
92
93
  uploadAttachment: '上传附件',
93
94
  remoteAttachment: '远程地址',
94
95
  attachmentNamePlaceholder: '请输入附件名称',
95
96
  attachmentUrlPlaceholder: '请输入附件地址',
96
97
  attachmentDownloadTitle: '点击下载附件',
97
- attachmentDefaultName: '附件'
98
+ attachmentDefaultName: '附件',
99
+
100
+ //数学公式插件语言配置
101
+ insertMathformula: '插入数学公式',
102
+ mathformulaPlaceholder: '请输入LaTex语法'
98
103
  }
@@ -8,6 +8,7 @@ import InsertAttachment from './insertAttachment/insertAttachment.vue'
8
8
  import { InsertAttachmentUploadErrorType } from './insertAttachment/props'
9
9
  import { event as DapEvent, common as DapCommon } from 'dap-util'
10
10
  import { hasLinkInRange, hasPreInRange, hasQuoteInRange } from '../../core/function'
11
+ import { hasMathformulaInRange } from '../mathformula'
11
12
 
12
13
  export type AttachmentOptionsType = {
13
14
  //排序
@@ -18,6 +19,8 @@ export type AttachmentOptionsType = {
18
19
  leftBorder?: boolean
19
20
  //按钮是否显示右侧边框
20
21
  rightBorder?: boolean
22
+ //按钮是否禁用
23
+ disabled?: boolean
21
24
  //定义可选择的文件类型,默认不限制类型,设定此参数后选择文件时会自动过滤非符合的文件类型
22
25
  accept?: string
23
26
  //支持的类型数组
@@ -75,9 +78,9 @@ export const attachment = (options?: AttachmentOptionsType) => {
75
78
  }
76
79
  const plugin: PluginType = (editifyInstance: ComponentInternalInstance, editTrans: (key: string) => any) => {
77
80
  let isDisabled = false
78
- //如果光标范围内有链接、代码块和引用则禁用
81
+ //如果光标范围内有数学公式、链接、代码块和引用则禁用
79
82
  if (editifyInstance.exposed!.editor.value) {
80
- isDisabled = hasPreInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value) || hasLinkInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value) || hasQuoteInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value)
83
+ isDisabled = hasMathformulaInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value) || hasPreInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value) || hasLinkInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value) || hasQuoteInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value)
81
84
  }
82
85
  return {
83
86
  name: 'attachment',
@@ -97,7 +100,8 @@ export const attachment = (options?: AttachmentOptionsType) => {
97
100
  leftBorder: options!.leftBorder,
98
101
  rightBorder: options!.rightBorder,
99
102
  hideScroll: true,
100
- disabled: isDisabled,
103
+ active: false,
104
+ disabled: isDisabled || options!.disabled,
101
105
  default: () => h(Icon, { value: 'attachment' }),
102
106
  layer: (_name: string, btnInstance: InstanceType<typeof Button>) =>
103
107
  h(InsertAttachment, {
@@ -131,15 +135,9 @@ export const attachment = (options?: AttachmentOptionsType) => {
131
135
  const attachmentElement = new AlexElement('closed', 'span', marks, null, null)
132
136
  //插入编辑器
133
137
  editor.insertElement(attachmentElement)
134
- //创建空文本元素
135
- const leftSpace = AlexElement.getSpaceElement()
136
- const rightSpace = AlexElement.getSpaceElement()
137
- //将空白文本元素插入附件两端
138
- editor.addElementBefore(leftSpace, attachmentElement)
139
- editor.addElementAfter(rightSpace, attachmentElement)
140
138
  //移动光标到新插入的元素
141
- editor.range!.anchor.moveToEnd(rightSpace)
142
- editor.range!.focus.moveToEnd(rightSpace)
139
+ editor.range!.anchor.moveToEnd(attachmentElement)
140
+ editor.range!.focus.moveToEnd(attachmentElement)
143
141
  })
144
142
  //渲染
145
143
  editor.formatElementStack()
@@ -185,10 +183,16 @@ export const attachment = (options?: AttachmentOptionsType) => {
185
183
  }
186
184
  return el
187
185
  },
188
- //span元素粘贴保留data-editify-attachment
189
- pasteKeepMarks: {
190
- 'data-editify-attachment': ['span'],
191
- 'data-editify-attachment-name': ['span']
186
+ //附件文件自定义保留的标记
187
+ pasteKeepMarks: el => {
188
+ const marks: ObjectType = {}
189
+ if (el.parsedom == 'span' && el.hasMarks() && el.marks!['data-editify-attachment']) {
190
+ marks['data-editify-attachment'] = el.marks!['data-editify-attachment']
191
+ if (el.marks!['data-editify-attachment-name']) {
192
+ marks['data-editify-attachment-name'] = el.marks!['data-editify-attachment-name']
193
+ }
194
+ }
195
+ return marks
192
196
  },
193
197
  //自定义渲染规范
194
198
  renderRule: (el: AlexElement) => {
@@ -215,6 +219,13 @@ export const attachment = (options?: AttachmentOptionsType) => {
215
219
  const spaceText = AlexElement.getSpaceElement()
216
220
  editor.addElementAfter(spaceText, el)
217
221
  }
222
+ //如果光标在元素上则更新光标位置
223
+ if (editor.range && el.isContains(editor.range.anchor.element)) {
224
+ editor.range.anchor.moveToEnd(editor.getNextElement(el)!)
225
+ }
226
+ if (editor.range && el.isContains(editor.range.focus.element)) {
227
+ editor.range.focus.moveToEnd(editor.getNextElement(el)!)
228
+ }
218
229
  }
219
230
  }
220
231
  }
@@ -130,6 +130,7 @@
130
130
  background-color: transparent;
131
131
  outline: none;
132
132
  box-sizing: border-box;
133
+ font-family: inherit;
133
134
 
134
135
  &::-webkit-input-placeholder,
135
136
  &::placeholder {