@tiptap/core 2.5.0-beta.4 → 2.5.0-beta.6
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 +37 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +37 -43
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +37 -43
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/core/src/utilities/removeDuplicates.d.ts +2 -2
- package/package.json +2 -2
- package/src/commands/insertContentAt.ts +0 -5
- package/src/commands/setContent.ts +22 -10
- package/src/commands/updateAttributes.ts +25 -40
- package/src/helpers/createNodeFromContent.ts +5 -2
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* Supports numbers, strings and objects.
|
|
4
4
|
*/
|
|
5
5
|
export declare function removeDuplicates<T>(array: T[], by?: {
|
|
6
|
-
(value: any, replacer?: (
|
|
7
|
-
(value: any, replacer?: (
|
|
6
|
+
(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
|
|
7
|
+
(value: any, replacer?: (number | string)[] | null, space?: string | number): string;
|
|
8
8
|
}): T[];
|
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.5.0-beta.
|
|
4
|
+
"version": "2.5.0-beta.6",
|
|
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.5.0-beta.
|
|
35
|
+
"@tiptap/pm": "^2.5.0-beta.6"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@tiptap/pm": "^2.0.0"
|
|
@@ -84,11 +84,6 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|
|
84
84
|
return false
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
// don’t dispatch an empty fragment because this can lead to strange errors
|
|
88
|
-
if (content.toString() === '<>') {
|
|
89
|
-
return true
|
|
90
|
-
}
|
|
91
|
-
|
|
92
87
|
let { from, to } = typeof position === 'number' ? { from: position, to: position } : { from: position.from, to: position.to }
|
|
93
88
|
|
|
94
89
|
let isOnlyTextContent = true
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ParseOptions } from '@tiptap/pm/model'
|
|
2
2
|
|
|
3
3
|
import { createDocument } from '../helpers/createDocument.js'
|
|
4
4
|
import { Content, RawCommands } from '../types.js'
|
|
@@ -44,22 +44,34 @@ declare module '@tiptap/core' {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
export const setContent: RawCommands['setContent'] = (content, emitUpdate = false, parseOptions = {}, options = {}) => ({
|
|
47
|
+
export const setContent: RawCommands['setContent'] = (content, emitUpdate = false, parseOptions = {}, options = {}) => ({
|
|
48
|
+
editor, tr, dispatch, commands,
|
|
49
|
+
}) => {
|
|
48
50
|
const { doc } = tr
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
document = createDocument(content, editor.schema, parseOptions, {
|
|
52
|
+
// This is to keep backward compatibility with the previous behavior
|
|
53
|
+
// TODO remove this in the next major version
|
|
54
|
+
if (parseOptions.preserveWhitespace !== 'full') {
|
|
55
|
+
const document = createDocument(content, editor.schema, parseOptions, {
|
|
54
56
|
errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,
|
|
55
57
|
})
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
|
|
59
|
+
if (dispatch) {
|
|
60
|
+
tr.replaceWith(0, doc.content.size, document).setMeta('preventUpdate', !emitUpdate)
|
|
61
|
+
}
|
|
62
|
+
return true
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
if (dispatch) {
|
|
61
|
-
tr.
|
|
66
|
+
tr.setMeta('preventUpdate', !emitUpdate)
|
|
62
67
|
}
|
|
63
68
|
|
|
64
|
-
return
|
|
69
|
+
return commands.insertContentAt(
|
|
70
|
+
{ from: 0, to: doc.content.size },
|
|
71
|
+
content,
|
|
72
|
+
{
|
|
73
|
+
parseOptions,
|
|
74
|
+
errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,
|
|
75
|
+
},
|
|
76
|
+
)
|
|
65
77
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Mark, MarkType, Node, NodeType,
|
|
3
|
-
} from '@tiptap/pm/model'
|
|
4
|
-
import { SelectionRange } from '@tiptap/pm/state'
|
|
1
|
+
import { MarkType, NodeType } from '@tiptap/pm/model'
|
|
5
2
|
|
|
6
3
|
import { getMarkType } from '../helpers/getMarkType.js'
|
|
7
4
|
import { getNodeType } from '../helpers/getNodeType.js'
|
|
@@ -54,49 +51,37 @@ export const updateAttributes: RawCommands['updateAttributes'] = (typeOrName, at
|
|
|
54
51
|
}
|
|
55
52
|
|
|
56
53
|
if (dispatch) {
|
|
57
|
-
|
|
58
|
-
let lastNode: Node | undefined
|
|
59
|
-
let trimmedFrom: number
|
|
60
|
-
let trimmedTo: number
|
|
61
|
-
|
|
62
|
-
tr.selection.ranges.forEach((range: SelectionRange) => {
|
|
54
|
+
tr.selection.ranges.forEach(range => {
|
|
63
55
|
const from = range.$from.pos
|
|
64
56
|
const to = range.$to.pos
|
|
65
57
|
|
|
66
|
-
state.doc.nodesBetween(from, to, (node
|
|
58
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
67
59
|
if (nodeType && nodeType === node.type) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
tr.setNodeMarkup(pos, undefined, {
|
|
61
|
+
...node.attrs,
|
|
62
|
+
...attributes,
|
|
63
|
+
})
|
|
72
64
|
}
|
|
73
|
-
})
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
if (lastNode) {
|
|
77
65
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
66
|
+
if (markType && node.marks.length) {
|
|
67
|
+
node.marks.forEach(mark => {
|
|
68
|
+
if (markType === mark.type) {
|
|
69
|
+
const trimmedFrom = Math.max(pos, from)
|
|
70
|
+
const trimmedTo = Math.min(pos + node.nodeSize, to)
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
}
|
|
72
|
+
tr.addMark(
|
|
73
|
+
trimmedFrom,
|
|
74
|
+
trimmedTo,
|
|
75
|
+
markType.create({
|
|
76
|
+
...mark.attrs,
|
|
77
|
+
...attributes,
|
|
78
|
+
}),
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
})
|
|
100
85
|
}
|
|
101
86
|
|
|
102
87
|
return true
|
|
@@ -60,6 +60,7 @@ export function createNodeFromContent(
|
|
|
60
60
|
if (isTextContent) {
|
|
61
61
|
let schemaToUse = schema
|
|
62
62
|
let hasInvalidContent = false
|
|
63
|
+
let invalidContent = ''
|
|
63
64
|
|
|
64
65
|
// Only ever check for invalid content if we're supposed to throw an error
|
|
65
66
|
if (options.errorOnInvalidContent) {
|
|
@@ -75,9 +76,11 @@ export function createNodeFromContent(
|
|
|
75
76
|
parseDOM: [
|
|
76
77
|
{
|
|
77
78
|
tag: '*',
|
|
78
|
-
getAttrs:
|
|
79
|
+
getAttrs: e => {
|
|
79
80
|
// If this is ever called, we know that the content has something that we don't know how to handle in the schema
|
|
80
81
|
hasInvalidContent = true
|
|
82
|
+
// Try to stringify the element for a more helpful error message
|
|
83
|
+
invalidContent = typeof e === 'string' ? e : e.outerHTML
|
|
81
84
|
return null
|
|
82
85
|
},
|
|
83
86
|
},
|
|
@@ -94,7 +97,7 @@ export function createNodeFromContent(
|
|
|
94
97
|
: parser.parse(elementFromString(content), options.parseOptions)
|
|
95
98
|
|
|
96
99
|
if (options.errorOnInvalidContent && hasInvalidContent) {
|
|
97
|
-
throw new Error('[tiptap error]: Invalid HTML content')
|
|
100
|
+
throw new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) })
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
return response
|