@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.
- package/LICENSE.md +1 -1
- package/dist/index.cjs +352 -238
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1084 -1431
- package/dist/index.d.ts +1084 -1431
- package/dist/index.js +344 -235
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime/jsx-runtime.cjs +56 -0
- package/dist/jsx-runtime/jsx-runtime.cjs.map +1 -0
- package/dist/jsx-runtime/jsx-runtime.d.cts +22 -0
- package/dist/jsx-runtime/jsx-runtime.d.ts +22 -0
- package/dist/jsx-runtime/jsx-runtime.js +26 -0
- package/dist/jsx-runtime/jsx-runtime.js.map +1 -0
- package/jsx-runtime/index.cjs +1 -0
- package/jsx-runtime/index.d.cts +1 -0
- package/jsx-runtime/index.d.ts +1 -0
- package/jsx-runtime/index.js +1 -0
- package/package.json +20 -3
- package/src/Editor.ts +104 -22
- package/src/Extendable.ts +483 -0
- package/src/Extension.ts +5 -490
- package/src/ExtensionManager.ts +55 -10
- package/src/Mark.ts +135 -623
- package/src/MarkView.ts +66 -0
- package/src/Node.ts +325 -829
- package/src/commands/clearContent.ts +9 -4
- package/src/commands/focus.ts +7 -1
- package/src/commands/insertContentAt.ts +6 -2
- package/src/commands/setContent.ts +15 -14
- package/src/extensions/delete.ts +89 -0
- package/src/extensions/index.ts +1 -0
- package/src/extensions/keymap.ts +4 -0
- package/src/helpers/getExtensionField.ts +10 -7
- package/src/index.ts +3 -7
- package/src/jsx-runtime.ts +64 -0
- package/src/types.ts +334 -19
- package/src/utilities/elementFromString.ts +3 -0
- package/src/utilities/index.ts +1 -0
- package/src/utilities/mergeAttributes.ts +1 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/jsx-runtime.ts
|
|
21
|
+
var jsx_runtime_exports = {};
|
|
22
|
+
__export(jsx_runtime_exports, {
|
|
23
|
+
Fragment: () => Fragment,
|
|
24
|
+
createElement: () => h,
|
|
25
|
+
h: () => h,
|
|
26
|
+
jsx: () => h,
|
|
27
|
+
jsxDEV: () => h,
|
|
28
|
+
jsxs: () => h
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(jsx_runtime_exports);
|
|
31
|
+
function Fragment(props) {
|
|
32
|
+
return props.children;
|
|
33
|
+
}
|
|
34
|
+
var h = (tag, attributes) => {
|
|
35
|
+
if (tag === "slot") {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
if (tag instanceof Function) {
|
|
39
|
+
return tag(attributes);
|
|
40
|
+
}
|
|
41
|
+
const { children, ...rest } = attributes != null ? attributes : {};
|
|
42
|
+
if (tag === "svg") {
|
|
43
|
+
throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");
|
|
44
|
+
}
|
|
45
|
+
return [tag, rest, children];
|
|
46
|
+
};
|
|
47
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
48
|
+
0 && (module.exports = {
|
|
49
|
+
Fragment,
|
|
50
|
+
createElement,
|
|
51
|
+
h,
|
|
52
|
+
jsx,
|
|
53
|
+
jsxDEV,
|
|
54
|
+
jsxs
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=jsx-runtime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/jsx-runtime.ts"],"sourcesContent":["export type Attributes = Record<string, any>\n\nexport type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray\n/**\n * Better describes the output of a `renderHTML` function in prosemirror\n * @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec\n */\nexport type DOMOutputSpecArray =\n | [string]\n | [string, Attributes]\n | [string, 0]\n | [string, Attributes, 0]\n | [string, Attributes, DOMOutputSpecArray | 0]\n | [string, DOMOutputSpecArray]\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace JSX {\n // @ts-ignore - conflict with React typings\n type Element = [string, ...any[]]\n // @ts-ignore - conflict with React typings\n interface IntrinsicElements {\n // @ts-ignore - conflict with React typings\n [key: string]: any\n }\n }\n}\n\nexport type JSXRenderer = (\n tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement),\n props?: Attributes,\n ...children: JSXRenderer[]\n) => DOMOutputSpecArray | DOMOutputSpecElement\n\nexport function Fragment(props: { children: JSXRenderer[] }) {\n return props.children\n}\n\nexport const h: JSXRenderer = (tag, attributes) => {\n // Treat the slot tag as the Prosemirror hole to render content into\n if (tag === 'slot') {\n return 0\n }\n\n // If the tag is a function, call it with the props\n if (tag instanceof Function) {\n return tag(attributes)\n }\n\n const { children, ...rest } = attributes ?? {}\n\n if (tag === 'svg') {\n throw new Error('SVG elements are not supported in the JSX syntax, use the array syntax instead')\n }\n\n // Otherwise, return the tag, attributes, and children\n return [tag, rest, children]\n}\n\n// See\n// https://esbuild.github.io/api/#jsx-import-source\n// https://www.typescriptlang.org/tsconfig/#jsxImportSource\n\nexport { h as createElement, h as jsx, h as jsxDEV, h as jsxs }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCO,SAAS,SAAS,OAAoC;AAC3D,SAAO,MAAM;AACf;AAEO,IAAM,IAAiB,CAAC,KAAK,eAAe;AAEjD,MAAI,QAAQ,QAAQ;AAClB,WAAO;AAAA,EACT;AAGA,MAAI,eAAe,UAAU;AAC3B,WAAO,IAAI,UAAU;AAAA,EACvB;AAEA,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI,kCAAc,CAAC;AAE7C,MAAI,QAAQ,OAAO;AACjB,UAAM,IAAI,MAAM,gFAAgF;AAAA,EAClG;AAGA,SAAO,CAAC,KAAK,MAAM,QAAQ;AAC7B;","names":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type Attributes = Record<string, any>;
|
|
2
|
+
type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray;
|
|
3
|
+
/**
|
|
4
|
+
* Better describes the output of a `renderHTML` function in prosemirror
|
|
5
|
+
* @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec
|
|
6
|
+
*/
|
|
7
|
+
type DOMOutputSpecArray = [string] | [string, Attributes] | [string, 0] | [string, Attributes, 0] | [string, Attributes, DOMOutputSpecArray | 0] | [string, DOMOutputSpecArray];
|
|
8
|
+
declare global {
|
|
9
|
+
namespace JSX {
|
|
10
|
+
type Element = [string, ...any[]];
|
|
11
|
+
interface IntrinsicElements {
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
type JSXRenderer = (tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement), props?: Attributes, ...children: JSXRenderer[]) => DOMOutputSpecArray | DOMOutputSpecElement;
|
|
17
|
+
declare function Fragment(props: {
|
|
18
|
+
children: JSXRenderer[];
|
|
19
|
+
}): JSXRenderer[];
|
|
20
|
+
declare const h: JSXRenderer;
|
|
21
|
+
|
|
22
|
+
export { type Attributes, type DOMOutputSpecArray, type DOMOutputSpecElement, Fragment, type JSXRenderer, h as createElement, h, h as jsx, h as jsxDEV, h as jsxs };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type Attributes = Record<string, any>;
|
|
2
|
+
type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray;
|
|
3
|
+
/**
|
|
4
|
+
* Better describes the output of a `renderHTML` function in prosemirror
|
|
5
|
+
* @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec
|
|
6
|
+
*/
|
|
7
|
+
type DOMOutputSpecArray = [string] | [string, Attributes] | [string, 0] | [string, Attributes, 0] | [string, Attributes, DOMOutputSpecArray | 0] | [string, DOMOutputSpecArray];
|
|
8
|
+
declare global {
|
|
9
|
+
namespace JSX {
|
|
10
|
+
type Element = [string, ...any[]];
|
|
11
|
+
interface IntrinsicElements {
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
type JSXRenderer = (tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement), props?: Attributes, ...children: JSXRenderer[]) => DOMOutputSpecArray | DOMOutputSpecElement;
|
|
17
|
+
declare function Fragment(props: {
|
|
18
|
+
children: JSXRenderer[];
|
|
19
|
+
}): JSXRenderer[];
|
|
20
|
+
declare const h: JSXRenderer;
|
|
21
|
+
|
|
22
|
+
export { type Attributes, type DOMOutputSpecArray, type DOMOutputSpecElement, Fragment, type JSXRenderer, h as createElement, h, h as jsx, h as jsxDEV, h as jsxs };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/jsx-runtime.ts
|
|
2
|
+
function Fragment(props) {
|
|
3
|
+
return props.children;
|
|
4
|
+
}
|
|
5
|
+
var h = (tag, attributes) => {
|
|
6
|
+
if (tag === "slot") {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
if (tag instanceof Function) {
|
|
10
|
+
return tag(attributes);
|
|
11
|
+
}
|
|
12
|
+
const { children, ...rest } = attributes != null ? attributes : {};
|
|
13
|
+
if (tag === "svg") {
|
|
14
|
+
throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");
|
|
15
|
+
}
|
|
16
|
+
return [tag, rest, children];
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
Fragment,
|
|
20
|
+
h as createElement,
|
|
21
|
+
h,
|
|
22
|
+
h as jsx,
|
|
23
|
+
h as jsxDEV,
|
|
24
|
+
h as jsxs
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=jsx-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/jsx-runtime.ts"],"sourcesContent":["export type Attributes = Record<string, any>\n\nexport type DOMOutputSpecElement = 0 | Attributes | DOMOutputSpecArray\n/**\n * Better describes the output of a `renderHTML` function in prosemirror\n * @see https://prosemirror.net/docs/ref/#model.DOMOutputSpec\n */\nexport type DOMOutputSpecArray =\n | [string]\n | [string, Attributes]\n | [string, 0]\n | [string, Attributes, 0]\n | [string, Attributes, DOMOutputSpecArray | 0]\n | [string, DOMOutputSpecArray]\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace JSX {\n // @ts-ignore - conflict with React typings\n type Element = [string, ...any[]]\n // @ts-ignore - conflict with React typings\n interface IntrinsicElements {\n // @ts-ignore - conflict with React typings\n [key: string]: any\n }\n }\n}\n\nexport type JSXRenderer = (\n tag: 'slot' | string | ((props?: Attributes) => DOMOutputSpecArray | DOMOutputSpecElement),\n props?: Attributes,\n ...children: JSXRenderer[]\n) => DOMOutputSpecArray | DOMOutputSpecElement\n\nexport function Fragment(props: { children: JSXRenderer[] }) {\n return props.children\n}\n\nexport const h: JSXRenderer = (tag, attributes) => {\n // Treat the slot tag as the Prosemirror hole to render content into\n if (tag === 'slot') {\n return 0\n }\n\n // If the tag is a function, call it with the props\n if (tag instanceof Function) {\n return tag(attributes)\n }\n\n const { children, ...rest } = attributes ?? {}\n\n if (tag === 'svg') {\n throw new Error('SVG elements are not supported in the JSX syntax, use the array syntax instead')\n }\n\n // Otherwise, return the tag, attributes, and children\n return [tag, rest, children]\n}\n\n// See\n// https://esbuild.github.io/api/#jsx-import-source\n// https://www.typescriptlang.org/tsconfig/#jsxImportSource\n\nexport { h as createElement, h as jsx, h as jsxDEV, h as jsxs }\n"],"mappings":";AAkCO,SAAS,SAAS,OAAoC;AAC3D,SAAO,MAAM;AACf;AAEO,IAAM,IAAiB,CAAC,KAAK,eAAe;AAEjD,MAAI,QAAQ,QAAQ;AAClB,WAAO;AAAA,EACT;AAGA,MAAI,eAAe,UAAU;AAC3B,WAAO,IAAI,UAAU;AAAA,EACvB;AAEA,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI,kCAAc,CAAC;AAE7C,MAAI,QAAQ,OAAO;AACjB,UAAM,IAAI,MAAM,gFAAgF;AAAA,EAClG;AAGA,SAAO,CAAC,KAAK,MAAM,QAAQ;AAC7B;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../dist/jsx-runtime/jsx-runtime.cjs'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../src/jsx-runtime.ts'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from '../src/jsx-runtime.ts'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../dist/jsx-runtime/jsx-runtime.js'
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/core",
|
|
3
3
|
"description": "headless rich text editor",
|
|
4
|
-
"version": "3.0.0-next.
|
|
4
|
+
"version": "3.0.0-next.6",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -24,6 +24,22 @@
|
|
|
24
24
|
},
|
|
25
25
|
"import": "./dist/index.js",
|
|
26
26
|
"require": "./dist/index.cjs"
|
|
27
|
+
},
|
|
28
|
+
"./jsx-runtime": {
|
|
29
|
+
"types": {
|
|
30
|
+
"import": "./jsx-runtime/index.d.ts",
|
|
31
|
+
"require": "./jsx-runtime/index.d.cts"
|
|
32
|
+
},
|
|
33
|
+
"import": "./jsx-runtime/index.js",
|
|
34
|
+
"require": "./jsx-runtime/index.cjs"
|
|
35
|
+
},
|
|
36
|
+
"./jsx-dev-runtime": {
|
|
37
|
+
"types": {
|
|
38
|
+
"import": "./jsx-dev-runtime/index.d.ts",
|
|
39
|
+
"require": "./jsx-dev-runtime/index.d.cts"
|
|
40
|
+
},
|
|
41
|
+
"import": "./jsx-dev-runtime/index.js",
|
|
42
|
+
"require": "./jsx-dev-runtime/index.cjs"
|
|
27
43
|
}
|
|
28
44
|
},
|
|
29
45
|
"main": "dist/index.cjs",
|
|
@@ -31,10 +47,11 @@
|
|
|
31
47
|
"types": "dist/index.d.ts",
|
|
32
48
|
"files": [
|
|
33
49
|
"src",
|
|
34
|
-
"dist"
|
|
50
|
+
"dist",
|
|
51
|
+
"jsx-runtime"
|
|
35
52
|
],
|
|
36
53
|
"devDependencies": {
|
|
37
|
-
"@tiptap/pm": "^3.0.0-next.
|
|
54
|
+
"@tiptap/pm": "^3.0.0-next.6"
|
|
38
55
|
},
|
|
39
56
|
"peerDependencies": {
|
|
40
57
|
"@tiptap/pm": "^3.0.0-next.1"
|
package/src/Editor.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { ExtensionManager } from './ExtensionManager.js'
|
|
|
9
9
|
import {
|
|
10
10
|
ClipboardTextSerializer,
|
|
11
11
|
Commands,
|
|
12
|
+
Delete,
|
|
12
13
|
Drop,
|
|
13
14
|
Editable,
|
|
14
15
|
FocusEvents,
|
|
@@ -24,6 +25,7 @@ import { getTextSerializersFromSchema } from './helpers/getTextSerializersFromSc
|
|
|
24
25
|
import { isActive } from './helpers/isActive.js'
|
|
25
26
|
import { isNodeEmpty } from './helpers/isNodeEmpty.js'
|
|
26
27
|
import { resolveFocusPosition } from './helpers/resolveFocusPosition.js'
|
|
28
|
+
import type { Storage } from './index.js'
|
|
27
29
|
import { NodePos } from './NodePos.js'
|
|
28
30
|
import { style } from './style.js'
|
|
29
31
|
import {
|
|
@@ -56,16 +58,18 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
56
58
|
|
|
57
59
|
public schema!: Schema
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
private editorView: EditorView | null = null
|
|
60
62
|
|
|
61
63
|
public isFocused = false
|
|
62
64
|
|
|
65
|
+
private editorState!: EditorState
|
|
66
|
+
|
|
63
67
|
/**
|
|
64
68
|
* The editor is considered initialized after the `create` event has been emitted.
|
|
65
69
|
*/
|
|
66
70
|
public isInitialized = false
|
|
67
71
|
|
|
68
|
-
public extensionStorage:
|
|
72
|
+
public extensionStorage: Storage = {} as Storage
|
|
69
73
|
|
|
70
74
|
/**
|
|
71
75
|
* A unique ID for this editor instance.
|
|
@@ -73,7 +77,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
73
77
|
public instanceId = Math.random().toString(36).slice(2, 9)
|
|
74
78
|
|
|
75
79
|
public options: EditorOptions = {
|
|
76
|
-
element: document.createElement('div'),
|
|
80
|
+
element: typeof document !== 'undefined' ? document.createElement('div') : null,
|
|
77
81
|
content: '',
|
|
78
82
|
injectCSS: true,
|
|
79
83
|
injectNonce: undefined,
|
|
@@ -100,6 +104,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
100
104
|
},
|
|
101
105
|
onPaste: () => null,
|
|
102
106
|
onDrop: () => null,
|
|
107
|
+
onDelete: () => null,
|
|
103
108
|
}
|
|
104
109
|
|
|
105
110
|
constructor(options: Partial<EditorOptions> = {}) {
|
|
@@ -111,8 +116,6 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
111
116
|
this.on('beforeCreate', this.options.onBeforeCreate)
|
|
112
117
|
this.emit('beforeCreate', { editor: this })
|
|
113
118
|
this.on('contentError', this.options.onContentError)
|
|
114
|
-
this.createView()
|
|
115
|
-
this.injectCSS()
|
|
116
119
|
this.on('create', this.options.onCreate)
|
|
117
120
|
this.on('update', this.options.onUpdate)
|
|
118
121
|
this.on('selectionUpdate', this.options.onSelectionUpdate)
|
|
@@ -122,6 +125,30 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
122
125
|
this.on('destroy', this.options.onDestroy)
|
|
123
126
|
this.on('drop', ({ event, slice, moved }) => this.options.onDrop(event, slice, moved))
|
|
124
127
|
this.on('paste', ({ event, slice }) => this.options.onPaste(event, slice))
|
|
128
|
+
this.on('delete', this.options.onDelete)
|
|
129
|
+
|
|
130
|
+
const initialDoc = this.createDoc()
|
|
131
|
+
const selection = resolveFocusPosition(initialDoc, this.options.autofocus)
|
|
132
|
+
|
|
133
|
+
// Set editor state immediately, so that it's available independently from the view
|
|
134
|
+
this.editorState = EditorState.create({
|
|
135
|
+
doc: initialDoc,
|
|
136
|
+
schema: this.schema,
|
|
137
|
+
selection: selection || undefined,
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
if (this.options.element) {
|
|
141
|
+
this.mount(this.options.element)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public mount(el: NonNullable<EditorOptions['element']> & {}) {
|
|
146
|
+
if (typeof document === 'undefined') {
|
|
147
|
+
throw new Error(
|
|
148
|
+
`[tiptap error]: The editor cannot be mounted because there is no 'document' defined in this environment.`,
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
this.createView(el)
|
|
125
152
|
|
|
126
153
|
window.setTimeout(() => {
|
|
127
154
|
if (this.isDestroyed) {
|
|
@@ -137,7 +164,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
137
164
|
/**
|
|
138
165
|
* Returns the editor storage.
|
|
139
166
|
*/
|
|
140
|
-
public get storage():
|
|
167
|
+
public get storage(): Storage {
|
|
141
168
|
return this.extensionStorage
|
|
142
169
|
}
|
|
143
170
|
|
|
@@ -166,7 +193,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
166
193
|
* Inject CSS styles.
|
|
167
194
|
*/
|
|
168
195
|
private injectCSS(): void {
|
|
169
|
-
if (this.options.injectCSS && document) {
|
|
196
|
+
if (this.options.injectCSS && typeof document !== 'undefined') {
|
|
170
197
|
this.css = createStyleTag(style, this.options.injectNonce)
|
|
171
198
|
}
|
|
172
199
|
}
|
|
@@ -182,7 +209,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
182
209
|
...options,
|
|
183
210
|
}
|
|
184
211
|
|
|
185
|
-
if (!this.
|
|
212
|
+
if (!this.editorView || !this.state || this.isDestroyed) {
|
|
186
213
|
return
|
|
187
214
|
}
|
|
188
215
|
|
|
@@ -214,11 +241,57 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
214
241
|
return this.options.editable && this.view && this.view.editable
|
|
215
242
|
}
|
|
216
243
|
|
|
244
|
+
/**
|
|
245
|
+
* Returns the editor state.
|
|
246
|
+
*/
|
|
247
|
+
public get view(): EditorView {
|
|
248
|
+
if (this.editorView) {
|
|
249
|
+
return this.editorView
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return new Proxy(
|
|
253
|
+
{
|
|
254
|
+
state: this.editorState,
|
|
255
|
+
updateState: (state: EditorState): ReturnType<EditorView['updateState']> => {
|
|
256
|
+
this.editorState = state
|
|
257
|
+
},
|
|
258
|
+
dispatch: (tr: Transaction): ReturnType<EditorView['dispatch']> => {
|
|
259
|
+
this.editorState = this.state.apply(tr)
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
// Stub some commonly accessed properties to prevent errors
|
|
263
|
+
composing: false,
|
|
264
|
+
dragging: null,
|
|
265
|
+
editable: true,
|
|
266
|
+
} as EditorView,
|
|
267
|
+
{
|
|
268
|
+
get: (obj, key) => {
|
|
269
|
+
// Specifically always return the most recent editorState
|
|
270
|
+
if (key === 'state') {
|
|
271
|
+
return this.editorState
|
|
272
|
+
}
|
|
273
|
+
if (key in obj) {
|
|
274
|
+
return Reflect.get(obj, key)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// We throw an error here, because we know the view is not available
|
|
278
|
+
throw new Error(
|
|
279
|
+
`[tiptap error]: The editor view is not available. Cannot access view['${key as string}']. The editor may not be mounted yet.`,
|
|
280
|
+
)
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
) as EditorView
|
|
284
|
+
}
|
|
285
|
+
|
|
217
286
|
/**
|
|
218
287
|
* Returns the editor state.
|
|
219
288
|
*/
|
|
220
289
|
public get state(): EditorState {
|
|
221
|
-
|
|
290
|
+
if (this.editorView) {
|
|
291
|
+
this.editorState = this.view.state
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return this.editorState
|
|
222
295
|
}
|
|
223
296
|
|
|
224
297
|
/**
|
|
@@ -297,6 +370,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
297
370
|
Tabindex,
|
|
298
371
|
Drop,
|
|
299
372
|
Paste,
|
|
373
|
+
Delete,
|
|
300
374
|
].filter(ext => {
|
|
301
375
|
if (typeof this.options.enableCoreExtensions === 'object') {
|
|
302
376
|
return (
|
|
@@ -330,9 +404,9 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
330
404
|
}
|
|
331
405
|
|
|
332
406
|
/**
|
|
333
|
-
* Creates
|
|
407
|
+
* Creates the initial document.
|
|
334
408
|
*/
|
|
335
|
-
private
|
|
409
|
+
private createDoc(): ProseMirrorNode {
|
|
336
410
|
let doc: ProseMirrorNode
|
|
337
411
|
|
|
338
412
|
try {
|
|
@@ -351,8 +425,12 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
351
425
|
editor: this,
|
|
352
426
|
error: e as Error,
|
|
353
427
|
disableCollaboration: () => {
|
|
354
|
-
if (
|
|
355
|
-
this.storage
|
|
428
|
+
if (
|
|
429
|
+
'collaboration' in this.storage &&
|
|
430
|
+
typeof this.storage.collaboration === 'object' &&
|
|
431
|
+
this.storage.collaboration
|
|
432
|
+
) {
|
|
433
|
+
;(this.storage.collaboration as any).isDisabled = true
|
|
356
434
|
}
|
|
357
435
|
// To avoid syncing back invalid content, reinitialize the extensions without the collaboration extension
|
|
358
436
|
this.options.extensions = this.options.extensions.filter(extension => extension.name !== 'collaboration')
|
|
@@ -367,9 +445,14 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
367
445
|
errorOnInvalidContent: false,
|
|
368
446
|
})
|
|
369
447
|
}
|
|
370
|
-
|
|
448
|
+
return doc
|
|
449
|
+
}
|
|
371
450
|
|
|
372
|
-
|
|
451
|
+
/**
|
|
452
|
+
* Creates a ProseMirror view.
|
|
453
|
+
*/
|
|
454
|
+
private createView(element: NonNullable<EditorOptions['element']> & {}): void {
|
|
455
|
+
this.editorView = new EditorView(element, {
|
|
373
456
|
...this.options.editorProps,
|
|
374
457
|
attributes: {
|
|
375
458
|
// add `role="textbox"` to the editor element
|
|
@@ -377,10 +460,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
377
460
|
...this.options.editorProps?.attributes,
|
|
378
461
|
},
|
|
379
462
|
dispatchTransaction: this.dispatchTransaction.bind(this),
|
|
380
|
-
state:
|
|
381
|
-
doc,
|
|
382
|
-
selection: selection || undefined,
|
|
383
|
-
}),
|
|
463
|
+
state: this.editorState,
|
|
384
464
|
})
|
|
385
465
|
|
|
386
466
|
// `editor.view` is not yet available at this time.
|
|
@@ -393,6 +473,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
393
473
|
|
|
394
474
|
this.createNodeViews()
|
|
395
475
|
this.prependClass()
|
|
476
|
+
this.injectCSS()
|
|
396
477
|
|
|
397
478
|
// Let’s store the editor instance in the DOM element.
|
|
398
479
|
// So we’ll have access to it for tests.
|
|
@@ -411,6 +492,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
411
492
|
}
|
|
412
493
|
|
|
413
494
|
this.view.setProps({
|
|
495
|
+
markViews: this.extensionManager.markViews,
|
|
414
496
|
nodeViews: this.extensionManager.nodeViews,
|
|
415
497
|
})
|
|
416
498
|
}
|
|
@@ -602,15 +684,15 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
602
684
|
public destroy(): void {
|
|
603
685
|
this.emit('destroy')
|
|
604
686
|
|
|
605
|
-
if (this.
|
|
687
|
+
if (this.editorView) {
|
|
606
688
|
// Cleanup our reference to prevent circular references which caused memory leaks
|
|
607
689
|
// @ts-ignore
|
|
608
|
-
const dom = this.
|
|
690
|
+
const dom = this.editorView.dom as TiptapEditorHTMLElement
|
|
609
691
|
|
|
610
692
|
if (dom && dom.editor) {
|
|
611
693
|
delete dom.editor
|
|
612
694
|
}
|
|
613
|
-
this.
|
|
695
|
+
this.editorView.destroy()
|
|
614
696
|
}
|
|
615
697
|
|
|
616
698
|
this.removeAllListeners()
|