@tiptap/core 2.6.5 → 2.7.0-pre.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 +113 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +112 -23
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +113 -22
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/core/src/NodeView.d.ts +20 -8
- package/dist/packages/core/src/index.d.ts +2 -0
- package/dist/packages/core/src/plugins/DropPlugin.d.ts +3 -0
- package/dist/packages/core/src/plugins/PastePlugin.d.ts +3 -0
- package/dist/packages/core/src/types.d.ts +35 -15
- package/package.json +3 -3
- package/src/Editor.ts +18 -1
- package/src/ExtensionManager.ts +15 -10
- package/src/InputRule.ts +14 -11
- package/src/NodeView.ts +39 -8
- package/src/commands/toggleNode.ts +11 -2
- package/src/extensions/keymap.ts +5 -2
- package/src/helpers/createNodeFromContent.ts +7 -1
- package/src/index.ts +2 -0
- package/src/plugins/DropPlugin.ts +14 -0
- package/src/plugins/PastePlugin.ts +14 -0
- package/src/types.ts +46 -17
- package/src/utilities/mergeAttributes.ts +18 -1
package/dist/index.js
CHANGED
|
@@ -319,7 +319,18 @@ function mergeAttributes(...objects) {
|
|
|
319
319
|
mergedAttributes[key] = [...existingClasses, ...insertClasses].join(' ');
|
|
320
320
|
}
|
|
321
321
|
else if (key === 'style') {
|
|
322
|
-
|
|
322
|
+
const newStyles = value ? value.split(';').map((style) => style.trim()).filter(Boolean) : [];
|
|
323
|
+
const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(';').map((style) => style.trim()).filter(Boolean) : [];
|
|
324
|
+
const styleMap = new Map();
|
|
325
|
+
existingStyles.forEach(style => {
|
|
326
|
+
const [property, val] = style.split(':').map(part => part.trim());
|
|
327
|
+
styleMap.set(property, val);
|
|
328
|
+
});
|
|
329
|
+
newStyles.forEach(style => {
|
|
330
|
+
const [property, val] = style.split(':').map(part => part.trim());
|
|
331
|
+
styleMap.set(property, val);
|
|
332
|
+
});
|
|
333
|
+
mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join('; ');
|
|
323
334
|
}
|
|
324
335
|
else {
|
|
325
336
|
mergedAttributes[key] = value;
|
|
@@ -713,16 +724,6 @@ function inputRulesPlugin(props) {
|
|
|
713
724
|
},
|
|
714
725
|
},
|
|
715
726
|
props: {
|
|
716
|
-
handleTextInput(view, from, to, text) {
|
|
717
|
-
return run$1({
|
|
718
|
-
editor,
|
|
719
|
-
from,
|
|
720
|
-
to,
|
|
721
|
-
text,
|
|
722
|
-
rules,
|
|
723
|
-
plugin,
|
|
724
|
-
});
|
|
725
|
-
},
|
|
726
727
|
handleDOMEvents: {
|
|
727
728
|
compositionend: view => {
|
|
728
729
|
setTimeout(() => {
|
|
@@ -740,6 +741,19 @@ function inputRulesPlugin(props) {
|
|
|
740
741
|
});
|
|
741
742
|
return false;
|
|
742
743
|
},
|
|
744
|
+
keyup(view, event) {
|
|
745
|
+
if (event.key.length === 1) {
|
|
746
|
+
return run$1({
|
|
747
|
+
editor,
|
|
748
|
+
from: view.state.selection.from,
|
|
749
|
+
to: view.state.selection.from,
|
|
750
|
+
text: '',
|
|
751
|
+
rules,
|
|
752
|
+
plugin,
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
return false;
|
|
756
|
+
},
|
|
743
757
|
},
|
|
744
758
|
// add support for input rules to trigger on enter
|
|
745
759
|
// this is useful for example for code blocks
|
|
@@ -1150,15 +1164,19 @@ class ExtensionManager {
|
|
|
1150
1164
|
if (!addNodeView) {
|
|
1151
1165
|
return [];
|
|
1152
1166
|
}
|
|
1153
|
-
const nodeview = (node, view, getPos, decorations) => {
|
|
1167
|
+
const nodeview = (node, view, getPos, decorations, innerDecorations) => {
|
|
1154
1168
|
const HTMLAttributes = getRenderedAttributes(node, extensionAttributes);
|
|
1155
1169
|
return addNodeView()({
|
|
1156
|
-
|
|
1170
|
+
// pass-through
|
|
1157
1171
|
node,
|
|
1158
|
-
|
|
1172
|
+
view,
|
|
1173
|
+
getPos: getPos,
|
|
1159
1174
|
decorations,
|
|
1160
|
-
|
|
1175
|
+
innerDecorations,
|
|
1176
|
+
// tiptap-specific
|
|
1177
|
+
editor,
|
|
1161
1178
|
extension,
|
|
1179
|
+
HTMLAttributes,
|
|
1162
1180
|
});
|
|
1163
1181
|
};
|
|
1164
1182
|
return [extension.name, nodeview];
|
|
@@ -1766,7 +1784,11 @@ function createNodeFromContent(content, schema, options) {
|
|
|
1766
1784
|
if (isArrayContent) {
|
|
1767
1785
|
return Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)));
|
|
1768
1786
|
}
|
|
1769
|
-
|
|
1787
|
+
const node = schema.nodeFromJSON(content);
|
|
1788
|
+
if (options.errorOnInvalidContent) {
|
|
1789
|
+
node.check();
|
|
1790
|
+
}
|
|
1791
|
+
return node;
|
|
1770
1792
|
}
|
|
1771
1793
|
catch (error) {
|
|
1772
1794
|
if (options.errorOnInvalidContent) {
|
|
@@ -3312,10 +3334,17 @@ const toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state,
|
|
|
3312
3334
|
const type = getNodeType(typeOrName, state.schema);
|
|
3313
3335
|
const toggleType = getNodeType(toggleTypeOrName, state.schema);
|
|
3314
3336
|
const isActive = isNodeActive(state, type, attributes);
|
|
3337
|
+
let attributesToCopy;
|
|
3338
|
+
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
3339
|
+
// only copy attributes if the selection is pointing to a node of the same type
|
|
3340
|
+
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
3341
|
+
}
|
|
3315
3342
|
if (isActive) {
|
|
3316
|
-
return commands.setNode(toggleType);
|
|
3343
|
+
return commands.setNode(toggleType, attributesToCopy);
|
|
3317
3344
|
}
|
|
3318
|
-
|
|
3345
|
+
// If the node is not active, we want to set the new node type with the given attributes
|
|
3346
|
+
// Copying over the attributes from the current node if the selection is pointing to a node of the same type
|
|
3347
|
+
return commands.setNode(type, { ...attributesToCopy, ...attributes });
|
|
3319
3348
|
};
|
|
3320
3349
|
|
|
3321
3350
|
const toggleWrap = (typeOrName, attributes = {}) => ({ state, commands }) => {
|
|
@@ -3649,7 +3678,8 @@ const Keymap = Extension.create({
|
|
|
3649
3678
|
appendTransaction: (transactions, oldState, newState) => {
|
|
3650
3679
|
const docChanges = transactions.some(transaction => transaction.docChanged)
|
|
3651
3680
|
&& !oldState.doc.eq(newState.doc);
|
|
3652
|
-
|
|
3681
|
+
const ignoreTr = transactions.some(transaction => transaction.getMeta('preventClearDocument'));
|
|
3682
|
+
if (!docChanges || ignoreTr) {
|
|
3653
3683
|
return;
|
|
3654
3684
|
}
|
|
3655
3685
|
const { empty, from, to } = oldState.selection;
|
|
@@ -3659,7 +3689,7 @@ const Keymap = Extension.create({
|
|
|
3659
3689
|
if (empty || !allWasSelected) {
|
|
3660
3690
|
return;
|
|
3661
3691
|
}
|
|
3662
|
-
const isEmpty =
|
|
3692
|
+
const isEmpty = isNodeEmpty(newState.doc);
|
|
3663
3693
|
if (!isEmpty) {
|
|
3664
3694
|
return;
|
|
3665
3695
|
}
|
|
@@ -3883,6 +3913,28 @@ class NodePos {
|
|
|
3883
3913
|
}
|
|
3884
3914
|
}
|
|
3885
3915
|
|
|
3916
|
+
const DropPlugin = (onDrop) => {
|
|
3917
|
+
return new Plugin({
|
|
3918
|
+
key: new PluginKey('tiptapDrop'),
|
|
3919
|
+
props: {
|
|
3920
|
+
handleDrop: (_, e, slice, moved) => {
|
|
3921
|
+
onDrop(e, slice, moved);
|
|
3922
|
+
},
|
|
3923
|
+
},
|
|
3924
|
+
});
|
|
3925
|
+
};
|
|
3926
|
+
|
|
3927
|
+
const PastePlugin = (onPaste) => {
|
|
3928
|
+
return new Plugin({
|
|
3929
|
+
key: new PluginKey('tiptapPaste'),
|
|
3930
|
+
props: {
|
|
3931
|
+
handlePaste: (_view, e, slice) => {
|
|
3932
|
+
onPaste(e, slice);
|
|
3933
|
+
},
|
|
3934
|
+
},
|
|
3935
|
+
});
|
|
3936
|
+
};
|
|
3937
|
+
|
|
3886
3938
|
const style = `.ProseMirror {
|
|
3887
3939
|
position: relative;
|
|
3888
3940
|
}
|
|
@@ -4007,6 +4059,8 @@ class Editor extends EventEmitter {
|
|
|
4007
4059
|
onBlur: () => null,
|
|
4008
4060
|
onDestroy: () => null,
|
|
4009
4061
|
onContentError: ({ error }) => { throw error; },
|
|
4062
|
+
onPaste: () => null,
|
|
4063
|
+
onDrop: () => null,
|
|
4010
4064
|
};
|
|
4011
4065
|
this.isCapturingTransaction = false;
|
|
4012
4066
|
this.capturedTransaction = null;
|
|
@@ -4026,6 +4080,12 @@ class Editor extends EventEmitter {
|
|
|
4026
4080
|
this.on('focus', this.options.onFocus);
|
|
4027
4081
|
this.on('blur', this.options.onBlur);
|
|
4028
4082
|
this.on('destroy', this.options.onDestroy);
|
|
4083
|
+
if (this.options.onPaste) {
|
|
4084
|
+
this.registerPlugin(PastePlugin(this.options.onPaste));
|
|
4085
|
+
}
|
|
4086
|
+
if (this.options.onDrop) {
|
|
4087
|
+
this.registerPlugin(DropPlugin(this.options.onDrop));
|
|
4088
|
+
}
|
|
4029
4089
|
window.setTimeout(() => {
|
|
4030
4090
|
if (this.isDestroyed) {
|
|
4031
4091
|
return;
|
|
@@ -4153,7 +4213,12 @@ class Editor extends EventEmitter {
|
|
|
4153
4213
|
FocusEvents,
|
|
4154
4214
|
Keymap,
|
|
4155
4215
|
Tabindex,
|
|
4156
|
-
]
|
|
4216
|
+
].filter(ext => {
|
|
4217
|
+
if (typeof this.options.enableCoreExtensions === 'object') {
|
|
4218
|
+
return this.options.enableCoreExtensions[ext.name] !== false;
|
|
4219
|
+
}
|
|
4220
|
+
return true;
|
|
4221
|
+
}) : [];
|
|
4157
4222
|
const allExtensions = [...coreExtensions, ...this.options.extensions].filter(extension => {
|
|
4158
4223
|
return ['extension', 'node', 'mark'].includes(extension === null || extension === void 0 ? void 0 : extension.type);
|
|
4159
4224
|
});
|
|
@@ -4762,6 +4827,9 @@ class NodeView {
|
|
|
4762
4827
|
this.extension = props.extension;
|
|
4763
4828
|
this.node = props.node;
|
|
4764
4829
|
this.decorations = props.decorations;
|
|
4830
|
+
this.innerDecorations = props.innerDecorations;
|
|
4831
|
+
this.view = props.view;
|
|
4832
|
+
this.HTMLAttributes = props.HTMLAttributes;
|
|
4765
4833
|
this.getPos = props.getPos;
|
|
4766
4834
|
this.mount();
|
|
4767
4835
|
}
|
|
@@ -4800,9 +4868,13 @@ class NodeView {
|
|
|
4800
4868
|
y = handleBox.y - domBox.y + offsetY;
|
|
4801
4869
|
}
|
|
4802
4870
|
(_g = event.dataTransfer) === null || _g === void 0 ? void 0 : _g.setDragImage(this.dom, x, y);
|
|
4871
|
+
const pos = this.getPos();
|
|
4872
|
+
if (typeof pos !== 'number') {
|
|
4873
|
+
return;
|
|
4874
|
+
}
|
|
4803
4875
|
// we need to tell ProseMirror that we want to move the whole node
|
|
4804
4876
|
// so we create a NodeSelection
|
|
4805
|
-
const selection = NodeSelection.create(view.state.doc,
|
|
4877
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
4806
4878
|
const transaction = view.state.tr.setSelection(selection);
|
|
4807
4879
|
view.dispatch(transaction);
|
|
4808
4880
|
}
|
|
@@ -4873,6 +4945,11 @@ class NodeView {
|
|
|
4873
4945
|
}
|
|
4874
4946
|
return true;
|
|
4875
4947
|
}
|
|
4948
|
+
/**
|
|
4949
|
+
* Called when a DOM [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) or a selection change happens within the view.
|
|
4950
|
+
* @return `false` if the editor should re-read the selection or re-parse the range around the mutation
|
|
4951
|
+
* @return `true` if it can safely be ignored.
|
|
4952
|
+
*/
|
|
4876
4953
|
ignoreMutation(mutation) {
|
|
4877
4954
|
if (!this.dom || !this.contentDOM) {
|
|
4878
4955
|
return true;
|
|
@@ -4919,9 +4996,15 @@ class NodeView {
|
|
|
4919
4996
|
}
|
|
4920
4997
|
return true;
|
|
4921
4998
|
}
|
|
4999
|
+
/**
|
|
5000
|
+
* Update the attributes of the prosemirror node.
|
|
5001
|
+
*/
|
|
4922
5002
|
updateAttributes(attributes) {
|
|
4923
5003
|
this.editor.commands.command(({ tr }) => {
|
|
4924
5004
|
const pos = this.getPos();
|
|
5005
|
+
if (typeof pos !== 'number') {
|
|
5006
|
+
return false;
|
|
5007
|
+
}
|
|
4925
5008
|
tr.setNodeMarkup(pos, undefined, {
|
|
4926
5009
|
...this.node.attrs,
|
|
4927
5010
|
...attributes,
|
|
@@ -4929,8 +5012,14 @@ class NodeView {
|
|
|
4929
5012
|
return true;
|
|
4930
5013
|
});
|
|
4931
5014
|
}
|
|
5015
|
+
/**
|
|
5016
|
+
* Delete the node.
|
|
5017
|
+
*/
|
|
4932
5018
|
deleteNode() {
|
|
4933
5019
|
const from = this.getPos();
|
|
5020
|
+
if (typeof from !== 'number') {
|
|
5021
|
+
return;
|
|
5022
|
+
}
|
|
4934
5023
|
const to = from + this.node.nodeSize;
|
|
4935
5024
|
this.editor.commands.deleteRange({ from, to });
|
|
4936
5025
|
}
|
|
@@ -5065,5 +5154,5 @@ class Tracker {
|
|
|
5065
5154
|
}
|
|
5066
5155
|
}
|
|
5067
5156
|
|
|
5068
|
-
export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodePos, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, createChainableState, createDocument, createNodeFromContent, createStyleTag, defaultBlockAt, deleteProps, elementFromString, escapeForRegEx, index as extensions, findChildren, findChildrenInRange, findDuplicates, findParentNode, findParentNodeClosestToPos, fromString, generateHTML, generateJSON, generateText, getAttributes, getAttributesFromExtensions, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAtPosition, getNodeAttributes, getNodeType, getRenderedAttributes, getSchema, getSchemaByResolvedExtensions, getSchemaTypeByName, getSchemaTypeNameByName, getSplittedAttributes, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, injectExtensionAttributesToParseRule, inputRulesPlugin, isActive, isAtEndOfNode, isAtStartOfNode, isEmptyObject, isExtensionRulesEnabled, isFunction, isList, isMacOS, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isNumber, isPlainObject, isRegExp, isString, isTextSelection, isiOS, markInputRule, markPasteRule, mergeAttributes, mergeDeep, minMax, nodeInputRule, nodePasteRule, objectIncludes, pasteRulesPlugin, posToDOMRect, removeDuplicates, resolveFocusPosition, selectionToInsertionEnd, splitExtensions, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
|
|
5157
|
+
export { CommandManager, DropPlugin, Editor, Extension, InputRule, Mark, Node, NodePos, NodeView, PastePlugin, PasteRule, Tracker, callOrReturn, combineTransactionSteps, createChainableState, createDocument, createNodeFromContent, createStyleTag, defaultBlockAt, deleteProps, elementFromString, escapeForRegEx, index as extensions, findChildren, findChildrenInRange, findDuplicates, findParentNode, findParentNodeClosestToPos, fromString, generateHTML, generateJSON, generateText, getAttributes, getAttributesFromExtensions, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAtPosition, getNodeAttributes, getNodeType, getRenderedAttributes, getSchema, getSchemaByResolvedExtensions, getSchemaTypeByName, getSchemaTypeNameByName, getSplittedAttributes, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, injectExtensionAttributesToParseRule, inputRulesPlugin, isActive, isAtEndOfNode, isAtStartOfNode, isEmptyObject, isExtensionRulesEnabled, isFunction, isList, isMacOS, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isNumber, isPlainObject, isRegExp, isString, isTextSelection, isiOS, markInputRule, markPasteRule, mergeAttributes, mergeDeep, minMax, nodeInputRule, nodePasteRule, objectIncludes, pasteRulesPlugin, posToDOMRect, removeDuplicates, resolveFocusPosition, selectionToInsertionEnd, splitExtensions, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
|
|
5069
5158
|
//# sourceMappingURL=index.js.map
|