@tiptap/core 2.0.0-beta.217 → 2.0.0-beta.219
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 +90 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +77 -24
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +90 -23
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/core/src/NodeView.d.ts +3 -3
- package/dist/packages/core/src/commands/toggleList.d.ts +1 -1
- package/dist/packages/core/src/helpers/index.d.ts +14 -0
- package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +4 -0
- package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +2 -2
- package/dist/packages/core/src/types.d.ts +5 -2
- package/package.json +2 -2
- package/src/Editor.ts +1 -1
- package/src/NodeView.ts +14 -6
- package/src/commands/insertContentAt.ts +9 -1
- package/src/commands/splitListItem.ts +12 -0
- package/src/commands/toggleList.ts +28 -7
- package/src/helpers/createNodeFromContent.ts +1 -1
- package/src/helpers/index.ts +14 -0
- package/src/inputRules/wrappingInputRule.ts +33 -8
- package/src/pasteRules/nodePasteRule.ts +2 -2
- package/src/types.ts +8 -2
package/dist/index.cjs
CHANGED
|
@@ -1575,7 +1575,7 @@ function createNodeFromContent(content, schema, options) {
|
|
|
1575
1575
|
};
|
|
1576
1576
|
if (typeof content === 'object' && content !== null) {
|
|
1577
1577
|
try {
|
|
1578
|
-
if (Array.isArray(content)) {
|
|
1578
|
+
if (Array.isArray(content) && content.length > 0) {
|
|
1579
1579
|
return model.Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)));
|
|
1580
1580
|
}
|
|
1581
1581
|
return schema.nodeFromJSON(content);
|
|
@@ -1660,7 +1660,17 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
|
|
|
1660
1660
|
// if there is only plain text we have to use `insertText`
|
|
1661
1661
|
// because this will keep the current marks
|
|
1662
1662
|
if (isOnlyTextContent) {
|
|
1663
|
-
|
|
1663
|
+
// if value is string, we can use it directly
|
|
1664
|
+
// otherwise if it is an array, we have to join it
|
|
1665
|
+
if (Array.isArray(value)) {
|
|
1666
|
+
tr.insertText(value.map(v => v.text || '').join(''), from, to);
|
|
1667
|
+
}
|
|
1668
|
+
else if (typeof value === 'object' && !!value && !!value.text) {
|
|
1669
|
+
tr.insertText(value.text, from, to);
|
|
1670
|
+
}
|
|
1671
|
+
else {
|
|
1672
|
+
tr.insertText(value, from, to);
|
|
1673
|
+
}
|
|
1664
1674
|
}
|
|
1665
1675
|
else {
|
|
1666
1676
|
tr.replaceWith(from, to, content);
|
|
@@ -2250,6 +2260,20 @@ function getMarksBetween(from, to, doc) {
|
|
|
2250
2260
|
return marks;
|
|
2251
2261
|
}
|
|
2252
2262
|
|
|
2263
|
+
function getSplittedAttributes(extensionAttributes, typeName, attributes) {
|
|
2264
|
+
return Object.fromEntries(Object
|
|
2265
|
+
.entries(attributes)
|
|
2266
|
+
.filter(([name]) => {
|
|
2267
|
+
const extensionAttribute = extensionAttributes.find(item => {
|
|
2268
|
+
return item.type === typeName && item.name === name;
|
|
2269
|
+
});
|
|
2270
|
+
if (!extensionAttribute) {
|
|
2271
|
+
return false;
|
|
2272
|
+
}
|
|
2273
|
+
return extensionAttribute.attribute.keepOnSplit;
|
|
2274
|
+
}));
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2253
2277
|
function isMarkActive(state, typeOrName, attributes = {}) {
|
|
2254
2278
|
const { empty, ranges } = state.selection;
|
|
2255
2279
|
const type = typeOrName ? getMarkType(typeOrName, state.schema) : null;
|
|
@@ -2519,20 +2543,6 @@ const sinkListItem = typeOrName => ({ state, dispatch }) => {
|
|
|
2519
2543
|
return schemaList.sinkListItem(type)(state, dispatch);
|
|
2520
2544
|
};
|
|
2521
2545
|
|
|
2522
|
-
function getSplittedAttributes(extensionAttributes, typeName, attributes) {
|
|
2523
|
-
return Object.fromEntries(Object
|
|
2524
|
-
.entries(attributes)
|
|
2525
|
-
.filter(([name]) => {
|
|
2526
|
-
const extensionAttribute = extensionAttributes.find(item => {
|
|
2527
|
-
return item.type === typeName && item.name === name;
|
|
2528
|
-
});
|
|
2529
|
-
if (!extensionAttribute) {
|
|
2530
|
-
return false;
|
|
2531
|
-
}
|
|
2532
|
-
return extensionAttribute.attribute.keepOnSplit;
|
|
2533
|
-
}));
|
|
2534
|
-
}
|
|
2535
|
-
|
|
2536
2546
|
function ensureMarks(state, splittableMarks) {
|
|
2537
2547
|
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
|
|
2538
2548
|
if (marks) {
|
|
@@ -2679,7 +2689,15 @@ const splitListItem = typeOrName => ({ tr, state: state$1, dispatch, editor, })
|
|
|
2679
2689
|
return false;
|
|
2680
2690
|
}
|
|
2681
2691
|
if (dispatch) {
|
|
2692
|
+
const { selection, storedMarks } = state$1;
|
|
2693
|
+
const { splittableMarks } = editor.extensionManager;
|
|
2694
|
+
const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks());
|
|
2682
2695
|
tr.split($from.pos, 2, types).scrollIntoView();
|
|
2696
|
+
if (!marks || !dispatch) {
|
|
2697
|
+
return true;
|
|
2698
|
+
}
|
|
2699
|
+
const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name));
|
|
2700
|
+
tr.ensureMarks(filteredMarks);
|
|
2683
2701
|
}
|
|
2684
2702
|
return true;
|
|
2685
2703
|
};
|
|
@@ -2718,13 +2736,14 @@ const joinListForwards = (tr, listType) => {
|
|
|
2718
2736
|
tr.join(after);
|
|
2719
2737
|
return true;
|
|
2720
2738
|
};
|
|
2721
|
-
const toggleList = (listTypeOrName, itemTypeOrName) => ({ editor, tr, state, dispatch, chain, commands, can, }) => {
|
|
2722
|
-
const { extensions } = editor.extensionManager;
|
|
2739
|
+
const toggleList = (listTypeOrName, itemTypeOrName, keepMarks) => ({ editor, tr, state, dispatch, chain, commands, can, }) => {
|
|
2740
|
+
const { extensions, splittableMarks } = editor.extensionManager;
|
|
2723
2741
|
const listType = getNodeType(listTypeOrName, state.schema);
|
|
2724
2742
|
const itemType = getNodeType(itemTypeOrName, state.schema);
|
|
2725
|
-
const { selection } = state;
|
|
2743
|
+
const { selection, storedMarks } = state;
|
|
2726
2744
|
const { $from, $to } = selection;
|
|
2727
2745
|
const range = $from.blockRange($to);
|
|
2746
|
+
const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks());
|
|
2728
2747
|
if (!range) {
|
|
2729
2748
|
return false;
|
|
2730
2749
|
}
|
|
@@ -2748,10 +2767,27 @@ const toggleList = (listTypeOrName, itemTypeOrName) => ({ editor, tr, state, dis
|
|
|
2748
2767
|
.run();
|
|
2749
2768
|
}
|
|
2750
2769
|
}
|
|
2770
|
+
if (!keepMarks || !marks || !dispatch) {
|
|
2771
|
+
return chain()
|
|
2772
|
+
// try to convert node to default node if needed
|
|
2773
|
+
.command(() => {
|
|
2774
|
+
const canWrapInList = can().wrapInList(listType);
|
|
2775
|
+
if (canWrapInList) {
|
|
2776
|
+
return true;
|
|
2777
|
+
}
|
|
2778
|
+
return commands.clearNodes();
|
|
2779
|
+
})
|
|
2780
|
+
.wrapInList(listType)
|
|
2781
|
+
.command(() => joinListBackwards(tr, listType))
|
|
2782
|
+
.command(() => joinListForwards(tr, listType))
|
|
2783
|
+
.run();
|
|
2784
|
+
}
|
|
2751
2785
|
return (chain()
|
|
2752
2786
|
// try to convert node to default node if needed
|
|
2753
2787
|
.command(() => {
|
|
2754
2788
|
const canWrapInList = can().wrapInList(listType);
|
|
2789
|
+
const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name));
|
|
2790
|
+
tr.ensureMarks(filteredMarks);
|
|
2755
2791
|
if (canWrapInList) {
|
|
2756
2792
|
return true;
|
|
2757
2793
|
}
|
|
@@ -3549,8 +3585,8 @@ class Editor extends EventEmitter {
|
|
|
3549
3585
|
return getText(this.state.doc, {
|
|
3550
3586
|
blockSeparator,
|
|
3551
3587
|
textSerializers: {
|
|
3552
|
-
...textSerializers,
|
|
3553
3588
|
...getTextSerializersFromSchema(this.schema),
|
|
3589
|
+
...textSerializers,
|
|
3554
3590
|
},
|
|
3555
3591
|
});
|
|
3556
3592
|
}
|
|
@@ -3732,7 +3768,7 @@ function textInputRule(config) {
|
|
|
3732
3768
|
function wrappingInputRule(config) {
|
|
3733
3769
|
return new InputRule({
|
|
3734
3770
|
find: config.find,
|
|
3735
|
-
handler: ({ state, range, match }) => {
|
|
3771
|
+
handler: ({ state, range, match, chain, }) => {
|
|
3736
3772
|
const attributes = callOrReturn(config.getAttributes, undefined, match) || {};
|
|
3737
3773
|
const tr = state.tr.delete(range.from, range.to);
|
|
3738
3774
|
const $start = tr.doc.resolve(range.from);
|
|
@@ -3742,6 +3778,20 @@ function wrappingInputRule(config) {
|
|
|
3742
3778
|
return null;
|
|
3743
3779
|
}
|
|
3744
3780
|
tr.wrap(blockRange, wrapping);
|
|
3781
|
+
if (config.keepMarks && config.editor) {
|
|
3782
|
+
const { selection, storedMarks } = state;
|
|
3783
|
+
const { splittableMarks } = config.editor.extensionManager;
|
|
3784
|
+
const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks());
|
|
3785
|
+
if (marks) {
|
|
3786
|
+
const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name));
|
|
3787
|
+
tr.ensureMarks(filteredMarks);
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
if (config.keepAttributes) {
|
|
3791
|
+
/** If the nodeType is `bulletList` or `orderedList` set the `nodeType` as `listItem` */
|
|
3792
|
+
const nodeType = config.type.name === 'bulletList' || config.type.name === 'orderedList' ? 'listItem' : 'taskList';
|
|
3793
|
+
chain().updateAttributes(nodeType, attributes).run();
|
|
3794
|
+
}
|
|
3745
3795
|
const before = tr.doc.resolve(range.from - 1).nodeBefore;
|
|
3746
3796
|
if (before
|
|
3747
3797
|
&& before.type === config.type
|
|
@@ -3970,10 +4020,11 @@ class NodeView {
|
|
|
3970
4020
|
if (!isInElement) {
|
|
3971
4021
|
return false;
|
|
3972
4022
|
}
|
|
4023
|
+
const isDragEvent = event.type.startsWith('drag');
|
|
3973
4024
|
const isDropEvent = event.type === 'drop';
|
|
3974
4025
|
const isInput = ['INPUT', 'BUTTON', 'SELECT', 'TEXTAREA'].includes(target.tagName) || target.isContentEditable;
|
|
3975
4026
|
// any input event within node views should be ignored by ProseMirror
|
|
3976
|
-
if (isInput && !isDropEvent) {
|
|
4027
|
+
if (isInput && !isDropEvent && !isDragEvent) {
|
|
3977
4028
|
return true;
|
|
3978
4029
|
}
|
|
3979
4030
|
const { isEditable } = this.editor;
|
|
@@ -3984,7 +4035,6 @@ class NodeView {
|
|
|
3984
4035
|
const isPasteEvent = event.type === 'paste';
|
|
3985
4036
|
const isCutEvent = event.type === 'cut';
|
|
3986
4037
|
const isClickEvent = event.type === 'mousedown';
|
|
3987
|
-
const isDragEvent = event.type.startsWith('drag');
|
|
3988
4038
|
// ProseMirror tries to drag selectable nodes
|
|
3989
4039
|
// even if `draggable` is set to `false`
|
|
3990
4040
|
// this fix prevents that
|
|
@@ -4004,6 +4054,9 @@ class NodeView {
|
|
|
4004
4054
|
document.addEventListener('dragend', () => {
|
|
4005
4055
|
this.isDragging = false;
|
|
4006
4056
|
}, { once: true });
|
|
4057
|
+
document.addEventListener('drop', () => {
|
|
4058
|
+
this.isDragging = false;
|
|
4059
|
+
}, { once: true });
|
|
4007
4060
|
document.addEventListener('mouseup', () => {
|
|
4008
4061
|
this.isDragging = false;
|
|
4009
4062
|
}, { once: true });
|
|
@@ -4217,6 +4270,9 @@ exports.PasteRule = PasteRule;
|
|
|
4217
4270
|
exports.Tracker = Tracker;
|
|
4218
4271
|
exports.callOrReturn = callOrReturn;
|
|
4219
4272
|
exports.combineTransactionSteps = combineTransactionSteps;
|
|
4273
|
+
exports.createChainableState = createChainableState;
|
|
4274
|
+
exports.createDocument = createDocument;
|
|
4275
|
+
exports.createNodeFromContent = createNodeFromContent;
|
|
4220
4276
|
exports.createStyleTag = createStyleTag;
|
|
4221
4277
|
exports.defaultBlockAt = defaultBlockAt;
|
|
4222
4278
|
exports.deleteProps = deleteProps;
|
|
@@ -4233,6 +4289,7 @@ exports.generateHTML = generateHTML;
|
|
|
4233
4289
|
exports.generateJSON = generateJSON;
|
|
4234
4290
|
exports.generateText = generateText;
|
|
4235
4291
|
exports.getAttributes = getAttributes;
|
|
4292
|
+
exports.getAttributesFromExtensions = getAttributesFromExtensions;
|
|
4236
4293
|
exports.getChangedRanges = getChangedRanges;
|
|
4237
4294
|
exports.getDebugJSON = getDebugJSON;
|
|
4238
4295
|
exports.getExtensionField = getExtensionField;
|
|
@@ -4243,14 +4300,21 @@ exports.getMarkType = getMarkType;
|
|
|
4243
4300
|
exports.getMarksBetween = getMarksBetween;
|
|
4244
4301
|
exports.getNodeAttributes = getNodeAttributes;
|
|
4245
4302
|
exports.getNodeType = getNodeType;
|
|
4303
|
+
exports.getRenderedAttributes = getRenderedAttributes;
|
|
4246
4304
|
exports.getSchema = getSchema;
|
|
4305
|
+
exports.getSchemaByResolvedExtensions = getSchemaByResolvedExtensions;
|
|
4306
|
+
exports.getSchemaTypeByName = getSchemaTypeByName;
|
|
4307
|
+
exports.getSchemaTypeNameByName = getSchemaTypeNameByName;
|
|
4308
|
+
exports.getSplittedAttributes = getSplittedAttributes;
|
|
4247
4309
|
exports.getText = getText;
|
|
4248
4310
|
exports.getTextBetween = getTextBetween;
|
|
4249
4311
|
exports.getTextContentFromNodes = getTextContentFromNodes;
|
|
4250
4312
|
exports.getTextSerializersFromSchema = getTextSerializersFromSchema;
|
|
4313
|
+
exports.injectExtensionAttributesToParseRule = injectExtensionAttributesToParseRule;
|
|
4251
4314
|
exports.inputRulesPlugin = inputRulesPlugin;
|
|
4252
4315
|
exports.isActive = isActive;
|
|
4253
4316
|
exports.isEmptyObject = isEmptyObject;
|
|
4317
|
+
exports.isExtensionRulesEnabled = isExtensionRulesEnabled;
|
|
4254
4318
|
exports.isFunction = isFunction;
|
|
4255
4319
|
exports.isList = isList;
|
|
4256
4320
|
exports.isMacOS = isMacOS;
|
|
@@ -4275,6 +4339,9 @@ exports.objectIncludes = objectIncludes;
|
|
|
4275
4339
|
exports.pasteRulesPlugin = pasteRulesPlugin;
|
|
4276
4340
|
exports.posToDOMRect = posToDOMRect;
|
|
4277
4341
|
exports.removeDuplicates = removeDuplicates;
|
|
4342
|
+
exports.resolveFocusPosition = resolveFocusPosition;
|
|
4343
|
+
exports.selectionToInsertionEnd = selectionToInsertionEnd;
|
|
4344
|
+
exports.splitExtensions = splitExtensions;
|
|
4278
4345
|
exports.textInputRule = textInputRule;
|
|
4279
4346
|
exports.textPasteRule = textPasteRule;
|
|
4280
4347
|
exports.textblockTypeInputRule = textblockTypeInputRule;
|