@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.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/examples/App.vue +342 -0
  4. package/examples/content.js +1 -0
  5. package/examples/main.ts +4 -0
  6. package/examples/test.html +23 -0
  7. package/lib/extensions/Extension.d.ts +172 -0
  8. package/lib/extensions/align/index.d.ts +10 -0
  9. package/lib/extensions/attachment/index.d.ts +29 -0
  10. package/lib/extensions/back-color/index.d.ts +9 -0
  11. package/lib/extensions/blockquote/index.d.ts +12 -0
  12. package/lib/extensions/bold/index.d.ts +9 -0
  13. package/lib/extensions/code/index.d.ts +12 -0
  14. package/lib/extensions/code-block/hljs.d.ts +12 -0
  15. package/lib/extensions/code-block/index.d.ts +15 -0
  16. package/lib/extensions/color/index.d.ts +9 -0
  17. package/lib/extensions/font-family/index.d.ts +9 -0
  18. package/lib/extensions/font-size/index.d.ts +9 -0
  19. package/lib/extensions/heading/index.d.ts +13 -0
  20. package/lib/extensions/history/index.d.ts +10 -0
  21. package/lib/extensions/horizontal/index.d.ts +7 -0
  22. package/lib/extensions/image/index.d.ts +26 -0
  23. package/lib/extensions/indent/index.d.ts +8 -0
  24. package/lib/extensions/index.d.ts +29 -0
  25. package/lib/extensions/italic/index.d.ts +9 -0
  26. package/lib/extensions/line-height/index.d.ts +9 -0
  27. package/lib/extensions/link/index.d.ts +27 -0
  28. package/lib/extensions/list/index.d.ts +18 -0
  29. package/lib/extensions/math/index.d.ts +11 -0
  30. package/lib/extensions/strikethrough/index.d.ts +9 -0
  31. package/lib/extensions/subscript/index.d.ts +9 -0
  32. package/lib/extensions/superscript/index.d.ts +9 -0
  33. package/lib/extensions/table/index.d.ts +21 -0
  34. package/lib/extensions/task/index.d.ts +12 -0
  35. package/lib/extensions/text/index.d.ts +14 -0
  36. package/lib/extensions/underline/index.d.ts +9 -0
  37. package/lib/extensions/video/index.d.ts +27 -0
  38. package/lib/index.d.ts +3 -0
  39. package/lib/kaitify-core.es.js +38337 -0
  40. package/lib/kaitify-core.umd.js +2 -0
  41. package/lib/model/Editor.d.ts +504 -0
  42. package/lib/model/History.d.ts +42 -0
  43. package/lib/model/KNode.d.ts +258 -0
  44. package/lib/model/Selection.d.ts +29 -0
  45. package/lib/model/config/dom-observe.d.ts +10 -0
  46. package/lib/model/config/event-handler.d.ts +33 -0
  47. package/lib/model/config/format-patch.d.ts +25 -0
  48. package/lib/model/config/format-rules.d.ts +37 -0
  49. package/lib/model/config/function.d.ts +84 -0
  50. package/lib/model/index.d.ts +6 -0
  51. package/lib/tools/index.d.ts +49 -0
  52. package/lib/view/index.d.ts +21 -0
  53. package/lib/view/js-render/dom-patch.d.ts +65 -0
  54. package/lib/view/js-render/index.d.ts +5 -0
  55. package/package.json +52 -0
  56. package/src/css/style.less +56 -0
  57. package/src/css/var.less +45 -0
  58. package/src/extensions/Extension.ts +200 -0
  59. package/src/extensions/align/index.ts +115 -0
  60. package/src/extensions/attachment/icon.svg +1 -0
  61. package/src/extensions/attachment/index.ts +293 -0
  62. package/src/extensions/attachment/style.less +25 -0
  63. package/src/extensions/back-color/index.ts +56 -0
  64. package/src/extensions/blockquote/index.ts +144 -0
  65. package/src/extensions/blockquote/style.less +16 -0
  66. package/src/extensions/bold/index.ts +77 -0
  67. package/src/extensions/code/index.ts +295 -0
  68. package/src/extensions/code/style.less +14 -0
  69. package/src/extensions/code-block/hljs.less +183 -0
  70. package/src/extensions/code-block/hljs.ts +95 -0
  71. package/src/extensions/code-block/index.ts +308 -0
  72. package/src/extensions/code-block/style.less +20 -0
  73. package/src/extensions/color/index.ts +56 -0
  74. package/src/extensions/font-family/index.ts +80 -0
  75. package/src/extensions/font-size/index.ts +56 -0
  76. package/src/extensions/heading/index.ts +164 -0
  77. package/src/extensions/heading/style.less +42 -0
  78. package/src/extensions/history/index.ts +96 -0
  79. package/src/extensions/horizontal/index.ts +45 -0
  80. package/src/extensions/horizontal/style.less +13 -0
  81. package/src/extensions/image/index.ts +242 -0
  82. package/src/extensions/image/style.less +8 -0
  83. package/src/extensions/indent/index.ts +98 -0
  84. package/src/extensions/index.ts +29 -0
  85. package/src/extensions/italic/index.ts +77 -0
  86. package/src/extensions/line-height/index.ts +113 -0
  87. package/src/extensions/link/index.ts +184 -0
  88. package/src/extensions/link/style.less +19 -0
  89. package/src/extensions/list/index.ts +410 -0
  90. package/src/extensions/list/style.less +19 -0
  91. package/src/extensions/math/index.ts +233 -0
  92. package/src/extensions/math/style.less +21 -0
  93. package/src/extensions/strikethrough/index.ts +78 -0
  94. package/src/extensions/subscript/index.ts +77 -0
  95. package/src/extensions/superscript/index.ts +77 -0
  96. package/src/extensions/table/index.ts +1148 -0
  97. package/src/extensions/table/style.less +71 -0
  98. package/src/extensions/task/index.ts +243 -0
  99. package/src/extensions/task/style.less +59 -0
  100. package/src/extensions/text/index.ts +359 -0
  101. package/src/extensions/underline/index.ts +78 -0
  102. package/src/extensions/video/index.ts +273 -0
  103. package/src/extensions/video/style.less +8 -0
  104. package/src/index.ts +9 -0
  105. package/src/model/Editor.ts +1963 -0
  106. package/src/model/History.ts +115 -0
  107. package/src/model/KNode.ts +677 -0
  108. package/src/model/Selection.ts +39 -0
  109. package/src/model/config/dom-observe.ts +184 -0
  110. package/src/model/config/event-handler.ts +237 -0
  111. package/src/model/config/format-patch.ts +215 -0
  112. package/src/model/config/format-rules.ts +218 -0
  113. package/src/model/config/function.ts +1018 -0
  114. package/src/model/index.ts +6 -0
  115. package/src/tools/index.ts +156 -0
  116. package/src/view/index.ts +46 -0
  117. package/src/view/js-render/dom-patch.ts +324 -0
  118. package/src/view/js-render/index.ts +210 -0
  119. package/vite-env.d.ts +2 -0
@@ -0,0 +1,113 @@
1
+ import { KNode, KNodeStylesType } from '@/model'
2
+ import { getSelectionBlockNodes } from '@/model/config/function'
3
+ import { deleteProperty } from '@/tools'
4
+ import { Extension } from '../Extension'
5
+
6
+ declare module '../../model' {
7
+ interface EditorCommandsType {
8
+ isLineHeight?: (value: string | number) => boolean
9
+ setLineHeight?: (value: string | number) => Promise<void>
10
+ unsetLineHeight?: (value: string | number) => Promise<void>
11
+ }
12
+ }
13
+
14
+ /**
15
+ * 删除指定块节点及以上块节点的行高样式
16
+ */
17
+ const clearLineHeight = (blockNode: KNode, value: string | number) => {
18
+ const matchNode = blockNode.getMatchNode({ styles: { lineHeight: value } })
19
+ if (matchNode) {
20
+ matchNode.styles = deleteProperty(matchNode.styles!, 'lineHeight')
21
+ clearLineHeight(matchNode, value)
22
+ }
23
+ }
24
+
25
+ export const LineHeightExtension = () =>
26
+ Extension.create({
27
+ name: 'lineHeight',
28
+ pasteKeepStyles(node) {
29
+ const styles: KNodeStylesType = {}
30
+ if (node.isBlock() && node.hasStyles()) {
31
+ if (node.styles!.hasOwnProperty('lineHeight')) styles.lineHeight = node.styles!.lineHeight
32
+ }
33
+ return styles
34
+ },
35
+ addCommands() {
36
+ /**
37
+ * 光标所在的块节点是否都是符合的行高
38
+ */
39
+ const isLineHeight = (value: string | number) => {
40
+ if (!this.selection.focused()) {
41
+ return false
42
+ }
43
+ //起点和终点在一起
44
+ if (this.selection.collapsed()) {
45
+ const block = this.selection.start!.node.getBlock()
46
+ return !!block.getMatchNode({ styles: { lineHeight: value } })
47
+ }
48
+ //起点和终点不在一起
49
+ const blockNodes = getSelectionBlockNodes.apply(this)
50
+ return blockNodes.every(item => {
51
+ return !!item.getMatchNode({ styles: { lineHeight: value } })
52
+ })
53
+ }
54
+
55
+ /**
56
+ * 设置行高
57
+ */
58
+ const setLineHeight = async (value: string | number) => {
59
+ if (isLineHeight(value)) {
60
+ return
61
+ }
62
+ //起点和终点在一起
63
+ if (this.selection.collapsed()) {
64
+ const blockNode = this.selection.start!.node.getBlock()
65
+ const styles: KNodeStylesType = blockNode.hasStyles() ? blockNode.styles! : {}
66
+ blockNode.styles = {
67
+ ...styles,
68
+ lineHeight: value
69
+ }
70
+ }
71
+ //起点和终点不在一起
72
+ else {
73
+ const blockNodes = getSelectionBlockNodes.apply(this)
74
+ blockNodes.forEach(item => {
75
+ const styles: KNodeStylesType = item.hasStyles() ? item.styles! : {}
76
+ item.styles = {
77
+ ...styles,
78
+ lineHeight: value
79
+ }
80
+ })
81
+ }
82
+ await this.updateView()
83
+ }
84
+
85
+ /**
86
+ * 取消行高
87
+ */
88
+ const unsetLineHeight = async (value: string | number) => {
89
+ if (!isLineHeight(value)) {
90
+ return
91
+ }
92
+ //起点和终点在一起
93
+ if (this.selection.collapsed()) {
94
+ const blockNode = this.selection.start!.node.getBlock()
95
+ clearLineHeight(blockNode, value)
96
+ }
97
+ //起点和终点不在一起
98
+ else {
99
+ const blockNodes = getSelectionBlockNodes.apply(this)
100
+ blockNodes.forEach(item => {
101
+ clearLineHeight(item, value)
102
+ })
103
+ }
104
+ await this.updateView()
105
+ }
106
+
107
+ return {
108
+ isLineHeight,
109
+ setLineHeight,
110
+ unsetLineHeight
111
+ }
112
+ }
113
+ })
@@ -0,0 +1,184 @@
1
+ import { KNode, KNodeMarksType } from '@/model'
2
+ import { splitNodeToNodes } from '@/model/config/function'
3
+ import { Extension } from '../Extension'
4
+ import './style.less'
5
+ import { deleteProperty } from '@/tools'
6
+
7
+ /**
8
+ * 插入链接方法入参类型
9
+ */
10
+ export type SetLinkOptionType = {
11
+ href: string
12
+ text?: string
13
+ newOpen?: boolean
14
+ }
15
+
16
+ /**
17
+ * 更新链接方法入参类型
18
+ */
19
+ export type UpdateLinkOptionType = {
20
+ href?: string
21
+ newOpen?: boolean
22
+ }
23
+
24
+ declare module '../../model' {
25
+ interface EditorCommandsType {
26
+ getLink?: () => KNode | null
27
+ hasLink?: () => boolean
28
+ setLink?: (options: SetLinkOptionType) => Promise<void>
29
+ updateLink?: (options: UpdateLinkOptionType) => Promise<void>
30
+ unsetLink?: () => Promise<void>
31
+ }
32
+ }
33
+
34
+ export const LinkExtension = () =>
35
+ Extension.create({
36
+ name: 'link',
37
+ extraKeepTags: ['a'],
38
+ domParseNodeCallback(node) {
39
+ if (node.isMatch({ tag: 'a' })) {
40
+ node.type = 'inline'
41
+ }
42
+ return node
43
+ },
44
+ pasteKeepMarks(node) {
45
+ const marks: KNodeMarksType = {}
46
+ if (node.isMatch({ tag: 'a' }) && node.hasMarks()) {
47
+ if (node.marks!.hasOwnProperty('href')) marks['href'] = node.marks!['href']
48
+ if (node.marks!.hasOwnProperty('target')) marks['target'] = node.marks!['target']
49
+ }
50
+ return marks
51
+ },
52
+ formatRules: [
53
+ ({ editor, node }) => {
54
+ //链接只能是行内节点且只能有文本节点和闭合节点
55
+ if (node.isMatch({ tag: 'a' }) && node.hasChildren()) {
56
+ node.type = 'inline'
57
+ node.children!.forEach(item => {
58
+ splitNodeToNodes.apply(editor, [item])
59
+ })
60
+ }
61
+ }
62
+ ],
63
+ addCommands() {
64
+ /**
65
+ * 获取光标所在的链接,如果光标不在一个链接内,返回null
66
+ */
67
+ const getLink = () => {
68
+ return this.getMatchNodeBySelection({ tag: 'a' })
69
+ }
70
+
71
+ /**
72
+ * 判断光标范围内是否有链接
73
+ */
74
+ const hasLink = () => {
75
+ return this.isSelectionNodesSomeMatch({
76
+ tag: 'a'
77
+ })
78
+ }
79
+
80
+ /**
81
+ * 设置连接
82
+ */
83
+ const setLink = async (options: SetLinkOptionType) => {
84
+ if (!this.selection.focused() || hasLink()) {
85
+ return
86
+ }
87
+ if (!options.href) {
88
+ return
89
+ }
90
+ //起点和终点在一起
91
+ if (this.selection.collapsed()) {
92
+ if (!options.text) {
93
+ return
94
+ }
95
+ const marks: KNodeMarksType = {
96
+ href: options.href
97
+ }
98
+ if (options.newOpen) {
99
+ marks.target = '_blank'
100
+ }
101
+ const linkNode = KNode.create({
102
+ type: 'inline',
103
+ tag: 'a',
104
+ marks,
105
+ children: [
106
+ {
107
+ type: 'text',
108
+ textContent: options.text
109
+ }
110
+ ]
111
+ })
112
+ this.insertNode(linkNode)
113
+ }
114
+ //起点和终点不在一起
115
+ else {
116
+ const marks: KNodeMarksType = {
117
+ href: options.href
118
+ }
119
+ if (options.newOpen) {
120
+ marks.target = '_blank'
121
+ }
122
+ const linkNode = KNode.create({
123
+ type: 'inline',
124
+ tag: 'a',
125
+ marks,
126
+ children: []
127
+ })
128
+ this.getFocusSplitNodesBySelection('all').forEach((item, index) => {
129
+ const newNode = item.clone(true)
130
+ this.addNode(newNode, linkNode, index)
131
+ })
132
+ this.insertNode(linkNode)
133
+ }
134
+ await this.updateView()
135
+ }
136
+
137
+ /**
138
+ * 更新链接
139
+ */
140
+ const updateLink = async (options: UpdateLinkOptionType) => {
141
+ if (!this.selection.focused()) {
142
+ return
143
+ }
144
+ if (!options.href && typeof options.newOpen != 'boolean') {
145
+ return
146
+ }
147
+ const linkNode = getLink()
148
+ if (!linkNode) {
149
+ return
150
+ }
151
+ if (options.href) {
152
+ linkNode.marks!.href = options.href
153
+ }
154
+ if (typeof options.newOpen == 'boolean') {
155
+ if (options.newOpen) {
156
+ linkNode.marks!.target = '_blank'
157
+ } else {
158
+ linkNode.marks = deleteProperty(linkNode.marks!, 'target')
159
+ }
160
+ }
161
+ await this.updateView()
162
+ }
163
+
164
+ /**
165
+ * 取消链接
166
+ */
167
+ const unsetLink = async () => {
168
+ if (!this.selection.focused()) {
169
+ return
170
+ }
171
+ const linkNode = getLink()
172
+ if (!linkNode) {
173
+ return
174
+ }
175
+ linkNode.children!.forEach(item => {
176
+ this.addNodeBefore(item, linkNode)
177
+ })
178
+ linkNode.children = []
179
+ await this.updateView()
180
+ }
181
+
182
+ return { getLink, hasLink, setLink, updateLink, unsetLink }
183
+ }
184
+ })
@@ -0,0 +1,19 @@
1
+ .Kaitify {
2
+ a {
3
+ color: #06c27c;
4
+ text-decoration: none;
5
+
6
+ &:hover {
7
+ text-decoration: underline;
8
+ }
9
+ }
10
+
11
+ //非编辑状态下
12
+ &:not([contenteditable='true']) {
13
+ a {
14
+ &:hover {
15
+ cursor: pointer;
16
+ }
17
+ }
18
+ }
19
+ }