vue-editify 0.1.39 → 0.1.41
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/examples/App.vue +11 -6
- package/lib/core/function.d.ts +18 -6
- package/lib/core/tool.d.ts +0 -6
- package/lib/editify.es.js +325 -210
- package/lib/editify.umd.js +1 -1
- package/lib/index.d.ts +4 -3
- 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/components/button/button.less +1 -1
- package/src/components/icon/icon.less +1 -1
- package/src/components/menu/menu.vue +2 -2
- package/src/components/toolbar/toolbar.vue +91 -85
- package/src/core/function.ts +89 -58
- package/src/core/rule.ts +60 -4
- package/src/core/tool.ts +2 -23
- package/src/editify/editify.less +35 -3
- package/src/editify/editify.vue +37 -32
- package/src/icon/iconfont.ttf +0 -0
- package/src/icon/iconfont.woff +0 -0
- package/src/index.ts +4 -3
- package/src/locale/en_US.ts +1 -0
- package/src/locale/zh_CN.ts +1 -0
- package/src/plugins/mathformula/index.ts +114 -27
- package/src/plugins/mathformula/insertMathformula/insertMathformula.vue +12 -2
- package/src/plugins/mathformula/insertMathformula/props.ts +5 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
@font-face {
|
2
2
|
font-family: 'editify-icon';
|
3
|
-
src: url('../../icon/iconfont.woff?t=
|
3
|
+
src: url('../../icon/iconfont.woff?t=2024051301') format('woff'), url('../../icon/iconfont.ttf?t=2024051301') format('truetype');
|
4
4
|
}
|
5
5
|
|
6
6
|
.editify-icon {
|
@@ -14,7 +14,7 @@ import InsertVideo from '../insertVideo/insertVideo.vue'
|
|
14
14
|
import InsertTable from '../insertTable/insertTable.vue'
|
15
15
|
import { h, getCurrentInstance, ref, computed, inject, ComponentInternalInstance, Ref, ComputedRef, defineComponent } from 'vue'
|
16
16
|
import { common as DapCommon } from 'dap-util'
|
17
|
-
import { getRangeText, setHeading, setIndentIncrease, setIndentDecrease, setQuote, setAlign, setList, setTask, setTextStyle, setTextMark, removeTextStyle, removeTextMark, setLineHeight, insertLink, insertImage, insertVideo, insertTable, insertCodeBlock, hasPreInRange, hasTableInRange, hasQuoteInRange, hasLinkInRange, isRangeInQuote, isRangeInList, isRangeInTask, queryTextStyle, queryTextMark,
|
17
|
+
import { getRangeText, setHeading, setIndentIncrease, setIndentDecrease, setQuote, setAlign, setList, setTask, setTextStyle, setTextMark, removeTextStyle, removeTextMark, setLineHeight, insertLink, insertImage, insertVideo, insertTable, insertCodeBlock, hasPreInRange, hasTableInRange, hasQuoteInRange, hasLinkInRange, isRangeInQuote, isRangeInList, isRangeInTask, queryTextStyle, queryTextMark, getMatchElementsByRange, hasImageInRange, hasVideoInRange, insertSeparator } from '../../core/function'
|
18
18
|
import { MenuProps } from './props'
|
19
19
|
import { MenuModeType, ObjectType, PluginResultType, MenuExtendType, MenuSequenceType, mergeObject } from '../../core/tool'
|
20
20
|
import { AlexEditor, AlexElementsRangeType } from 'alex-editor'
|
@@ -923,7 +923,7 @@ const handleRangeUpdate = () => {
|
|
923
923
|
tableConfig.value.disabled = value_hasPreInRange || value_hasTableInRange || value_hasQuoteInRange || extraDisabled('table')
|
924
924
|
|
925
925
|
//代码块按钮激活
|
926
|
-
codeBlockConfig.value.active =
|
926
|
+
codeBlockConfig.value.active = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'pre' }).length == 1
|
927
927
|
//代码块按钮禁用
|
928
928
|
codeBlockConfig.value.disabled = value_hasTableInRange || value_hasQuoteInRange || value_hasImageInRange || value_hasVideoInRange || extraDisabled('codeBlock')
|
929
929
|
|
@@ -100,7 +100,7 @@
|
|
100
100
|
<Icon value="delete-column"></Icon>
|
101
101
|
</Button>
|
102
102
|
<!-- 删除表格 -->
|
103
|
-
<Button @operate="deleteElement('table')" name="deleteTable" :title="$editTrans('deleteTable')" :tooltip="config.tooltip" :color="color">
|
103
|
+
<Button @operate="deleteElement('table')" leftBorder name="deleteTable" :title="$editTrans('deleteTable')" :tooltip="config.tooltip" :color="color">
|
104
104
|
<Icon value="delete-table"></Icon>
|
105
105
|
</Button>
|
106
106
|
</template>
|
@@ -201,7 +201,7 @@ import Checkbox from '../checkbox/checkbox.vue'
|
|
201
201
|
import Colors from '../colors/colors.vue'
|
202
202
|
import { AlexEditor, AlexElement, AlexElementsRangeType } from 'alex-editor'
|
203
203
|
import { common as DapCommon } from 'dap-util'
|
204
|
-
import {
|
204
|
+
import { getMatchElementsByRange, removeTextStyle, removeTextMark, setTextStyle, setLineHeight, setTextMark, setList, setTask, setHeading, setAlign, isRangeInList, isRangeInTask, queryTextStyle, queryTextMark } from '../../core/function'
|
205
205
|
import { ToolbarProps } from './props'
|
206
206
|
import { Ref, computed, inject, ref } from 'vue'
|
207
207
|
import { ObjectType } from '../../core/tool'
|
@@ -229,6 +229,7 @@ const linkConfig = ref<ObjectType>({
|
|
229
229
|
//链接是否新窗口打开
|
230
230
|
newOpen: false
|
231
231
|
})
|
232
|
+
|
232
233
|
//视频参数配置
|
233
234
|
const videoConfig = ref<ObjectType>({
|
234
235
|
//是否显示控制器
|
@@ -240,6 +241,7 @@ const videoConfig = ref<ObjectType>({
|
|
240
241
|
//是否静音
|
241
242
|
muted: false
|
242
243
|
})
|
244
|
+
|
243
245
|
//代码块选择语言按钮配置
|
244
246
|
const languageConfig = ref<ObjectType>({
|
245
247
|
show: props.config.codeBlock!.languages!.show,
|
@@ -254,6 +256,8 @@ const languageConfig = ref<ObjectType>({
|
|
254
256
|
active: false,
|
255
257
|
disabled: false
|
256
258
|
})
|
259
|
+
|
260
|
+
/** 以下是文本工具条的配置参数信息 */
|
257
261
|
//标题按钮配置
|
258
262
|
const headingConfig = ref<ObjectType>({
|
259
263
|
show: props.config.text!.heading!.show,
|
@@ -674,36 +678,36 @@ const modifyLink = () => {
|
|
674
678
|
if (!linkConfig.value.url) {
|
675
679
|
return
|
676
680
|
}
|
677
|
-
const
|
678
|
-
if (
|
679
|
-
|
681
|
+
const links = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'a' })
|
682
|
+
if (links.length == 1) {
|
683
|
+
links[0].marks!.href = linkConfig.value.url
|
680
684
|
if (linkConfig.value.newOpen) {
|
681
|
-
|
685
|
+
links[0].marks!.target = '_blank'
|
682
686
|
} else {
|
683
|
-
delete
|
687
|
+
delete links[0].marks!.target
|
684
688
|
}
|
689
|
+
editor.value.formatElementStack()
|
690
|
+
editor.value.domRender()
|
685
691
|
}
|
686
|
-
editor.value.formatElementStack()
|
687
|
-
editor.value.domRender()
|
688
692
|
}
|
689
693
|
//移除链接
|
690
694
|
const removeLink = () => {
|
691
|
-
const
|
692
|
-
if (
|
693
|
-
|
694
|
-
delete
|
695
|
-
delete
|
696
|
-
delete
|
695
|
+
const links = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'a' })
|
696
|
+
if (links.length == 1) {
|
697
|
+
links[0].parsedom = AlexElement.TEXT_NODE
|
698
|
+
delete links[0].marks!['target']
|
699
|
+
delete links[0].marks!['href']
|
700
|
+
delete links[0].marks!['data-editify-element']
|
701
|
+
editor.value.formatElementStack()
|
702
|
+
editor.value.domRender()
|
703
|
+
editor.value.rangeRender()
|
697
704
|
}
|
698
|
-
editor.value.formatElementStack()
|
699
|
-
editor.value.domRender()
|
700
|
-
editor.value.rangeRender()
|
701
705
|
}
|
702
706
|
//选择代码语言
|
703
707
|
const selectLanguage = (_name: string, value: string) => {
|
704
|
-
const
|
705
|
-
if (
|
706
|
-
Object.assign(
|
708
|
+
const pres = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'pre' })
|
709
|
+
if (pres.length == 1) {
|
710
|
+
Object.assign(pres[0].marks!, {
|
707
711
|
'data-editify-hljs': value
|
708
712
|
})
|
709
713
|
editor.value.formatElementStack()
|
@@ -717,15 +721,15 @@ const insertParagraphWithPre = (type: string | undefined = 'up') => {
|
|
717
721
|
editor.value.range!.anchor.element = editor.value.range!.focus.element
|
718
722
|
editor.value.range!.anchor.offset = editor.value.range!.focus.offset
|
719
723
|
}
|
720
|
-
const
|
721
|
-
if (
|
724
|
+
const pres = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'pre' })
|
725
|
+
if (pres.length == 1) {
|
722
726
|
const paragraph = new AlexElement('block', AlexElement.BLOCK_NODE, null, null, null)
|
723
727
|
const breakEl = new AlexElement('closed', 'br', null, null, null)
|
724
728
|
editor.value.addElementTo(breakEl, paragraph)
|
725
729
|
if (type == 'up') {
|
726
|
-
editor.value.addElementBefore(paragraph,
|
730
|
+
editor.value.addElementBefore(paragraph, pres[0])
|
727
731
|
} else {
|
728
|
-
editor.value.addElementAfter(paragraph,
|
732
|
+
editor.value.addElementAfter(paragraph, pres[0])
|
729
733
|
}
|
730
734
|
editor.value.range!.anchor.moveToEnd(paragraph)
|
731
735
|
editor.value.range!.focus.moveToEnd(paragraph)
|
@@ -740,17 +744,17 @@ const insertTableColumn = (type: string | undefined = 'left') => {
|
|
740
744
|
editor.value.range!.anchor.element = editor.value.range!.focus.element
|
741
745
|
editor.value.range!.anchor.offset = editor.value.range!.focus.offset
|
742
746
|
}
|
743
|
-
const
|
744
|
-
const
|
745
|
-
const
|
746
|
-
if (
|
747
|
-
const rows =
|
748
|
-
const index =
|
749
|
-
return item.isEqual(
|
747
|
+
const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
|
748
|
+
const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'td' })
|
749
|
+
const tbodys = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'tbody' })
|
750
|
+
if (tables.length == 1 && tbodys.length == 1 && columns.length == 1) {
|
751
|
+
const rows = tbodys[0].children
|
752
|
+
const index = columns[0].parent!.children!.findIndex(item => {
|
753
|
+
return item.isEqual(columns[0])
|
750
754
|
})
|
751
755
|
//插入列
|
752
756
|
rows!.forEach(row => {
|
753
|
-
const newColumn =
|
757
|
+
const newColumn = columns[0].clone(false)
|
754
758
|
const breakEl = new AlexElement('closed', 'br', null, null, null)
|
755
759
|
editor.value.addElementTo(breakEl, newColumn)
|
756
760
|
if (type == 'left') {
|
@@ -760,7 +764,7 @@ const insertTableColumn = (type: string | undefined = 'left') => {
|
|
760
764
|
}
|
761
765
|
})
|
762
766
|
//插入col
|
763
|
-
const colgroup =
|
767
|
+
const colgroup = tables[0].children!.find(item => {
|
764
768
|
return item.parsedom == 'colgroup'
|
765
769
|
})!
|
766
770
|
const col = new AlexElement('closed', 'col', null, null, null)
|
@@ -772,11 +776,11 @@ const insertTableColumn = (type: string | undefined = 'left') => {
|
|
772
776
|
//渲染
|
773
777
|
editor.value.formatElementStack()
|
774
778
|
if (type == 'left') {
|
775
|
-
const previousColumn = editor.value.getPreviousElement(
|
779
|
+
const previousColumn = editor.value.getPreviousElement(columns[0])!
|
776
780
|
editor.value.range!.anchor.moveToStart(previousColumn)
|
777
781
|
editor.value.range!.focus.moveToStart(previousColumn)
|
778
782
|
} else {
|
779
|
-
const nextColumn = editor.value.getNextElement(
|
783
|
+
const nextColumn = editor.value.getNextElement(columns[0])!
|
780
784
|
editor.value.range!.anchor.moveToStart(nextColumn)
|
781
785
|
editor.value.range!.focus.moveToStart(nextColumn)
|
782
786
|
}
|
@@ -790,19 +794,19 @@ const insertTableRow = (type: string | undefined = 'up') => {
|
|
790
794
|
editor.value.range!.anchor.element = editor.value.range!.focus.element
|
791
795
|
editor.value.range!.anchor.offset = editor.value.range!.focus.offset
|
792
796
|
}
|
793
|
-
const
|
794
|
-
const
|
795
|
-
if (
|
796
|
-
const newRow =
|
797
|
+
const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
|
798
|
+
const rows = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'tr' })
|
799
|
+
if (tables.length == 1 && rows.length == 1) {
|
800
|
+
const newRow = rows[0].clone()
|
797
801
|
newRow.children!.forEach(column => {
|
798
802
|
column.children = []
|
799
803
|
const breakEl = new AlexElement('closed', 'br', null, null, null)
|
800
804
|
editor.value.addElementTo(breakEl, column)
|
801
805
|
})
|
802
806
|
if (type == 'up') {
|
803
|
-
editor.value.addElementBefore(newRow,
|
807
|
+
editor.value.addElementBefore(newRow, rows[0])
|
804
808
|
} else {
|
805
|
-
editor.value.addElementAfter(newRow,
|
809
|
+
editor.value.addElementAfter(newRow, rows[0])
|
806
810
|
}
|
807
811
|
editor.value.formatElementStack()
|
808
812
|
editor.value.range!.anchor.moveToStart(newRow)
|
@@ -817,15 +821,15 @@ const insertTableRow = (type: string | undefined = 'up') => {
|
|
817
821
|
}
|
818
822
|
//表格前后插入段落
|
819
823
|
const insertParagraphWithTable = (type: string | undefined = 'up') => {
|
820
|
-
const
|
821
|
-
if (
|
824
|
+
const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
|
825
|
+
if (tables.length == 1) {
|
822
826
|
const paragraph = new AlexElement('block', AlexElement.BLOCK_NODE, null, null, null)
|
823
827
|
const breakEl = new AlexElement('closed', 'br', null, null, null)
|
824
828
|
editor.value.addElementTo(breakEl, paragraph)
|
825
829
|
if (type == 'up') {
|
826
|
-
editor.value.addElementBefore(paragraph,
|
830
|
+
editor.value.addElementBefore(paragraph, tables[0])
|
827
831
|
} else {
|
828
|
-
editor.value.addElementAfter(paragraph,
|
832
|
+
editor.value.addElementAfter(paragraph, tables[0])
|
829
833
|
}
|
830
834
|
editor.value.range!.anchor.moveToEnd(paragraph)
|
831
835
|
editor.value.range!.focus.moveToEnd(paragraph)
|
@@ -836,9 +840,9 @@ const insertParagraphWithTable = (type: string | undefined = 'up') => {
|
|
836
840
|
}
|
837
841
|
//删除元素
|
838
842
|
const deleteElement = (parsedom: string) => {
|
839
|
-
const
|
840
|
-
if (
|
841
|
-
|
843
|
+
const elements = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom })
|
844
|
+
if (elements.length == 1) {
|
845
|
+
elements[0].toEmpty()
|
842
846
|
editor.value.formatElementStack()
|
843
847
|
editor.value.domRender()
|
844
848
|
editor.value.rangeRender()
|
@@ -850,17 +854,17 @@ const deleteTableRow = () => {
|
|
850
854
|
editor.value.range!.anchor.element = editor.value.range!.focus.element
|
851
855
|
editor.value.range!.anchor.offset = editor.value.range!.focus.offset
|
852
856
|
}
|
853
|
-
const
|
854
|
-
const
|
855
|
-
if (
|
856
|
-
const parent =
|
857
|
+
const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
|
858
|
+
const rows = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'tr' })
|
859
|
+
if (tables.length == 1 && rows.length == 1) {
|
860
|
+
const parent = rows[0].parent!
|
857
861
|
if (parent.children!.length == 1) {
|
858
862
|
deleteElement('table')
|
859
863
|
return
|
860
864
|
}
|
861
|
-
const previousRow = editor.value.getPreviousElement(
|
862
|
-
const nextRow = editor.value.getNextElement(
|
863
|
-
|
865
|
+
const previousRow = editor.value.getPreviousElement(rows[0])!
|
866
|
+
const nextRow = editor.value.getNextElement(rows[0])!
|
867
|
+
rows[0].toEmpty()
|
864
868
|
editor.value.formatElementStack()
|
865
869
|
if (previousRow) {
|
866
870
|
editor.value.range!.anchor.moveToEnd(previousRow.children![0])
|
@@ -883,27 +887,27 @@ const deleteTableColumn = () => {
|
|
883
887
|
editor.value.range!.anchor.element = editor.value.range!.focus.element
|
884
888
|
editor.value.range!.anchor.offset = editor.value.range!.focus.offset
|
885
889
|
}
|
886
|
-
const
|
887
|
-
const
|
888
|
-
const
|
889
|
-
if (
|
890
|
-
const rows =
|
891
|
-
const parent =
|
890
|
+
const columns = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'td' })
|
891
|
+
const tbodys = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'tbody' })
|
892
|
+
const tables = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'table' })
|
893
|
+
if (tables.length == 1 && tbodys.length == 1 && columns.length == 1) {
|
894
|
+
const rows = tbodys[0].children!
|
895
|
+
const parent = columns[0].parent!
|
892
896
|
if (parent.children!.length == 1) {
|
893
897
|
deleteElement('table')
|
894
898
|
return
|
895
899
|
}
|
896
|
-
const previousColumn = editor.value.getPreviousElement(
|
897
|
-
const nextColumn = editor.value.getNextElement(
|
898
|
-
const index =
|
899
|
-
return item.isEqual(
|
900
|
+
const previousColumn = editor.value.getPreviousElement(columns[0])!
|
901
|
+
const nextColumn = editor.value.getNextElement(columns[0])!
|
902
|
+
const index = columns[0].parent!.children!.findIndex(item => {
|
903
|
+
return item.isEqual(columns[0])
|
900
904
|
})
|
901
905
|
//删除列
|
902
906
|
rows.forEach(row => {
|
903
907
|
row.children![index].toEmpty()
|
904
908
|
})
|
905
909
|
//删除col
|
906
|
-
const colgroup =
|
910
|
+
const colgroup = tables[0].children!.find(item => {
|
907
911
|
return item.parsedom == 'colgroup'
|
908
912
|
})!
|
909
913
|
colgroup.children![index].toEmpty()
|
@@ -922,29 +926,31 @@ const deleteTableColumn = () => {
|
|
922
926
|
}
|
923
927
|
//浮层显示时
|
924
928
|
const layerShow = () => {
|
925
|
-
//代码块初始化展示设置
|
926
|
-
if (props.type == 'codeBlock') {
|
927
|
-
const pre = getCurrentParsedomElement(editor.value, dataRangeCaches.value, 'pre')
|
928
|
-
if (pre) {
|
929
|
-
languageConfig.value.displayConfig.value = pre.marks!['data-editify-hljs'] || ''
|
930
|
-
}
|
931
|
-
}
|
932
929
|
//链接初始化展示
|
933
|
-
|
934
|
-
const
|
935
|
-
if (
|
936
|
-
linkConfig.value.url =
|
937
|
-
linkConfig.value.newOpen =
|
930
|
+
if (props.type == 'link') {
|
931
|
+
const links = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'a' })
|
932
|
+
if (links.length == 1) {
|
933
|
+
linkConfig.value.url = links[0].marks!['href']
|
934
|
+
linkConfig.value.newOpen = links[0].marks!['target'] == '_blank'
|
938
935
|
}
|
939
936
|
}
|
940
937
|
//视频初始化显示
|
941
938
|
else if (props.type == 'video') {
|
942
|
-
const
|
943
|
-
if (
|
944
|
-
videoConfig.value.autoplay = !!
|
945
|
-
videoConfig.value.loop = !!
|
946
|
-
videoConfig.value.controls = !!
|
947
|
-
videoConfig.value.muted = !!
|
939
|
+
const videos = getMatchElementsByRange(editor.value, dataRangeCaches.value, { parsedom: 'video' })
|
940
|
+
if (videos.length == 1) {
|
941
|
+
videoConfig.value.autoplay = !!videos[0].marks!['autoplay']
|
942
|
+
videoConfig.value.loop = !!videos[0].marks!['loop']
|
943
|
+
videoConfig.value.controls = !!videos[0].marks!['controls']
|
944
|
+
videoConfig.value.muted = !!videos[0].marks!['muted']
|
945
|
+
}
|
946
|
+
}
|
947
|
+
//代码块初始化展示设置
|
948
|
+
else if (props.type == 'codeBlock') {
|
949
|
+
const pres = getMatchElementsByRange(editor.value, dataRangeCaches.value, {
|
950
|
+
parsedom: 'pre'
|
951
|
+
})
|
952
|
+
if (pres.length == 1) {
|
953
|
+
languageConfig.value.displayConfig.value = pres[0].marks!['data-editify-hljs'] || ''
|
948
954
|
}
|
949
955
|
}
|
950
956
|
//文本工具条初始化显示
|
package/src/core/function.ts
CHANGED
@@ -6,63 +6,94 @@ import { common as DapCommon } from 'dap-util'
|
|
6
6
|
import { cloneData, queryHasValue, getButtonOptionsConfig, ObjectType } from './tool'
|
7
7
|
import { ButtonOptionsItemType } from '../components/button/props'
|
8
8
|
|
9
|
+
export type ElementMatchConfig = {
|
10
|
+
parsedom?: string
|
11
|
+
marks?: ObjectType
|
12
|
+
styles?: ObjectType
|
13
|
+
}
|
14
|
+
|
9
15
|
/**
|
10
|
-
*
|
16
|
+
* 判断元素是否符合指定的条件
|
11
17
|
* @param element
|
12
|
-
* @param
|
18
|
+
* @param config
|
13
19
|
* @returns
|
14
20
|
*/
|
15
|
-
export const
|
21
|
+
export const elementIsMatch = (element: AlexElement, config: ElementMatchConfig) => {
|
22
|
+
//如果是文本元素直接返回false
|
23
|
+
if (element.isText()) {
|
24
|
+
return false
|
25
|
+
}
|
26
|
+
//默认是符合的
|
27
|
+
let isMatch = true
|
28
|
+
//如果存在parsedom判断并且parsedom不一样
|
29
|
+
if (config.parsedom && config.parsedom != element.parsedom) {
|
30
|
+
isMatch = false
|
31
|
+
}
|
32
|
+
//如果存在marks判断
|
33
|
+
if (config.marks) {
|
34
|
+
const hasMarks = Object.keys(config.marks).every(key => {
|
35
|
+
return element.hasMarks() && element.marks![key] && element.marks![key] == config.marks![key]
|
36
|
+
})
|
37
|
+
//如果不是所有的mark都有
|
38
|
+
if (!hasMarks) {
|
39
|
+
isMatch = false
|
40
|
+
}
|
41
|
+
}
|
42
|
+
//如果存在styles判断
|
43
|
+
if (config.styles) {
|
44
|
+
const hasStyles = Object.keys(config.styles).every(key => {
|
45
|
+
return element.hasStyles() && element.styles![key] && element.styles![key] == config.styles![key]
|
46
|
+
})
|
47
|
+
//如果不是所有的styles都有
|
48
|
+
if (!hasStyles) {
|
49
|
+
isMatch = false
|
50
|
+
}
|
51
|
+
}
|
52
|
+
return isMatch
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* 判断元素是否在符合条件的元素下,如果是返回符合条件的元素,否则返回null
|
57
|
+
* @param element
|
58
|
+
* @param config
|
59
|
+
* @returns
|
60
|
+
*/
|
61
|
+
export const getMatchElementByElement = (element: AlexElement, config: ElementMatchConfig): AlexElement | null => {
|
16
62
|
if (element.isBlock()) {
|
17
|
-
return element
|
63
|
+
return elementIsMatch(element, config) ? element : null
|
18
64
|
}
|
19
|
-
if (
|
65
|
+
if (elementIsMatch(element, config)) {
|
20
66
|
return element
|
21
67
|
}
|
22
|
-
return
|
68
|
+
return getMatchElementByElement(element.parent!, config)
|
23
69
|
}
|
24
70
|
|
25
71
|
/**
|
26
|
-
*
|
72
|
+
* 判断光标范围内的元素是否在符合条件的元素下,如果是所有的返回符合条件的元素,否则返回[]
|
27
73
|
* @param editor
|
28
74
|
* @param dataRangeCaches
|
29
|
-
* @param
|
75
|
+
* @param config
|
30
76
|
* @returns
|
31
77
|
*/
|
32
|
-
export const
|
78
|
+
export const getMatchElementsByRange = (editor: AlexEditor, dataRangeCaches: AlexElementsRangeType, config: ElementMatchConfig) => {
|
79
|
+
let elements: AlexElement[] = []
|
33
80
|
if (!editor.range) {
|
34
|
-
return
|
81
|
+
return elements
|
35
82
|
}
|
36
83
|
if (editor.range.anchor.element.isEqual(editor.range.focus.element)) {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
return getParsedomElementByElement(item.element, parsedom)
|
41
|
-
})
|
42
|
-
let hasNull = arr.some(el => {
|
43
|
-
return el == null
|
44
|
-
})
|
45
|
-
//如果存在null,则表示有的选区元素不在指定标签下,返回null
|
46
|
-
if (hasNull) {
|
47
|
-
return null
|
48
|
-
}
|
49
|
-
//如果只有一个元素,则返回该元素
|
50
|
-
if (arr.length == 1) {
|
51
|
-
return arr[0]!
|
52
|
-
}
|
53
|
-
//默认数组中的元素都相等
|
54
|
-
let flag = true
|
55
|
-
for (let i = 1; i < arr.length; i++) {
|
56
|
-
if (!arr[i]!.isEqual(arr[0]!)) {
|
57
|
-
flag = false
|
58
|
-
break
|
84
|
+
const element = getMatchElementByElement(editor.range.anchor.element, config)
|
85
|
+
if (element) {
|
86
|
+
elements = [element]
|
59
87
|
}
|
88
|
+
return elements
|
60
89
|
}
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
90
|
+
dataRangeCaches.flatList.forEach(item => {
|
91
|
+
const element = getMatchElementByElement(item.element, config)
|
92
|
+
if (element && !elements.some(el => el.isEqual(element))) {
|
93
|
+
elements.push(element)
|
94
|
+
}
|
95
|
+
})
|
96
|
+
return elements
|
66
97
|
}
|
67
98
|
|
68
99
|
/**
|
@@ -132,10 +163,10 @@ export const hasPreInRange = (editor: AlexEditor, dataRangeCaches: AlexElementsR
|
|
132
163
|
return false
|
133
164
|
}
|
134
165
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
135
|
-
return !!
|
166
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'pre' })
|
136
167
|
}
|
137
168
|
return dataRangeCaches.flatList.some(item => {
|
138
|
-
return !!
|
169
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'pre' })
|
139
170
|
})
|
140
171
|
}
|
141
172
|
|
@@ -150,10 +181,10 @@ export const isRangeInPre = (editor: AlexEditor, dataRangeCaches: AlexElementsRa
|
|
150
181
|
return false
|
151
182
|
}
|
152
183
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
153
|
-
return !!
|
184
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'pre' })
|
154
185
|
}
|
155
186
|
return dataRangeCaches.list.every(item => {
|
156
|
-
return !!
|
187
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'pre' })
|
157
188
|
})
|
158
189
|
}
|
159
190
|
|
@@ -168,10 +199,10 @@ export const hasQuoteInRange = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
168
199
|
return false
|
169
200
|
}
|
170
201
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
171
|
-
return !!
|
202
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'blockquote' })
|
172
203
|
}
|
173
204
|
return dataRangeCaches.flatList.some(item => {
|
174
|
-
return !!
|
205
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'blockquote' })
|
175
206
|
})
|
176
207
|
}
|
177
208
|
|
@@ -186,10 +217,10 @@ export const isRangeInQuote = (editor: AlexEditor, dataRangeCaches: AlexElements
|
|
186
217
|
return false
|
187
218
|
}
|
188
219
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
189
|
-
return !!
|
220
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'blockquote' })
|
190
221
|
}
|
191
222
|
return dataRangeCaches.list.every(item => {
|
192
|
-
return !!
|
223
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'blockquote' })
|
193
224
|
})
|
194
225
|
}
|
195
226
|
|
@@ -278,10 +309,10 @@ export const hasLinkInRange = (editor: AlexEditor, dataRangeCaches: AlexElements
|
|
278
309
|
return false
|
279
310
|
}
|
280
311
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
281
|
-
return !!
|
312
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'a' })
|
282
313
|
}
|
283
314
|
return dataRangeCaches.flatList.some(item => {
|
284
|
-
return !!
|
315
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'a' })
|
285
316
|
})
|
286
317
|
}
|
287
318
|
|
@@ -296,10 +327,10 @@ export const hasTableInRange = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
296
327
|
return false
|
297
328
|
}
|
298
329
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
299
|
-
return !!
|
330
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'table' })
|
300
331
|
}
|
301
332
|
return dataRangeCaches.flatList.some(item => {
|
302
|
-
return !!
|
333
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'table' })
|
303
334
|
})
|
304
335
|
}
|
305
336
|
|
@@ -314,10 +345,10 @@ export const hasImageInRange = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
314
345
|
return false
|
315
346
|
}
|
316
347
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
317
|
-
return !!
|
348
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'img' })
|
318
349
|
}
|
319
350
|
return dataRangeCaches.flatList.some(item => {
|
320
|
-
return !!
|
351
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'img' })
|
321
352
|
})
|
322
353
|
}
|
323
354
|
|
@@ -332,10 +363,10 @@ export const hasVideoInRange = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
332
363
|
return false
|
333
364
|
}
|
334
365
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|
335
|
-
return !!
|
366
|
+
return !!getMatchElementByElement(editor.range.anchor.element, { parsedom: 'video' })
|
336
367
|
}
|
337
368
|
return dataRangeCaches.flatList.some(item => {
|
338
|
-
return !!
|
369
|
+
return !!getMatchElementByElement(item.element, { parsedom: 'video' })
|
339
370
|
})
|
340
371
|
}
|
341
372
|
|
@@ -1298,10 +1329,10 @@ export const insertCodeBlock = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
1298
1329
|
if (!editor.range) {
|
1299
1330
|
return
|
1300
1331
|
}
|
1301
|
-
const
|
1302
|
-
if (
|
1332
|
+
const pres = getMatchElementsByRange(editor, dataRangeCaches, { parsedom: 'pre' })
|
1333
|
+
if (pres.length == 1) {
|
1303
1334
|
let content = ''
|
1304
|
-
AlexElement.flatElements(
|
1335
|
+
AlexElement.flatElements(pres[0].children!)
|
1305
1336
|
.filter(item => {
|
1306
1337
|
return item.isText()
|
1307
1338
|
})
|
@@ -1313,9 +1344,9 @@ export const insertCodeBlock = (editor: AlexEditor, dataRangeCaches: AlexElement
|
|
1313
1344
|
const paragraph = new AlexElement('block', AlexElement.BLOCK_NODE, null, null, null)
|
1314
1345
|
const text = new AlexElement('text', null, null, null, item)
|
1315
1346
|
editor.addElementTo(text, paragraph)
|
1316
|
-
editor.addElementBefore(paragraph,
|
1347
|
+
editor.addElementBefore(paragraph, pres[0])
|
1317
1348
|
})
|
1318
|
-
|
1349
|
+
pres[0].toEmpty()
|
1319
1350
|
} else {
|
1320
1351
|
//起点和终点在一起
|
1321
1352
|
if (editor.range.anchor.isEqual(editor.range.focus)) {
|