@tiptap/core 3.18.0 → 3.20.0
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 +56 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -2
- package/dist/index.d.ts +38 -2
- package/dist/index.js +56 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/Editor.ts +8 -3
- package/src/Extendable.ts +24 -0
- package/src/ExtensionManager.ts +42 -1
- package/src/__tests__/transformPastedHTML.test.ts +575 -0
- package/src/helpers/getAttributesFromExtensions.ts +20 -1
- package/src/helpers/isMarkActive.ts +5 -0
- package/src/types.ts +11 -1
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.
|
|
4
|
+
"version": "3.20.0",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"jsx-dev-runtime"
|
|
53
53
|
],
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@tiptap/pm": "^3.
|
|
55
|
+
"@tiptap/pm": "^3.20.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@tiptap/pm": "^3.
|
|
58
|
+
"@tiptap/pm": "^3.20.0"
|
|
59
59
|
},
|
|
60
60
|
"repository": {
|
|
61
61
|
"type": "git",
|
package/src/Editor.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { MarkType, Node as ProseMirrorNode, NodeType, Schema } from '@tiptap/pm/model'
|
|
3
3
|
import type { Plugin, PluginKey, Transaction } from '@tiptap/pm/state'
|
|
4
4
|
import { EditorState } from '@tiptap/pm/state'
|
|
5
|
-
import { EditorView } from '@tiptap/pm/view'
|
|
5
|
+
import { type DirectEditorProps, EditorView } from '@tiptap/pm/view'
|
|
6
6
|
|
|
7
7
|
import { CommandManager } from './CommandManager.js'
|
|
8
8
|
import { EventEmitter } from './EventEmitter.js'
|
|
@@ -300,7 +300,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
/**
|
|
303
|
-
* Returns the editor
|
|
303
|
+
* Returns the editor view.
|
|
304
304
|
*/
|
|
305
305
|
public get view(): EditorView {
|
|
306
306
|
if (this.editorView) {
|
|
@@ -523,11 +523,15 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
523
523
|
// If a user provided a custom `dispatchTransaction` through `editorProps`,
|
|
524
524
|
// we use that as the base dispatch function.
|
|
525
525
|
// Otherwise, we use Tiptap's internal `dispatchTransaction` method.
|
|
526
|
-
const baseDispatch = (editorProps as
|
|
526
|
+
const baseDispatch = (editorProps as DirectEditorProps).dispatchTransaction || this.dispatchTransaction.bind(this)
|
|
527
527
|
const dispatch = enableExtensionDispatchTransaction
|
|
528
528
|
? this.extensionManager.dispatchTransaction(baseDispatch)
|
|
529
529
|
: baseDispatch
|
|
530
530
|
|
|
531
|
+
// Compose transformPastedHTML from extensions and user-provided editorProps
|
|
532
|
+
const baseTransformPastedHTML = (editorProps as DirectEditorProps).transformPastedHTML
|
|
533
|
+
const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML)
|
|
534
|
+
|
|
531
535
|
this.editorView = new EditorView(element, {
|
|
532
536
|
...editorProps,
|
|
533
537
|
attributes: {
|
|
@@ -536,6 +540,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
536
540
|
...editorProps?.attributes,
|
|
537
541
|
},
|
|
538
542
|
dispatchTransaction: dispatch,
|
|
543
|
+
transformPastedHTML,
|
|
539
544
|
state: this.editorState,
|
|
540
545
|
markViews: this.extensionManager.markViews,
|
|
541
546
|
nodeViews: this.extensionManager.nodeViews,
|
package/src/Extendable.ts
CHANGED
|
@@ -213,6 +213,30 @@ export interface ExtendableConfig<
|
|
|
213
213
|
parent: ParentConfig<Config>['addProseMirrorPlugins']
|
|
214
214
|
}) => Plugin[]
|
|
215
215
|
|
|
216
|
+
/**
|
|
217
|
+
* This function transforms pasted HTML content before it's parsed.
|
|
218
|
+
* Extensions can use this to modify or clean up pasted HTML.
|
|
219
|
+
* The transformations are chained - each extension's transform receives
|
|
220
|
+
* the output from the previous extension's transform.
|
|
221
|
+
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#transform-pasted-html
|
|
222
|
+
* @example
|
|
223
|
+
* transformPastedHTML(html) {
|
|
224
|
+
* // Remove all style attributes
|
|
225
|
+
* return html.replace(/style="[^"]*"/g, '')
|
|
226
|
+
* }
|
|
227
|
+
*/
|
|
228
|
+
transformPastedHTML?: (
|
|
229
|
+
this: {
|
|
230
|
+
name: string
|
|
231
|
+
options: Options
|
|
232
|
+
storage: Storage
|
|
233
|
+
editor: Editor
|
|
234
|
+
type: PMType
|
|
235
|
+
parent: ParentConfig<Config>['transformPastedHTML']
|
|
236
|
+
},
|
|
237
|
+
html: string,
|
|
238
|
+
) => string
|
|
239
|
+
|
|
216
240
|
/**
|
|
217
241
|
* This function adds additional extensions to the editor. This is useful for
|
|
218
242
|
* building extension kits.
|
package/src/ExtensionManager.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { keymap } from '@tiptap/pm/keymap'
|
|
2
2
|
import type { Schema } from '@tiptap/pm/model'
|
|
3
3
|
import type { Plugin, Transaction } from '@tiptap/pm/state'
|
|
4
|
-
import type { MarkViewConstructor, NodeViewConstructor } from '@tiptap/pm/view'
|
|
4
|
+
import type { EditorView, MarkViewConstructor, NodeViewConstructor } from '@tiptap/pm/view'
|
|
5
5
|
|
|
6
6
|
import type { Editor } from './Editor.js'
|
|
7
7
|
import {
|
|
@@ -277,6 +277,47 @@ export class ExtensionManager {
|
|
|
277
277
|
}, baseDispatch)
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Get the composed transformPastedHTML function from all extensions.
|
|
282
|
+
* @param baseTransform The base transform function (e.g. from the editor props)
|
|
283
|
+
* @returns A composed transform function that chains all extension transforms
|
|
284
|
+
*/
|
|
285
|
+
transformPastedHTML(
|
|
286
|
+
baseTransform?: (html: string, view?: any) => string,
|
|
287
|
+
): (html: string, view?: EditorView) => string {
|
|
288
|
+
const { editor } = this
|
|
289
|
+
const extensions = sortExtensions([...this.extensions])
|
|
290
|
+
|
|
291
|
+
return extensions.reduce(
|
|
292
|
+
(transform, extension) => {
|
|
293
|
+
const context = {
|
|
294
|
+
name: extension.name,
|
|
295
|
+
options: extension.options,
|
|
296
|
+
storage: this.editor.extensionStorage[extension.name as keyof Storage],
|
|
297
|
+
editor,
|
|
298
|
+
type: getSchemaTypeByName(extension.name, this.schema),
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const extensionTransform = getExtensionField<AnyConfig['transformPastedHTML']>(
|
|
302
|
+
extension,
|
|
303
|
+
'transformPastedHTML',
|
|
304
|
+
context,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
if (!extensionTransform) {
|
|
308
|
+
return transform
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return (html: string, view?: any) => {
|
|
312
|
+
// Chain the transforms: pass the result of the previous transform to the next
|
|
313
|
+
const transformedHtml = transform(html, view)
|
|
314
|
+
return extensionTransform.call(context, transformedHtml)
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
baseTransform || ((html: string) => html),
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
|
|
280
321
|
get markViews(): Record<string, MarkViewConstructor> {
|
|
281
322
|
const { editor } = this
|
|
282
323
|
const { markExtensions } = splitExtensions(this.extensions)
|