@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 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
- tr.insertText(value, from, to);
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;