@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.cjs
CHANGED
|
@@ -321,7 +321,18 @@ function mergeAttributes(...objects) {
|
|
|
321
321
|
mergedAttributes[key] = [...existingClasses, ...insertClasses].join(' ');
|
|
322
322
|
}
|
|
323
323
|
else if (key === 'style') {
|
|
324
|
-
|
|
324
|
+
const newStyles = value ? value.split(';').map((style) => style.trim()).filter(Boolean) : [];
|
|
325
|
+
const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(';').map((style) => style.trim()).filter(Boolean) : [];
|
|
326
|
+
const styleMap = new Map();
|
|
327
|
+
existingStyles.forEach(style => {
|
|
328
|
+
const [property, val] = style.split(':').map(part => part.trim());
|
|
329
|
+
styleMap.set(property, val);
|
|
330
|
+
});
|
|
331
|
+
newStyles.forEach(style => {
|
|
332
|
+
const [property, val] = style.split(':').map(part => part.trim());
|
|
333
|
+
styleMap.set(property, val);
|
|
334
|
+
});
|
|
335
|
+
mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join('; ');
|
|
325
336
|
}
|
|
326
337
|
else {
|
|
327
338
|
mergedAttributes[key] = value;
|
|
@@ -1152,15 +1163,19 @@ class ExtensionManager {
|
|
|
1152
1163
|
if (!addNodeView) {
|
|
1153
1164
|
return [];
|
|
1154
1165
|
}
|
|
1155
|
-
const nodeview = (node, view, getPos, decorations) => {
|
|
1166
|
+
const nodeview = (node, view, getPos, decorations, innerDecorations) => {
|
|
1156
1167
|
const HTMLAttributes = getRenderedAttributes(node, extensionAttributes);
|
|
1157
1168
|
return addNodeView()({
|
|
1158
|
-
|
|
1169
|
+
// pass-through
|
|
1159
1170
|
node,
|
|
1160
|
-
|
|
1171
|
+
view,
|
|
1172
|
+
getPos: getPos,
|
|
1161
1173
|
decorations,
|
|
1162
|
-
|
|
1174
|
+
innerDecorations,
|
|
1175
|
+
// tiptap-specific
|
|
1176
|
+
editor,
|
|
1163
1177
|
extension,
|
|
1178
|
+
HTMLAttributes,
|
|
1164
1179
|
});
|
|
1165
1180
|
};
|
|
1166
1181
|
return [extension.name, nodeview];
|
|
@@ -3318,10 +3333,17 @@ const toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state,
|
|
|
3318
3333
|
const type = getNodeType(typeOrName, state.schema);
|
|
3319
3334
|
const toggleType = getNodeType(toggleTypeOrName, state.schema);
|
|
3320
3335
|
const isActive = isNodeActive(state, type, attributes);
|
|
3336
|
+
let attributesToCopy;
|
|
3337
|
+
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
3338
|
+
// only copy attributes if the selection is pointing to a node of the same type
|
|
3339
|
+
attributesToCopy = state.selection.$anchor.parent.attrs;
|
|
3340
|
+
}
|
|
3321
3341
|
if (isActive) {
|
|
3322
|
-
return commands.setNode(toggleType);
|
|
3342
|
+
return commands.setNode(toggleType, attributesToCopy);
|
|
3323
3343
|
}
|
|
3324
|
-
|
|
3344
|
+
// If the node is not active, we want to set the new node type with the given attributes
|
|
3345
|
+
// Copying over the attributes from the current node if the selection is pointing to a node of the same type
|
|
3346
|
+
return commands.setNode(type, { ...attributesToCopy, ...attributes });
|
|
3325
3347
|
};
|
|
3326
3348
|
|
|
3327
3349
|
const toggleWrap = (typeOrName, attributes = {}) => ({ state, commands }) => {
|
|
@@ -3655,7 +3677,8 @@ const Keymap = Extension.create({
|
|
|
3655
3677
|
appendTransaction: (transactions, oldState, newState) => {
|
|
3656
3678
|
const docChanges = transactions.some(transaction => transaction.docChanged)
|
|
3657
3679
|
&& !oldState.doc.eq(newState.doc);
|
|
3658
|
-
|
|
3680
|
+
const ignoreTr = transactions.some(transaction => transaction.getMeta('preventClearDocument'));
|
|
3681
|
+
if (!docChanges || ignoreTr) {
|
|
3659
3682
|
return;
|
|
3660
3683
|
}
|
|
3661
3684
|
const { empty, from, to } = oldState.selection;
|
|
@@ -3665,7 +3688,7 @@ const Keymap = Extension.create({
|
|
|
3665
3688
|
if (empty || !allWasSelected) {
|
|
3666
3689
|
return;
|
|
3667
3690
|
}
|
|
3668
|
-
const isEmpty =
|
|
3691
|
+
const isEmpty = isNodeEmpty(newState.doc);
|
|
3669
3692
|
if (!isEmpty) {
|
|
3670
3693
|
return;
|
|
3671
3694
|
}
|
|
@@ -3889,6 +3912,28 @@ class NodePos {
|
|
|
3889
3912
|
}
|
|
3890
3913
|
}
|
|
3891
3914
|
|
|
3915
|
+
const DropPlugin = (onDrop) => {
|
|
3916
|
+
return new state.Plugin({
|
|
3917
|
+
key: new state.PluginKey('tiptapDrop'),
|
|
3918
|
+
props: {
|
|
3919
|
+
handleDrop: (_, e, slice, moved) => {
|
|
3920
|
+
onDrop(e, slice, moved);
|
|
3921
|
+
},
|
|
3922
|
+
},
|
|
3923
|
+
});
|
|
3924
|
+
};
|
|
3925
|
+
|
|
3926
|
+
const PastePlugin = (onPaste) => {
|
|
3927
|
+
return new state.Plugin({
|
|
3928
|
+
key: new state.PluginKey('tiptapPaste'),
|
|
3929
|
+
props: {
|
|
3930
|
+
handlePaste: (_view, e, slice) => {
|
|
3931
|
+
onPaste(e, slice);
|
|
3932
|
+
},
|
|
3933
|
+
},
|
|
3934
|
+
});
|
|
3935
|
+
};
|
|
3936
|
+
|
|
3892
3937
|
const style = `.ProseMirror {
|
|
3893
3938
|
position: relative;
|
|
3894
3939
|
}
|
|
@@ -4013,6 +4058,8 @@ class Editor extends EventEmitter {
|
|
|
4013
4058
|
onBlur: () => null,
|
|
4014
4059
|
onDestroy: () => null,
|
|
4015
4060
|
onContentError: ({ error }) => { throw error; },
|
|
4061
|
+
onPaste: () => null,
|
|
4062
|
+
onDrop: () => null,
|
|
4016
4063
|
};
|
|
4017
4064
|
this.isCapturingTransaction = false;
|
|
4018
4065
|
this.capturedTransaction = null;
|
|
@@ -4032,6 +4079,12 @@ class Editor extends EventEmitter {
|
|
|
4032
4079
|
this.on('focus', this.options.onFocus);
|
|
4033
4080
|
this.on('blur', this.options.onBlur);
|
|
4034
4081
|
this.on('destroy', this.options.onDestroy);
|
|
4082
|
+
if (this.options.onPaste) {
|
|
4083
|
+
this.registerPlugin(PastePlugin(this.options.onPaste));
|
|
4084
|
+
}
|
|
4085
|
+
if (this.options.onDrop) {
|
|
4086
|
+
this.registerPlugin(DropPlugin(this.options.onDrop));
|
|
4087
|
+
}
|
|
4035
4088
|
window.setTimeout(() => {
|
|
4036
4089
|
if (this.isDestroyed) {
|
|
4037
4090
|
return;
|
|
@@ -4159,7 +4212,12 @@ class Editor extends EventEmitter {
|
|
|
4159
4212
|
FocusEvents,
|
|
4160
4213
|
Keymap,
|
|
4161
4214
|
Tabindex,
|
|
4162
|
-
]
|
|
4215
|
+
].filter(ext => {
|
|
4216
|
+
if (typeof this.options.enableCoreExtensions === 'object') {
|
|
4217
|
+
return this.options.enableCoreExtensions[ext.name] !== false;
|
|
4218
|
+
}
|
|
4219
|
+
return true;
|
|
4220
|
+
}) : [];
|
|
4163
4221
|
const allExtensions = [...coreExtensions, ...this.options.extensions].filter(extension => {
|
|
4164
4222
|
return ['extension', 'node', 'mark'].includes(extension === null || extension === void 0 ? void 0 : extension.type);
|
|
4165
4223
|
});
|
|
@@ -4768,6 +4826,9 @@ class NodeView {
|
|
|
4768
4826
|
this.extension = props.extension;
|
|
4769
4827
|
this.node = props.node;
|
|
4770
4828
|
this.decorations = props.decorations;
|
|
4829
|
+
this.innerDecorations = props.innerDecorations;
|
|
4830
|
+
this.view = props.view;
|
|
4831
|
+
this.HTMLAttributes = props.HTMLAttributes;
|
|
4771
4832
|
this.getPos = props.getPos;
|
|
4772
4833
|
this.mount();
|
|
4773
4834
|
}
|
|
@@ -4806,9 +4867,13 @@ class NodeView {
|
|
|
4806
4867
|
y = handleBox.y - domBox.y + offsetY;
|
|
4807
4868
|
}
|
|
4808
4869
|
(_g = event.dataTransfer) === null || _g === void 0 ? void 0 : _g.setDragImage(this.dom, x, y);
|
|
4870
|
+
const pos = this.getPos();
|
|
4871
|
+
if (typeof pos !== 'number') {
|
|
4872
|
+
return;
|
|
4873
|
+
}
|
|
4809
4874
|
// we need to tell ProseMirror that we want to move the whole node
|
|
4810
4875
|
// so we create a NodeSelection
|
|
4811
|
-
const selection = state.NodeSelection.create(view.state.doc,
|
|
4876
|
+
const selection = state.NodeSelection.create(view.state.doc, pos);
|
|
4812
4877
|
const transaction = view.state.tr.setSelection(selection);
|
|
4813
4878
|
view.dispatch(transaction);
|
|
4814
4879
|
}
|
|
@@ -4879,6 +4944,11 @@ class NodeView {
|
|
|
4879
4944
|
}
|
|
4880
4945
|
return true;
|
|
4881
4946
|
}
|
|
4947
|
+
/**
|
|
4948
|
+
* Called when a DOM [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) or a selection change happens within the view.
|
|
4949
|
+
* @return `false` if the editor should re-read the selection or re-parse the range around the mutation
|
|
4950
|
+
* @return `true` if it can safely be ignored.
|
|
4951
|
+
*/
|
|
4882
4952
|
ignoreMutation(mutation) {
|
|
4883
4953
|
if (!this.dom || !this.contentDOM) {
|
|
4884
4954
|
return true;
|
|
@@ -4925,9 +4995,15 @@ class NodeView {
|
|
|
4925
4995
|
}
|
|
4926
4996
|
return true;
|
|
4927
4997
|
}
|
|
4998
|
+
/**
|
|
4999
|
+
* Update the attributes of the prosemirror node.
|
|
5000
|
+
*/
|
|
4928
5001
|
updateAttributes(attributes) {
|
|
4929
5002
|
this.editor.commands.command(({ tr }) => {
|
|
4930
5003
|
const pos = this.getPos();
|
|
5004
|
+
if (typeof pos !== 'number') {
|
|
5005
|
+
return false;
|
|
5006
|
+
}
|
|
4931
5007
|
tr.setNodeMarkup(pos, undefined, {
|
|
4932
5008
|
...this.node.attrs,
|
|
4933
5009
|
...attributes,
|
|
@@ -4935,8 +5011,14 @@ class NodeView {
|
|
|
4935
5011
|
return true;
|
|
4936
5012
|
});
|
|
4937
5013
|
}
|
|
5014
|
+
/**
|
|
5015
|
+
* Delete the node.
|
|
5016
|
+
*/
|
|
4938
5017
|
deleteNode() {
|
|
4939
5018
|
const from = this.getPos();
|
|
5019
|
+
if (typeof from !== 'number') {
|
|
5020
|
+
return;
|
|
5021
|
+
}
|
|
4940
5022
|
const to = from + this.node.nodeSize;
|
|
4941
5023
|
this.editor.commands.deleteRange({ from, to });
|
|
4942
5024
|
}
|
|
@@ -5072,6 +5154,7 @@ class Tracker {
|
|
|
5072
5154
|
}
|
|
5073
5155
|
|
|
5074
5156
|
exports.CommandManager = CommandManager;
|
|
5157
|
+
exports.DropPlugin = DropPlugin;
|
|
5075
5158
|
exports.Editor = Editor;
|
|
5076
5159
|
exports.Extension = Extension;
|
|
5077
5160
|
exports.InputRule = InputRule;
|
|
@@ -5079,6 +5162,7 @@ exports.Mark = Mark;
|
|
|
5079
5162
|
exports.Node = Node;
|
|
5080
5163
|
exports.NodePos = NodePos;
|
|
5081
5164
|
exports.NodeView = NodeView;
|
|
5165
|
+
exports.PastePlugin = PastePlugin;
|
|
5082
5166
|
exports.PasteRule = PasteRule;
|
|
5083
5167
|
exports.Tracker = Tracker;
|
|
5084
5168
|
exports.callOrReturn = callOrReturn;
|