@tiptap/core 2.6.6 → 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 +108 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +107 -22
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +108 -21
- 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/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];
|
|
@@ -3316,10 +3334,17 @@ const toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state,
|
|
|
3316
3334
|
const type = getNodeType(typeOrName, state.schema);
|
|
3317
3335
|
const toggleType = getNodeType(toggleTypeOrName, state.schema);
|
|
3318
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
|
+
}
|
|
3319
3342
|
if (isActive) {
|
|
3320
|
-
return commands.setNode(toggleType);
|
|
3343
|
+
return commands.setNode(toggleType, attributesToCopy);
|
|
3321
3344
|
}
|
|
3322
|
-
|
|
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 });
|
|
3323
3348
|
};
|
|
3324
3349
|
|
|
3325
3350
|
const toggleWrap = (typeOrName, attributes = {}) => ({ state, commands }) => {
|
|
@@ -3653,7 +3678,8 @@ const Keymap = Extension.create({
|
|
|
3653
3678
|
appendTransaction: (transactions, oldState, newState) => {
|
|
3654
3679
|
const docChanges = transactions.some(transaction => transaction.docChanged)
|
|
3655
3680
|
&& !oldState.doc.eq(newState.doc);
|
|
3656
|
-
|
|
3681
|
+
const ignoreTr = transactions.some(transaction => transaction.getMeta('preventClearDocument'));
|
|
3682
|
+
if (!docChanges || ignoreTr) {
|
|
3657
3683
|
return;
|
|
3658
3684
|
}
|
|
3659
3685
|
const { empty, from, to } = oldState.selection;
|
|
@@ -3663,7 +3689,7 @@ const Keymap = Extension.create({
|
|
|
3663
3689
|
if (empty || !allWasSelected) {
|
|
3664
3690
|
return;
|
|
3665
3691
|
}
|
|
3666
|
-
const isEmpty =
|
|
3692
|
+
const isEmpty = isNodeEmpty(newState.doc);
|
|
3667
3693
|
if (!isEmpty) {
|
|
3668
3694
|
return;
|
|
3669
3695
|
}
|
|
@@ -3887,6 +3913,28 @@ class NodePos {
|
|
|
3887
3913
|
}
|
|
3888
3914
|
}
|
|
3889
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
|
+
|
|
3890
3938
|
const style = `.ProseMirror {
|
|
3891
3939
|
position: relative;
|
|
3892
3940
|
}
|
|
@@ -4011,6 +4059,8 @@ class Editor extends EventEmitter {
|
|
|
4011
4059
|
onBlur: () => null,
|
|
4012
4060
|
onDestroy: () => null,
|
|
4013
4061
|
onContentError: ({ error }) => { throw error; },
|
|
4062
|
+
onPaste: () => null,
|
|
4063
|
+
onDrop: () => null,
|
|
4014
4064
|
};
|
|
4015
4065
|
this.isCapturingTransaction = false;
|
|
4016
4066
|
this.capturedTransaction = null;
|
|
@@ -4030,6 +4080,12 @@ class Editor extends EventEmitter {
|
|
|
4030
4080
|
this.on('focus', this.options.onFocus);
|
|
4031
4081
|
this.on('blur', this.options.onBlur);
|
|
4032
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
|
+
}
|
|
4033
4089
|
window.setTimeout(() => {
|
|
4034
4090
|
if (this.isDestroyed) {
|
|
4035
4091
|
return;
|
|
@@ -4157,7 +4213,12 @@ class Editor extends EventEmitter {
|
|
|
4157
4213
|
FocusEvents,
|
|
4158
4214
|
Keymap,
|
|
4159
4215
|
Tabindex,
|
|
4160
|
-
]
|
|
4216
|
+
].filter(ext => {
|
|
4217
|
+
if (typeof this.options.enableCoreExtensions === 'object') {
|
|
4218
|
+
return this.options.enableCoreExtensions[ext.name] !== false;
|
|
4219
|
+
}
|
|
4220
|
+
return true;
|
|
4221
|
+
}) : [];
|
|
4161
4222
|
const allExtensions = [...coreExtensions, ...this.options.extensions].filter(extension => {
|
|
4162
4223
|
return ['extension', 'node', 'mark'].includes(extension === null || extension === void 0 ? void 0 : extension.type);
|
|
4163
4224
|
});
|
|
@@ -4766,6 +4827,9 @@ class NodeView {
|
|
|
4766
4827
|
this.extension = props.extension;
|
|
4767
4828
|
this.node = props.node;
|
|
4768
4829
|
this.decorations = props.decorations;
|
|
4830
|
+
this.innerDecorations = props.innerDecorations;
|
|
4831
|
+
this.view = props.view;
|
|
4832
|
+
this.HTMLAttributes = props.HTMLAttributes;
|
|
4769
4833
|
this.getPos = props.getPos;
|
|
4770
4834
|
this.mount();
|
|
4771
4835
|
}
|
|
@@ -4804,9 +4868,13 @@ class NodeView {
|
|
|
4804
4868
|
y = handleBox.y - domBox.y + offsetY;
|
|
4805
4869
|
}
|
|
4806
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
|
+
}
|
|
4807
4875
|
// we need to tell ProseMirror that we want to move the whole node
|
|
4808
4876
|
// so we create a NodeSelection
|
|
4809
|
-
const selection = NodeSelection.create(view.state.doc,
|
|
4877
|
+
const selection = NodeSelection.create(view.state.doc, pos);
|
|
4810
4878
|
const transaction = view.state.tr.setSelection(selection);
|
|
4811
4879
|
view.dispatch(transaction);
|
|
4812
4880
|
}
|
|
@@ -4877,6 +4945,11 @@ class NodeView {
|
|
|
4877
4945
|
}
|
|
4878
4946
|
return true;
|
|
4879
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
|
+
*/
|
|
4880
4953
|
ignoreMutation(mutation) {
|
|
4881
4954
|
if (!this.dom || !this.contentDOM) {
|
|
4882
4955
|
return true;
|
|
@@ -4923,9 +4996,15 @@ class NodeView {
|
|
|
4923
4996
|
}
|
|
4924
4997
|
return true;
|
|
4925
4998
|
}
|
|
4999
|
+
/**
|
|
5000
|
+
* Update the attributes of the prosemirror node.
|
|
5001
|
+
*/
|
|
4926
5002
|
updateAttributes(attributes) {
|
|
4927
5003
|
this.editor.commands.command(({ tr }) => {
|
|
4928
5004
|
const pos = this.getPos();
|
|
5005
|
+
if (typeof pos !== 'number') {
|
|
5006
|
+
return false;
|
|
5007
|
+
}
|
|
4929
5008
|
tr.setNodeMarkup(pos, undefined, {
|
|
4930
5009
|
...this.node.attrs,
|
|
4931
5010
|
...attributes,
|
|
@@ -4933,8 +5012,14 @@ class NodeView {
|
|
|
4933
5012
|
return true;
|
|
4934
5013
|
});
|
|
4935
5014
|
}
|
|
5015
|
+
/**
|
|
5016
|
+
* Delete the node.
|
|
5017
|
+
*/
|
|
4936
5018
|
deleteNode() {
|
|
4937
5019
|
const from = this.getPos();
|
|
5020
|
+
if (typeof from !== 'number') {
|
|
5021
|
+
return;
|
|
5022
|
+
}
|
|
4938
5023
|
const to = from + this.node.nodeSize;
|
|
4939
5024
|
this.editor.commands.deleteRange({ from, to });
|
|
4940
5025
|
}
|
|
@@ -5069,5 +5154,5 @@ class Tracker {
|
|
|
5069
5154
|
}
|
|
5070
5155
|
}
|
|
5071
5156
|
|
|
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 };
|
|
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 };
|
|
5073
5158
|
//# sourceMappingURL=index.js.map
|