@tiptap/core 2.5.5 → 2.5.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.
@@ -154,9 +154,7 @@ export type GlobalAttributes = {
154
154
  /**
155
155
  * The attributes to add to the node or mark types.
156
156
  */
157
- attributes: {
158
- [key: string]: Attribute;
159
- };
157
+ attributes: Record<string, Attribute | undefined>;
160
158
  }[];
161
159
  export type PickValue<T, K extends keyof T> = T[K];
162
160
  export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
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.5",
4
+ "version": "2.5.6",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -32,10 +32,10 @@
32
32
  "dist"
33
33
  ],
34
34
  "devDependencies": {
35
- "@tiptap/pm": "^2.5.5"
35
+ "@tiptap/pm": "^2.5.6"
36
36
  },
37
37
  "peerDependencies": {
38
- "@tiptap/pm": "^2.5.5"
38
+ "@tiptap/pm": "^2.5.6"
39
39
  },
40
40
  "repository": {
41
41
  "type": "git",
package/src/Editor.ts CHANGED
@@ -349,6 +349,10 @@ export class Editor extends EventEmitter<EditorEvents> {
349
349
  * Creates all node views.
350
350
  */
351
351
  public createNodeViews(): void {
352
+ if (this.view.isDestroyed) {
353
+ return
354
+ }
355
+
352
356
  this.view.setProps({
353
357
  nodeViews: this.extensionManager.nodeViews,
354
358
  })
@@ -61,18 +61,30 @@ export const splitBlock: RawCommands['splitBlock'] = ({ keepMarks = true } = {})
61
61
  return false
62
62
  }
63
63
 
64
- if (dispatch) {
65
- const atEnd = $to.parentOffset === $to.parent.content.size
66
-
67
- if (selection instanceof TextSelection) {
68
- tr.deleteSelection()
69
- }
70
-
71
- const deflt = $from.depth === 0
72
- ? undefined
73
- : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)))
74
-
75
- let types = atEnd && deflt
64
+ const atEnd = $to.parentOffset === $to.parent.content.size
65
+
66
+ const deflt = $from.depth === 0
67
+ ? undefined
68
+ : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)))
69
+
70
+ let types = atEnd && deflt
71
+ ? [
72
+ {
73
+ type: deflt,
74
+ attrs: newAttributes,
75
+ },
76
+ ]
77
+ : undefined
78
+
79
+ let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types)
80
+
81
+ if (
82
+ !types
83
+ && !can
84
+ && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : undefined)
85
+ ) {
86
+ can = true
87
+ types = deflt
76
88
  ? [
77
89
  {
78
90
  type: deflt,
@@ -80,26 +92,14 @@ export const splitBlock: RawCommands['splitBlock'] = ({ keepMarks = true } = {})
80
92
  },
81
93
  ]
82
94
  : undefined
95
+ }
83
96
 
84
- let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types)
85
-
86
- if (
87
- !types
88
- && !can
89
- && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : undefined)
90
- ) {
91
- can = true
92
- types = deflt
93
- ? [
94
- {
95
- type: deflt,
96
- attrs: newAttributes,
97
- },
98
- ]
99
- : undefined
100
- }
101
-
97
+ if (dispatch) {
102
98
  if (can) {
99
+ if (selection instanceof TextSelection) {
100
+ tr.deleteSelection()
101
+ }
102
+
103
103
  tr.split(tr.mapping.map($from.pos), 1, types)
104
104
 
105
105
  if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {
@@ -119,5 +119,5 @@ export const splitBlock: RawCommands['splitBlock'] = ({ keepMarks = true } = {})
119
119
  tr.scrollIntoView()
120
120
  }
121
121
 
122
- return true
122
+ return can
123
123
  }
@@ -1,7 +1,7 @@
1
1
  import { Node as ProseMirrorNode } from '@tiptap/pm/model'
2
2
 
3
3
  export function isNodeEmpty(node: ProseMirrorNode): boolean {
4
- const defaultContent = node.type.createAndFill()
4
+ const defaultContent = node.type.createAndFill(node.attrs)
5
5
 
6
6
  if (!defaultContent) {
7
7
  return false
package/src/types.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import {
2
- Mark as ProseMirrorMark, Node as ProseMirrorNode, NodeType, ParseOptions,
2
+ Mark as ProseMirrorMark,
3
+ Node as ProseMirrorNode,
4
+ NodeType,
5
+ ParseOptions,
3
6
  } from '@tiptap/pm/model'
4
7
  import { EditorState, Transaction } from '@tiptap/pm/state'
5
8
  import {
@@ -14,267 +17,265 @@ import {
14
17
  import { Mark } from './Mark.js'
15
18
  import { Node } from './Node.js'
16
19
 
17
- export type AnyConfig = ExtensionConfig | NodeConfig | MarkConfig
18
- export type AnyExtension = Extension | Node | Mark
19
- export type Extensions = AnyExtension[]
20
+ export type AnyConfig = ExtensionConfig | NodeConfig | MarkConfig;
21
+ export type AnyExtension = Extension | Node | Mark;
22
+ export type Extensions = AnyExtension[];
20
23
 
21
24
  export type ParentConfig<T> = Partial<{
22
25
  [P in keyof T]: Required<T>[P] extends (...args: any) => any
23
26
  ? (...args: Parameters<Required<T>[P]>) => ReturnType<Required<T>[P]>
24
- : T[P]
25
- }>
27
+ : T[P];
28
+ }>;
26
29
 
27
- export type Primitive = null | undefined | string | number | boolean | symbol | bigint
30
+ export type Primitive = null | undefined | string | number | boolean | symbol | bigint;
28
31
 
29
32
  export type RemoveThis<T> = T extends (...args: any) => any
30
33
  ? (...args: Parameters<T>) => ReturnType<T>
31
- : T
34
+ : T;
32
35
 
33
- export type MaybeReturnType<T> = T extends (...args: any) => any ? ReturnType<T> : T
36
+ export type MaybeReturnType<T> = T extends (...args: any) => any ? ReturnType<T> : T;
34
37
 
35
38
  export type MaybeThisParameterType<T> = Exclude<T, Primitive> extends (...args: any) => any
36
39
  ? ThisParameterType<Exclude<T, Primitive>>
37
- : any
40
+ : any;
38
41
 
39
42
  export interface EditorEvents {
40
- beforeCreate: { editor: Editor }
41
- create: { editor: Editor }
43
+ beforeCreate: { editor: Editor };
44
+ create: { editor: Editor };
42
45
  contentError: {
43
- editor: Editor,
44
- error: Error,
46
+ editor: Editor;
47
+ error: Error;
45
48
  /**
46
49
  * If called, will re-initialize the editor with the collaboration extension removed.
47
50
  * This will prevent syncing back deletions of content not present in the current schema.
48
51
  */
49
- disableCollaboration: () => void
50
- }
51
- update: { editor: Editor; transaction: Transaction }
52
- selectionUpdate: { editor: Editor; transaction: Transaction }
53
- beforeTransaction: { editor: Editor; transaction: Transaction, nextState: EditorState }
54
- transaction: { editor: Editor; transaction: Transaction }
55
- focus: { editor: Editor; event: FocusEvent; transaction: Transaction }
56
- blur: { editor: Editor; event: FocusEvent; transaction: Transaction }
57
- destroy: void
52
+ disableCollaboration: () => void;
53
+ };
54
+ update: { editor: Editor; transaction: Transaction };
55
+ selectionUpdate: { editor: Editor; transaction: Transaction };
56
+ beforeTransaction: { editor: Editor; transaction: Transaction; nextState: EditorState };
57
+ transaction: { editor: Editor; transaction: Transaction };
58
+ focus: { editor: Editor; event: FocusEvent; transaction: Transaction };
59
+ blur: { editor: Editor; event: FocusEvent; transaction: Transaction };
60
+ destroy: void;
58
61
  }
59
62
 
60
- export type EnableRules = (AnyExtension | string)[] | boolean
63
+ export type EnableRules = (AnyExtension | string)[] | boolean;
61
64
 
62
65
  export interface EditorOptions {
63
- element: Element
64
- content: Content
65
- extensions: Extensions
66
- injectCSS: boolean
67
- injectNonce: string | undefined
68
- autofocus: FocusPosition
69
- editable: boolean
70
- editorProps: EditorProps
71
- parseOptions: ParseOptions
66
+ element: Element;
67
+ content: Content;
68
+ extensions: Extensions;
69
+ injectCSS: boolean;
70
+ injectNonce: string | undefined;
71
+ autofocus: FocusPosition;
72
+ editable: boolean;
73
+ editorProps: EditorProps;
74
+ parseOptions: ParseOptions;
72
75
  coreExtensionOptions?: {
73
76
  clipboardTextSerializer?: {
74
- blockSeparator?: string
75
- }
76
- }
77
- enableInputRules: EnableRules
78
- enablePasteRules: EnableRules
79
- enableCoreExtensions: boolean
77
+ blockSeparator?: string;
78
+ };
79
+ };
80
+ enableInputRules: EnableRules;
81
+ enablePasteRules: EnableRules;
82
+ enableCoreExtensions: boolean;
80
83
  /**
81
84
  * If `true`, the editor will check the content for errors on initialization.
82
85
  * Emitting the `contentError` event if the content is invalid.
83
86
  * Which can be used to show a warning or error message to the user.
84
87
  * @default false
85
88
  */
86
- enableContentCheck: boolean
87
- onBeforeCreate: (props: EditorEvents['beforeCreate']) => void
88
- onCreate: (props: EditorEvents['create']) => void
89
+ enableContentCheck: boolean;
90
+ onBeforeCreate: (props: EditorEvents['beforeCreate']) => void;
91
+ onCreate: (props: EditorEvents['create']) => void;
89
92
  /**
90
93
  * Called when the editor encounters an error while parsing the content.
91
94
  * Only enabled if `enableContentCheck` is `true`.
92
95
  */
93
- onContentError: (props: EditorEvents['contentError']) => void
94
- onUpdate: (props: EditorEvents['update']) => void
95
- onSelectionUpdate: (props: EditorEvents['selectionUpdate']) => void
96
- onTransaction: (props: EditorEvents['transaction']) => void
97
- onFocus: (props: EditorEvents['focus']) => void
98
- onBlur: (props: EditorEvents['blur']) => void
99
- onDestroy: (props: EditorEvents['destroy']) => void
96
+ onContentError: (props: EditorEvents['contentError']) => void;
97
+ onUpdate: (props: EditorEvents['update']) => void;
98
+ onSelectionUpdate: (props: EditorEvents['selectionUpdate']) => void;
99
+ onTransaction: (props: EditorEvents['transaction']) => void;
100
+ onFocus: (props: EditorEvents['focus']) => void;
101
+ onBlur: (props: EditorEvents['blur']) => void;
102
+ onDestroy: (props: EditorEvents['destroy']) => void;
100
103
  }
101
104
 
102
- export type HTMLContent = string
105
+ export type HTMLContent = string;
103
106
 
104
107
  export type JSONContent = {
105
- type?: string
106
- attrs?: Record<string, any>
107
- content?: JSONContent[]
108
+ type?: string;
109
+ attrs?: Record<string, any>;
110
+ content?: JSONContent[];
108
111
  marks?: {
109
- type: string
110
- attrs?: Record<string, any>
111
- [key: string]: any
112
- }[]
113
- text?: string
114
- [key: string]: any
115
- }
112
+ type: string;
113
+ attrs?: Record<string, any>;
114
+ [key: string]: any;
115
+ }[];
116
+ text?: string;
117
+ [key: string]: any;
118
+ };
116
119
 
117
- export type Content = HTMLContent | JSONContent | JSONContent[] | null
120
+ export type Content = HTMLContent | JSONContent | JSONContent[] | null;
118
121
 
119
122
  export type CommandProps = {
120
- editor: Editor
121
- tr: Transaction
122
- commands: SingleCommands
123
- can: () => CanCommands
124
- chain: () => ChainedCommands
125
- state: EditorState
126
- view: EditorView
127
- dispatch: ((args?: any) => any) | undefined
128
- }
123
+ editor: Editor;
124
+ tr: Transaction;
125
+ commands: SingleCommands;
126
+ can: () => CanCommands;
127
+ chain: () => ChainedCommands;
128
+ state: EditorState;
129
+ view: EditorView;
130
+ dispatch: ((args?: any) => any) | undefined;
131
+ };
129
132
 
130
- export type Command = (props: CommandProps) => boolean
133
+ export type Command = (props: CommandProps) => boolean;
131
134
 
132
- export type CommandSpec = (...args: any[]) => Command
135
+ export type CommandSpec = (...args: any[]) => Command;
133
136
 
134
- export type KeyboardShortcutCommand = (props: { editor: Editor }) => boolean
137
+ export type KeyboardShortcutCommand = (props: { editor: Editor }) => boolean;
135
138
 
136
139
  export type Attribute = {
137
- default?: any
138
- rendered?: boolean
139
- renderHTML?: ((attributes: Record<string, any>) => Record<string, any> | null) | null
140
- parseHTML?: ((element: HTMLElement) => any | null) | null
141
- keepOnSplit?: boolean
142
- isRequired?: boolean
143
- }
140
+ default?: any;
141
+ rendered?: boolean;
142
+ renderHTML?: ((attributes: Record<string, any>) => Record<string, any> | null) | null;
143
+ parseHTML?: ((element: HTMLElement) => any | null) | null;
144
+ keepOnSplit?: boolean;
145
+ isRequired?: boolean;
146
+ };
144
147
 
145
148
  export type Attributes = {
146
- [key: string]: Attribute
147
- }
149
+ [key: string]: Attribute;
150
+ };
148
151
 
149
152
  export type ExtensionAttribute = {
150
- type: string
151
- name: string
152
- attribute: Required<Attribute>
153
- }
153
+ type: string;
154
+ name: string;
155
+ attribute: Required<Attribute>;
156
+ };
154
157
 
155
158
  export type GlobalAttributes = {
156
159
  /**
157
160
  * The node & mark types this attribute should be applied to.
158
161
  */
159
- types: string[]
162
+ types: string[];
160
163
  /**
161
164
  * The attributes to add to the node or mark types.
162
165
  */
163
- attributes: {
164
- [key: string]: Attribute
165
- }
166
- }[]
166
+ attributes: Record<string, Attribute | undefined>;
167
+ }[];
167
168
 
168
- export type PickValue<T, K extends keyof T> = T[K]
169
+ export type PickValue<T, K extends keyof T> = T[K];
169
170
 
170
171
  export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
171
- k: infer I,
172
+ k: infer I
172
173
  ) => void
173
174
  ? I
174
- : never
175
+ : never;
175
176
 
176
177
  export type Diff<T extends keyof any, U extends keyof any> = ({ [P in T]: P } & {
177
- [P in U]: never
178
- } & { [x: string]: never })[T]
178
+ [P in U]: never;
179
+ } & { [x: string]: never })[T];
179
180
 
180
- export type Overwrite<T, U> = Pick<T, Diff<keyof T, keyof U>> & U
181
+ export type Overwrite<T, U> = Pick<T, Diff<keyof T, keyof U>> & U;
181
182
 
182
- export type ValuesOf<T> = T[keyof T]
183
+ export type ValuesOf<T> = T[keyof T];
183
184
 
184
- export type KeysWithTypeOf<T, Type> = { [P in keyof T]: T[P] extends Type ? P : never }[keyof T]
185
+ export type KeysWithTypeOf<T, Type> = { [P in keyof T]: T[P] extends Type ? P : never }[keyof T];
185
186
 
186
187
  export type DecorationWithType = Decoration & {
187
- type: NodeType
188
- }
188
+ type: NodeType;
189
+ };
189
190
 
190
191
  export type NodeViewProps = {
191
- editor: Editor
192
- node: ProseMirrorNode
193
- decorations: DecorationWithType[]
194
- selected: boolean
195
- extension: Node
196
- getPos: () => number
197
- updateAttributes: (attributes: Record<string, any>) => void
198
- deleteNode: () => void
199
- }
192
+ editor: Editor;
193
+ node: ProseMirrorNode;
194
+ decorations: DecorationWithType[];
195
+ selected: boolean;
196
+ extension: Node;
197
+ getPos: () => number;
198
+ updateAttributes: (attributes: Record<string, any>) => void;
199
+ deleteNode: () => void;
200
+ };
200
201
 
201
202
  export interface NodeViewRendererOptions {
202
- stopEvent: ((props: { event: Event }) => boolean) | null
203
+ stopEvent: ((props: { event: Event }) => boolean) | null;
203
204
  ignoreMutation:
204
205
  | ((props: { mutation: MutationRecord | { type: 'selection'; target: Element } }) => boolean)
205
- | null
206
- contentDOMElementTag: string
206
+ | null;
207
+ contentDOMElementTag: string;
207
208
  }
208
209
 
209
210
  export type NodeViewRendererProps = {
210
- editor: Editor
211
- node: ProseMirrorNode
212
- getPos: (() => number) | boolean
213
- HTMLAttributes: Record<string, any>
214
- decorations: Decoration[]
215
- extension: Node
216
- }
211
+ editor: Editor;
212
+ node: ProseMirrorNode;
213
+ getPos: (() => number) | boolean;
214
+ HTMLAttributes: Record<string, any>;
215
+ decorations: Decoration[];
216
+ extension: Node;
217
+ };
217
218
 
218
- export type NodeViewRenderer = (props: NodeViewRendererProps) => NodeView | {}
219
+ export type NodeViewRenderer = (props: NodeViewRendererProps) => NodeView | {};
219
220
 
220
- export type AnyCommands = Record<string, (...args: any[]) => Command>
221
+ export type AnyCommands = Record<string, (...args: any[]) => Command>;
221
222
 
222
223
  export type UnionCommands<T = Command> = UnionToIntersection<
223
224
  ValuesOf<Pick<Commands<T>, KeysWithTypeOf<Commands<T>, {}>>>
224
- >
225
+ >;
225
226
 
226
227
  export type RawCommands = {
227
- [Item in keyof UnionCommands]: UnionCommands<Command>[Item]
228
- }
228
+ [Item in keyof UnionCommands]: UnionCommands<Command>[Item];
229
+ };
229
230
 
230
231
  export type SingleCommands = {
231
- [Item in keyof UnionCommands]: UnionCommands<boolean>[Item]
232
- }
232
+ [Item in keyof UnionCommands]: UnionCommands<boolean>[Item];
233
+ };
233
234
 
234
235
  export type ChainedCommands = {
235
- [Item in keyof UnionCommands]: UnionCommands<ChainedCommands>[Item]
236
+ [Item in keyof UnionCommands]: UnionCommands<ChainedCommands>[Item];
236
237
  } & {
237
- run: () => boolean
238
- }
238
+ run: () => boolean;
239
+ };
239
240
 
240
- export type CanCommands = SingleCommands & { chain: () => ChainedCommands }
241
+ export type CanCommands = SingleCommands & { chain: () => ChainedCommands };
241
242
 
242
- export type FocusPosition = 'start' | 'end' | 'all' | number | boolean | null
243
+ export type FocusPosition = 'start' | 'end' | 'all' | number | boolean | null;
243
244
 
244
245
  export type Range = {
245
- from: number
246
- to: number
247
- }
246
+ from: number;
247
+ to: number;
248
+ };
248
249
 
249
250
  export type NodeRange = {
250
- node: ProseMirrorNode
251
- from: number
252
- to: number
253
- }
251
+ node: ProseMirrorNode;
252
+ from: number;
253
+ to: number;
254
+ };
254
255
 
255
256
  export type MarkRange = {
256
- mark: ProseMirrorMark
257
- from: number
258
- to: number
259
- }
257
+ mark: ProseMirrorMark;
258
+ from: number;
259
+ to: number;
260
+ };
260
261
 
261
- export type Predicate = (node: ProseMirrorNode) => boolean
262
+ export type Predicate = (node: ProseMirrorNode) => boolean;
262
263
 
263
264
  export type NodeWithPos = {
264
- node: ProseMirrorNode
265
- pos: number
266
- }
265
+ node: ProseMirrorNode;
266
+ pos: number;
267
+ };
267
268
 
268
269
  export type TextSerializer = (props: {
269
- node: ProseMirrorNode
270
- pos: number
271
- parent: ProseMirrorNode
272
- index: number
273
- range: Range
274
- }) => string
270
+ node: ProseMirrorNode;
271
+ pos: number;
272
+ parent: ProseMirrorNode;
273
+ index: number;
274
+ range: Range;
275
+ }) => string;
275
276
 
276
277
  export type ExtendedRegExpMatchArray = RegExpMatchArray & {
277
- data?: Record<string, any>
278
- }
278
+ data?: Record<string, any>;
279
+ };
279
280
 
280
- export type Dispatch = ((args?: any) => any) | undefined
281
+ export type Dispatch = ((args?: any) => any) | undefined;