@tiptap/core 2.6.6 → 2.7.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 +95 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +94 -12
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +95 -11
- 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/NodeView.ts +39 -8
- package/src/commands/toggleNode.ts +11 -2
- package/src/extensions/keymap.ts +5 -2
- 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;
|
|
@@ -1150,15 +1161,19 @@ class ExtensionManager {
|
|
|
1150
1161
|
if (!addNodeView) {
|
|
1151
1162
|
return [];
|
|
1152
1163
|
}
|
|
1153
|
-
const nodeview = (node, view, getPos, decorations) => {
|
|
1164
|
+
const nodeview = (node, view, getPos, decorations, innerDecorations) => {
|
|
1154
1165
|
const HTMLAttributes = getRenderedAttributes(node, extensionAttributes);
|
|
1155
1166
|
return addNodeView()({
|
|
1156
|
-
|
|
1167
|
+
// pass-through
|
|
1157
1168
|
node,
|
|
1158
|
-
|
|
1169
|
+
view,
|
|
1170
|
+
getPos: getPos,
|
|
1159
1171
|
decorations,
|
|
1160
|
-
|
|
1172
|
+
innerDecorations,
|
|
1173
|
+
// tiptap-specific
|
|
1174
|
+
editor,
|
|
1161
1175
|
extension,
|
|
1176
|
+
HTMLAttributes,
|
|
1162
1177
|
});
|
|
1163
1178
|
};
|
|
1164
1179
|
return [extension.name, nodeview];
|
|
@@ -3316,10 +3331,17 @@ const toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state,
|
|
|
3316
3331
|
const type = getNodeType(typeOrName, state.schema);
|
|
3317
3332
|
const toggleType = getNodeType(toggleTypeOrName, state.schema);
|
|
3318
3333
|
const isActive = isNodeActive(state, type, attributes);
|
|
3334
|
+
let attributesToCopy;
|
|
3335
|
+
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
3336
|
+
// only copy attributes if the selection is pointing to a node of the same type
|
|
3337
|
+
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
3338
|
+
}
|
|
3319
3339
|
if (isActive) {
|
|
3320
|
-
return commands.setNode(toggleType);
|
|
3340
|
+
return commands.setNode(toggleType, attributesToCopy);
|
|
3321
3341
|
}
|
|
3322
|
-
|
|
3342
|
+
// If the node is not active, we want to set the new node type with the given attributes
|
|
3343
|
+
// Copying over the attributes from the current node if the selection is pointing to a node of the same type
|
|
3344
|
+
return commands.setNode(type, { ...attributesToCopy, ...attributes });
|
|
3323
3345
|
};
|
|
3324
3346
|
|
|
3325
3347
|
const toggleWrap = (typeOrName, attributes = {}) => ({ state, commands }) => {
|
|
@@ -3653,7 +3675,8 @@ const Keymap = Extension.create({
|
|
|
3653
3675
|
appendTransaction: (transactions, oldState, newState) => {
|
|
3654
3676
|
const docChanges = transactions.some(transaction => transaction.docChanged)
|
|
3655
3677
|
&& !oldState.doc.eq(newState.doc);
|
|
3656
|
-
|
|
3678
|
+
const ignoreTr = transactions.some(transaction => transaction.getMeta('preventClearDocument'));
|
|
3679
|
+
if (!docChanges || ignoreTr) {
|
|
3657
3680
|
return;
|
|
3658
3681
|
}
|
|
3659
3682
|
const { empty, from, to } = oldState.selection;
|
|
@@ -3663,7 +3686,7 @@ const Keymap = Extension.create({
|
|
|
3663
3686
|
if (empty || !allWasSelected) {
|
|
3664
3687
|
return;
|
|
3665
3688
|
}
|
|
3666
|
-
const isEmpty =
|
|
3689
|
+
const isEmpty = isNodeEmpty(newState.doc);
|
|
3667
3690
|
if (!isEmpty) {
|
|
3668
3691
|
return;
|
|
3669
3692
|
}
|
|
@@ -3887,6 +3910,28 @@ class NodePos {
|
|
|
3887
3910
|
}
|
|
3888
3911
|
}
|
|
3889
3912
|
|
|
3913
|
+
const DropPlugin = (onDrop) => {
|
|
3914
|
+
return new Plugin({
|
|
3915
|
+
key: new PluginKey('tiptapDrop'),
|
|
3916
|
+
props: {
|
|
3917
|
+
handleDrop: (_, e, slice, moved) => {
|
|
3918
|
+
onDrop(e, slice, moved);
|
|
3919
|
+
},
|
|
3920
|
+
},
|
|
3921
|
+
});
|
|
3922
|
+
};
|
|
3923
|
+
|
|
3924
|
+
const PastePlugin = (onPaste) => {
|
|
3925
|
+
return new Plugin({
|
|
3926
|
+
key: new PluginKey('tiptapPaste'),
|
|
3927
|
+
props: {
|
|
3928
|
+
handlePaste: (_view, e, slice) => {
|
|
3929
|
+
onPaste(e, slice);
|
|
3930
|
+
},
|
|
3931
|
+
},
|
|
3932
|
+
});
|
|
3933
|
+
};
|
|
3934
|
+
|
|
3890
3935
|
const style = `.ProseMirror {
|
|
3891
3936
|
position: relative;
|
|
3892
3937
|
}
|
|
@@ -4011,6 +4056,8 @@ class Editor extends EventEmitter {
|
|
|
4011
4056
|
onBlur: () => null,
|
|
4012
4057
|
onDestroy: () => null,
|
|
4013
4058
|
onContentError: ({ error }) => { throw error; },
|
|
4059
|
+
onPaste: () => null,
|
|
4060
|
+
onDrop: () => null,
|
|
4014
4061
|
};
|
|
4015
4062
|
this.isCapturingTransaction = false;
|
|
4016
4063
|
this.capturedTransaction = null;
|
|
@@ -4030,6 +4077,12 @@ class Editor extends EventEmitter {
|
|
|
4030
4077
|
this.on('focus', this.options.onFocus);
|
|
4031
4078
|
this.on('blur', this.options.onBlur);
|
|
4032
4079
|
this.on('destroy', this.options.onDestroy);
|
|
4080
|
+
if (this.options.onPaste) {
|
|
4081
|
+
this.registerPlugin(PastePlugin(this.options.onPaste));
|
|
4082
|
+
}
|
|
4083
|
+
if (this.options.onDrop) {
|
|
4084
|
+
this.registerPlugin(DropPlugin(this.options.onDrop));
|
|
4085
|
+
}
|
|
4033
4086
|
window.setTimeout(() => {
|
|
4034
4087
|
if (this.isDestroyed) {
|
|
4035
4088
|
return;
|
|
@@ -4157,7 +4210,12 @@ class Editor extends EventEmitter {
|
|
|
4157
4210
|
FocusEvents,
|
|
4158
4211
|
Keymap,
|
|
4159
4212
|
Tabindex,
|
|
4160
|
-
]
|
|
4213
|
+
].filter(ext => {
|
|
4214
|
+
if (typeof this.options.enableCoreExtensions === 'object') {
|
|
4215
|
+
return this.options.enableCoreExtensions[ext.name] !== false;
|
|
4216
|
+
}
|
|
4217
|
+
return true;
|
|
4218
|
+
}) : [];
|
|
4161
4219
|
const allExtensions = [...coreExtensions, ...this.options.extensions].filter(extension => {
|
|
4162
4220
|
return ['extension', 'node', 'mark'].includes(extension === null || extension === void 0 ? void 0 : extension.type);
|
|
4163
4221
|
});
|
|
@@ -4766,6 +4824,9 @@ class NodeView {
|
|
|
4766
4824
|
this.extension = props.extension;
|
|
4767
4825
|
this.node = props.node;
|
|
4768
4826
|
this.decorations = props.decorations;
|
|
4827
|
+
this.innerDecorations = props.innerDecorations;
|
|
4828
|
+
this.view = props.view;
|
|
4829
|
+
this.HTMLAttributes = props.HTMLAttributes;
|
|
4769
4830
|
this.getPos = props.getPos;
|
|
4770
4831
|
this.mount();
|
|
4771
4832
|
}
|
|
@@ -4804,9 +4865,13 @@ class NodeView {
|
|
|
4804
4865
|
y = handleBox.y - domBox.y + offsetY;
|
|
4805
4866
|
}
|
|
4806
4867
|
(_g = event.dataTransfer) === null || _g === void 0 ? void 0 : _g.setDragImage(this.dom, x, y);
|
|
4868
|
+
const pos = this.getPos();
|
|
4869
|
+
if (typeof pos !== 'number') {
|
|
4870
|
+
return;
|
|
4871
|
+
}
|
|
4807
4872
|
// we need to tell ProseMirror that we want to move the whole node
|
|
4808
4873
|
// so we create a NodeSelection
|
|
4809
|
-
const selection = NodeSelection.create(view.state.doc,
|
|
4874
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
4810
4875
|
const transaction = view.state.tr.setSelection(selection);
|
|
4811
4876
|
view.dispatch(transaction);
|
|
4812
4877
|
}
|
|
@@ -4877,6 +4942,11 @@ class NodeView {
|
|
|
4877
4942
|
}
|
|
4878
4943
|
return true;
|
|
4879
4944
|
}
|
|
4945
|
+
/**
|
|
4946
|
+
* Called when a DOM [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) or a selection change happens within the view.
|
|
4947
|
+
* @return `false` if the editor should re-read the selection or re-parse the range around the mutation
|
|
4948
|
+
* @return `true` if it can safely be ignored.
|
|
4949
|
+
*/
|
|
4880
4950
|
ignoreMutation(mutation) {
|
|
4881
4951
|
if (!this.dom || !this.contentDOM) {
|
|
4882
4952
|
return true;
|
|
@@ -4923,9 +4993,15 @@ class NodeView {
|
|
|
4923
4993
|
}
|
|
4924
4994
|
return true;
|
|
4925
4995
|
}
|
|
4996
|
+
/**
|
|
4997
|
+
* Update the attributes of the prosemirror node.
|
|
4998
|
+
*/
|
|
4926
4999
|
updateAttributes(attributes) {
|
|
4927
5000
|
this.editor.commands.command(({ tr }) => {
|
|
4928
5001
|
const pos = this.getPos();
|
|
5002
|
+
if (typeof pos !== 'number') {
|
|
5003
|
+
return false;
|
|
5004
|
+
}
|
|
4929
5005
|
tr.setNodeMarkup(pos, undefined, {
|
|
4930
5006
|
...this.node.attrs,
|
|
4931
5007
|
...attributes,
|
|
@@ -4933,8 +5009,14 @@ class NodeView {
|
|
|
4933
5009
|
return true;
|
|
4934
5010
|
});
|
|
4935
5011
|
}
|
|
5012
|
+
/**
|
|
5013
|
+
* Delete the node.
|
|
5014
|
+
*/
|
|
4936
5015
|
deleteNode() {
|
|
4937
5016
|
const from = this.getPos();
|
|
5017
|
+
if (typeof from !== 'number') {
|
|
5018
|
+
return;
|
|
5019
|
+
}
|
|
4938
5020
|
const to = from + this.node.nodeSize;
|
|
4939
5021
|
this.editor.commands.deleteRange({ from, to });
|
|
4940
5022
|
}
|
|
@@ -5069,5 +5151,5 @@ class Tracker {
|
|
|
5069
5151
|
}
|
|
5070
5152
|
}
|
|
5071
5153
|
|
|
5072
|
-
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 };
|
|
5154
|
+
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 };
|
|
5073
5155
|
//# sourceMappingURL=index.js.map
|