vue-editify 0.1.39 → 0.1.40
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.
- package/lib/editify.es.js +88 -17
- package/lib/editify.umd.js +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/plugins/mathformula/index.d.ts +18 -0
- package/lib/plugins/mathformula/insertMathformula/insertMathformula.vue.d.ts +9 -0
- package/lib/plugins/mathformula/insertMathformula/props.d.ts +4 -0
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/src/editify/editify.less +27 -2
- package/src/index.ts +2 -2
- package/src/plugins/mathformula/index.ts +114 -26
- package/src/plugins/mathformula/insertMathformula/insertMathformula.vue +11 -1
- package/src/plugins/mathformula/insertMathformula/props.ts +5 -0
package/package.json
CHANGED
package/src/editify/editify.less
CHANGED
@@ -380,6 +380,21 @@
|
|
380
380
|
}
|
381
381
|
}
|
382
382
|
|
383
|
+
//数学公式样式
|
384
|
+
:deep(span[data-editify-mathformula]) {
|
385
|
+
display: inline-block;
|
386
|
+
border: 1px dashed @border-color;
|
387
|
+
padding: 6px 10px;
|
388
|
+
border-radius: 4px;
|
389
|
+
margin: 0 4px;
|
390
|
+
transition: all 200ms;
|
391
|
+
|
392
|
+
&:hover {
|
393
|
+
cursor: pointer;
|
394
|
+
background: @background-dark;
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
383
398
|
//禁用样式
|
384
399
|
&.editify-disabled {
|
385
400
|
cursor: auto !important;
|
@@ -387,16 +402,26 @@
|
|
387
402
|
&.editify-placeholder::before {
|
388
403
|
cursor: auto;
|
389
404
|
}
|
390
|
-
|
391
405
|
:deep(a) {
|
392
406
|
cursor: pointer;
|
393
407
|
}
|
394
|
-
|
395
408
|
:deep(table) {
|
396
409
|
td:not(:last-child)::after {
|
397
410
|
cursor: auto;
|
398
411
|
}
|
399
412
|
}
|
413
|
+
:deep(span[data-editify-mathformula]) {
|
414
|
+
display: inline-block;
|
415
|
+
border: none;
|
416
|
+
padding: 6px 10px;
|
417
|
+
border-radius: none;
|
418
|
+
margin: 0 4px;
|
419
|
+
|
420
|
+
&:hover {
|
421
|
+
cursor: auto;
|
422
|
+
background: none;
|
423
|
+
}
|
424
|
+
}
|
400
425
|
}
|
401
426
|
}
|
402
427
|
|
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.
|
21
|
+
const version = '0.1.40'
|
22
22
|
|
23
23
|
//导出AlexElement元素
|
24
24
|
export { AlexElement } from 'alex-editor'
|
@@ -29,7 +29,7 @@ export type { InsertAttachmentUploadErrorType } from './plugins/attachment/inser
|
|
29
29
|
export { attachment, isAttachment, hasAttachmentInRange } from './plugins/attachment'
|
30
30
|
//导出mathformula插件相关的方法和类型
|
31
31
|
export type { MathformulaOptionsType } from './plugins/mathformula'
|
32
|
-
export { mathformula, isMathformula, isUnderMathformula, getMathformulaElement } from './plugins/mathformula'
|
32
|
+
export { mathformula, isMathformula, isUnderMathformula, getMathformulaElement, hasMathformulaInRange, getMathformulaElementByRange } from './plugins/mathformula'
|
33
33
|
|
34
34
|
//导出组件和安装函数
|
35
35
|
export { install as default, install, Editify, version }
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { common as DapCommon
|
1
|
+
import { common as DapCommon } from 'dap-util'
|
2
2
|
import { ObjectType, PluginType, cloneData } from '../../core/tool'
|
3
3
|
import { ComponentInternalInstance, h } from 'vue'
|
4
4
|
|
@@ -21,6 +21,8 @@ export type MathformulaOptionsType = {
|
|
21
21
|
rightBorder?: boolean
|
22
22
|
//按钮是否禁用
|
23
23
|
disabled?: boolean
|
24
|
+
//公式异常处理
|
25
|
+
handleError?: (error: Error) => void
|
24
26
|
}
|
25
27
|
|
26
28
|
/**
|
@@ -32,7 +34,11 @@ export const isMathformula = (el: AlexElement) => {
|
|
32
34
|
return el.parsedom == 'span' && el.hasMarks() && el.marks!['data-editify-mathformula']
|
33
35
|
}
|
34
36
|
|
35
|
-
|
37
|
+
/**
|
38
|
+
* 判断某个元素是否在公式元素内
|
39
|
+
* @param el
|
40
|
+
* @returns
|
41
|
+
*/
|
36
42
|
export const isUnderMathformula = (el: AlexElement): boolean => {
|
37
43
|
if (isMathformula(el)) {
|
38
44
|
return true
|
@@ -43,7 +49,11 @@ export const isUnderMathformula = (el: AlexElement): boolean => {
|
|
43
49
|
return false
|
44
50
|
}
|
45
51
|
|
46
|
-
|
52
|
+
/**
|
53
|
+
* 根据某个元素获取所在的公式元素,如果不在公式元素内则返回null
|
54
|
+
* @param el
|
55
|
+
* @returns
|
56
|
+
*/
|
47
57
|
export const getMathformulaElement = (el: AlexElement): AlexElement | null => {
|
48
58
|
if (isMathformula(el)) {
|
49
59
|
return el
|
@@ -72,6 +82,48 @@ export const hasMathformulaInRange = (editor: AlexEditor, dataRangeCaches: AlexE
|
|
72
82
|
})
|
73
83
|
}
|
74
84
|
|
85
|
+
/**
|
86
|
+
* 选区是否在某个公式元素下,如果是返回该公式元素否则返回null
|
87
|
+
* @param editor
|
88
|
+
* @param dataRangeCaches
|
89
|
+
* @returns
|
90
|
+
*/
|
91
|
+
export const getMathformulaElementByRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType) => {
|
92
|
+
if (!editor.range) {
|
93
|
+
return null
|
94
|
+
}
|
95
|
+
if (editor.range.anchor.element.isEqual(editor.range.focus.element)) {
|
96
|
+
return getMathformulaElement(editor.range.anchor.element)
|
97
|
+
}
|
98
|
+
const arr = dataRangeCaches.list.map(item => {
|
99
|
+
return getMathformulaElement(item.element)
|
100
|
+
})
|
101
|
+
let hasNull = arr.some(el => {
|
102
|
+
return el == null
|
103
|
+
})
|
104
|
+
//如果存在null,则表示有的选区元素不在公式元素下,返回null
|
105
|
+
if (hasNull) {
|
106
|
+
return null
|
107
|
+
}
|
108
|
+
//如果只有一个元素,则返回该元素
|
109
|
+
if (arr.length == 1) {
|
110
|
+
return arr[0]!
|
111
|
+
}
|
112
|
+
//默认数组中的元素都相等
|
113
|
+
let flag = true
|
114
|
+
for (let i = 1; i < arr.length; i++) {
|
115
|
+
if (!arr[i]!.isEqual(arr[0]!)) {
|
116
|
+
flag = false
|
117
|
+
break
|
118
|
+
}
|
119
|
+
}
|
120
|
+
//如果相等,则返回该元素
|
121
|
+
if (flag) {
|
122
|
+
return arr[0]
|
123
|
+
}
|
124
|
+
return null
|
125
|
+
}
|
126
|
+
|
75
127
|
/**
|
76
128
|
* 数学公式插件
|
77
129
|
* @param options
|
@@ -82,18 +134,23 @@ export const mathformula = (options?: MathformulaOptionsType) => {
|
|
82
134
|
options = {}
|
83
135
|
}
|
84
136
|
const plugin: PluginType = (editifyInstance: ComponentInternalInstance, editTrans: (key: string) => any) => {
|
85
|
-
|
86
|
-
|
137
|
+
//是否禁用该插件按钮
|
138
|
+
let isDisabled: boolean = false
|
139
|
+
//如果光标范围内有链接、代码块则禁用
|
87
140
|
if (editifyInstance.exposed!.editor.value) {
|
88
|
-
isDisabled =
|
141
|
+
isDisabled = hasPreInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value) || hasLinkInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value)
|
89
142
|
}
|
143
|
+
//数学公式文本框内置LaTex文本内容
|
144
|
+
let defaultLaTexContent: string = ''
|
145
|
+
|
90
146
|
return {
|
147
|
+
//插件名称
|
91
148
|
name: 'mathformula',
|
92
149
|
//菜单项配置
|
93
150
|
menu: {
|
94
151
|
sequence: options!.sequence || 101,
|
95
152
|
extraDisabled: (name: string) => {
|
96
|
-
|
153
|
+
//如果光标选区内有数学公式则禁用链接、图片、视频、表格和代码块菜单
|
97
154
|
if (name == 'link' || name == 'image' || name == 'video' || name == 'table' || name == 'codeBlock') {
|
98
155
|
return hasMathformulaInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value)
|
99
156
|
}
|
@@ -105,36 +162,67 @@ export const mathformula = (options?: MathformulaOptionsType) => {
|
|
105
162
|
leftBorder: options!.leftBorder,
|
106
163
|
rightBorder: options!.rightBorder,
|
107
164
|
hideScroll: true,
|
108
|
-
active: false,
|
165
|
+
active: editifyInstance.exposed!.editor.value ? hasMathformulaInRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value) : false,
|
109
166
|
disabled: isDisabled || options!.disabled,
|
167
|
+
//浮层展开时触发的事件
|
168
|
+
onLayerShow() {
|
169
|
+
//获取选区所在的数学公式元素
|
170
|
+
const mathformulaElement = getMathformulaElementByRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value)
|
171
|
+
//如果该元素存在,则设置默认的LaTex文本内容
|
172
|
+
if (mathformulaElement) {
|
173
|
+
defaultLaTexContent = mathformulaElement.marks!['data-editify-mathformula'] || ''
|
174
|
+
}
|
175
|
+
},
|
110
176
|
default: () => h(Icon, { value: 'mathformula' }),
|
111
177
|
layer: (_name: string, btnInstance: InstanceType<typeof Button>) => {
|
112
178
|
return h(InsertMathformula, {
|
113
179
|
color: <string | null>editifyInstance.props.color,
|
180
|
+
defaultLaTexContent: defaultLaTexContent,
|
114
181
|
onInsert: (content: string) => {
|
182
|
+
//如果公式文本框有内容则进行下一步处理
|
115
183
|
if (content) {
|
116
184
|
//获取编辑器对象
|
117
185
|
const editor = <AlexEditor>editifyInstance.exposed!.editor.value
|
118
|
-
|
119
|
-
const
|
120
|
-
|
186
|
+
//获取选区所在的数学公式元素
|
187
|
+
const mathformulaElement = getMathformulaElementByRange(editifyInstance.exposed!.editor.value, editifyInstance.exposed!.dataRangeCaches.value)
|
188
|
+
//如果在数学公式下
|
189
|
+
if (mathformulaElement) {
|
190
|
+
//清除该数学公式
|
191
|
+
mathformulaElement.toEmpty()
|
192
|
+
//移动光标到后一个元素上
|
193
|
+
editor.range!.anchor.moveToStart(editor.getNextElement(mathformulaElement)!)
|
194
|
+
editor.range!.focus.moveToStart(editor.getNextElement(mathformulaElement)!)
|
195
|
+
}
|
196
|
+
//定义转换后的mathml内容
|
197
|
+
let mathml: string = ''
|
198
|
+
try {
|
199
|
+
//获取转换后的mathml
|
200
|
+
mathml = KaTex.renderToString(content, {
|
121
201
|
output: 'mathml',
|
122
|
-
throwOnError:
|
202
|
+
throwOnError: true
|
123
203
|
})
|
124
|
-
)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
204
|
+
} catch (error) {
|
205
|
+
mathml = ''
|
206
|
+
if (typeof options!.handleError == 'function') {
|
207
|
+
options!.handleError(error as Error)
|
208
|
+
}
|
209
|
+
}
|
210
|
+
//如果mathml存在则表示数学公式渲染成功则插入到编辑器
|
211
|
+
if (mathml) {
|
212
|
+
//设置最终的html内容
|
213
|
+
const html = `<span data-editify-mathformula="${content}" contenteditable="false">${mathml}</span>`
|
214
|
+
//html内容转为元素数组
|
215
|
+
const elements = editor.parseHtml(html)
|
216
|
+
//插入编辑器
|
217
|
+
editor.insertElement(elements[0])
|
218
|
+
//移动光标到新插入的元素
|
219
|
+
editor.range!.anchor.moveToEnd(elements[0])
|
220
|
+
editor.range!.focus.moveToEnd(elements[0])
|
221
|
+
//渲染
|
222
|
+
editor.formatElementStack()
|
223
|
+
editor.domRender()
|
224
|
+
editor.rangeRender()
|
225
|
+
}
|
138
226
|
}
|
139
227
|
//关闭浮层
|
140
228
|
btnInstance.show = false
|
@@ -8,7 +8,7 @@
|
|
8
8
|
</div>
|
9
9
|
</template>
|
10
10
|
<script setup lang="ts">
|
11
|
-
import { inject, ref } from 'vue'
|
11
|
+
import { inject, ref, watch } from 'vue'
|
12
12
|
import { InsertMathformulaProps } from './props'
|
13
13
|
|
14
14
|
defineOptions({
|
@@ -36,5 +36,15 @@ const handleInputBlur = (e: Event) => {
|
|
36
36
|
const insertMathformula = () => {
|
37
37
|
emits('insert', latexContent.value)
|
38
38
|
}
|
39
|
+
|
40
|
+
watch(
|
41
|
+
() => props.defaultLaTexContent,
|
42
|
+
newVal => {
|
43
|
+
latexContent.value = newVal
|
44
|
+
},
|
45
|
+
{
|
46
|
+
immediate: true
|
47
|
+
}
|
48
|
+
)
|
39
49
|
</script>
|
40
50
|
<style scoped src="./insertMathformula.less"></style>
|