@tiptap/core 3.0.0-next.4 → 3.0.0-next.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.
Files changed (39) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/index.cjs +352 -238
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +1084 -1431
  5. package/dist/index.d.ts +1084 -1431
  6. package/dist/index.js +344 -235
  7. package/dist/index.js.map +1 -1
  8. package/dist/jsx-runtime/jsx-runtime.cjs +56 -0
  9. package/dist/jsx-runtime/jsx-runtime.cjs.map +1 -0
  10. package/dist/jsx-runtime/jsx-runtime.d.cts +22 -0
  11. package/dist/jsx-runtime/jsx-runtime.d.ts +22 -0
  12. package/dist/jsx-runtime/jsx-runtime.js +26 -0
  13. package/dist/jsx-runtime/jsx-runtime.js.map +1 -0
  14. package/jsx-runtime/index.cjs +1 -0
  15. package/jsx-runtime/index.d.cts +1 -0
  16. package/jsx-runtime/index.d.ts +1 -0
  17. package/jsx-runtime/index.js +1 -0
  18. package/package.json +20 -3
  19. package/src/Editor.ts +104 -22
  20. package/src/Extendable.ts +483 -0
  21. package/src/Extension.ts +5 -490
  22. package/src/ExtensionManager.ts +55 -10
  23. package/src/Mark.ts +135 -623
  24. package/src/MarkView.ts +66 -0
  25. package/src/Node.ts +325 -829
  26. package/src/commands/clearContent.ts +9 -4
  27. package/src/commands/focus.ts +7 -1
  28. package/src/commands/insertContentAt.ts +6 -2
  29. package/src/commands/setContent.ts +15 -14
  30. package/src/extensions/delete.ts +89 -0
  31. package/src/extensions/index.ts +1 -0
  32. package/src/extensions/keymap.ts +4 -0
  33. package/src/helpers/getExtensionField.ts +10 -7
  34. package/src/index.ts +3 -7
  35. package/src/jsx-runtime.ts +64 -0
  36. package/src/types.ts +334 -19
  37. package/src/utilities/elementFromString.ts +3 -0
  38. package/src/utilities/index.ts +1 -0
  39. package/src/utilities/mergeAttributes.ts +1 -1
package/src/types.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import { Mark as ProseMirrorMark, Node as ProseMirrorNode, ParseOptions, Slice } from '@tiptap/pm/model'
2
2
  import { EditorState, Transaction } from '@tiptap/pm/state'
3
- import { Mappable } from '@tiptap/pm/transform'
3
+ import { Mappable, Transform } from '@tiptap/pm/transform'
4
4
  import {
5
5
  Decoration,
6
6
  DecorationAttrs,
7
7
  EditorProps,
8
8
  EditorView,
9
+ MarkView,
10
+ MarkViewConstructor,
9
11
  NodeView,
10
12
  NodeViewConstructor,
11
13
  ViewMutationRecord,
@@ -37,10 +39,26 @@ export type MaybeThisParameterType<T> =
37
39
  Exclude<T, Primitive> extends (...args: any) => any ? ThisParameterType<Exclude<T, Primitive>> : any
38
40
 
39
41
  export interface EditorEvents {
40
- beforeCreate: { editor: Editor }
41
- create: { editor: Editor }
42
+ beforeCreate: {
43
+ /**
44
+ * The editor instance
45
+ */
46
+ editor: Editor
47
+ }
48
+ create: {
49
+ /**
50
+ * The editor instance
51
+ */
52
+ editor: Editor
53
+ }
42
54
  contentError: {
55
+ /**
56
+ * The editor instance
57
+ */
43
58
  editor: Editor
59
+ /**
60
+ * The error that occurred while parsing the content
61
+ */
44
62
  error: Error
45
63
  /**
46
64
  * If called, will re-initialize the editor with the collaboration extension removed.
@@ -48,35 +66,253 @@ export interface EditorEvents {
48
66
  */
49
67
  disableCollaboration: () => void
50
68
  }
51
- update: { editor: Editor; transaction: Transaction; appendedTransactions: Transaction[] }
52
- selectionUpdate: { editor: Editor; transaction: Transaction }
53
- beforeTransaction: { editor: Editor; transaction: Transaction; nextState: EditorState }
54
- transaction: { editor: Editor; transaction: Transaction; appendedTransactions: Transaction[] }
55
- focus: { editor: Editor; event: FocusEvent; transaction: Transaction }
56
- blur: { editor: Editor; event: FocusEvent; transaction: Transaction }
69
+ update: {
70
+ /**
71
+ * The editor instance
72
+ */
73
+ editor: Editor
74
+ /**
75
+ * The transaction that caused the update
76
+ */
77
+ transaction: Transaction
78
+ /**
79
+ * Appended transactions that were added to the initial transaction by plugins
80
+ */
81
+ appendedTransactions: Transaction[]
82
+ }
83
+ selectionUpdate: {
84
+ /**
85
+ * The editor instance
86
+ */
87
+ editor: Editor
88
+ /**
89
+ * The transaction that caused the selection update
90
+ */
91
+ transaction: Transaction
92
+ }
93
+ beforeTransaction: {
94
+ /**
95
+ * The editor instance
96
+ */
97
+ editor: Editor
98
+ /**
99
+ * The transaction that will be applied
100
+ */
101
+ transaction: Transaction
102
+ /**
103
+ * The next state of the editor after the transaction is applied
104
+ */
105
+ nextState: EditorState
106
+ }
107
+ transaction: {
108
+ /**
109
+ * The editor instance
110
+ */
111
+ editor: Editor
112
+ /**
113
+ * The initial transaction
114
+ */
115
+ transaction: Transaction
116
+ /**
117
+ * Appended transactions that were added to the initial transaction by plugins
118
+ */
119
+ appendedTransactions: Transaction[]
120
+ }
121
+ focus: {
122
+ /**
123
+ * The editor instance
124
+ */
125
+ editor: Editor
126
+ /**
127
+ * The focus event
128
+ */
129
+ event: FocusEvent
130
+ /**
131
+ * The transaction that caused the focus
132
+ */
133
+ transaction: Transaction
134
+ }
135
+ blur: {
136
+ /**
137
+ * The editor instance
138
+ */
139
+ editor: Editor
140
+ /**
141
+ * The focus event
142
+ */
143
+ event: FocusEvent
144
+ /**
145
+ * The transaction that caused the blur
146
+ */
147
+ transaction: Transaction
148
+ }
57
149
  destroy: void
58
- paste: { editor: Editor; event: ClipboardEvent; slice: Slice }
59
- drop: { editor: Editor; event: DragEvent; slice: Slice; moved: boolean }
150
+ paste: {
151
+ /**
152
+ * The editor instance
153
+ */
154
+ editor: Editor
155
+ /**
156
+ * The clipboard event
157
+ */
158
+ event: ClipboardEvent
159
+ /**
160
+ * The slice that was pasted
161
+ */
162
+ slice: Slice
163
+ }
164
+ drop: {
165
+ /**
166
+ * The editor instance
167
+ */
168
+ editor: Editor
169
+ /**
170
+ * The drag event
171
+ */
172
+ event: DragEvent
173
+ /**
174
+ * The slice that was dropped
175
+ */
176
+ slice: Slice
177
+ /**
178
+ * Whether the content was moved (true) or copied (false)
179
+ */
180
+ moved: boolean
181
+ }
182
+ delete: {
183
+ /**
184
+ * The editor instance
185
+ */
186
+ editor: Editor
187
+ /**
188
+ * The range of the deleted content (before the deletion)
189
+ */
190
+ deletedRange: Range
191
+ /**
192
+ * The new range of positions of where the deleted content was in the new document (after the deletion)
193
+ */
194
+ newRange: Range
195
+ /**
196
+ * The transaction that caused the deletion
197
+ */
198
+ transaction: Transaction
199
+ /**
200
+ * The combined transform (including all appended transactions) that caused the deletion
201
+ */
202
+ combinedTransform: Transform
203
+ /**
204
+ * Whether the deletion was partial (only a part of this content was deleted)
205
+ */
206
+ partial: boolean
207
+ /**
208
+ * This is the start position of the mark in the document (before the deletion)
209
+ */
210
+ from: number
211
+ /**
212
+ * This is the end position of the mark in the document (before the deletion)
213
+ */
214
+ to: number
215
+ } & (
216
+ | {
217
+ /**
218
+ * The content that was deleted
219
+ */
220
+ type: 'node'
221
+ /**
222
+ * The node which the deletion occurred in
223
+ * @note This can be a parent node of the deleted content
224
+ */
225
+ node: ProseMirrorNode
226
+ /**
227
+ * The new start position of the node in the document (after the deletion)
228
+ */
229
+ newFrom: number
230
+ /**
231
+ * The new end position of the node in the document (after the deletion)
232
+ */
233
+ newTo: number
234
+ }
235
+ | {
236
+ /**
237
+ * The content that was deleted
238
+ */
239
+ type: 'mark'
240
+ /**
241
+ * The mark that was deleted
242
+ */
243
+ mark: ProseMirrorMark
244
+ }
245
+ )
60
246
  }
61
247
 
62
248
  export type EnableRules = (AnyExtension | string)[] | boolean
63
249
 
64
250
  export interface EditorOptions {
65
- element: Element
251
+ /**
252
+ * The element or selector to bind the editor to
253
+ * If `null` is passed, the editor will not be mounted automatically
254
+ * If a function is passed, it will be called with the editor's root element
255
+ */
256
+ element: Element | null
257
+ /**
258
+ * The content of the editor (HTML, JSON, or a JSON array)
259
+ */
66
260
  content: Content
261
+ /**
262
+ * The extensions to use
263
+ */
67
264
  extensions: Extensions
265
+ /**
266
+ * Whether to inject base CSS styles
267
+ */
68
268
  injectCSS: boolean
269
+ /**
270
+ * A nonce to use for CSP while injecting styles
271
+ */
69
272
  injectNonce: string | undefined
273
+ /**
274
+ * The editor's initial focus position
275
+ */
70
276
  autofocus: FocusPosition
277
+ /**
278
+ * Whether the editor is editable
279
+ */
71
280
  editable: boolean
281
+ /**
282
+ * The editor's props
283
+ */
72
284
  editorProps: EditorProps
285
+ /**
286
+ * The editor's content parser options
287
+ */
73
288
  parseOptions: ParseOptions
289
+ /**
290
+ * The editor's core extension options
291
+ */
74
292
  coreExtensionOptions?: {
75
293
  clipboardTextSerializer?: {
76
294
  blockSeparator?: string
77
295
  }
296
+ delete?: {
297
+ /**
298
+ * Whether the `delete` extension should be called asynchronously to avoid blocking the editor while processing deletions
299
+ * @default true deletion events are called asynchronously
300
+ */
301
+ async?: boolean
302
+ /**
303
+ * Allows filtering the transactions that are processed by the `delete` extension.
304
+ * If the function returns `true`, the transaction will be ignored.
305
+ */
306
+ filterTransaction?: (transaction: Transaction) => boolean
307
+ }
78
308
  }
309
+ /**
310
+ * Whether to enable input rules behavior
311
+ */
79
312
  enableInputRules: EnableRules
313
+ /**
314
+ * Whether to enable paste rules behavior
315
+ */
80
316
  enablePasteRules: EnableRules
81
317
  /**
82
318
  * Determines whether core extensions are enabled.
@@ -106,7 +342,8 @@ export interface EditorOptions {
106
342
  | 'keymap'
107
343
  | 'tabindex'
108
344
  | 'drop'
109
- | 'paste',
345
+ | 'paste'
346
+ | 'delete',
110
347
  false
111
348
  >
112
349
  >
@@ -117,25 +354,65 @@ export interface EditorOptions {
117
354
  * @default false
118
355
  */
119
356
  enableContentCheck: boolean
357
+ /**
358
+ * Called before the editor is constructed.
359
+ */
120
360
  onBeforeCreate: (props: EditorEvents['beforeCreate']) => void
361
+ /**
362
+ * Called after the editor is constructed.
363
+ */
121
364
  onCreate: (props: EditorEvents['create']) => void
122
365
  /**
123
366
  * Called when the editor encounters an error while parsing the content.
124
367
  * Only enabled if `enableContentCheck` is `true`.
125
368
  */
126
369
  onContentError: (props: EditorEvents['contentError']) => void
370
+ /**
371
+ * Called when the editor's content is updated.
372
+ */
127
373
  onUpdate: (props: EditorEvents['update']) => void
374
+ /**
375
+ * Called when the editor's selection is updated.
376
+ */
128
377
  onSelectionUpdate: (props: EditorEvents['selectionUpdate']) => void
378
+ /**
379
+ * Called after a transaction is applied to the editor.
380
+ */
129
381
  onTransaction: (props: EditorEvents['transaction']) => void
382
+ /**
383
+ * Called on focus events.
384
+ */
130
385
  onFocus: (props: EditorEvents['focus']) => void
386
+ /**
387
+ * Called on blur events.
388
+ */
131
389
  onBlur: (props: EditorEvents['blur']) => void
390
+ /**
391
+ * Called when the editor is destroyed.
392
+ */
132
393
  onDestroy: (props: EditorEvents['destroy']) => void
394
+ /**
395
+ * Called when content is pasted into the editor.
396
+ */
133
397
  onPaste: (e: ClipboardEvent, slice: Slice) => void
398
+ /**
399
+ * Called when content is dropped into the editor.
400
+ */
134
401
  onDrop: (e: DragEvent, slice: Slice, moved: boolean) => void
402
+ /**
403
+ * Called when content is deleted from the editor.
404
+ */
405
+ onDelete: (props: EditorEvents['delete']) => void
135
406
  }
136
407
 
408
+ /**
409
+ * The editor's content as HTML
410
+ */
137
411
  export type HTMLContent = string
138
412
 
413
+ /**
414
+ * Loosely describes a JSON representation of a Prosemirror document or node
415
+ */
139
416
  export type JSONContent = {
140
417
  type?: string
141
418
  attrs?: Record<string, any>
@@ -154,10 +431,10 @@ export type JSONContent = {
154
431
  */
155
432
  export type MarkType<
156
433
  Type extends string | { name: string } = any,
157
- Attributes extends undefined | Record<string, any> = any,
434
+ TAttributes extends undefined | Record<string, any> = any,
158
435
  > = {
159
436
  type: Type
160
- attrs: Attributes
437
+ attrs: TAttributes
161
438
  }
162
439
 
163
440
  /**
@@ -165,13 +442,13 @@ export type MarkType<
165
442
  */
166
443
  export type NodeType<
167
444
  Type extends string | { name: string } = any,
168
- Attributes extends undefined | Record<string, any> = any,
445
+ TAttributes extends undefined | Record<string, any> = any,
169
446
  NodeMarkType extends MarkType = any,
170
- Content extends (NodeType | TextType)[] = any,
447
+ TContent extends (NodeType | TextType)[] = any,
171
448
  > = {
172
449
  type: Type
173
- attrs: Attributes
174
- content?: Content
450
+ attrs: TAttributes
451
+ content?: TContent
175
452
  marks?: NodeMarkType[]
176
453
  }
177
454
 
@@ -346,6 +623,44 @@ export interface NodeViewRendererProps {
346
623
 
347
624
  export type NodeViewRenderer = (props: NodeViewRendererProps) => NodeView
348
625
 
626
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
627
+ export interface MarkViewProps extends MarkViewRendererProps {}
628
+
629
+ export interface MarkViewRendererProps {
630
+ // pass-through from prosemirror
631
+ /**
632
+ * The node that is being rendered.
633
+ */
634
+ mark: Parameters<MarkViewConstructor>[0]
635
+ /**
636
+ * The editor's view.
637
+ */
638
+ view: Parameters<MarkViewConstructor>[1]
639
+ /**
640
+ * indicates whether the mark's content is inline
641
+ */
642
+ inline: Parameters<MarkViewConstructor>[2]
643
+ // tiptap-specific
644
+ /**
645
+ * The editor instance.
646
+ */
647
+ editor: Editor
648
+ /**
649
+ * The extension that is responsible for the mark.
650
+ */
651
+ extension: Mark
652
+ /**
653
+ * The HTML attributes that should be added to the mark's DOM element.
654
+ */
655
+ HTMLAttributes: Record<string, any>
656
+ }
657
+
658
+ export type MarkViewRenderer = (props: MarkViewRendererProps) => MarkView
659
+
660
+ export interface MarkViewRendererOptions {
661
+ ignoreMutation: ((props: { mutation: ViewMutationRecord }) => boolean) | null
662
+ }
663
+
349
664
  export type AnyCommands = Record<string, (...args: any[]) => Command>
350
665
 
351
666
  export type UnionCommands<T = Command> = UnionToIntersection<
@@ -15,6 +15,9 @@ const removeWhitespaces = (node: HTMLElement) => {
15
15
  }
16
16
 
17
17
  export function elementFromString(value: string): HTMLElement {
18
+ if (typeof window === 'undefined') {
19
+ throw new Error('[tiptap error]: there is no window object available, so this function cannot be used')
20
+ }
18
21
  // add a wrapper to preserve leading and trailing whitespace
19
22
  const wrappedValue = `<body>${value}</body>`
20
23
 
@@ -5,6 +5,7 @@ export * from './elementFromString.js'
5
5
  export * from './escapeForRegEx.js'
6
6
  export * from './findDuplicates.js'
7
7
  export * from './fromString.js'
8
+ export * from './isAndroid.js'
8
9
  export * from './isEmptyObject.js'
9
10
  export * from './isFunction.js'
10
11
  export * from './isiOS.js'
@@ -14,7 +14,7 @@ export function mergeAttributes(...objects: Record<string, any>[]): Record<strin
14
14
  }
15
15
 
16
16
  if (key === 'class') {
17
- const valueClasses: string[] = value ? value.split(' ') : []
17
+ const valueClasses: string[] = value ? String(value).split(' ') : []
18
18
  const existingClasses: string[] = mergedAttributes[key] ? mergedAttributes[key].split(' ') : []
19
19
 
20
20
  const insertClasses = valueClasses.filter(valueClass => !existingClasses.includes(valueClass))