@tiptap/core 2.2.0-rc.8 → 2.2.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/dist/index.cjs +60 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +60 -17
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +60 -17
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/core/src/NodePos.d.ts +5 -1
- package/package.json +2 -2
- package/src/NodePos.ts +56 -15
- package/src/helpers/getMarksBetween.ts +1 -1
- package/src/utilities/elementFromString.ts +19 -1
|
@@ -3,10 +3,14 @@ import { Editor } from './Editor.js';
|
|
|
3
3
|
import { Content, Range } from './types.js';
|
|
4
4
|
export declare class NodePos {
|
|
5
5
|
private resolvedPos;
|
|
6
|
+
private isBlock;
|
|
6
7
|
private editor;
|
|
7
|
-
|
|
8
|
+
private get name();
|
|
9
|
+
constructor(pos: ResolvedPos, editor: Editor, isBlock?: boolean, node?: Node | null);
|
|
10
|
+
private currentNode;
|
|
8
11
|
get node(): Node;
|
|
9
12
|
get element(): HTMLElement;
|
|
13
|
+
actualDepth: number | null;
|
|
10
14
|
get depth(): number;
|
|
11
15
|
get pos(): number;
|
|
12
16
|
get content(): Fragment;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/core",
|
|
3
3
|
"description": "headless rich text editor",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dist"
|
|
33
33
|
],
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@tiptap/pm": "^2.2.
|
|
35
|
+
"@tiptap/pm": "^2.2.1"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@tiptap/pm": "^2.0.0"
|
package/src/NodePos.ts
CHANGED
|
@@ -8,23 +8,35 @@ import { Content, Range } from './types.js'
|
|
|
8
8
|
export class NodePos {
|
|
9
9
|
private resolvedPos: ResolvedPos
|
|
10
10
|
|
|
11
|
+
private isBlock: boolean
|
|
12
|
+
|
|
11
13
|
private editor: Editor
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
private get name(): string {
|
|
16
|
+
return this.node.type.name
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
constructor(pos: ResolvedPos, editor: Editor, isBlock = false, node: Node | null = null) {
|
|
20
|
+
this.isBlock = isBlock
|
|
14
21
|
this.resolvedPos = pos
|
|
15
22
|
this.editor = editor
|
|
23
|
+
this.currentNode = node
|
|
16
24
|
}
|
|
17
25
|
|
|
26
|
+
private currentNode: Node | null = null
|
|
27
|
+
|
|
18
28
|
get node(): Node {
|
|
19
|
-
return this.resolvedPos.node()
|
|
29
|
+
return this.currentNode || this.resolvedPos.node()
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
get element(): HTMLElement {
|
|
23
33
|
return this.editor.view.domAtPos(this.pos).node as HTMLElement
|
|
24
34
|
}
|
|
25
35
|
|
|
36
|
+
public actualDepth: number | null = null
|
|
37
|
+
|
|
26
38
|
get depth(): number {
|
|
27
|
-
return this.resolvedPos.depth
|
|
39
|
+
return this.actualDepth ?? this.resolvedPos.depth
|
|
28
40
|
}
|
|
29
41
|
|
|
30
42
|
get pos(): number {
|
|
@@ -36,7 +48,20 @@ export class NodePos {
|
|
|
36
48
|
}
|
|
37
49
|
|
|
38
50
|
set content(content: Content) {
|
|
39
|
-
|
|
51
|
+
let from = this.from
|
|
52
|
+
let to = this.to
|
|
53
|
+
|
|
54
|
+
if (this.isBlock) {
|
|
55
|
+
if (this.content.size === 0) {
|
|
56
|
+
console.error(`You can’t set content on a block node. Tried to set content on ${this.name} at ${this.pos}`)
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
from = this.from + 1
|
|
61
|
+
to = this.to - 1
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.editor.commands.insertContentAt({ from, to }, content)
|
|
40
65
|
}
|
|
41
66
|
|
|
42
67
|
get attributes() : { [key: string]: any } {
|
|
@@ -52,6 +77,10 @@ export class NodePos {
|
|
|
52
77
|
}
|
|
53
78
|
|
|
54
79
|
get from(): number {
|
|
80
|
+
if (this.isBlock) {
|
|
81
|
+
return this.pos
|
|
82
|
+
}
|
|
83
|
+
|
|
55
84
|
return this.resolvedPos.start(this.resolvedPos.depth)
|
|
56
85
|
}
|
|
57
86
|
|
|
@@ -63,6 +92,10 @@ export class NodePos {
|
|
|
63
92
|
}
|
|
64
93
|
|
|
65
94
|
get to(): number {
|
|
95
|
+
if (this.isBlock) {
|
|
96
|
+
return this.pos + this.size
|
|
97
|
+
}
|
|
98
|
+
|
|
66
99
|
return this.resolvedPos.end(this.resolvedPos.depth) + (this.node.isText ? 0 : 1)
|
|
67
100
|
}
|
|
68
101
|
|
|
@@ -78,7 +111,7 @@ export class NodePos {
|
|
|
78
111
|
}
|
|
79
112
|
|
|
80
113
|
get before(): NodePos | null {
|
|
81
|
-
let $pos = this.resolvedPos.doc.resolve(this.from - 2)
|
|
114
|
+
let $pos = this.resolvedPos.doc.resolve(this.from - (this.isBlock ? 1 : 2))
|
|
82
115
|
|
|
83
116
|
if ($pos.depth !== this.depth) {
|
|
84
117
|
$pos = this.resolvedPos.doc.resolve(this.from - 3)
|
|
@@ -88,7 +121,7 @@ export class NodePos {
|
|
|
88
121
|
}
|
|
89
122
|
|
|
90
123
|
get after(): NodePos | null {
|
|
91
|
-
let $pos = this.resolvedPos.doc.resolve(this.to + 2)
|
|
124
|
+
let $pos = this.resolvedPos.doc.resolve(this.to + (this.isBlock ? 2 : 1))
|
|
92
125
|
|
|
93
126
|
if ($pos.depth !== this.depth) {
|
|
94
127
|
$pos = this.resolvedPos.doc.resolve(this.to + 3)
|
|
@@ -101,14 +134,22 @@ export class NodePos {
|
|
|
101
134
|
const children: NodePos[] = []
|
|
102
135
|
|
|
103
136
|
this.node.content.forEach((node, offset) => {
|
|
104
|
-
const
|
|
137
|
+
const isBlock = node.isBlock && !node.isTextblock
|
|
138
|
+
|
|
139
|
+
const targetPos = this.pos + offset + (isBlock ? 0 : 1)
|
|
105
140
|
const $pos = this.resolvedPos.doc.resolve(targetPos)
|
|
106
141
|
|
|
107
|
-
if ($pos.depth
|
|
142
|
+
if (!isBlock && $pos.depth <= this.depth) {
|
|
108
143
|
return
|
|
109
144
|
}
|
|
110
145
|
|
|
111
|
-
|
|
146
|
+
const childNodePos = new NodePos($pos, this.editor, isBlock, isBlock ? node : null)
|
|
147
|
+
|
|
148
|
+
if (isBlock) {
|
|
149
|
+
childNodePos.actualDepth = this.depth + 1
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
children.push(new NodePos($pos, this.editor, isBlock, isBlock ? node : null))
|
|
112
153
|
})
|
|
113
154
|
|
|
114
155
|
return children
|
|
@@ -160,14 +201,14 @@ export class NodePos {
|
|
|
160
201
|
let nodes: NodePos[] = []
|
|
161
202
|
|
|
162
203
|
// iterate through children recursively finding all nodes which match the selector with the node name
|
|
163
|
-
if (!this.children || this.children.length === 0) {
|
|
204
|
+
if (this.isBlock || !this.children || this.children.length === 0) {
|
|
164
205
|
return nodes
|
|
165
206
|
}
|
|
166
207
|
|
|
167
|
-
this.children.forEach(
|
|
168
|
-
if (
|
|
208
|
+
this.children.forEach(childPos => {
|
|
209
|
+
if (childPos.node.type.name === selector) {
|
|
169
210
|
if (Object.keys(attributes).length > 0) {
|
|
170
|
-
const nodeAttributes =
|
|
211
|
+
const nodeAttributes = childPos.node.attrs
|
|
171
212
|
const attrKeys = Object.keys(attributes)
|
|
172
213
|
|
|
173
214
|
for (let index = 0; index < attrKeys.length; index += 1) {
|
|
@@ -179,14 +220,14 @@ export class NodePos {
|
|
|
179
220
|
}
|
|
180
221
|
}
|
|
181
222
|
|
|
182
|
-
nodes.push(
|
|
223
|
+
nodes.push(childPos)
|
|
183
224
|
|
|
184
225
|
if (firstItemOnly) {
|
|
185
226
|
return
|
|
186
227
|
}
|
|
187
228
|
}
|
|
188
229
|
|
|
189
|
-
nodes = nodes.concat(
|
|
230
|
+
nodes = nodes.concat(childPos.querySelectorAll(selector))
|
|
190
231
|
})
|
|
191
232
|
|
|
192
233
|
return nodes
|
|
@@ -1,6 +1,24 @@
|
|
|
1
|
+
const removeWhitespaces = (node: HTMLElement) => {
|
|
2
|
+
const children = node.childNodes
|
|
3
|
+
|
|
4
|
+
for (let i = children.length - 1; i >= 0; i -= 1) {
|
|
5
|
+
const child = children[i]
|
|
6
|
+
|
|
7
|
+
if (child.nodeType === 3 && child.nodeValue && /^(\n\s\s|\n)$/.test(child.nodeValue)) {
|
|
8
|
+
node.removeChild(child)
|
|
9
|
+
} else if (child.nodeType === 1) {
|
|
10
|
+
removeWhitespaces(child as HTMLElement)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return node
|
|
15
|
+
}
|
|
16
|
+
|
|
1
17
|
export function elementFromString(value: string): HTMLElement {
|
|
2
18
|
// add a wrapper to preserve leading and trailing whitespace
|
|
3
19
|
const wrappedValue = `<body>${value}</body>`
|
|
4
20
|
|
|
5
|
-
|
|
21
|
+
const html = new window.DOMParser().parseFromString(wrappedValue, 'text/html').body
|
|
22
|
+
|
|
23
|
+
return removeWhitespaces(html)
|
|
6
24
|
}
|