@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,71 @@
1
+ .Kaitify {
2
+ table {
3
+ display: table;
4
+ width: 100%;
5
+ border: 1px solid var(--kaitify-border-color);
6
+ border-collapse: collapse;
7
+ margin: 0 0 var(--kaitify-large-margin) 0;
8
+
9
+ td {
10
+ border: 1px solid var(--kaitify-border-color);
11
+ padding: var(--kaitify-padding);
12
+ vertical-align: middle;
13
+ max-width: 100%;
14
+ min-width: 50px;
15
+ }
16
+
17
+ tr:first-child {
18
+ background: #f1f2f3;
19
+
20
+ td {
21
+ font-weight: bold;
22
+ }
23
+ }
24
+
25
+ tr:nth-child(2n + 3) {
26
+ background: fade(#f1f2f3, 20);
27
+ }
28
+ }
29
+
30
+ //非编辑状态下
31
+ &:not([contenteditable='true']) {
32
+ table {
33
+ tr:not(:first-child) {
34
+ transition: background 300ms;
35
+
36
+ &:hover {
37
+ background: fade(#f1f2f3, 50);
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ :root[kaitify-dark] .Kaitify {
45
+ table {
46
+ tr:first-child {
47
+ background: #2a2a2a;
48
+
49
+ td {
50
+ font-weight: bold;
51
+ }
52
+ }
53
+
54
+ tr:nth-child(2n + 3) {
55
+ background: fade(#2a2a2a, 20);
56
+ }
57
+ }
58
+
59
+ //非编辑状态下
60
+ &:not([contenteditable='true']) {
61
+ table {
62
+ tr:not(:first-child) {
63
+ transition: background 300ms;
64
+
65
+ &:hover {
66
+ background: fade(#2a2a2a, 50);
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,243 @@
1
+ import { event as DapEvent, element as DapElement } from 'dap-util'
2
+ import { Editor, KNode, KNodeMarksType } from '@/model'
3
+ import { getSelectionBlockNodes } from '@/model/config/function'
4
+ import { Extension } from '../Extension'
5
+ import './style.less'
6
+
7
+ declare module '../../model' {
8
+ interface EditorCommandsType {
9
+ getTask?: () => KNode | null
10
+ hasTask?: () => boolean
11
+ allTask?: () => boolean
12
+ setTask?: () => Promise<void>
13
+ unsetTask?: () => Promise<void>
14
+ }
15
+ }
16
+
17
+ /**
18
+ * 块节点转为待办
19
+ */
20
+ const toTask = (editor: Editor, node: KNode) => {
21
+ if (!node.isBlock()) {
22
+ return
23
+ }
24
+ //是固定的块节点或者内嵌套的块节点
25
+ if (node.fixed || node.nested) {
26
+ //创建待办节点
27
+ const taskNode = KNode.create({
28
+ type: 'block',
29
+ tag: 'div',
30
+ marks: {
31
+ 'kaitify-task': 'undo'
32
+ },
33
+ children: []
34
+ })
35
+ //将块节点的子节点给待办节点
36
+ node.children!.forEach((item, index) => {
37
+ editor.addNode(item, taskNode, index)
38
+ })
39
+ //清空原来的块节点
40
+ node.children = []
41
+ //将待办节点添加到块节点下
42
+ taskNode.parent = node
43
+ node.children = [taskNode]
44
+ }
45
+ //非固定块节点
46
+ else {
47
+ editor.toParagraph(node)
48
+ node.tag = 'div'
49
+ node.marks = {
50
+ 'kaitify-task': 'undo'
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * 编辑器点击切换待办状态
57
+ */
58
+ const toggleTaskStatus = function (editor: Editor) {
59
+ DapEvent.off(editor.$el!, `click.task`)
60
+ DapEvent.on(editor.$el!, `click.task`, e => {
61
+ //不可编辑状态下无法切换
62
+ if (!editor.isEditable()) {
63
+ return
64
+ }
65
+ const event = e as MouseEvent
66
+ const elm = event.target as HTMLElement
67
+ if (elm === editor.$el) {
68
+ return
69
+ }
70
+ const node = editor.findNode(elm)
71
+ const matchNode = node.getMatchNode({
72
+ tag: 'div',
73
+ marks: {
74
+ 'kaitify-task': true
75
+ }
76
+ })
77
+ //点击的元素是待办
78
+ if (matchNode) {
79
+ const dom = editor.findDom(matchNode)
80
+ const rect = DapElement.getElementBounding(dom)
81
+ //在复选框范围内
82
+ if (event.clientX >= Math.abs(rect.left) && event.clientX <= Math.abs(rect.left + 16) && event.clientY >= Math.abs(rect.top + elm.offsetHeight / 2 - 8) && event.clientY <= Math.abs(rect.top + elm.offsetHeight / 2 + 8)) {
83
+ if (matchNode.marks!['kaitify-task'] == 'undo') {
84
+ matchNode.marks!['kaitify-task'] = 'done'
85
+ } else {
86
+ matchNode.marks!['kaitify-task'] = 'undo'
87
+ }
88
+ editor.setSelectionAfter(matchNode, 'all')
89
+ editor.updateView()
90
+ }
91
+ }
92
+ })
93
+ }
94
+
95
+ export const TaskExtension = () =>
96
+ Extension.create({
97
+ name: 'task',
98
+ pasteKeepMarks(node) {
99
+ const marks: KNodeMarksType = {}
100
+ if (
101
+ node.isMatch({
102
+ tag: 'div',
103
+ marks: {
104
+ 'kaitify-task': true
105
+ }
106
+ })
107
+ ) {
108
+ marks['kaitify-task'] = node.marks!['kaitify-task']
109
+ }
110
+ return marks
111
+ },
112
+ afterUpdateView() {
113
+ //切换待办状态
114
+ toggleTaskStatus(this)
115
+ },
116
+ onInsertParagraph(node) {
117
+ if (
118
+ node.isMatch({
119
+ tag: 'div',
120
+ marks: {
121
+ 'kaitify-task': true
122
+ }
123
+ })
124
+ ) {
125
+ node.marks!['kaitify-task'] = 'undo'
126
+ }
127
+ },
128
+ formatRules: [
129
+ //待办列表必须是块节点
130
+ ({ node }) => {
131
+ if (
132
+ node.isMatch({
133
+ tag: 'div',
134
+ marks: {
135
+ 'kaitify-task': true
136
+ }
137
+ })
138
+ ) {
139
+ node.type = 'block'
140
+ }
141
+ }
142
+ ],
143
+ addCommands() {
144
+ /**
145
+ * 获取光标所在的待办节点,如果光标不在一个待办节点内,返回null
146
+ */
147
+ const getTask = () => {
148
+ return this.getMatchNodeBySelection({
149
+ tag: 'div',
150
+ marks: {
151
+ 'kaitify-task': true
152
+ }
153
+ })
154
+ }
155
+
156
+ /**
157
+ * 判断光标范围内是否有待办节点
158
+ */
159
+ const hasTask = () => {
160
+ return this.isSelectionNodesSomeMatch({
161
+ tag: 'div',
162
+ marks: {
163
+ 'kaitify-task': true
164
+ }
165
+ })
166
+ }
167
+
168
+ /**
169
+ * 光标范围内是否都是待办节点
170
+ */
171
+ const allTask = () => {
172
+ return this.isSelectionNodesAllMatch({
173
+ tag: 'div',
174
+ marks: {
175
+ 'kaitify-task': true
176
+ }
177
+ })
178
+ }
179
+
180
+ /**
181
+ * 设置待办
182
+ */
183
+ const setTask = async () => {
184
+ if (allTask()) {
185
+ return
186
+ }
187
+ //起点和终点在一起
188
+ if (this.selection.collapsed()) {
189
+ const blockNode = this.selection.start!.node.getBlock()
190
+ toTask(this, blockNode)
191
+ }
192
+ //起点和终点不在一起
193
+ else {
194
+ const blockNodes = getSelectionBlockNodes.apply(this)
195
+ blockNodes.forEach(item => {
196
+ toTask(this, item)
197
+ })
198
+ }
199
+ await this.updateView()
200
+ }
201
+
202
+ /**
203
+ * 取消待办
204
+ */
205
+ const unsetTask = async () => {
206
+ if (!allTask()) {
207
+ return
208
+ }
209
+ //起点和终点在一起
210
+ if (this.selection.collapsed()) {
211
+ const matchNode = this.selection.start!.node.getMatchNode({
212
+ tag: 'div',
213
+ marks: {
214
+ 'kaitify-task': true
215
+ }
216
+ })
217
+ if (matchNode) this.toParagraph(matchNode)
218
+ }
219
+ //起点和终点不在一起
220
+ else {
221
+ const blockNodes = getSelectionBlockNodes.apply(this)
222
+ blockNodes.forEach(item => {
223
+ const matchNode = item.getMatchNode({
224
+ tag: 'div',
225
+ marks: {
226
+ 'kaitify-task': true
227
+ }
228
+ })
229
+ if (matchNode) this.toParagraph(matchNode)
230
+ })
231
+ }
232
+ await this.updateView()
233
+ }
234
+
235
+ return {
236
+ getTask,
237
+ hasTask,
238
+ allTask,
239
+ setTask,
240
+ unsetTask
241
+ }
242
+ }
243
+ })
@@ -0,0 +1,59 @@
1
+ .Kaitify {
2
+ div[kaitify-task] {
3
+ display: block;
4
+ position: relative;
5
+ margin: 0 0 var(--kaitify-large-margin) 0;
6
+ padding: 0 0 0 26px;
7
+ width: 100%;
8
+
9
+ &:last-child {
10
+ margin-bottom: 0 !important;
11
+ }
12
+
13
+ &::before {
14
+ position: absolute;
15
+ left: 0;
16
+ top: 50%;
17
+ transform: translateY(-50%);
18
+ content: '';
19
+ width: 16px;
20
+ height: 16px;
21
+ border: 1px solid var(--kaitify-theme);
22
+ border-radius: var(--kaitify-border-radius);
23
+ user-select: none;
24
+ touch-action: none;
25
+ }
26
+
27
+ &[kaitify-task='done'] {
28
+ text-decoration: line-through;
29
+
30
+ &::before {
31
+ background: var(--kaitify-theme);
32
+ }
33
+
34
+ &::after {
35
+ content: '';
36
+ position: absolute;
37
+ left: 2px;
38
+ top: 50%;
39
+ width: 5px;
40
+ height: 10px;
41
+ margin-top: -2.5px;
42
+ border: solid var(--kaitify-theme);
43
+ border-width: 0 2px 2px 0;
44
+ transform: rotate(45deg) translateY(-50%);
45
+ border-color: #fff;
46
+ user-select: none;
47
+ touch-action: none;
48
+ }
49
+ }
50
+ }
51
+
52
+ &[contenteditable='true'] {
53
+ div[kaitify-task] {
54
+ &::before {
55
+ cursor: pointer;
56
+ }
57
+ }
58
+ }
59
+ }