@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/dist/index.d.cts
CHANGED
|
@@ -719,6 +719,26 @@ interface ExtendableConfig<Options = any, Storage = any, Config extends Extensio
|
|
|
719
719
|
type: PMType;
|
|
720
720
|
parent: ParentConfig<Config>['addProseMirrorPlugins'];
|
|
721
721
|
}) => Plugin[];
|
|
722
|
+
/**
|
|
723
|
+
* This function transforms pasted HTML content before it's parsed.
|
|
724
|
+
* Extensions can use this to modify or clean up pasted HTML.
|
|
725
|
+
* The transformations are chained - each extension's transform receives
|
|
726
|
+
* the output from the previous extension's transform.
|
|
727
|
+
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#transform-pasted-html
|
|
728
|
+
* @example
|
|
729
|
+
* transformPastedHTML(html) {
|
|
730
|
+
* // Remove all style attributes
|
|
731
|
+
* return html.replace(/style="[^"]*"/g, '')
|
|
732
|
+
* }
|
|
733
|
+
*/
|
|
734
|
+
transformPastedHTML?: (this: {
|
|
735
|
+
name: string;
|
|
736
|
+
options: Options;
|
|
737
|
+
storage: Storage;
|
|
738
|
+
editor: Editor;
|
|
739
|
+
type: PMType;
|
|
740
|
+
parent: ParentConfig<Config>['transformPastedHTML'];
|
|
741
|
+
}, html: string) => string;
|
|
722
742
|
/**
|
|
723
743
|
* This function adds additional extensions to the editor. This is useful for
|
|
724
744
|
* building extension kits.
|
|
@@ -1496,8 +1516,18 @@ type ExtensionAttribute = {
|
|
|
1496
1516
|
type GlobalAttributes = {
|
|
1497
1517
|
/**
|
|
1498
1518
|
* The node & mark types this attribute should be applied to.
|
|
1519
|
+
* Can be a specific array of type names, or a shorthand string:
|
|
1520
|
+
* - `'*'` applies to all nodes (excluding text) and all marks
|
|
1521
|
+
* - `'nodes'` applies to all nodes (excluding the built-in text node)
|
|
1522
|
+
* - `'marks'` applies to all marks
|
|
1523
|
+
* - `string[]` applies to specific node/mark types by name
|
|
1524
|
+
* @example
|
|
1525
|
+
* types: '*' // All nodes and marks
|
|
1526
|
+
* types: 'nodes' // All nodes
|
|
1527
|
+
* types: 'marks' // All marks
|
|
1528
|
+
* types: ['heading', 'paragraph'] // Specific types
|
|
1499
1529
|
*/
|
|
1500
|
-
types: string[];
|
|
1530
|
+
types: string[] | 'nodes' | 'marks' | '*';
|
|
1501
1531
|
/**
|
|
1502
1532
|
* The attributes to add to the node or mark types.
|
|
1503
1533
|
*/
|
|
@@ -2320,6 +2350,12 @@ declare class ExtensionManager {
|
|
|
2320
2350
|
* @returns A composed dispatch function
|
|
2321
2351
|
*/
|
|
2322
2352
|
dispatchTransaction(baseDispatch: (tr: Transaction) => void): (tr: Transaction) => void;
|
|
2353
|
+
/**
|
|
2354
|
+
* Get the composed transformPastedHTML function from all extensions.
|
|
2355
|
+
* @param baseTransform The base transform function (e.g. from the editor props)
|
|
2356
|
+
* @returns A composed transform function that chains all extension transforms
|
|
2357
|
+
*/
|
|
2358
|
+
transformPastedHTML(baseTransform?: (html: string, view?: any) => string): (html: string, view?: EditorView) => string;
|
|
2323
2359
|
get markViews(): Record<string, MarkViewConstructor>;
|
|
2324
2360
|
/**
|
|
2325
2361
|
* Go through all extensions, create extension storages & setup marks
|
|
@@ -3528,7 +3564,7 @@ declare class Editor extends EventEmitter<EditorEvents> {
|
|
|
3528
3564
|
*/
|
|
3529
3565
|
get isEditable(): boolean;
|
|
3530
3566
|
/**
|
|
3531
|
-
* Returns the editor
|
|
3567
|
+
* Returns the editor view.
|
|
3532
3568
|
*/
|
|
3533
3569
|
get view(): EditorView;
|
|
3534
3570
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -719,6 +719,26 @@ interface ExtendableConfig<Options = any, Storage = any, Config extends Extensio
|
|
|
719
719
|
type: PMType;
|
|
720
720
|
parent: ParentConfig<Config>['addProseMirrorPlugins'];
|
|
721
721
|
}) => Plugin[];
|
|
722
|
+
/**
|
|
723
|
+
* This function transforms pasted HTML content before it's parsed.
|
|
724
|
+
* Extensions can use this to modify or clean up pasted HTML.
|
|
725
|
+
* The transformations are chained - each extension's transform receives
|
|
726
|
+
* the output from the previous extension's transform.
|
|
727
|
+
* @see https://tiptap.dev/docs/editor/guide/custom-extensions#transform-pasted-html
|
|
728
|
+
* @example
|
|
729
|
+
* transformPastedHTML(html) {
|
|
730
|
+
* // Remove all style attributes
|
|
731
|
+
* return html.replace(/style="[^"]*"/g, '')
|
|
732
|
+
* }
|
|
733
|
+
*/
|
|
734
|
+
transformPastedHTML?: (this: {
|
|
735
|
+
name: string;
|
|
736
|
+
options: Options;
|
|
737
|
+
storage: Storage;
|
|
738
|
+
editor: Editor;
|
|
739
|
+
type: PMType;
|
|
740
|
+
parent: ParentConfig<Config>['transformPastedHTML'];
|
|
741
|
+
}, html: string) => string;
|
|
722
742
|
/**
|
|
723
743
|
* This function adds additional extensions to the editor. This is useful for
|
|
724
744
|
* building extension kits.
|
|
@@ -1496,8 +1516,18 @@ type ExtensionAttribute = {
|
|
|
1496
1516
|
type GlobalAttributes = {
|
|
1497
1517
|
/**
|
|
1498
1518
|
* The node & mark types this attribute should be applied to.
|
|
1519
|
+
* Can be a specific array of type names, or a shorthand string:
|
|
1520
|
+
* - `'*'` applies to all nodes (excluding text) and all marks
|
|
1521
|
+
* - `'nodes'` applies to all nodes (excluding the built-in text node)
|
|
1522
|
+
* - `'marks'` applies to all marks
|
|
1523
|
+
* - `string[]` applies to specific node/mark types by name
|
|
1524
|
+
* @example
|
|
1525
|
+
* types: '*' // All nodes and marks
|
|
1526
|
+
* types: 'nodes' // All nodes
|
|
1527
|
+
* types: 'marks' // All marks
|
|
1528
|
+
* types: ['heading', 'paragraph'] // Specific types
|
|
1499
1529
|
*/
|
|
1500
|
-
types: string[];
|
|
1530
|
+
types: string[] | 'nodes' | 'marks' | '*';
|
|
1501
1531
|
/**
|
|
1502
1532
|
* The attributes to add to the node or mark types.
|
|
1503
1533
|
*/
|
|
@@ -2320,6 +2350,12 @@ declare class ExtensionManager {
|
|
|
2320
2350
|
* @returns A composed dispatch function
|
|
2321
2351
|
*/
|
|
2322
2352
|
dispatchTransaction(baseDispatch: (tr: Transaction) => void): (tr: Transaction) => void;
|
|
2353
|
+
/**
|
|
2354
|
+
* Get the composed transformPastedHTML function from all extensions.
|
|
2355
|
+
* @param baseTransform The base transform function (e.g. from the editor props)
|
|
2356
|
+
* @returns A composed transform function that chains all extension transforms
|
|
2357
|
+
*/
|
|
2358
|
+
transformPastedHTML(baseTransform?: (html: string, view?: any) => string): (html: string, view?: EditorView) => string;
|
|
2323
2359
|
get markViews(): Record<string, MarkViewConstructor>;
|
|
2324
2360
|
/**
|
|
2325
2361
|
* Go through all extensions, create extension storages & setup marks
|
|
@@ -3528,7 +3564,7 @@ declare class Editor extends EventEmitter<EditorEvents> {
|
|
|
3528
3564
|
*/
|
|
3529
3565
|
get isEditable(): boolean;
|
|
3530
3566
|
/**
|
|
3531
|
-
* Returns the editor
|
|
3567
|
+
* Returns the editor view.
|
|
3532
3568
|
*/
|
|
3533
3569
|
get view(): EditorView;
|
|
3534
3570
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1348,6 +1348,9 @@ function getAttributesFromExtensions(extensions) {
|
|
|
1348
1348
|
keepOnSplit: true,
|
|
1349
1349
|
isRequired: false
|
|
1350
1350
|
};
|
|
1351
|
+
const nodeExtensionTypes = nodeExtensions.filter((ext) => ext.name !== "text").map((ext) => ext.name);
|
|
1352
|
+
const markExtensionTypes = markExtensions.map((ext) => ext.name);
|
|
1353
|
+
const allExtensionTypes = [...nodeExtensionTypes, ...markExtensionTypes];
|
|
1351
1354
|
extensions.forEach((extension) => {
|
|
1352
1355
|
const context = {
|
|
1353
1356
|
name: extension.name,
|
|
@@ -1365,7 +1368,19 @@ function getAttributesFromExtensions(extensions) {
|
|
|
1365
1368
|
}
|
|
1366
1369
|
const globalAttributes = addGlobalAttributes();
|
|
1367
1370
|
globalAttributes.forEach((globalAttribute) => {
|
|
1368
|
-
|
|
1371
|
+
let resolvedTypes;
|
|
1372
|
+
if (Array.isArray(globalAttribute.types)) {
|
|
1373
|
+
resolvedTypes = globalAttribute.types;
|
|
1374
|
+
} else if (globalAttribute.types === "*") {
|
|
1375
|
+
resolvedTypes = allExtensionTypes;
|
|
1376
|
+
} else if (globalAttribute.types === "nodes") {
|
|
1377
|
+
resolvedTypes = nodeExtensionTypes;
|
|
1378
|
+
} else if (globalAttribute.types === "marks") {
|
|
1379
|
+
resolvedTypes = markExtensionTypes;
|
|
1380
|
+
} else {
|
|
1381
|
+
resolvedTypes = [];
|
|
1382
|
+
}
|
|
1383
|
+
resolvedTypes.forEach((type) => {
|
|
1369
1384
|
Object.entries(globalAttribute.attributes).forEach(([name, attribute]) => {
|
|
1370
1385
|
extensionAttributes.push({
|
|
1371
1386
|
type,
|
|
@@ -1983,6 +1998,9 @@ function isMarkActive(state, typeOrName, attributes = {}) {
|
|
|
1983
1998
|
const from = $from.pos;
|
|
1984
1999
|
const to = $to.pos;
|
|
1985
2000
|
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
2001
|
+
if (type && node.inlineContent && !node.type.allowsMarkType(type)) {
|
|
2002
|
+
return false;
|
|
2003
|
+
}
|
|
1986
2004
|
if (!node.isText && !node.marks.length) {
|
|
1987
2005
|
return;
|
|
1988
2006
|
}
|
|
@@ -3683,6 +3701,39 @@ var ExtensionManager = class {
|
|
|
3683
3701
|
};
|
|
3684
3702
|
}, baseDispatch);
|
|
3685
3703
|
}
|
|
3704
|
+
/**
|
|
3705
|
+
* Get the composed transformPastedHTML function from all extensions.
|
|
3706
|
+
* @param baseTransform The base transform function (e.g. from the editor props)
|
|
3707
|
+
* @returns A composed transform function that chains all extension transforms
|
|
3708
|
+
*/
|
|
3709
|
+
transformPastedHTML(baseTransform) {
|
|
3710
|
+
const { editor } = this;
|
|
3711
|
+
const extensions = sortExtensions([...this.extensions]);
|
|
3712
|
+
return extensions.reduce(
|
|
3713
|
+
(transform, extension) => {
|
|
3714
|
+
const context = {
|
|
3715
|
+
name: extension.name,
|
|
3716
|
+
options: extension.options,
|
|
3717
|
+
storage: this.editor.extensionStorage[extension.name],
|
|
3718
|
+
editor,
|
|
3719
|
+
type: getSchemaTypeByName(extension.name, this.schema)
|
|
3720
|
+
};
|
|
3721
|
+
const extensionTransform = getExtensionField(
|
|
3722
|
+
extension,
|
|
3723
|
+
"transformPastedHTML",
|
|
3724
|
+
context
|
|
3725
|
+
);
|
|
3726
|
+
if (!extensionTransform) {
|
|
3727
|
+
return transform;
|
|
3728
|
+
}
|
|
3729
|
+
return (html, view) => {
|
|
3730
|
+
const transformedHtml = transform(html, view);
|
|
3731
|
+
return extensionTransform.call(context, transformedHtml);
|
|
3732
|
+
};
|
|
3733
|
+
},
|
|
3734
|
+
baseTransform || ((html) => html)
|
|
3735
|
+
);
|
|
3736
|
+
}
|
|
3686
3737
|
get markViews() {
|
|
3687
3738
|
const { editor } = this;
|
|
3688
3739
|
const { markExtensions } = splitExtensions(this.extensions);
|
|
@@ -4705,7 +4756,7 @@ var Editor = class extends EventEmitter {
|
|
|
4705
4756
|
return this.options.editable && this.view && this.view.editable;
|
|
4706
4757
|
}
|
|
4707
4758
|
/**
|
|
4708
|
-
* Returns the editor
|
|
4759
|
+
* Returns the editor view.
|
|
4709
4760
|
*/
|
|
4710
4761
|
get view() {
|
|
4711
4762
|
if (this.editorView) {
|
|
@@ -4874,6 +4925,8 @@ var Editor = class extends EventEmitter {
|
|
|
4874
4925
|
const { editorProps, enableExtensionDispatchTransaction } = this.options;
|
|
4875
4926
|
const baseDispatch = editorProps.dispatchTransaction || this.dispatchTransaction.bind(this);
|
|
4876
4927
|
const dispatch = enableExtensionDispatchTransaction ? this.extensionManager.dispatchTransaction(baseDispatch) : baseDispatch;
|
|
4928
|
+
const baseTransformPastedHTML = editorProps.transformPastedHTML;
|
|
4929
|
+
const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML);
|
|
4877
4930
|
this.editorView = new EditorView(element, {
|
|
4878
4931
|
...editorProps,
|
|
4879
4932
|
attributes: {
|
|
@@ -4882,6 +4935,7 @@ var Editor = class extends EventEmitter {
|
|
|
4882
4935
|
...editorProps == null ? void 0 : editorProps.attributes
|
|
4883
4936
|
},
|
|
4884
4937
|
dispatchTransaction: dispatch,
|
|
4938
|
+
transformPastedHTML,
|
|
4885
4939
|
state: this.editorState,
|
|
4886
4940
|
markViews: this.extensionManager.markViews,
|
|
4887
4941
|
nodeViews: this.extensionManager.nodeViews
|