vue-editify 0.2.13 → 0.2.15

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 (190) hide show
  1. package/examples/App.vue +49 -67
  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 +86 -53
  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 +8879 -7668
  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 +104 -69
  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 +96 -7
  126. package/src/core/tool.ts +234 -78
  127. package/src/editify/editify.less +2 -0
  128. package/src/editify/editify.vue +182 -185
  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 +128 -0
  138. package/src/feature/attachment.ts +109 -0
  139. package/src/feature/backColor.ts +171 -0
  140. package/src/feature/bold.ts +136 -0
  141. package/src/feature/code.ts +136 -0
  142. package/src/feature/codeBlock.ts +204 -0
  143. package/src/feature/fontFamily.ts +140 -0
  144. package/src/feature/fontSize.ts +142 -0
  145. package/src/feature/foreColor.ts +173 -0
  146. package/src/feature/formatClear.ts +118 -0
  147. package/src/feature/fullScreen.ts +57 -0
  148. package/src/feature/heading.ts +154 -0
  149. package/src/feature/image.ts +225 -0
  150. package/src/feature/indent.ts +73 -0
  151. package/src/feature/infoBlock.ts +94 -0
  152. package/src/feature/italic.ts +136 -0
  153. package/src/feature/lineHeight.ts +165 -0
  154. package/src/feature/link.ts +149 -0
  155. package/src/feature/mathformula.ts +147 -0
  156. package/src/feature/orderList.ts +116 -0
  157. package/src/feature/panel.ts +108 -0
  158. package/src/feature/quote.ts +61 -0
  159. package/src/feature/redo.ts +56 -0
  160. package/src/feature/separator.ts +62 -0
  161. package/src/feature/sourceView.ts +59 -0
  162. package/src/feature/strikethrough.ts +136 -0
  163. package/src/feature/sub.ts +136 -0
  164. package/src/feature/super.ts +136 -0
  165. package/src/feature/table.ts +994 -0
  166. package/src/feature/task.ts +116 -0
  167. package/src/feature/underline.ts +136 -0
  168. package/src/feature/undo.ts +56 -0
  169. package/src/feature/unorderList.ts +116 -0
  170. package/src/feature/video.ts +339 -0
  171. package/src/hljs/index.ts +1 -1
  172. package/src/index.ts +69 -21
  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
@@ -0,0 +1,165 @@
1
+ import { computed, defineComponent, h, inject, PropType, Ref, ref } from 'vue'
2
+ import { AlexElementsRangeType, AlexEditor } from 'alex-editor'
3
+ import { common as DapCommon } from 'dap-util'
4
+ import { MenuDisplayButtonType } from '@/core/tool'
5
+ import { hasPreInRange, setLineHeight } from '@/core/function'
6
+ import { Button, ButtonOptionsItemType } from '@/components/button'
7
+
8
+ /**
9
+ * feature名称
10
+ */
11
+ const FEATURE_NAME = 'lineHeight'
12
+
13
+ /**
14
+ * 工具栏 - 行高
15
+ */
16
+ export const LineHeightToolbarButton = defineComponent(
17
+ (props, { expose }) => {
18
+ const editor = inject<Ref<AlexEditor>>('editor')!
19
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
20
+ const $editTrans = inject<(key: string) => any>('$editTrans')!
21
+
22
+ const btnRef = ref<InstanceType<typeof Button> | null>(null)
23
+
24
+ const selectVal = computed<string | number>(() => {
25
+ const findHeightItem = props.config.options!.find((item: string | number | ButtonOptionsItemType) => {
26
+ let val: string | number | ButtonOptionsItemType = item
27
+ if (DapCommon.isObject(item)) {
28
+ val = (item as ButtonOptionsItemType).value!
29
+ }
30
+ return dataRangeCaches.value.list.every(el => {
31
+ if (el.element.isBlock() || el.element.isInblock()) {
32
+ return el.element.hasStyles() && el.element.styles!['line-height'] == val
33
+ }
34
+ const block = el.element.getBlock()
35
+ const inblock = el.element.getInblock()
36
+ if (inblock) {
37
+ return inblock.hasStyles() && inblock.styles!['line-height'] == val
38
+ }
39
+ return block.hasStyles() && block.styles!['line-height'] == val
40
+ })
41
+ })
42
+ return findHeightItem ? (DapCommon.isObject(findHeightItem) ? ((findHeightItem as ButtonOptionsItemType).value as string | number) : (findHeightItem as string | number)) : (props.config.defaultValue as string | number)
43
+ })
44
+
45
+ expose({
46
+ btnRef
47
+ })
48
+
49
+ return () => {
50
+ return props.config.show
51
+ ? h(Button, {
52
+ ref: btnRef,
53
+ name: FEATURE_NAME,
54
+ type: 'display',
55
+ title: $editTrans('lineHeight'),
56
+ tooltip: props.tooltip,
57
+ color: props.color,
58
+ zIndex: props.zIndex,
59
+ leftBorder: props.config.leftBorder,
60
+ rightBorder: props.config.rightBorder,
61
+ active: false,
62
+ disabled: props.config.disabled,
63
+ displayConfig: {
64
+ options: props.config.options,
65
+ value: selectVal.value,
66
+ width: props.config.width,
67
+ maxHeight: props.config.maxHeight
68
+ },
69
+ onOperate: (_name: string, val: string) => {
70
+ setLineHeight(editor.value, dataRangeCaches.value, val)
71
+ editor.value.formatElementStack()
72
+ editor.value.domRender()
73
+ editor.value.rangeRender()
74
+ }
75
+ })
76
+ : null
77
+ }
78
+ },
79
+ {
80
+ name: `_${FEATURE_NAME}`,
81
+ props: {
82
+ color: String,
83
+ zIndex: Number,
84
+ config: Object as PropType<MenuDisplayButtonType>,
85
+ tooltip: Boolean
86
+ }
87
+ }
88
+ )
89
+
90
+ /**
91
+ * 菜单栏 - 行高
92
+ */
93
+ export const LineHeightMenuButton = defineComponent(
94
+ props => {
95
+ const editor = inject<Ref<AlexEditor>>('editor')!
96
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
97
+ const $editTrans = inject<(key: string) => any>('$editTrans')!
98
+ const isSourceView = inject<Ref<boolean>>('isSourceView')!
99
+ const rangeKey = inject<Ref<number | null>>('rangeKey')!
100
+
101
+ const selectVal = computed<string>(() => {
102
+ const findHeightItem = props.config.options!.find((item: string | number | ButtonOptionsItemType) => {
103
+ let val: string | number | ButtonOptionsItemType = item
104
+ if (DapCommon.isObject(item)) {
105
+ val = (item as ButtonOptionsItemType).value!
106
+ }
107
+ if (rangeKey.value && editor.value.range && editor.value.range.anchor.isEqual(editor.value.range!.focus)) {
108
+ const block = editor.value.range!.anchor.element.getBlock()
109
+ return block.hasStyles() && block.styles!['line-height'] == val
110
+ }
111
+ return dataRangeCaches.value.list.every(el => {
112
+ if (el.element.isBlock() || el.element.isInblock()) {
113
+ return el.element.hasStyles() && el.element.styles!['line-height'] == val
114
+ }
115
+ const block = el.element.getBlock()
116
+ const inblock = el.element.getInblock()
117
+ if (inblock) {
118
+ return inblock.hasStyles() && inblock.styles!['line-height'] == val
119
+ }
120
+ return block.hasStyles() && block.styles!['line-height'] == val
121
+ })
122
+ })
123
+ return findHeightItem ? (DapCommon.isObject(findHeightItem) ? ((findHeightItem as ButtonOptionsItemType).value as string) : (findHeightItem as string)) : (props.config.defaultValue as string)
124
+ })
125
+
126
+ return () => {
127
+ return props.config.show
128
+ ? h(Button, {
129
+ name: FEATURE_NAME,
130
+ tooltip: props.tooltip,
131
+ color: props.color,
132
+ zIndex: props.zIndex,
133
+ type: 'display',
134
+ displayConfig: {
135
+ options: props.config.options,
136
+ value: selectVal.value,
137
+ width: props.config.width,
138
+ maxHeight: props.config.maxHeight
139
+ },
140
+ title: $editTrans('lineHeight'),
141
+ leftBorder: props.config.leftBorder,
142
+ rightBorder: props.config.rightBorder,
143
+ disabled: props.disabled || isSourceView.value || hasPreInRange(editor.value, dataRangeCaches.value) || props.config.disabled,
144
+ active: false,
145
+ onOperate: (_name, val) => {
146
+ setLineHeight(editor.value, dataRangeCaches.value, <string | number>val)
147
+ editor.value.formatElementStack()
148
+ editor.value.domRender()
149
+ editor.value.rangeRender()
150
+ }
151
+ })
152
+ : null
153
+ }
154
+ },
155
+ {
156
+ name: `_${FEATURE_NAME}`,
157
+ props: {
158
+ color: String,
159
+ zIndex: Number,
160
+ config: Object as PropType<MenuDisplayButtonType>,
161
+ tooltip: Boolean,
162
+ disabled: Boolean
163
+ }
164
+ }
165
+ )
@@ -0,0 +1,149 @@
1
+ import { computed, defineComponent, h, inject, PropType, ref, Ref } from 'vue'
2
+ import { UpdateLink } from '@/components/updateLink'
3
+ import { getMatchElementByRange, getRangeText, hasAttachmentInRange, hasLinkInRange, hasMathformulaInRange, hasPreInRange, insertLink } from '@/core/function'
4
+ import { AlexEditor, AlexElement, AlexElementsRangeType } from 'alex-editor'
5
+ import { Button } from '@/components/button'
6
+ import { Icon } from '@/components/icon'
7
+ import { InsertLink } from '@/components/insertLink'
8
+ import { MenuSelectButtonType } from '@/core/tool'
9
+
10
+ /**
11
+ * feature名称
12
+ */
13
+ const FEATURE_NAME = 'link'
14
+
15
+ /**
16
+ * 工具栏 - 编辑链接
17
+ */
18
+ export const linkToolbar = defineComponent(
19
+ props => {
20
+ const editor = inject<Ref<AlexEditor>>('editor')!
21
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
22
+
23
+ const preset = computed(() => {
24
+ const link = getMatchElementByRange(editor.value, dataRangeCaches.value, { parsedom: 'a' })
25
+ if (link) {
26
+ return {
27
+ url: link.marks!['href'],
28
+ newOpen: link.marks!['target'] == '_blank'
29
+ }
30
+ }
31
+ return {
32
+ url: '',
33
+ newOpen: false
34
+ }
35
+ })
36
+
37
+ return () => {
38
+ return h(UpdateLink, {
39
+ color: props.color,
40
+ toolbar: true,
41
+ presetNewOpen: preset.value.newOpen,
42
+ presetUrl: preset.value.url,
43
+ onModify: (url: string, newOpen: boolean) => {
44
+ if (!url) {
45
+ return
46
+ }
47
+ const link = getMatchElementByRange(editor.value, dataRangeCaches.value, { parsedom: 'a' })
48
+ if (link) {
49
+ link.marks!.href = url
50
+ if (newOpen) {
51
+ link.marks!.target = '_blank'
52
+ } else {
53
+ delete link.marks!.target
54
+ }
55
+ editor.value.formatElementStack()
56
+ editor.value.domRender()
57
+ }
58
+ },
59
+ onRemove: () => {
60
+ const link = getMatchElementByRange(editor.value, dataRangeCaches.value, { parsedom: 'a' })
61
+ if (link) {
62
+ link.parsedom = AlexElement.TEXT_NODE
63
+ delete link.marks!['target']
64
+ delete link.marks!['href']
65
+ delete link.marks!['data-editify-element']
66
+ editor.value.formatElementStack()
67
+ editor.value.domRender()
68
+ editor.value.rangeRender()
69
+ }
70
+ }
71
+ })
72
+ }
73
+ },
74
+ {
75
+ name: `_${FEATURE_NAME}`,
76
+ props: {
77
+ color: String
78
+ }
79
+ }
80
+ )
81
+
82
+ /**
83
+ * 菜单栏 - 插入链接
84
+ */
85
+ export const LinkMenuButton = defineComponent(
86
+ props => {
87
+ const editor = inject<Ref<AlexEditor>>('editor')!
88
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
89
+ const $editTrans = inject<(key: string) => any>('$editTrans')!
90
+ const isSourceView = inject<Ref<boolean>>('isSourceView')!
91
+
92
+ const btnRef = ref<InstanceType<typeof Button> | null>(null)
93
+
94
+ const presetText = computed<string>(() => getRangeText(dataRangeCaches.value))
95
+
96
+ return () => {
97
+ return props.config.show
98
+ ? h(
99
+ Button,
100
+ {
101
+ ref: btnRef,
102
+ name: FEATURE_NAME,
103
+ tooltip: props.tooltip,
104
+ color: props.color,
105
+ zIndex: props.zIndex,
106
+ type: 'select',
107
+ hideScroll: true,
108
+ title: $editTrans('insertLink'),
109
+ leftBorder: props.config.leftBorder,
110
+ rightBorder: props.config.rightBorder,
111
+ active: false,
112
+ disabled: props.disabled || isSourceView.value || hasLinkInRange(editor.value, dataRangeCaches.value) || hasPreInRange(editor.value, dataRangeCaches.value) || hasAttachmentInRange(editor.value, dataRangeCaches.value) || hasMathformulaInRange(editor.value, dataRangeCaches.value) || props.config.disabled
113
+ },
114
+ {
115
+ default: () =>
116
+ h(Icon, {
117
+ value: 'link'
118
+ }),
119
+ layer: () =>
120
+ h(InsertLink, {
121
+ color: props.color,
122
+ presetText: presetText.value,
123
+ onInsert: (text: string, url: string, newOpen: boolean) => {
124
+ if (!url) {
125
+ return
126
+ }
127
+ insertLink(editor.value, text, url, newOpen)
128
+ editor.value.formatElementStack()
129
+ editor.value.domRender()
130
+ editor.value.rangeRender()
131
+ btnRef.value!.show = false
132
+ }
133
+ })
134
+ }
135
+ )
136
+ : null
137
+ }
138
+ },
139
+ {
140
+ name: `_${FEATURE_NAME}`,
141
+ props: {
142
+ color: String,
143
+ zIndex: Number,
144
+ config: Object as PropType<MenuSelectButtonType>,
145
+ tooltip: Boolean,
146
+ disabled: Boolean
147
+ }
148
+ }
149
+ )
@@ -0,0 +1,147 @@
1
+ import { computed, defineComponent, h, inject, PropType, ref, Ref } from 'vue'
2
+ import { AlexEditor, AlexElementsRangeType } from 'alex-editor'
3
+ import 'katex/dist/katex.css'
4
+ import KaTex from 'katex'
5
+ import { MenuMathformulaButtonType } from '@/core/tool'
6
+ import { Button } from '@/components/button'
7
+ import { getMatchElementByRange, hasLinkInRange, hasPreInRange } from '@/core/function'
8
+ import { Icon } from '@/components/icon'
9
+ import { InsertMathformula } from '@/components/insertMathformula'
10
+
11
+ /**
12
+ * feature名称
13
+ */
14
+ const FEATURE_NAME = 'mathformula'
15
+
16
+ /**
17
+ * 数学公式额外保留的标签
18
+ */
19
+ export const extraKeepTagsForMathformula = ['math', 'mrow', 'mi', 'mo', 'mn', 'msup', 'msub', 'mfrac', 'msqrt', 'mroot', 'munder', 'mover', 'munderover', 'mtable', 'mtr', 'mtd', 'mtext', 'mspace', 'mmultiscripts', 'menclose', 'mglyph', 'maction', 'maligngroup', 'malignmark', 'mprescripts', 'none', 'mpadded', 'ms', 'mphantom', 'mstyle', 'merror', 'mscarries', 'mscarry', 'msline', 'msgroup', 'msrow', 'mscolumn', 'mstack', 'mlongdiv', 'mlabeledtr', 'mlabeledmultiscripts', 'semantics', 'msubsup']
20
+
21
+ /**
22
+ * 菜单栏 - 插入数学公式
23
+ */
24
+ export const MathformulaMenuButton = defineComponent(
25
+ props => {
26
+ const editor = inject<Ref<AlexEditor>>('editor')!
27
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
28
+ const $editTrans = inject<(key: string) => any>('$editTrans')!
29
+ const isSourceView = inject<Ref<boolean>>('isSourceView')!
30
+
31
+ const btnRef = ref<InstanceType<typeof Button> | null>(null)
32
+
33
+ const defaultLaTexContent = computed<string>(() => {
34
+ //获取选区所在的数学公式元素
35
+ const mathformulaElement = getMatchElementByRange(editor.value, dataRangeCaches.value, {
36
+ parsedom: 'span',
37
+ marks: {
38
+ 'data-editify-mathformula': true
39
+ }
40
+ })
41
+ if (mathformulaElement) {
42
+ return mathformulaElement.marks!['data-editify-mathformula'] || ''
43
+ }
44
+ return ''
45
+ })
46
+
47
+ return () => {
48
+ return props.config.show
49
+ ? h(
50
+ Button,
51
+ {
52
+ ref: btnRef,
53
+ name: FEATURE_NAME,
54
+ tooltip: props.tooltip,
55
+ color: props.color,
56
+ zIndex: props.zIndex,
57
+ type: 'select',
58
+ hideScroll: true,
59
+ title: $editTrans('insertMathformula'),
60
+ leftBorder: props.config.leftBorder,
61
+ rightBorder: props.config.rightBorder,
62
+ active: !!getMatchElementByRange(editor.value, dataRangeCaches.value, {
63
+ parsedom: 'span',
64
+ marks: {
65
+ 'data-editify-mathformula': true
66
+ }
67
+ }),
68
+ disabled: props.disabled || isSourceView.value || hasPreInRange(editor.value, dataRangeCaches.value) || hasLinkInRange(editor.value, dataRangeCaches.value) || props.config.disabled
69
+ },
70
+ {
71
+ default: () =>
72
+ h(Icon, {
73
+ value: 'mathformula'
74
+ }),
75
+ layer: () =>
76
+ h(InsertMathformula, {
77
+ color: props.color,
78
+ defaultLaTexContent: defaultLaTexContent.value,
79
+ onInsert: (content: string) => {
80
+ //如果公式文本框有内容则进行下一步处理
81
+ if (content) {
82
+ //获取选区所在的数学公式元素
83
+ const mathformulaElement = getMatchElementByRange(editor.value, dataRangeCaches.value, {
84
+ parsedom: 'span',
85
+ marks: {
86
+ 'data-editify-mathformula': true
87
+ }
88
+ })
89
+ //如果在数学公式下
90
+ if (mathformulaElement) {
91
+ //清除该数学公式
92
+ mathformulaElement.toEmpty()
93
+ //移动光标到后一个元素上
94
+ editor.value.range!.anchor.moveToStart(editor.value.getNextElement(mathformulaElement)!)
95
+ editor.value.range!.focus.moveToStart(editor.value.getNextElement(mathformulaElement)!)
96
+ }
97
+ //定义转换后的mathml内容
98
+ let mathml: string = ''
99
+ try {
100
+ //获取转换后的mathml
101
+ mathml = KaTex.renderToString(content, {
102
+ output: 'mathml',
103
+ throwOnError: true
104
+ })
105
+ } catch (error) {
106
+ mathml = ''
107
+ if (typeof props.config!.handleError == 'function') {
108
+ props.config!.handleError(error as Error)
109
+ }
110
+ }
111
+ //如果mathml存在则表示数学公式渲染成功则插入到编辑器
112
+ if (mathml) {
113
+ //设置最终的html内容
114
+ const html = `<span data-editify-mathformula="${content}" contenteditable="false">${mathml}</span>`
115
+ //html内容转为元素数组
116
+ const elements = editor.value.parseHtml(html)
117
+ //插入编辑器
118
+ editor.value.insertElement(elements[0])
119
+ //移动光标到新插入的元素
120
+ editor.value.range!.anchor.moveToEnd(elements[0])
121
+ editor.value.range!.focus.moveToEnd(elements[0])
122
+ //渲染
123
+ editor.value.formatElementStack()
124
+ editor.value.domRender()
125
+ editor.value.rangeRender()
126
+ }
127
+ }
128
+ //关闭浮层
129
+ btnRef.value!.show = false
130
+ }
131
+ })
132
+ }
133
+ )
134
+ : null
135
+ }
136
+ },
137
+ {
138
+ name: `_${FEATURE_NAME}`,
139
+ props: {
140
+ color: String,
141
+ zIndex: Number,
142
+ config: Object as PropType<MenuMathformulaButtonType>,
143
+ tooltip: Boolean,
144
+ disabled: Boolean
145
+ }
146
+ }
147
+ )
@@ -0,0 +1,116 @@
1
+ import { defineComponent, h, inject, PropType, Ref, ref } from 'vue'
2
+ import { AlexElementsRangeType, AlexEditor } from 'alex-editor'
3
+ import { MenuButtonType } from '@/core/tool'
4
+ import { hasPanelInRange, hasPreInRange, hasTableInRange, rangeIsInList, setList } from '@/core/function'
5
+ import { Button } from '@/components/button'
6
+ import { Icon } from '@/components/icon'
7
+
8
+ /**
9
+ * feature名称
10
+ */
11
+ const FEATURE_NAME = 'orderList'
12
+
13
+ /**
14
+ * 工具栏 - 有序列表
15
+ */
16
+ export const OrderListToolbarButton = defineComponent(
17
+ (props, { expose }) => {
18
+ const editor = inject<Ref<AlexEditor>>('editor')!
19
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
20
+ const $editTrans = inject<(key: string) => any>('$editTrans')!
21
+
22
+ const btnRef = ref<InstanceType<typeof Button> | null>(null)
23
+
24
+ expose({
25
+ btnRef
26
+ })
27
+
28
+ return () => {
29
+ return props.config.show
30
+ ? h(
31
+ Button,
32
+ {
33
+ ref: btnRef,
34
+ name: FEATURE_NAME,
35
+ title: $editTrans('orderList'),
36
+ tooltip: props.tooltip,
37
+ color: props.color,
38
+ zIndex: props.zIndex,
39
+ leftBorder: props.config.leftBorder,
40
+ rightBorder: props.config.rightBorder,
41
+ active: rangeIsInList(editor.value, dataRangeCaches.value, true),
42
+ disabled: props.config.disabled,
43
+ onOperate: () => {
44
+ setList(editor.value, dataRangeCaches.value, true)
45
+ editor.value.formatElementStack()
46
+ editor.value.domRender()
47
+ editor.value.rangeRender()
48
+ }
49
+ },
50
+ {
51
+ default: () => h(Icon, { value: 'list-ordered' })
52
+ }
53
+ )
54
+ : null
55
+ }
56
+ },
57
+ {
58
+ name: `_${FEATURE_NAME}`,
59
+ props: {
60
+ color: String,
61
+ zIndex: Number,
62
+ config: Object as PropType<MenuButtonType>,
63
+ tooltip: Boolean
64
+ }
65
+ }
66
+ )
67
+
68
+ /**
69
+ * 菜单栏 - 有序列表
70
+ */
71
+ export const OrderListMenuButton = defineComponent(
72
+ props => {
73
+ const editor = inject<Ref<AlexEditor>>('editor')!
74
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
75
+ const $editTrans = inject<(key: string) => any>('$editTrans')!
76
+ const isSourceView = inject<Ref<boolean>>('isSourceView')!
77
+
78
+ return () => {
79
+ return props.config.show
80
+ ? h(
81
+ Button,
82
+ {
83
+ name: FEATURE_NAME,
84
+ tooltip: props.tooltip,
85
+ color: props.color,
86
+ zIndex: props.zIndex,
87
+ title: $editTrans('orderList'),
88
+ leftBorder: props.config.leftBorder,
89
+ rightBorder: props.config.rightBorder,
90
+ active: rangeIsInList(editor.value, dataRangeCaches.value, true),
91
+ disabled: props.disabled || isSourceView.value || hasPreInRange(editor.value, dataRangeCaches.value) || hasTableInRange(editor.value, dataRangeCaches.value) || hasPanelInRange(editor.value, dataRangeCaches.value) || props.config.disabled,
92
+ onOperate: () => {
93
+ setList(editor.value, dataRangeCaches.value, true)
94
+ editor.value.formatElementStack()
95
+ editor.value.domRender()
96
+ editor.value.rangeRender()
97
+ }
98
+ },
99
+ {
100
+ default: () => h(Icon, { value: 'list-ordered' })
101
+ }
102
+ )
103
+ : null
104
+ }
105
+ },
106
+ {
107
+ name: `_${FEATURE_NAME}`,
108
+ props: {
109
+ color: String,
110
+ zIndex: Number,
111
+ config: Object as PropType<MenuButtonType>,
112
+ tooltip: Boolean,
113
+ disabled: Boolean
114
+ }
115
+ }
116
+ )
@@ -0,0 +1,108 @@
1
+ import { defineComponent, h, inject, PropType, Ref } from 'vue'
2
+ import { AlexEditor, AlexElement, AlexElementsRangeType } from 'alex-editor'
3
+ import { Button } from '@/components/button'
4
+ import { MenuButtonType } from '@/core/tool'
5
+ import { Icon } from '@/components/icon'
6
+ import { hasMathformulaInRange, hasPanelInRange, hasTableInRange } from '@/core/function'
7
+
8
+ /**
9
+ * feature名称
10
+ */
11
+ const FEATURE_NAME = 'panel'
12
+
13
+ /**
14
+ * 菜单栏 - 插入面板
15
+ */
16
+ export const PanelMenuButton = defineComponent(
17
+ props => {
18
+ const editor = inject<Ref<AlexEditor>>('editor')!
19
+ const dataRangeCaches = inject<Ref<AlexElementsRangeType>>('dataRangeCaches')!
20
+ const $editTrans = inject<(key: string) => any>('$editTrans')!
21
+ const isSourceView = inject<Ref<boolean>>('isSourceView')!
22
+
23
+ return () => {
24
+ return props.config.show
25
+ ? h(
26
+ Button,
27
+ {
28
+ name: FEATURE_NAME,
29
+ tooltip: props.tooltip,
30
+ color: props.color,
31
+ zIndex: props.zIndex,
32
+ title: $editTrans('insertPanel'),
33
+ leftBorder: props.config.leftBorder,
34
+ rightBorder: props.config.rightBorder,
35
+ active: false,
36
+ disabled: props.disabled || isSourceView.value || hasPanelInRange(editor.value, dataRangeCaches.value) || hasTableInRange(editor.value, dataRangeCaches.value) || hasMathformulaInRange(editor.value, dataRangeCaches.value) || props.config.disabled,
37
+ onOperate: () => {
38
+ const panelElement = AlexElement.create({
39
+ type: 'block',
40
+ parsedom: 'div',
41
+ marks: {
42
+ 'data-editify-panel': 'true'
43
+ },
44
+ children: [
45
+ {
46
+ type: 'inblock',
47
+ parsedom: 'div',
48
+ behavior: 'block',
49
+ children: [
50
+ {
51
+ type: 'text',
52
+ textcontent: $editTrans('panelTitle')
53
+ }
54
+ ]
55
+ },
56
+ {
57
+ type: 'inblock',
58
+ parsedom: 'div',
59
+ behavior: 'block',
60
+ children: [
61
+ {
62
+ type: 'text',
63
+ textcontent: $editTrans('panelContent')
64
+ }
65
+ ]
66
+ }
67
+ ]
68
+ })
69
+ editor.value.insertElement(panelElement)
70
+ //面板后面插入段落
71
+ const paragraph = AlexElement.create({
72
+ type: 'block',
73
+ parsedom: AlexElement.BLOCK_NODE,
74
+ children: [
75
+ {
76
+ type: 'closed',
77
+ parsedom: 'br'
78
+ }
79
+ ]
80
+ })
81
+ editor.value.addElementAfter(paragraph, panelElement)
82
+ //移动光标到新插入的元素
83
+ editor.value.range!.anchor.moveToEnd(panelElement.children![0])
84
+ editor.value.range!.focus.moveToEnd(panelElement.children![0])
85
+ //渲染
86
+ editor.value.formatElementStack()
87
+ editor.value.domRender()
88
+ editor.value.rangeRender()
89
+ }
90
+ },
91
+ {
92
+ default: () => h(Icon, { value: 'panel' })
93
+ }
94
+ )
95
+ : null
96
+ }
97
+ },
98
+ {
99
+ name: `_${FEATURE_NAME}`,
100
+ props: {
101
+ color: String,
102
+ zIndex: Number,
103
+ config: Object as PropType<MenuButtonType>,
104
+ tooltip: Boolean,
105
+ disabled: Boolean
106
+ }
107
+ }
108
+ )