@kaitify/core 0.0.1-beta.1
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/LICENSE +21 -0
- package/README.md +3 -0
- package/examples/App.vue +342 -0
- package/examples/content.js +1 -0
- package/examples/main.ts +4 -0
- package/examples/test.html +23 -0
- package/lib/extensions/Extension.d.ts +172 -0
- package/lib/extensions/align/index.d.ts +10 -0
- package/lib/extensions/attachment/index.d.ts +29 -0
- package/lib/extensions/back-color/index.d.ts +9 -0
- package/lib/extensions/blockquote/index.d.ts +12 -0
- package/lib/extensions/bold/index.d.ts +9 -0
- package/lib/extensions/code/index.d.ts +12 -0
- package/lib/extensions/code-block/hljs.d.ts +12 -0
- package/lib/extensions/code-block/index.d.ts +15 -0
- package/lib/extensions/color/index.d.ts +9 -0
- package/lib/extensions/font-family/index.d.ts +9 -0
- package/lib/extensions/font-size/index.d.ts +9 -0
- package/lib/extensions/heading/index.d.ts +13 -0
- package/lib/extensions/history/index.d.ts +10 -0
- package/lib/extensions/horizontal/index.d.ts +7 -0
- package/lib/extensions/image/index.d.ts +26 -0
- package/lib/extensions/indent/index.d.ts +8 -0
- package/lib/extensions/index.d.ts +29 -0
- package/lib/extensions/italic/index.d.ts +9 -0
- package/lib/extensions/line-height/index.d.ts +9 -0
- package/lib/extensions/link/index.d.ts +27 -0
- package/lib/extensions/list/index.d.ts +18 -0
- package/lib/extensions/math/index.d.ts +11 -0
- package/lib/extensions/strikethrough/index.d.ts +9 -0
- package/lib/extensions/subscript/index.d.ts +9 -0
- package/lib/extensions/superscript/index.d.ts +9 -0
- package/lib/extensions/table/index.d.ts +21 -0
- package/lib/extensions/task/index.d.ts +12 -0
- package/lib/extensions/text/index.d.ts +14 -0
- package/lib/extensions/underline/index.d.ts +9 -0
- package/lib/extensions/video/index.d.ts +27 -0
- package/lib/index.d.ts +3 -0
- package/lib/kaitify-core.es.js +38337 -0
- package/lib/kaitify-core.umd.js +2 -0
- package/lib/model/Editor.d.ts +504 -0
- package/lib/model/History.d.ts +42 -0
- package/lib/model/KNode.d.ts +258 -0
- package/lib/model/Selection.d.ts +29 -0
- package/lib/model/config/dom-observe.d.ts +10 -0
- package/lib/model/config/event-handler.d.ts +33 -0
- package/lib/model/config/format-patch.d.ts +25 -0
- package/lib/model/config/format-rules.d.ts +37 -0
- package/lib/model/config/function.d.ts +84 -0
- package/lib/model/index.d.ts +6 -0
- package/lib/tools/index.d.ts +49 -0
- package/lib/view/index.d.ts +21 -0
- package/lib/view/js-render/dom-patch.d.ts +65 -0
- package/lib/view/js-render/index.d.ts +5 -0
- package/package.json +52 -0
- package/src/css/style.less +56 -0
- package/src/css/var.less +45 -0
- package/src/extensions/Extension.ts +200 -0
- package/src/extensions/align/index.ts +115 -0
- package/src/extensions/attachment/icon.svg +1 -0
- package/src/extensions/attachment/index.ts +293 -0
- package/src/extensions/attachment/style.less +25 -0
- package/src/extensions/back-color/index.ts +56 -0
- package/src/extensions/blockquote/index.ts +144 -0
- package/src/extensions/blockquote/style.less +16 -0
- package/src/extensions/bold/index.ts +77 -0
- package/src/extensions/code/index.ts +295 -0
- package/src/extensions/code/style.less +14 -0
- package/src/extensions/code-block/hljs.less +183 -0
- package/src/extensions/code-block/hljs.ts +95 -0
- package/src/extensions/code-block/index.ts +308 -0
- package/src/extensions/code-block/style.less +20 -0
- package/src/extensions/color/index.ts +56 -0
- package/src/extensions/font-family/index.ts +80 -0
- package/src/extensions/font-size/index.ts +56 -0
- package/src/extensions/heading/index.ts +164 -0
- package/src/extensions/heading/style.less +42 -0
- package/src/extensions/history/index.ts +96 -0
- package/src/extensions/horizontal/index.ts +45 -0
- package/src/extensions/horizontal/style.less +13 -0
- package/src/extensions/image/index.ts +242 -0
- package/src/extensions/image/style.less +8 -0
- package/src/extensions/indent/index.ts +98 -0
- package/src/extensions/index.ts +29 -0
- package/src/extensions/italic/index.ts +77 -0
- package/src/extensions/line-height/index.ts +113 -0
- package/src/extensions/link/index.ts +184 -0
- package/src/extensions/link/style.less +19 -0
- package/src/extensions/list/index.ts +410 -0
- package/src/extensions/list/style.less +19 -0
- package/src/extensions/math/index.ts +233 -0
- package/src/extensions/math/style.less +21 -0
- package/src/extensions/strikethrough/index.ts +78 -0
- package/src/extensions/subscript/index.ts +77 -0
- package/src/extensions/superscript/index.ts +77 -0
- package/src/extensions/table/index.ts +1148 -0
- package/src/extensions/table/style.less +71 -0
- package/src/extensions/task/index.ts +243 -0
- package/src/extensions/task/style.less +59 -0
- package/src/extensions/text/index.ts +359 -0
- package/src/extensions/underline/index.ts +78 -0
- package/src/extensions/video/index.ts +273 -0
- package/src/extensions/video/style.less +8 -0
- package/src/index.ts +9 -0
- package/src/model/Editor.ts +1963 -0
- package/src/model/History.ts +115 -0
- package/src/model/KNode.ts +677 -0
- package/src/model/Selection.ts +39 -0
- package/src/model/config/dom-observe.ts +184 -0
- package/src/model/config/event-handler.ts +237 -0
- package/src/model/config/format-patch.ts +215 -0
- package/src/model/config/format-rules.ts +218 -0
- package/src/model/config/function.ts +1018 -0
- package/src/model/index.ts +6 -0
- package/src/tools/index.ts +156 -0
- package/src/view/index.ts +46 -0
- package/src/view/js-render/dom-patch.ts +324 -0
- package/src/view/js-render/index.ts +210 -0
- package/vite-env.d.ts +2 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { string as DapString } from 'dap-util'
|
|
2
|
+
import { isZeroWidthText } from '@/tools'
|
|
3
|
+
import { Editor } from '../Editor'
|
|
4
|
+
import { KNode } from '../KNode'
|
|
5
|
+
import { applyMergeNode, convertToBlock, getAllowMergeNode } from './function'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 格式化函数类型
|
|
9
|
+
*/
|
|
10
|
+
export type RuleFunctionType = (state: { editor: Editor; node: KNode }) => void
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 针对节点自身:处理块节点的标签,部分块节点需要转为默认块节点标签
|
|
14
|
+
*/
|
|
15
|
+
export const fomratBlockTagParse: RuleFunctionType = ({ editor, node }) => {
|
|
16
|
+
if (node.isMatch({ tag: 'address' }) || node.isMatch({ tag: 'article' }) || node.isMatch({ tag: 'aside' }) || node.isMatch({ tag: 'nav' }) || node.isMatch({ tag: 'section' })) {
|
|
17
|
+
editor.toParagraph(node)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 针对子节点中的块节点:行内节点的子节点中含有块节点则该节点转为块节点;子节点中的其他节点也转为块节点
|
|
23
|
+
*/
|
|
24
|
+
export const formatBlockInChildren: RuleFunctionType = ({ editor, node }) => {
|
|
25
|
+
//当前节点存在子节点
|
|
26
|
+
if (node.hasChildren() && !node.isEmpty()) {
|
|
27
|
+
//子节点中存在非空的块节点
|
|
28
|
+
const hasBlock = node.children!.some(item => item.isBlock() && !item.isEmpty())
|
|
29
|
+
if (hasBlock) {
|
|
30
|
+
//将子节点中的非空非块节点转为块节点
|
|
31
|
+
node.children!.forEach(item => {
|
|
32
|
+
if (!item.isEmpty() && !item.isBlock()) {
|
|
33
|
+
convertToBlock.apply(editor, [item])
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
if (!node.isBlock()) {
|
|
37
|
+
convertToBlock.apply(editor, [node])
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 针对节点自身:处理不可编辑的非块级节点:在两侧添加零宽度无断空白字符 & 重置不可编辑节点内的光标位置
|
|
45
|
+
*/
|
|
46
|
+
export const formatUneditableNoodes: RuleFunctionType = ({ editor, node }) => {
|
|
47
|
+
const uneditableNode = node.getUneditable()
|
|
48
|
+
if (uneditableNode && !uneditableNode.isEmpty() && !uneditableNode.isBlock()) {
|
|
49
|
+
const previousNode = uneditableNode.getPrevious(uneditableNode.parent ? uneditableNode.parent!.children! : editor.stackNodes)
|
|
50
|
+
const nextNode = node.getNext(uneditableNode.parent ? uneditableNode.parent!.children! : editor.stackNodes)
|
|
51
|
+
//前一个节点不存在或者不是零宽度空白文本节点
|
|
52
|
+
if (!previousNode || !previousNode.isZeroWidthText()) {
|
|
53
|
+
const zeroWidthText = KNode.createZeroWidthText()
|
|
54
|
+
editor.addNodeBefore(zeroWidthText, uneditableNode)
|
|
55
|
+
}
|
|
56
|
+
//后一个节点不存在或者不是零宽度空白文本节点
|
|
57
|
+
if (!nextNode || !nextNode.isZeroWidthText()) {
|
|
58
|
+
const zeroWidthText = KNode.createZeroWidthText()
|
|
59
|
+
editor.addNodeAfter(zeroWidthText, uneditableNode)
|
|
60
|
+
}
|
|
61
|
+
//是用户操作的删除行为,则需要更新光标位置
|
|
62
|
+
if (editor.isUserDelection) {
|
|
63
|
+
//起点和终点都在不可编辑的节点里
|
|
64
|
+
if (editor.isSelectionInNode(uneditableNode, 'all')) {
|
|
65
|
+
const previousSelectionNode = editor.getPreviousSelectionNode(uneditableNode)!
|
|
66
|
+
const nexteSelectionNode = editor.getNextSelectionNode(uneditableNode)!
|
|
67
|
+
//起点和终点在一起
|
|
68
|
+
if (editor.selection.collapsed()) {
|
|
69
|
+
//如果光标在不可编辑节点的最前面,则移动到前一个可设置光标的节点的后面
|
|
70
|
+
const firstNode = editor.getFirstSelectionNodeInChildren(uneditableNode)!
|
|
71
|
+
if (firstNode.isEqual(editor.selection.start!.node) && editor.selection.start!.offset == 0) {
|
|
72
|
+
editor.setSelectionAfter(previousSelectionNode, 'all')
|
|
73
|
+
}
|
|
74
|
+
//否则一律设置到后一个可设置光标的节点的前面
|
|
75
|
+
else {
|
|
76
|
+
editor.setSelectionBefore(nexteSelectionNode, 'all')
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//起点和终点不在一起,则选中该不可编辑的节点
|
|
80
|
+
else {
|
|
81
|
+
editor.setSelectionAfter(previousSelectionNode, 'start')
|
|
82
|
+
editor.setSelectionBefore(nexteSelectionNode, 'end')
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//起点在不可编辑的节点里,则更新起点位置
|
|
86
|
+
else if (editor.isSelectionInNode(uneditableNode, 'start')) {
|
|
87
|
+
const nexteSelectionNode = editor.getNextSelectionNode(uneditableNode)!
|
|
88
|
+
editor.setSelectionBefore(nexteSelectionNode, 'start')
|
|
89
|
+
}
|
|
90
|
+
//终点在不可编辑的节点里,则更新终点位置
|
|
91
|
+
else if (editor.isSelectionInNode(uneditableNode, 'end')) {
|
|
92
|
+
const previousSelectionNode = editor.getPreviousSelectionNode(uneditableNode)!
|
|
93
|
+
editor.setSelectionAfter(previousSelectionNode, 'end')
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 针对节点的子节点数组:处理子节点中的占位符,如果占位符和其他节点共存则删除占位符,如果只存在占位符则将多个占位符合并为一个(光标可能会更新)
|
|
101
|
+
*/
|
|
102
|
+
export const formatPlaceholderMerge: RuleFunctionType = ({ editor, node }) => {
|
|
103
|
+
//当前节点存在子节点
|
|
104
|
+
if (node.hasChildren()) {
|
|
105
|
+
//过滤子节点中的空节点
|
|
106
|
+
const children = node.children!.filter(item => {
|
|
107
|
+
return !item.isEmpty()
|
|
108
|
+
})
|
|
109
|
+
//子节点数组中的占位符节点
|
|
110
|
+
const placeholderNodes = children.filter(item => {
|
|
111
|
+
return item.isPlaceholder()
|
|
112
|
+
})
|
|
113
|
+
//占位符节点在行内节点中则清除
|
|
114
|
+
if (node.isInline() && placeholderNodes.length) {
|
|
115
|
+
placeholderNodes.forEach(item => {
|
|
116
|
+
item.toEmpty()
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
//子节点数量大于1并且都是占位符,则只保留第一个
|
|
120
|
+
else if (children.length > 1 && placeholderNodes.length == children.length) {
|
|
121
|
+
//光标聚焦情况下
|
|
122
|
+
if (editor.selection.focused()) {
|
|
123
|
+
//如果起点在该节点里,则移动到第一个占位符上
|
|
124
|
+
if (node.isContains(editor.selection.start!.node)) {
|
|
125
|
+
editor.setSelectionBefore(placeholderNodes[0], 'start')
|
|
126
|
+
}
|
|
127
|
+
//如果终点在该节点里,则移动到第一个占位符上
|
|
128
|
+
if (node.isContains(editor.selection.end!.node)) {
|
|
129
|
+
editor.setSelectionBefore(placeholderNodes[0], 'end')
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
node.children = [placeholderNodes[0]]
|
|
133
|
+
}
|
|
134
|
+
//子节点数量大于1并且有占位符也有其他节点则把占位符节点都置为空节点
|
|
135
|
+
else if (children.length > 1 && placeholderNodes.length) {
|
|
136
|
+
placeholderNodes.forEach(item => {
|
|
137
|
+
item.toEmpty()
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* 针对节点自身:将文本节点内连续的零宽度无断空白字符合并(光标可能会更新)
|
|
145
|
+
*/
|
|
146
|
+
export const formatZeroWidthTextMerge: RuleFunctionType = ({ editor, node }) => {
|
|
147
|
+
//非空文本节点存在空白字符
|
|
148
|
+
if (node.isText() && !node.isEmpty() && node.textContent!.split('').some(item => isZeroWidthText(item))) {
|
|
149
|
+
let val = node.textContent!
|
|
150
|
+
let i = 0
|
|
151
|
+
while (i < val.length) {
|
|
152
|
+
//获取当前字符串
|
|
153
|
+
const chart = val.charAt(i)
|
|
154
|
+
//如果当前字符是空白字符并且前一个字符也是空白字符
|
|
155
|
+
if (i > 0 && isZeroWidthText(chart) && isZeroWidthText(val.charAt(i - 1))) {
|
|
156
|
+
//如果起点在节点上并且起点在当前这个空白字符上或者后面
|
|
157
|
+
if (editor.isSelectionInNode(node, 'start') && editor.selection.start!.offset >= i + 1) {
|
|
158
|
+
editor.selection.start!.offset -= 1
|
|
159
|
+
}
|
|
160
|
+
//如果终点在节点上并且终点在当前这个空白字符上或者后面
|
|
161
|
+
if (editor.isSelectionInNode(node, 'end') && editor.selection.end!.offset >= i + 1) {
|
|
162
|
+
editor.selection.end!.offset -= 1
|
|
163
|
+
}
|
|
164
|
+
//删除空白字符
|
|
165
|
+
val = DapString.delete(val, i, 1)
|
|
166
|
+
//跳过后续
|
|
167
|
+
continue
|
|
168
|
+
}
|
|
169
|
+
i++
|
|
170
|
+
}
|
|
171
|
+
node.textContent = val
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* 针对节点的子节点数组:兄弟节点合并策略(光标可能会更新)
|
|
177
|
+
*/
|
|
178
|
+
export const formatSiblingNodesMerge: RuleFunctionType = ({ editor, node }) => {
|
|
179
|
+
//有子节点并且子节点数大于1
|
|
180
|
+
if ((node.isBlock() || node.isInline()) && node.hasChildren() && node.children!.length > 1) {
|
|
181
|
+
let index = 0
|
|
182
|
+
//因为父子节点的合并操作会导致children没有,此时判断一下hasChildren
|
|
183
|
+
while (node.hasChildren() && index <= node.children!.length - 2) {
|
|
184
|
+
const newTargetNode = getAllowMergeNode.apply(editor, [node.children![index], 'nextSibling'])
|
|
185
|
+
if (newTargetNode) {
|
|
186
|
+
//兄弟节点合并
|
|
187
|
+
applyMergeNode.apply(editor, [node.children![index], 'nextSibling'])
|
|
188
|
+
//合并完成后执行合并空白文本
|
|
189
|
+
formatZeroWidthTextMerge({ editor, node: node.children![index] })
|
|
190
|
+
//子节点合并后可能只有一个子节点了,此时进行父子节点合并操作
|
|
191
|
+
if (node.hasChildren() && node.children!.length == 1) {
|
|
192
|
+
applyMergeNode.apply(editor, [node.children![0], 'parent'])
|
|
193
|
+
}
|
|
194
|
+
continue
|
|
195
|
+
}
|
|
196
|
+
index++
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* 针对节点的子节点数组:父子节点合并策略(光标可能会更新)
|
|
203
|
+
*/
|
|
204
|
+
export const formatParentNodeMerge: RuleFunctionType = ({ editor, node }) => {
|
|
205
|
+
//只有一个子节点
|
|
206
|
+
if ((node.isBlock() || node.isInline()) && node.hasChildren() && node.children!.length == 1) {
|
|
207
|
+
//父子节点进行合并
|
|
208
|
+
if (getAllowMergeNode.apply(editor, [node.children![0], 'parent'])) {
|
|
209
|
+
applyMergeNode.apply(editor, [node.children![0], 'parent'])
|
|
210
|
+
//父子节点合并后,可能父节点需要再和兄弟节点进行合并
|
|
211
|
+
if (getAllowMergeNode.apply(editor, [node, 'prevSibling'])) {
|
|
212
|
+
applyMergeNode.apply(editor, [node, 'prevSibling'])
|
|
213
|
+
} else if (getAllowMergeNode.apply(editor, [node, 'nextSibling'])) {
|
|
214
|
+
applyMergeNode.apply(editor, [node, 'nextSibling'])
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|