vue-editify 0.2.14 → 0.2.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. package/examples/App.vue +41 -88
  2. package/lib/components/button/button.vue.d.ts +62 -60
  3. package/lib/components/button/index.d.ts +4 -0
  4. package/lib/components/button/props.d.ts +12 -1
  5. package/lib/components/checkbox/checkbox.vue.d.ts +9 -9
  6. package/lib/components/checkbox/index.d.ts +4 -0
  7. package/lib/components/checkbox/props.d.ts +2 -2
  8. package/lib/components/colors/colors.vue.d.ts +4 -4
  9. package/lib/components/colors/index.d.ts +4 -0
  10. package/lib/components/colors/props.d.ts +2 -2
  11. package/lib/components/icon/index.d.ts +4 -0
  12. package/lib/components/insertAttachment/index.d.ts +4 -0
  13. package/lib/{plugins/attachment → components}/insertAttachment/insertAttachment.vue.d.ts +3 -3
  14. package/lib/{plugins/attachment → components}/insertAttachment/props.d.ts +1 -1
  15. package/lib/components/insertImage/index.d.ts +4 -0
  16. package/lib/components/insertImage/insertImage.vue.d.ts +3 -3
  17. package/lib/components/insertImage/props.d.ts +1 -1
  18. package/lib/components/insertLink/index.d.ts +4 -0
  19. package/lib/components/insertLink/insertLink.vue.d.ts +6 -6
  20. package/lib/components/insertLink/props.d.ts +3 -3
  21. package/lib/components/insertMathformula/index.d.ts +4 -0
  22. package/lib/{plugins/mathformula → components}/insertMathformula/insertMathformula.vue.d.ts +3 -3
  23. package/lib/{plugins/mathformula → components}/insertMathformula/props.d.ts +2 -2
  24. package/lib/components/insertTable/index.d.ts +4 -0
  25. package/lib/components/insertTable/insertTable.vue.d.ts +3 -3
  26. package/lib/components/insertTable/props.d.ts +2 -2
  27. package/lib/components/insertVideo/index.d.ts +4 -0
  28. package/lib/components/insertVideo/insertVideo.vue.d.ts +3 -3
  29. package/lib/components/insertVideo/props.d.ts +1 -1
  30. package/lib/components/layer/index.d.ts +4 -0
  31. package/lib/components/layer/layer.vue.d.ts +10 -8
  32. package/lib/components/tooltip/index.d.ts +4 -0
  33. package/lib/components/tooltip/tooltip.vue.d.ts +6 -4
  34. package/lib/components/triangle/index.d.ts +4 -0
  35. package/lib/components/triangle/triangle.vue.d.ts +1 -1
  36. package/lib/components/updateLink/index.d.ts +4 -0
  37. package/lib/components/updateLink/props.d.ts +17 -0
  38. package/lib/components/updateLink/updateLink.vue.d.ts +38 -0
  39. package/lib/core/function.d.ts +113 -36
  40. package/lib/core/rule.d.ts +20 -0
  41. package/lib/core/tool.d.ts +36 -34
  42. package/lib/editify/editify.vue.d.ts +18 -28
  43. package/lib/editify/menu/index.d.ts +4 -0
  44. package/lib/{components → editify}/menu/menu.vue.d.ts +3 -4
  45. package/lib/{components → editify}/menu/props.d.ts +1 -1
  46. package/lib/editify/props.d.ts +3 -7
  47. package/lib/editify/toolbar/index.d.ts +4 -0
  48. package/lib/{components → editify}/toolbar/props.d.ts +2 -2
  49. package/lib/{components → editify}/toolbar/toolbar.vue.d.ts +53 -53
  50. package/lib/editify.es.js +38964 -37727
  51. package/lib/editify.umd.js +2 -2
  52. package/lib/feature/align.d.ts +32 -0
  53. package/lib/feature/attachment.d.ts +18 -0
  54. package/lib/feature/backColor.d.ts +32 -0
  55. package/lib/feature/bold.d.ts +32 -0
  56. package/lib/feature/code.d.ts +32 -0
  57. package/lib/feature/codeBlock.d.ts +32 -0
  58. package/lib/feature/fontFamily.d.ts +32 -0
  59. package/lib/feature/fontSize.d.ts +32 -0
  60. package/lib/feature/foreColor.d.ts +32 -0
  61. package/lib/feature/formatClear.d.ts +32 -0
  62. package/lib/feature/fullScreen.d.ts +18 -0
  63. package/lib/feature/heading.d.ts +32 -0
  64. package/lib/feature/image.d.ts +32 -0
  65. package/lib/feature/indent.d.ts +18 -0
  66. package/lib/feature/infoBlock.d.ts +18 -0
  67. package/lib/feature/italic.d.ts +32 -0
  68. package/lib/feature/lineHeight.d.ts +32 -0
  69. package/lib/feature/link.d.ts +26 -0
  70. package/lib/feature/mathformula.d.ts +22 -0
  71. package/lib/feature/orderList.d.ts +32 -0
  72. package/lib/feature/panel.d.ts +18 -0
  73. package/lib/feature/quote.d.ts +18 -0
  74. package/lib/feature/redo.d.ts +18 -0
  75. package/lib/feature/separator.d.ts +18 -0
  76. package/lib/feature/sourceView.d.ts +18 -0
  77. package/lib/feature/strikethrough.d.ts +32 -0
  78. package/lib/feature/sub.d.ts +32 -0
  79. package/lib/feature/super.d.ts +32 -0
  80. package/lib/feature/table.d.ts +32 -0
  81. package/lib/feature/task.d.ts +32 -0
  82. package/lib/feature/underline.d.ts +32 -0
  83. package/lib/feature/undo.d.ts +18 -0
  84. package/lib/feature/unorderList.d.ts +32 -0
  85. package/lib/feature/video.d.ts +38 -0
  86. package/lib/index.d.ts +194 -202
  87. package/package.json +5 -5
  88. package/src/components/button/button.vue +21 -24
  89. package/src/components/button/index.ts +5 -0
  90. package/src/components/button/props.ts +14 -1
  91. package/src/components/checkbox/checkbox.vue +1 -1
  92. package/src/components/checkbox/index.ts +5 -0
  93. package/src/components/checkbox/props.ts +1 -1
  94. package/src/components/colors/colors.vue +3 -3
  95. package/src/components/colors/index.ts +5 -0
  96. package/src/components/colors/props.ts +2 -2
  97. package/src/components/icon/index.ts +5 -0
  98. package/src/components/insertAttachment/index.ts +5 -0
  99. package/src/{plugins/attachment → components}/insertAttachment/insertAttachment.vue +4 -2
  100. package/src/{plugins/attachment → components}/insertAttachment/props.ts +1 -1
  101. package/src/components/insertImage/index.ts +5 -0
  102. package/src/components/insertImage/insertImage.vue +5 -5
  103. package/src/components/insertImage/props.ts +1 -1
  104. package/src/components/insertLink/index.ts +5 -0
  105. package/src/components/insertLink/insertLink.vue +10 -10
  106. package/src/components/insertLink/props.ts +3 -3
  107. package/src/components/insertMathformula/index.ts +5 -0
  108. package/src/{plugins/mathformula → components}/insertMathformula/props.ts +2 -2
  109. package/src/components/insertTable/index.ts +5 -0
  110. package/src/components/insertTable/props.ts +2 -2
  111. package/src/components/insertVideo/index.ts +5 -0
  112. package/src/components/insertVideo/insertVideo.vue +2 -2
  113. package/src/components/insertVideo/props.ts +1 -1
  114. package/src/components/layer/index.ts +5 -0
  115. package/src/components/layer/layer.vue +42 -4
  116. package/src/components/tooltip/index.ts +5 -0
  117. package/src/components/tooltip/tooltip.vue +1 -1
  118. package/src/components/triangle/index.ts +5 -0
  119. package/src/components/triangle/triangle.vue +1 -1
  120. package/src/components/updateLink/index.ts +5 -0
  121. package/src/components/updateLink/props.ts +21 -0
  122. package/src/components/{toolbar/toolbar.less → updateLink/updateLink.less} +4 -20
  123. package/src/components/updateLink/updateLink.vue +74 -0
  124. package/src/core/function.ts +289 -97
  125. package/src/core/rule.ts +108 -29
  126. package/src/core/tool.ts +237 -81
  127. package/src/editify/editify.less +4 -0
  128. package/src/editify/editify.vue +183 -194
  129. package/src/editify/menu/index.ts +5 -0
  130. package/src/editify/menu/menu.vue +215 -0
  131. package/src/{components → editify}/menu/props.ts +1 -1
  132. package/src/editify/props.ts +7 -11
  133. package/src/editify/toolbar/index.ts +5 -0
  134. package/src/{components → editify}/toolbar/props.ts +1 -1
  135. package/src/editify/toolbar/toolbar.less +10 -0
  136. package/src/editify/toolbar/toolbar.vue +103 -0
  137. package/src/feature/align.ts +126 -0
  138. package/src/feature/attachment.ts +108 -0
  139. package/src/feature/backColor.ts +169 -0
  140. package/src/feature/bold.ts +134 -0
  141. package/src/feature/code.ts +134 -0
  142. package/src/feature/codeBlock.ts +201 -0
  143. package/src/feature/fontFamily.ts +138 -0
  144. package/src/feature/fontSize.ts +140 -0
  145. package/src/feature/foreColor.ts +171 -0
  146. package/src/feature/formatClear.ts +116 -0
  147. package/src/feature/fullScreen.ts +57 -0
  148. package/src/feature/heading.ts +152 -0
  149. package/src/feature/image.ts +222 -0
  150. package/src/feature/indent.ts +72 -0
  151. package/src/feature/infoBlock.ts +93 -0
  152. package/src/feature/italic.ts +134 -0
  153. package/src/feature/lineHeight.ts +163 -0
  154. package/src/feature/link.ts +146 -0
  155. package/src/feature/mathformula.ts +146 -0
  156. package/src/feature/orderList.ts +114 -0
  157. package/src/feature/panel.ts +107 -0
  158. package/src/feature/quote.ts +60 -0
  159. package/src/feature/redo.ts +56 -0
  160. package/src/feature/separator.ts +61 -0
  161. package/src/feature/sourceView.ts +59 -0
  162. package/src/feature/strikethrough.ts +134 -0
  163. package/src/feature/sub.ts +134 -0
  164. package/src/feature/super.ts +134 -0
  165. package/src/feature/table.ts +981 -0
  166. package/src/feature/task.ts +114 -0
  167. package/src/feature/underline.ts +134 -0
  168. package/src/feature/undo.ts +56 -0
  169. package/src/feature/unorderList.ts +114 -0
  170. package/src/feature/video.ts +335 -0
  171. package/src/hljs/index.ts +1 -1
  172. package/src/index.ts +82 -25
  173. package/src/locale/en_US.ts +3 -3
  174. package/src/locale/zh_CN.ts +3 -3
  175. package/lib/plugins/attachment/index.d.ts +0 -37
  176. package/lib/plugins/infoBlock/index.d.ts +0 -55
  177. package/lib/plugins/mathformula/index.d.ts +0 -49
  178. package/lib/plugins/panel/index.d.ts +0 -48
  179. package/src/components/menu/menu.vue +0 -1655
  180. package/src/components/toolbar/toolbar.vue +0 -1677
  181. package/src/plugins/attachment/index.ts +0 -237
  182. package/src/plugins/infoBlock/index.ts +0 -238
  183. package/src/plugins/mathformula/index.ts +0 -295
  184. package/src/plugins/panel/index.ts +0 -228
  185. package/tsconfig.json +0 -31
  186. package/tsconfig.node.json +0 -11
  187. /package/src/{plugins/attachment → components}/insertAttachment/insertAttachment.less +0 -0
  188. /package/src/{plugins/mathformula → components}/insertMathformula/insertMathformula.less +0 -0
  189. /package/src/{plugins/mathformula → components}/insertMathformula/insertMathformula.vue +0 -0
  190. /package/src/{components → editify}/menu/menu.less +0 -0
@@ -1,18 +1,18 @@
1
1
  <template>
2
- <div class="editify" :class="{ 'editify-fullscreen': isFullScreen, 'editify-autoheight': !isFullScreen && autoheight }" :style="{ zIndex: zIndex, paddingTop: isFullScreen ? '' : (offset || '') + 'px' }" ref="elRef">
2
+ <div class="editify" :class="{ 'editify-fullscreen': isFullScreen, 'editify-autoheight': !isFullScreen && isAutoHeight }" :style="{ zIndex: zIndex, paddingTop: isFullScreen ? '' : (offset || '') + 'px' }" ref="elRef">
3
3
  <!-- 菜单区域 -->
4
- <Menu ref="menuRef" v-if="menuConfig.use" :config="menuConfig" :color="color" :z-index="zIndex + 1"></Menu>
4
+ <Menu ref="menuRef" v-if="menuConfig.use && editor" :config="menuConfig" :color="color" :z-index="zIndex + 1"></Menu>
5
5
  <!-- 编辑层,与编辑区域宽高相同必须适配 -->
6
6
  <div ref="bodyRef" class="editify-body" :class="{ 'editify-border': showBorder, 'editify-menu_inner': menuConfig.use && menuConfig.mode == 'inner' }" :data-editify-uid="instance.uid">
7
7
  <!-- 编辑器 -->
8
- <div ref="contentRef" class="editify-content" :class="{ 'editify-placeholder': showPlaceholder, 'editify-disabled': disabled }" @click="handleEditorClick" @compositionstart="isInputChinese = true" @compositionend="isInputChinese = false" :data-editify-placeholder="placeholder"></div>
8
+ <div ref="contentRef" class="editify-content" :class="{ 'editify-placeholder': showPlaceholder, 'editify-disabled': isDisabled }" @click="handleEditorClick" @compositionstart="isInputChinese = true" @compositionend="isInputChinese = false" :data-editify-placeholder="placeholder"></div>
9
9
  <!-- 代码视图 -->
10
10
  <textarea v-if="isSourceView" :value="value" readonly class="editify-sourceview" />
11
11
  <!-- 工具条 -->
12
12
  <Toolbar ref="toolbarRef" v-model="toolbarOptions.show" :node="toolbarOptions.node!" :type="toolbarOptions.type" :scroll-node="contentRef!" :config="toolbarConfig" :color="color" :z-index="zIndex + 10"></Toolbar>
13
13
  </div>
14
14
  <!-- 编辑器尾部 -->
15
- <div v-if="showWordLength" class="editify-footer" :class="{ 'editify-fullscreen': isFullScreen && !isSourceView }" ref="footerRef" :style="{ zIndex: zIndex + 1 }">
15
+ <div v-if="showWordLength" class="editify-footer" :class="{ 'editify-fullscreen': isFullScreen && !isSourceView }" :style="{ zIndex: zIndex + 1 }">
16
16
  <!-- 字数统计 -->
17
17
  <div class="editify-footer-words">{{ $editTrans('totalWordCount') }}{{ textValue.length }}</div>
18
18
  </div>
@@ -22,13 +22,14 @@
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 { mergeObject, getToolbarConfig, getMenuConfig, MenuConfigType, ObjectType, ToolbarConfigType, PluginResultType, clickIsOut } from '@/core/tool'
26
- import { parseList, orderdListHandle, commonElementHandle, tableThTdHandle, tableFormatHandle, tableRangeMergedHandle, preHandle, specialInblockHandle } from '@/core/rule'
27
- import { isTask, elementToParagraph, getMatchElementByRange, hasTableInRange, hasLinkInRange, hasPreInRange, hasImageInRange, hasVideoInRange } from '@/core/function'
28
- import Toolbar from '@/components/toolbar/toolbar.vue'
29
- import Menu from '@/components/menu/menu.vue'
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'
30
28
  import { trans } from '@/locale'
31
29
  import { LanguagesItemType } from '@/hljs'
30
+ import { extraKeepTagsForMathformula } from '@/feature/mathformula'
31
+ import { Toolbar } from './toolbar'
32
+ import { Menu } from './menu'
32
33
  import { EditifyProps, EditifyResizeParamsType, EditifyToolbarOptionsType } from './props'
33
34
 
34
35
  //定义组件名称
@@ -45,6 +46,32 @@ const emits = defineEmits(['update:modelValue', 'focus', 'blur', 'change', 'keyd
45
46
  //设置国际化方法
46
47
  const $editTrans = trans(props.locale || 'zh_CN')
47
48
 
49
+ //菜单栏组件实例
50
+ const menuRef = ref<InstanceType<typeof Menu> | null>(null)
51
+ //工具栏组件实例
52
+ const toolbarRef = ref<InstanceType<typeof Toolbar> | null>(null)
53
+
54
+ //自身dom
55
+ const elRef = ref<HTMLElement | null>(null)
56
+ //编辑器主体dom
57
+ const bodyRef = ref<HTMLElement | null>(null)
58
+ //编辑器内容区域dom
59
+ const contentRef = ref<HTMLElement | null>(null)
60
+
61
+ //编辑器对象
62
+ const editor = ref<AlexEditor | null>(null)
63
+ //是否代码视图
64
+ const isSourceView = ref<boolean>(false)
65
+ //是否全屏
66
+ const isFullScreen = ref<boolean>(false)
67
+ //代表真实光标变化,如果为null表示光标不在编辑器内,否则就是大于0的数字
68
+ const rangeKey = ref<number | null>(0)
69
+ //光标选区范围内的元素数组
70
+ const dataRangeCaches = ref<AlexElementsRangeType>({
71
+ flatList: [],
72
+ list: []
73
+ })
74
+
48
75
  //是否编辑器内部修改值
49
76
  const isModelChange = ref<boolean>(false)
50
77
  //是否正在输入中文
@@ -66,27 +93,6 @@ const toolbarOptions = ref<EditifyToolbarOptionsType>({
66
93
  type: 'text'
67
94
  })
68
95
 
69
- const menuRef = ref<InstanceType<typeof Menu> | null>(null)
70
- const bodyRef = ref<HTMLElement | null>(null)
71
- const contentRef = ref<HTMLElement | null>(null)
72
- const toolbarRef = ref<InstanceType<typeof Toolbar> | null>(null)
73
- const footerRef = ref<HTMLElement | null>(null)
74
- const elRef = ref<HTMLElement | null>(null)
75
-
76
- //编辑器对象
77
- const editor = ref<AlexEditor | null>(null)
78
- //是否代码视图
79
- const isSourceView = ref<boolean>(false)
80
- //是否全屏
81
- const isFullScreen = ref<boolean>(false)
82
- //菜单栏是否可以使用标识
83
- const canUseMenu = ref<boolean>(false)
84
- //光标选取范围内的元素数组
85
- const dataRangeCaches = ref<AlexElementsRangeType>({
86
- flatList: [],
87
- list: []
88
- })
89
-
90
96
  //编辑器的值
91
97
  const value = computed<string>({
92
98
  set(val) {
@@ -98,7 +104,7 @@ const value = computed<string>({
98
104
  })
99
105
  //编辑器的纯文本值
100
106
  const textValue = computed<string>(() => {
101
- return (<HTMLElement>DapElement.string2dom(`<div>${value.value}</div>`)).innerText
107
+ return (DapElement.string2dom(`<div>${value.value}</div>`) as HTMLElement).innerText
102
108
  })
103
109
  //是否显示占位符
104
110
  const showPlaceholder = computed<boolean>(() => {
@@ -119,25 +125,23 @@ const showBorder = computed<boolean>(() => {
119
125
  })
120
126
  //最终生效的工具栏配置
121
127
  const toolbarConfig = computed<ToolbarConfigType>(() => {
122
- return <ToolbarConfigType>mergeObject(getToolbarConfig($editTrans, props.locale), props.toolbar || {})
123
- })
124
- //插件配置读取
125
- const pluginResultList = computed<PluginResultType[]>(() => {
126
- const pluginResultList: PluginResultType[] = []
127
- props.plugins.forEach(plugin => {
128
- let pluginResult = plugin(instance, $editTrans)
129
- pluginResultList.push(pluginResult)
130
- })
131
- return pluginResultList
128
+ return mergeObject(getToolbarConfig($editTrans, props.locale), props.toolbar || {}) as ToolbarConfigType
132
129
  })
133
130
  //最终生效的菜单栏配置
134
131
  const menuConfig = computed<MenuConfigType>(() => {
135
- return <MenuConfigType>mergeObject(getMenuConfig($editTrans, props.locale), props.menu || {})
132
+ return mergeObject(getMenuConfig($editTrans, props.locale), props.menu || {}) as MenuConfigType
136
133
  })
134
+ //编辑器菜单栏区域高度
135
+ const menuHeight = computed<number | null>(() => {
136
+ return menuRef.value ? menuRef.value.height : null
137
+ })
138
+
137
139
  //是否深色模式
138
140
  const isDark = computed<boolean>(() => props.dark)
139
- //编辑器菜单栏区域高度
140
- const menuHeight = computed<number | null>(() => (menuRef.value ? menuRef.value.height : null))
141
+ //是否禁用编辑器
142
+ const isDisabled = computed<boolean>(() => props.disabled)
143
+ //是否自适应高度
144
+ const isAutoHeight = computed<boolean>(() => props.autoheight)
141
145
 
142
146
  //编辑器内部修改值的方法
143
147
  const internalModify = (val: string) => {
@@ -152,54 +156,21 @@ const hideToolbar = () => {
152
156
  toolbarOptions.value.show = false
153
157
  toolbarOptions.value.node = null
154
158
  }
155
- //监听滚动隐藏工具条
156
- const handleScroll = () => {
157
- const setScroll = (el: HTMLElement) => {
158
- DapEvent.on(el, `scroll.editify_${instance.uid}`, () => {
159
- if (toolbarConfig.value.use && toolbarOptions.value.show) {
160
- hideToolbar()
161
- }
162
- })
163
- if (el.parentNode) {
164
- setScroll(<HTMLElement>el.parentNode)
165
- }
166
- }
167
- setScroll(contentRef.value!)
168
- }
169
- //移除上述滚动事件的监听
170
- const removeScrollHandle = () => {
171
- const removeScroll = (el: HTMLElement) => {
172
- DapEvent.off(el, `scroll.editify_${instance.uid}`)
173
- if (el.parentNode) {
174
- removeScroll(<HTMLElement>el.parentNode)
175
- }
176
- }
177
- removeScroll(contentRef.value!)
178
- }
179
159
  //工具条显示判断
180
160
  const handleToolbar = () => {
181
- if (props.disabled || isSourceView.value) {
161
+ if (isDisabled.value || isSourceView.value) {
182
162
  return
183
163
  }
184
164
  hideToolbar()
185
165
  nextTick(() => {
186
166
  const table = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'table' })
187
- const pre = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'pre' })
167
+ const codeBlock = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'pre' })
188
168
  const link = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'a' })
189
169
  const image = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'img' })
190
170
  const video = getMatchElementByRange(editor.value!, dataRangeCaches.value, { parsedom: 'video' })
191
- //显示链接工具条
192
- if (link) {
193
- toolbarOptions.value.type = 'link'
194
- toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${link.key}"]`
195
- if (toolbarOptions.value.show) {
196
- toolbarRef.value!.layerRef!.setPosition()
197
- } else {
198
- toolbarOptions.value.show = true
199
- }
200
- }
171
+
201
172
  //显示图片工具条
202
- else if (image) {
173
+ if (image) {
203
174
  toolbarOptions.value.type = 'image'
204
175
  toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${image.key}"]`
205
176
  if (toolbarOptions.value.show) {
@@ -218,6 +189,16 @@ const handleToolbar = () => {
218
189
  toolbarOptions.value.show = true
219
190
  }
220
191
  }
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
+ }
221
202
  //显示表格工具条
222
203
  else if (table) {
223
204
  toolbarOptions.value.type = 'table'
@@ -229,9 +210,9 @@ const handleToolbar = () => {
229
210
  }
230
211
  }
231
212
  //显示代码块工具条
232
- else if (pre) {
213
+ else if (codeBlock) {
233
214
  toolbarOptions.value.type = 'codeBlock'
234
- toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${pre.key}"]`
215
+ toolbarOptions.value.node = `[data-editify-uid="${instance.uid}"] [data-editify-element="${codeBlock.key}"]`
235
216
  if (toolbarOptions.value.show) {
236
217
  toolbarRef.value!.layerRef!.setPosition()
237
218
  } else {
@@ -240,9 +221,7 @@ const handleToolbar = () => {
240
221
  }
241
222
  //显示文本工具条
242
223
  else {
243
- const result = dataRangeCaches.value.flatList.filter((item: AlexElementRangeType) => {
244
- return item.element.isText()
245
- })
224
+ const result = dataRangeCaches.value.flatList.filter((item: AlexElementRangeType) => item.element.isText())
246
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)) {
247
226
  toolbarOptions.value.type = 'text'
248
227
  if (toolbarOptions.value.show) {
@@ -256,29 +235,10 @@ const handleToolbar = () => {
256
235
  }
257
236
  //初始创建编辑器
258
237
  const createEditor = () => {
259
- //注册插件:自定义规则校验函数
260
- let pluginRules: ((el: AlexElement) => void)[] = []
261
- pluginResultList.value.forEach(pluginResult => {
262
- if (pluginResult.renderRule) {
263
- pluginRules.push(pluginResult.renderRule)
264
- }
265
- })
266
- //注册插件:将插件定义的额外保留的标签数组与配置合并
267
- let extraKeepTags: string[] = [...props.extraKeepTags]
268
- pluginResultList.value.forEach(pluginResult => {
269
- if (pluginResult.extraKeepTags && Array.isArray(pluginResult.extraKeepTags)) {
270
- pluginResult.extraKeepTags.forEach(tag => {
271
- //如果不包含则加入数组
272
- if (!extraKeepTags.includes(tag)) {
273
- extraKeepTags.push(tag)
274
- }
275
- })
276
- }
277
- })
278
238
  //创建编辑器
279
239
  editor.value = new AlexEditor(contentRef.value!, {
280
240
  value: value.value,
281
- disabled: props.disabled,
241
+ disabled: isDisabled.value,
282
242
  renderRules: [
283
243
  el => {
284
244
  parseList(editor.value!, el)
@@ -299,14 +259,23 @@ const createEditor = () => {
299
259
  tableRangeMergedHandle(editor.value!, el)
300
260
  },
301
261
  el => {
302
- preHandle(editor.value!, el, !!(toolbarConfig.value?.use && toolbarConfig.value?.codeBlock?.languages?.show), <(string | LanguagesItemType)[]>toolbarConfig.value?.codeBlock?.languages?.options)
262
+ preHandle(editor.value!, el, !!(toolbarConfig.value?.use && toolbarConfig.value?.codeBlock?.languages?.show), toolbarConfig.value?.codeBlock?.languages?.options as (string | LanguagesItemType)[])
303
263
  },
304
264
  el => {
305
265
  specialInblockHandle(editor.value!, el)
306
266
  },
307
- ...pluginRules,
267
+ el => {
268
+ attachmentHandle(editor.value!, el, $editTrans)
269
+ },
270
+ el => {
271
+ mathformulaHandle(editor.value!, el)
272
+ },
273
+ el => {
274
+ infoBlockHandle(editor.value!, el, props.color)
275
+ },
308
276
  ...props.renderRules
309
277
  ],
278
+ extraKeepTags: [...extraKeepTagsForMathformula, ...props.extraKeepTags],
310
279
  allowCopy: props.allowCopy,
311
280
  allowPaste: props.allowPaste,
312
281
  allowCut: props.allowCut,
@@ -317,8 +286,7 @@ const createEditor = () => {
317
286
  customFilePaste: props.customFilePaste,
318
287
  customHtmlPaste: handleCustomHtmlPaste,
319
288
  customMerge: handleCustomMerge,
320
- customParseNode: handleCustomParseNode,
321
- extraKeepTags: extraKeepTags
289
+ customParseNode: handleCustomParseNode
322
290
  })
323
291
  //编辑器渲染后会有一个渲染过程,会改变内容,因此重新获取内容的值来设置value
324
292
  internalModify(editor.value.value)
@@ -333,11 +301,10 @@ const createEditor = () => {
333
301
  editor.value.on('deleteInStart', handleDeleteInStart)
334
302
  editor.value.on('deleteComplete', handleDeleteComplete)
335
303
  editor.value.on('afterRender', handleAfterRender)
336
- //格式化和dom渲染
337
- editor.value.formatElementStack()
304
+ //dom渲染
338
305
  editor.value.domRender()
339
306
  //自动获取焦点
340
- if (props.autofocus && !isSourceView.value && !props.disabled) {
307
+ if (props.autofocus && !isSourceView.value && !isDisabled.value) {
341
308
  collapseToEnd()
342
309
  }
343
310
  }
@@ -349,7 +316,7 @@ const setVideoHeight = () => {
349
316
  }
350
317
  //鼠标在页面按下:处理表格拖拽改变列宽、拖拽改变图片视频宽度和菜单栏是否使用判断
351
318
  const documentMouseDown = (e: Event) => {
352
- if (props.disabled) {
319
+ if (isDisabled.value) {
353
320
  return
354
321
  }
355
322
  const elm = e.target as HTMLElement
@@ -386,14 +353,14 @@ const documentMouseDown = (e: Event) => {
386
353
  }
387
354
  }
388
355
  }
389
- //如果点击了除编辑器外的地方,菜单栏不可使用
356
+ //如果点击了除编辑器外的地方,菜单栏不可使用,此时将range置为null
390
357
  if (clickIsOut(elRef.value!, elm) && !isSourceView.value) {
391
- canUseMenu.value = false
358
+ rangeKey.value = null
392
359
  }
393
360
  }
394
361
  //鼠标在页面移动:处理表格拖拽改变列宽、拖拽改变图片视频宽度
395
362
  const documentMouseMove = (e: Event) => {
396
- if (props.disabled) {
363
+ if (isDisabled.value) {
397
364
  return
398
365
  }
399
366
  const event = e as MouseEvent
@@ -448,7 +415,7 @@ const documentMouseMove = (e: Event) => {
448
415
  }
449
416
  //鼠标在页面松开:处理表格拖拽改变列宽、拖拽改变图片视频宽度
450
417
  const documentMouseUp = () => {
451
- if (props.disabled) {
418
+ if (isDisabled.value) {
452
419
  return
453
420
  }
454
421
  if (!resizeParams.value.element) {
@@ -469,7 +436,6 @@ const documentMouseUp = () => {
469
436
  const width = parseFloat(colgroup.children![index].marks!['width'])
470
437
  if (!isNaN(width)) {
471
438
  colgroup.children![index].marks!['width'] = `${Number(((width / resizeParams.value.element.parent!.elm!.offsetWidth) * 100).toFixed(2))}%`
472
- editor.value!.formatElementStack()
473
439
  editor.value!.domRender()
474
440
  editor.value!.rangeRender()
475
441
  }
@@ -487,7 +453,6 @@ const documentMouseUp = () => {
487
453
  width: `${Number(((width / DapElement.width(contentRef.value!)) * 100).toFixed(2))}%`
488
454
  }
489
455
  }
490
- editor.value!.formatElementStack()
491
456
  editor.value!.domRender()
492
457
  editor.value!.rangeRender()
493
458
  }
@@ -497,7 +462,7 @@ const documentMouseUp = () => {
497
462
  }
498
463
  //鼠标点击页面:处理任务列表复选框勾选
499
464
  const documentClick = (e: Event) => {
500
- if (props.disabled) {
465
+ if (isDisabled.value) {
501
466
  return
502
467
  }
503
468
  const elm = e.target as HTMLElement
@@ -508,7 +473,7 @@ const documentClick = (e: Event) => {
508
473
  if (key) {
509
474
  const element = editor.value!.getElementByKey(key)!
510
475
  //如果是任务列表元素
511
- if (isTask(element)) {
476
+ if (elementIsTask(element)) {
512
477
  const rect = DapElement.getElementBounding(elm)
513
478
  //在复选框范围内
514
479
  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)) {
@@ -525,7 +490,6 @@ const documentClick = (e: Event) => {
525
490
  }
526
491
  editor.value!.range!.anchor.moveToEnd(element)
527
492
  editor.value!.range!.focus.moveToEnd(element)
528
- editor.value!.formatElementStack()
529
493
  editor.value!.domRender()
530
494
  editor.value!.rangeRender()
531
495
  }
@@ -586,7 +550,7 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
586
550
  marks['target'] = el.marks!['target']
587
551
  }
588
552
  //有序和无序列表属性保留
589
- if (el.parsedom == 'div' && el.marks!['data-editify-list']) {
553
+ if (elementIsList(el, true) || elementIsList(el, false)) {
590
554
  marks['data-editify-list'] = el.marks!['data-editify-list']
591
555
  //有序列表保留序列号标记
592
556
  if (el.marks!['data-editify-value']) {
@@ -598,7 +562,7 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
598
562
  marks['data-editify-code'] = el.marks!['data-editify-code']
599
563
  }
600
564
  //任务列表属性保留
601
- if (el.parsedom == 'div' && el.marks!['data-editify-task']) {
565
+ if (elementIsTask(el)) {
602
566
  marks['data-editify-task'] = el.marks!['data-editify-task']
603
567
  }
604
568
  //表格列宽属性保留
@@ -617,6 +581,25 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
617
581
  if (['td', 'th'].includes(el.parsedom!) && el.marks!['data-editify-merged']) {
618
582
  marks['data-editify-merged'] = el.marks!['data-editify-merged']
619
583
  }
584
+ //附件属性保留
585
+ if (elementIsAttachment(el)) {
586
+ marks['data-editify-attachment'] = el.marks!['data-editify-attachment']
587
+ if (el.marks!['data-editify-attachment-name']) {
588
+ marks['data-editify-attachment-name'] = el.marks!['data-editify-attachment-name']
589
+ }
590
+ }
591
+ //数学公式内的属性全部保留
592
+ if (!!getMathformulaByElement(el)) {
593
+ marks = mergeObject(marks, cloneData(el.marks!))!
594
+ }
595
+ //面板属性保留
596
+ if (elementIsPanel(el)) {
597
+ marks['data-editify-panel'] = el.marks!['data-editify-panel']
598
+ }
599
+ //信息块属性保留
600
+ if (elementIsInfoBlock(el)) {
601
+ marks['data-editify-info'] = el.marks!['data-editify-info']
602
+ }
620
603
  }
621
604
  //处理需要保留的样式
622
605
  if (el.hasStyles()) {
@@ -636,18 +619,11 @@ const handleCustomHtmlPaste = async (elements: AlexElement[]) => {
636
619
  if ((el.isBlock() || el.isInblock()) && el.styles!['line-height']) {
637
620
  styles['line-height'] = el.styles!['line-height']
638
621
  }
639
- }
640
- //注册插件:自定义属性和样式的保留
641
- pluginResultList.value.forEach(pluginResult => {
642
- if (typeof pluginResult.pasteKeepMarks == 'function') {
643
- const keepMarks = pluginResult.pasteKeepMarks(el)
644
- marks = mergeObject(marks, keepMarks)!
645
- }
646
- if (typeof pluginResult.pasteKeepStyles == 'function') {
647
- const keepStyles = pluginResult.pasteKeepStyles(el)
648
- styles = mergeObject(styles, keepStyles)!
622
+ //数学公式内的样式全部保留
623
+ if (!!getMathformulaByElement(el)) {
624
+ styles = mergeObject(styles, cloneData(el.styles!))!
649
625
  }
650
- })
626
+ }
651
627
  //对外的自定义属性和样式保留
652
628
  if (typeof props.pasteKeepMarks == 'function') {
653
629
  marks = mergeObject(marks, props.pasteKeepMarks(el))!
@@ -690,27 +666,35 @@ const handleCustomMerge = (ele: AlexElement, preEle: AlexElement) => {
690
666
  }
691
667
  //针对node转为元素进行额外的处理
692
668
  const handleCustomParseNode = (ele: AlexElement) => {
693
- //注册插件:自定义元素转换处理
694
- pluginResultList.value.forEach(pluginResult => {
695
- if (pluginResult.customParseNode) {
696
- ele = pluginResult.customParseNode(ele)
697
- }
698
- })
669
+ //附件元素设为自闭合元素
670
+ if (elementIsAttachment(ele)) {
671
+ ele.type = 'closed'
672
+ }
673
+ //数学公式元素处理
674
+ if (elementIsMathformula(ele)) {
675
+ AlexElement.flatElements(ele.children!).forEach(item => {
676
+ //锁定元素防止合并
677
+ item.locked = true
678
+ //没有子元素的非文本元素设为自闭合元素
679
+ if (!item.isText() && !item.hasChildren()) {
680
+ item.type = 'closed'
681
+ }
682
+ })
683
+ }
699
684
  if (typeof props.customParseNode == 'function') {
700
685
  ele = props.customParseNode(ele)
701
686
  }
702
687
  return ele
703
688
  }
704
- //编辑区域键盘按下:设置缩进快捷键
689
+ //编辑区域键盘按下
705
690
  const handleEditorKeydown = (val: string, e: Event) => {
706
- if (props.disabled) {
691
+ if (isDisabled.value) {
707
692
  return
708
693
  }
709
694
  //单独按下tab键
710
- if ((<KeyboardEvent>e).key.toLocaleLowerCase() == 'tab' && !(<KeyboardEvent>e).metaKey && !(<KeyboardEvent>e).shiftKey && !(<KeyboardEvent>e).ctrlKey && !(<KeyboardEvent>e).altKey && props.tab) {
695
+ if ((e as KeyboardEvent).key.toLocaleLowerCase() == 'tab' && !(e as KeyboardEvent).metaKey && !(e as KeyboardEvent).shiftKey && !(e as KeyboardEvent).ctrlKey && !(e as KeyboardEvent).altKey && props.tab) {
711
696
  e.preventDefault()
712
697
  editor.value!.insertText(' ')
713
- editor.value!.formatElementStack()
714
698
  editor.value!.domRender()
715
699
  editor.value!.rangeRender()
716
700
  }
@@ -719,7 +703,7 @@ const handleEditorKeydown = (val: string, e: Event) => {
719
703
  }
720
704
  //编辑区域键盘松开
721
705
  const handleEditorKeyup = (val: string, e: Event) => {
722
- if (props.disabled) {
706
+ if (isDisabled.value) {
723
707
  return
724
708
  }
725
709
  //自定义键盘松开操作
@@ -727,7 +711,7 @@ const handleEditorKeyup = (val: string, e: Event) => {
727
711
  }
728
712
  //点击编辑器:处理图片和视频的光标聚集
729
713
  const handleEditorClick = (e: Event) => {
730
- if (props.disabled || isSourceView.value) {
714
+ if (isDisabled.value || isSourceView.value) {
731
715
  return
732
716
  }
733
717
  const elm = e.target as HTMLElement
@@ -747,7 +731,7 @@ const handleEditorClick = (e: Event) => {
747
731
  }
748
732
  //编辑器的值更新
749
733
  const handleEditorChange = (newVal: string, oldVal: string) => {
750
- if (props.disabled) {
734
+ if (isDisabled.value) {
751
735
  return
752
736
  }
753
737
  //内部修改
@@ -757,7 +741,7 @@ const handleEditorChange = (newVal: string, oldVal: string) => {
757
741
  }
758
742
  //编辑器失去焦点
759
743
  const handleEditorBlur = (val: string) => {
760
- if (props.disabled) {
744
+ if (isDisabled.value) {
761
745
  return
762
746
  }
763
747
  if (props.border && props.color && !isFullScreen.value) {
@@ -775,7 +759,7 @@ const handleEditorBlur = (val: string) => {
775
759
  }
776
760
  //编辑器获取焦点
777
761
  const handleEditorFocus = (val: string) => {
778
- if (props.disabled) {
762
+ if (isDisabled.value) {
779
763
  return
780
764
  }
781
765
  if (props.border && props.color && !isFullScreen.value) {
@@ -803,11 +787,7 @@ const handleEditorFocus = (val: string) => {
803
787
  bodyRef.value!.style.boxShadow = `0 0 8px rgba(${rgb[0]},${rgb[1]},${rgb[2]},0.5)`
804
788
  }
805
789
  }
806
- //获取焦点时可以使用菜单栏
807
- setTimeout(() => {
808
- canUseMenu.value = true
809
- emits('focus', val)
810
- }, 0)
790
+ emits('focus', val)
811
791
  }
812
792
  //编辑器换行
813
793
  const handleInsertParagraph = (element: AlexElement, previousElement: AlexElement) => {
@@ -823,7 +803,7 @@ const handleInsertParagraph = (element: AlexElement, previousElement: AlexElemen
823
803
  }
824
804
  }
825
805
  //如果当前换行元素是任务列表则改为不勾选状态
826
- if (isTask(element)) {
806
+ if (elementIsTask(element)) {
827
807
  element.marks!['data-editify-task'] = 'uncheck'
828
808
  }
829
809
  }
@@ -831,11 +811,15 @@ const handleInsertParagraph = (element: AlexElement, previousElement: AlexElemen
831
811
  }
832
812
  //编辑器焦点更新
833
813
  const handleRangeUpdate = () => {
834
- if (props.disabled) {
814
+ if (isDisabled.value) {
835
815
  return
836
816
  }
837
- //如果没有range禁用菜单栏
838
- canUseMenu.value = !!editor.value!.range
817
+ //更新rangeKey
818
+ if (rangeKey.value) {
819
+ rangeKey.value++
820
+ } else {
821
+ rangeKey.value = 1
822
+ }
839
823
 
840
824
  //没有range直接返回
841
825
  if (!editor.value!.range) {
@@ -851,16 +835,9 @@ const handleRangeUpdate = () => {
851
835
  }
852
836
  //延时200ms进行判断
853
837
  rangeUpdateTimer.value = setTimeout(() => {
854
- //如果使用工具条或者菜单栏
855
- if (toolbarConfig.value.use || menuConfig.value.use) {
856
- //如果使用工具条
857
- if (toolbarConfig.value.use) {
858
- handleToolbar()
859
- }
860
- //如果使用菜单栏
861
- if (menuConfig.value.use) {
862
- menuRef.value!.handleRangeUpdate()
863
- }
838
+ //如果使用工具条
839
+ if (toolbarConfig.value.use) {
840
+ handleToolbar()
864
841
  }
865
842
  }, 200)
866
843
  //触发rangeupdate事件
@@ -884,30 +861,47 @@ const handleDeleteComplete = () => {
884
861
  const handleAfterRender = () => {
885
862
  //设定视频高度
886
863
  setVideoHeight()
887
- //注册插件:自定义dom渲染后处理
888
- pluginResultList.value.forEach(pluginResult => {
889
- if (pluginResult.updateView) {
890
- pluginResult.updateView()
864
+ //附件元素下载事件设置
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()
884
+ })
891
885
  }
892
886
  })
893
887
  emits('updateview')
894
888
  }
895
889
  //api:光标设置到文档底部
896
890
  const collapseToEnd = () => {
897
- if (props.disabled) {
891
+ if (isDisabled.value) {
898
892
  return
899
893
  }
900
894
  editor.value!.collapseToEnd()
901
895
  editor.value!.rangeRender()
902
896
  DapElement.setScrollTop({
903
897
  el: contentRef.value!,
904
- number: 1000000,
898
+ number: DapElement.getScrollHeight(contentRef.value!),
905
899
  time: 0
906
900
  })
907
901
  }
908
902
  //api:光标设置到文档头部
909
903
  const collapseToStart = () => {
910
- if (props.disabled) {
904
+ if (isDisabled.value) {
911
905
  return
912
906
  }
913
907
  editor.value!.collapseToStart()
@@ -922,7 +916,7 @@ const collapseToStart = () => {
922
916
  }
923
917
  //api:撤销
924
918
  const undo = () => {
925
- if (props.disabled) {
919
+ if (isDisabled.value) {
926
920
  return
927
921
  }
928
922
  const historyRecord = editor.value!.history.get(-1)
@@ -930,14 +924,13 @@ const undo = () => {
930
924
  editor.value!.history.current = historyRecord.current
931
925
  editor.value!.stack = historyRecord.stack
932
926
  editor.value!.range = historyRecord.range
933
- editor.value!.formatElementStack()
934
927
  editor.value!.domRender(true)
935
928
  editor.value!.rangeRender()
936
929
  }
937
930
  }
938
931
  //api:重做
939
932
  const redo = () => {
940
- if (props.disabled) {
933
+ if (isDisabled.value) {
941
934
  return
942
935
  }
943
936
  const historyRecord = editor.value!.history.get(1)
@@ -945,7 +938,6 @@ const redo = () => {
945
938
  editor.value!.history.current = historyRecord.current
946
939
  editor.value!.stack = historyRecord.stack
947
940
  editor.value!.range = historyRecord.range
948
- editor.value!.formatElementStack()
949
941
  editor.value!.domRender(true)
950
942
  editor.value!.rangeRender()
951
943
  }
@@ -962,7 +954,6 @@ watch(
962
954
  //如果是外部修改,需要重新渲染编辑器
963
955
  editor.value!.stack = editor.value!.parseHtml(newVal)
964
956
  editor.value!.range = null
965
- editor.value!.formatElementStack()
966
957
  editor.value!.domRender()
967
958
  editor.value!.rangeRender()
968
959
  contentRef.value!.blur()
@@ -981,9 +972,9 @@ watch(
981
972
  }
982
973
  }
983
974
  )
984
- //监听disabled
975
+ //监听isDisabled
985
976
  watch(
986
- () => props.disabled,
977
+ () => isDisabled.value,
987
978
  newVal => {
988
979
  if (newVal) {
989
980
  editor.value!.setDisabled()
@@ -1010,8 +1001,6 @@ watch(
1010
1001
  onMounted(() => {
1011
1002
  //创建编辑器
1012
1003
  createEditor()
1013
- //监听滚动隐藏工具条
1014
- handleScroll()
1015
1004
  //鼠标按下监听
1016
1005
  DapEvent.on(document.documentElement, `mousedown.editify_${instance.uid}`, documentMouseDown)
1017
1006
  //鼠标移动监听
@@ -1025,8 +1014,6 @@ onMounted(() => {
1025
1014
  })
1026
1015
 
1027
1016
  onBeforeUnmount(() => {
1028
- //卸载绑定在滚动元素上的事件
1029
- removeScrollHandle()
1030
1017
  //卸载绑定在document.documentElement上的事件
1031
1018
  DapEvent.off(document.documentElement, `mousedown.editify_${instance.uid} mousemove.editify_${instance.uid} mouseup.editify_${instance.uid} click.editify_${instance.uid}`)
1032
1019
  //卸载绑定在window上的事件
@@ -1035,22 +1022,24 @@ onBeforeUnmount(() => {
1035
1022
  editor.value!.destroy()
1036
1023
  })
1037
1024
 
1038
- provide('$editTrans', $editTrans)
1039
- provide('editify', instance)
1025
+ provide('editor', editor)
1040
1026
  provide('isSourceView', isSourceView)
1041
1027
  provide('isFullScreen', isFullScreen)
1042
- provide('canUseMenu', canUseMenu)
1043
- provide('editor', editor)
1028
+ provide('rangeKey', rangeKey)
1044
1029
  provide('dataRangeCaches', dataRangeCaches)
1030
+ provide('undo', undo)
1031
+ provide('redo', redo)
1032
+ provide('$editTrans', $editTrans)
1045
1033
  provide('showBorder', showBorder)
1046
- provide('pluginResultList', pluginResultList)
1047
1034
  provide('isDark', isDark)
1035
+ provide('isDisabled', isDisabled)
1036
+ provide('isAutoHeight', isAutoHeight)
1048
1037
 
1049
1038
  defineExpose({
1050
1039
  editor,
1051
1040
  isSourceView,
1052
1041
  isFullScreen,
1053
- canUseMenu,
1042
+ rangeKey,
1054
1043
  dataRangeCaches,
1055
1044
  textValue,
1056
1045
  menuHeight,