@tiptap/core 2.5.9 → 2.6.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.
@@ -16,6 +16,10 @@ export declare class Editor extends EventEmitter<EditorEvents> {
16
16
  schema: Schema;
17
17
  view: EditorView;
18
18
  isFocused: boolean;
19
+ /**
20
+ * The editor is considered initialized after the `create` event has been emitted.
21
+ */
22
+ isInitialized: boolean;
19
23
  extensionStorage: Record<string, any>;
20
24
  options: EditorOptions;
21
25
  constructor(options?: Partial<EditorOptions>);
@@ -17,10 +17,10 @@ declare module '@tiptap/core' {
17
17
  */
18
18
  name: string;
19
19
  /**
20
- * The priority of your extension. The higher, the later it will be called
20
+ * The priority of your extension. The higher, the earlier it will be called
21
21
  * and will take precedence over other extensions with a lower priority.
22
- * @default 1000
23
- * @example 1001
22
+ * @default 100
23
+ * @example 101
24
24
  */
25
25
  priority?: number;
26
26
  /**
@@ -286,6 +286,7 @@ declare module '@tiptap/core' {
286
286
  editor: Editor;
287
287
  parent: ParentConfig<ExtensionConfig<Options, Storage>>['onTransaction'];
288
288
  }, props: {
289
+ editor: Editor;
289
290
  transaction: Transaction;
290
291
  }) => void) | null;
291
292
  /**
@@ -17,10 +17,10 @@ declare module '@tiptap/core' {
17
17
  */
18
18
  name: string;
19
19
  /**
20
- * The priority of your extension. The higher, the later it will be called
20
+ * The priority of your extension. The higher, the earlier it will be called
21
21
  * and will take precedence over other extensions with a lower priority.
22
- * @default 1000
23
- * @example 1001
22
+ * @default 100
23
+ * @example 101
24
24
  */
25
25
  priority?: number;
26
26
  /**
@@ -296,6 +296,7 @@ declare module '@tiptap/core' {
296
296
  type: MarkType;
297
297
  parent: ParentConfig<MarkConfig<Options, Storage>>['onTransaction'];
298
298
  }, props: {
299
+ editor: Editor;
299
300
  transaction: Transaction;
300
301
  }) => void) | null;
301
302
  /**
@@ -17,10 +17,10 @@ declare module '@tiptap/core' {
17
17
  */
18
18
  name: string;
19
19
  /**
20
- * The priority of your extension. The higher, the later it will be called
20
+ * The priority of your extension. The higher, the earlier it will be called
21
21
  * and will take precedence over other extensions with a lower priority.
22
- * @default 1000
23
- * @example 1001
22
+ * @default 100
23
+ * @example 101
24
24
  */
25
25
  priority?: number;
26
26
  /**
@@ -297,6 +297,7 @@ declare module '@tiptap/core' {
297
297
  type: NodeType;
298
298
  parent: ParentConfig<NodeConfig<Options, Storage>>['onTransaction'];
299
299
  }, props: {
300
+ editor: Editor;
300
301
  transaction: Transaction;
301
302
  }) => void) | null;
302
303
  /**
@@ -1,3 +1,4 @@
1
+ import type { Plugin, PluginKey } from '@tiptap/pm/state';
1
2
  import { RawCommands } from '../types.js';
2
3
  declare module '@tiptap/core' {
3
4
  interface Commands<ReturnType> {
@@ -8,7 +9,7 @@ declare module '@tiptap/core' {
8
9
  * @param value The value to store.
9
10
  * @example editor.commands.setMeta('foo', 'bar')
10
11
  */
11
- setMeta: (key: string, value: any) => ReturnType;
12
+ setMeta: (key: string | Plugin | PluginKey, value: any) => ReturnType;
12
13
  };
13
14
  }
14
15
  }
@@ -6,9 +6,10 @@ declare module '@tiptap/core' {
6
6
  /**
7
7
  * Splits one list item into two list items.
8
8
  * @param typeOrName The type or name of the node.
9
+ * @param overrideAttrs The attributes to ensure on the new node.
9
10
  * @example editor.commands.splitListItem('listItem')
10
11
  */
11
- splitListItem: (typeOrName: string | NodeType) => ReturnType;
12
+ splitListItem: (typeOrName: string | NodeType, overrideAttrs?: Record<string, any>) => ReturnType;
12
13
  };
13
14
  }
14
15
  }
@@ -1,6 +1,6 @@
1
1
  import { NodeType } from '@tiptap/pm/model';
2
2
  import { PasteRule, PasteRuleFinder } from '../PasteRule.js';
3
- import { ExtendedRegExpMatchArray } from '../types.js';
3
+ import { ExtendedRegExpMatchArray, JSONContent } from '../types.js';
4
4
  /**
5
5
  * Build an paste rule that adds a node when the
6
6
  * matched text is pasted into it.
@@ -10,4 +10,5 @@ export declare function nodePasteRule(config: {
10
10
  find: PasteRuleFinder;
11
11
  type: NodeType;
12
12
  getAttributes?: Record<string, any> | ((match: ExtendedRegExpMatchArray, event: ClipboardEvent) => Record<string, any>) | false | null;
13
+ getContent?: JSONContent[] | ((attrs: Record<string, any>) => JSONContent[]) | false | null;
13
14
  }): PasteRule;
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.9",
4
+ "version": "2.6.1",
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.9"
35
+ "@tiptap/pm": "^2.6.1"
36
36
  },
37
37
  "peerDependencies": {
38
- "@tiptap/pm": "^2.5.9"
38
+ "@tiptap/pm": "^2.6.1"
39
39
  },
40
40
  "repository": {
41
41
  "type": "git",
package/src/Editor.ts CHANGED
@@ -57,6 +57,11 @@ export class Editor extends EventEmitter<EditorEvents> {
57
57
 
58
58
  public isFocused = false
59
59
 
60
+ /**
61
+ * The editor is considered initialized after the `create` event has been emitted.
62
+ */
63
+ public isInitialized = false
64
+
60
65
  public extensionStorage: Record<string, any> = {}
61
66
 
62
67
  public options: EditorOptions = {
@@ -111,6 +116,7 @@ export class Editor extends EventEmitter<EditorEvents> {
111
116
 
112
117
  this.commands.focus(this.options.autofocus)
113
118
  this.emit('create', { editor: this })
119
+ this.isInitialized = true
114
120
  }, 0)
115
121
  }
116
122
 
package/src/Extension.ts CHANGED
@@ -32,10 +32,10 @@ declare module '@tiptap/core' {
32
32
  name: string
33
33
 
34
34
  /**
35
- * The priority of your extension. The higher, the later it will be called
35
+ * The priority of your extension. The higher, the earlier it will be called
36
36
  * and will take precedence over other extensions with a lower priority.
37
- * @default 1000
38
- * @example 1001
37
+ * @default 100
38
+ * @example 101
39
39
  */
40
40
  priority?: number
41
41
 
@@ -339,6 +339,7 @@ declare module '@tiptap/core' {
339
339
  parent: ParentConfig<ExtensionConfig<Options, Storage>>['onTransaction']
340
340
  },
341
341
  props: {
342
+ editor: Editor
342
343
  transaction: Transaction
343
344
  },
344
345
  ) => void)
package/src/Mark.ts CHANGED
@@ -35,10 +35,10 @@ declare module '@tiptap/core' {
35
35
  name: string
36
36
 
37
37
  /**
38
- * The priority of your extension. The higher, the later it will be called
38
+ * The priority of your extension. The higher, the earlier it will be called
39
39
  * and will take precedence over other extensions with a lower priority.
40
- * @default 1000
41
- * @example 1001
40
+ * @default 100
41
+ * @example 101
42
42
  */
43
43
  priority?: number
44
44
 
@@ -352,6 +352,7 @@ declare module '@tiptap/core' {
352
352
  parent: ParentConfig<MarkConfig<Options, Storage>>['onTransaction']
353
353
  },
354
354
  props: {
355
+ editor: Editor
355
356
  transaction: Transaction
356
357
  },
357
358
  ) => void)
package/src/Node.ts CHANGED
@@ -36,10 +36,10 @@ declare module '@tiptap/core' {
36
36
  name: string
37
37
 
38
38
  /**
39
- * The priority of your extension. The higher, the later it will be called
39
+ * The priority of your extension. The higher, the earlier it will be called
40
40
  * and will take precedence over other extensions with a lower priority.
41
- * @default 1000
42
- * @example 1001
41
+ * @default 100
42
+ * @example 101
43
43
  */
44
44
  priority?: number
45
45
 
@@ -354,6 +354,7 @@ declare module '@tiptap/core' {
354
354
  parent: ParentConfig<NodeConfig<Options, Storage>>['onTransaction']
355
355
  },
356
356
  props: {
357
+ editor: Editor
357
358
  transaction: Transaction
358
359
  },
359
360
  ) => void)
@@ -1,3 +1,5 @@
1
+ import type { Plugin, PluginKey } from '@tiptap/pm/state'
2
+
1
3
  import { RawCommands } from '../types.js'
2
4
 
3
5
  declare module '@tiptap/core' {
@@ -9,7 +11,7 @@ declare module '@tiptap/core' {
9
11
  * @param value The value to store.
10
12
  * @example editor.commands.setMeta('foo', 'bar')
11
13
  */
12
- setMeta: (key: string, value: any) => ReturnType,
14
+ setMeta: (key: string | Plugin | PluginKey, value: any) => ReturnType,
13
15
  }
14
16
  }
15
17
  }
@@ -14,14 +14,15 @@ declare module '@tiptap/core' {
14
14
  /**
15
15
  * Splits one list item into two list items.
16
16
  * @param typeOrName The type or name of the node.
17
+ * @param overrideAttrs The attributes to ensure on the new node.
17
18
  * @example editor.commands.splitListItem('listItem')
18
19
  */
19
- splitListItem: (typeOrName: string | NodeType) => ReturnType
20
+ splitListItem: (typeOrName: string | NodeType, overrideAttrs?: Record<string, any>) => ReturnType
20
21
  }
21
22
  }
22
23
  }
23
24
 
24
- export const splitListItem: RawCommands['splitListItem'] = typeOrName => ({
25
+ export const splitListItem: RawCommands['splitListItem'] = (typeOrName, overrideAttrs = {}) => ({
25
26
  tr, state, dispatch, editor,
26
27
  }) => {
27
28
  const type = getNodeType(typeOrName, state.schema)
@@ -70,11 +71,14 @@ export const splitListItem: RawCommands['splitListItem'] = typeOrName => ({
70
71
  const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3
71
72
 
72
73
  // Add a second list item with an empty default start node
73
- const newNextTypeAttributes = getSplittedAttributes(
74
- extensionAttributes,
75
- $from.node().type.name,
76
- $from.node().attrs,
77
- )
74
+ const newNextTypeAttributes = {
75
+ ...getSplittedAttributes(
76
+ extensionAttributes,
77
+ $from.node().type.name,
78
+ $from.node().attrs,
79
+ ),
80
+ ...overrideAttrs,
81
+ }
78
82
  const nextType = type.contentMatch.defaultType?.createAndFill(newNextTypeAttributes) || undefined
79
83
 
80
84
  wrap = wrap.append(Fragment.from(type.createAndFill(null, nextType) || undefined))
@@ -107,16 +111,22 @@ export const splitListItem: RawCommands['splitListItem'] = typeOrName => ({
107
111
 
108
112
  const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null
109
113
 
110
- const newTypeAttributes = getSplittedAttributes(
111
- extensionAttributes,
112
- grandParent.type.name,
113
- grandParent.attrs,
114
- )
115
- const newNextTypeAttributes = getSplittedAttributes(
116
- extensionAttributes,
117
- $from.node().type.name,
118
- $from.node().attrs,
119
- )
114
+ const newTypeAttributes = {
115
+ ...getSplittedAttributes(
116
+ extensionAttributes,
117
+ grandParent.type.name,
118
+ grandParent.attrs,
119
+ ),
120
+ ...overrideAttrs,
121
+ }
122
+ const newNextTypeAttributes = {
123
+ ...getSplittedAttributes(
124
+ extensionAttributes,
125
+ $from.node().type.name,
126
+ $from.node().attrs,
127
+ ),
128
+ ...overrideAttrs,
129
+ }
120
130
 
121
131
  tr.delete($from.pos, $to.pos)
122
132
 
@@ -1,7 +1,7 @@
1
1
  import { NodeType } from '@tiptap/pm/model'
2
2
 
3
3
  import { PasteRule, PasteRuleFinder } from '../PasteRule.js'
4
- import { ExtendedRegExpMatchArray } from '../types.js'
4
+ import { ExtendedRegExpMatchArray, JSONContent } from '../types.js'
5
5
  import { callOrReturn } from '../utilities/index.js'
6
6
 
7
7
  /**
@@ -17,6 +17,11 @@ export function nodePasteRule(config: {
17
17
  | ((match: ExtendedRegExpMatchArray, event: ClipboardEvent) => Record<string, any>)
18
18
  | false
19
19
  | null
20
+ getContent?:
21
+ | JSONContent[]
22
+ | ((attrs: Record<string, any>) => JSONContent[])
23
+ | false
24
+ | null
20
25
  }) {
21
26
  return new PasteRule({
22
27
  find: config.find,
@@ -24,16 +29,20 @@ export function nodePasteRule(config: {
24
29
  match, chain, range, pasteEvent,
25
30
  }) {
26
31
  const attributes = callOrReturn(config.getAttributes, undefined, match, pasteEvent)
32
+ const content = callOrReturn(config.getContent, undefined, attributes)
27
33
 
28
34
  if (attributes === false || attributes === null) {
29
35
  return null
30
36
  }
31
37
 
38
+ const node = { type: config.type.name, attrs: attributes } as JSONContent
39
+
40
+ if (content) {
41
+ node.content = content
42
+ }
43
+
32
44
  if (match.input) {
33
- chain().deleteRange(range).insertContentAt(range.from, {
34
- type: config.type.name,
35
- attrs: attributes,
36
- })
45
+ chain().deleteRange(range).insertContentAt(range.from, node)
37
46
  }
38
47
  },
39
48
  })