@tiptap/core 2.5.8 → 2.6.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.js CHANGED
@@ -964,7 +964,7 @@ function pasteRulesPlugin(props) {
964
964
 
965
965
  function findDuplicates(items) {
966
966
  const filtered = items.filter((el, index) => items.indexOf(el) !== index);
967
- return [...new Set(filtered)];
967
+ return Array.from(new Set(filtered));
968
968
  }
969
969
 
970
970
  class ExtensionManager {
@@ -2634,7 +2634,7 @@ function getMarksBetween(from, to, doc) {
2634
2634
  .resolve(from)
2635
2635
  .marks()
2636
2636
  .forEach(mark => {
2637
- const $pos = doc.resolve(from - 1);
2637
+ const $pos = doc.resolve(from);
2638
2638
  const range = getMarkRange($pos, mark.type);
2639
2639
  if (!range) {
2640
2640
  return;
@@ -2827,31 +2827,40 @@ function isList(name, extensions) {
2827
2827
  }
2828
2828
 
2829
2829
  /**
2830
- * Returns true if the given node is empty.
2831
- * When `checkChildren` is true (default), it will also check if all children are empty.
2830
+ * Returns true if the given prosemirror node is empty.
2832
2831
  */
2833
- function isNodeEmpty(node, { checkChildren } = { checkChildren: true }) {
2832
+ function isNodeEmpty(node, { checkChildren = true, ignoreWhitespace = false, } = {}) {
2833
+ var _a;
2834
+ if (ignoreWhitespace) {
2835
+ if (node.type.name === 'hardBreak') {
2836
+ // Hard breaks are considered empty
2837
+ return true;
2838
+ }
2839
+ if (node.isText) {
2840
+ return /^\s*$/m.test((_a = node.text) !== null && _a !== void 0 ? _a : '');
2841
+ }
2842
+ }
2834
2843
  if (node.isText) {
2835
2844
  return !node.text;
2836
2845
  }
2846
+ if (node.isAtom || node.isLeaf) {
2847
+ return false;
2848
+ }
2837
2849
  if (node.content.childCount === 0) {
2838
2850
  return true;
2839
2851
  }
2840
- if (node.isLeaf) {
2841
- return false;
2842
- }
2843
2852
  if (checkChildren) {
2844
- let hasSameContent = true;
2853
+ let isContentEmpty = true;
2845
2854
  node.content.forEach(childNode => {
2846
- if (hasSameContent === false) {
2855
+ if (isContentEmpty === false) {
2847
2856
  // Exit early for perf
2848
2857
  return;
2849
2858
  }
2850
- if (!isNodeEmpty(childNode)) {
2851
- hasSameContent = false;
2859
+ if (!isNodeEmpty(childNode, { ignoreWhitespace, checkChildren })) {
2860
+ isContentEmpty = false;
2852
2861
  }
2853
2862
  });
2854
- return hasSameContent;
2863
+ return isContentEmpty;
2855
2864
  }
2856
2865
  return false;
2857
2866
  }
@@ -3099,7 +3108,7 @@ const splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor
3099
3108
  return can;
3100
3109
  };
3101
3110
 
3102
- const splitListItem = typeOrName => ({ tr, state, dispatch, editor, }) => {
3111
+ const splitListItem = (typeOrName, overrideAttrs = {}) => ({ tr, state, dispatch, editor, }) => {
3103
3112
  var _a;
3104
3113
  const type = getNodeType(typeOrName, state.schema);
3105
3114
  const { $from, $to } = state.selection;
@@ -3135,7 +3144,10 @@ const splitListItem = typeOrName => ({ tr, state, dispatch, editor, }) => {
3135
3144
  // eslint-disable-next-line
3136
3145
  const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3;
3137
3146
  // Add a second list item with an empty default start node
3138
- const newNextTypeAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs);
3147
+ const newNextTypeAttributes = {
3148
+ ...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
3149
+ ...overrideAttrs,
3150
+ };
3139
3151
  const nextType = ((_a = type.contentMatch.defaultType) === null || _a === void 0 ? void 0 : _a.createAndFill(newNextTypeAttributes)) || undefined;
3140
3152
  wrap = wrap.append(Fragment.from(type.createAndFill(null, nextType) || undefined));
3141
3153
  const start = $from.before($from.depth - (depthBefore - 1));
@@ -3157,8 +3169,14 @@ const splitListItem = typeOrName => ({ tr, state, dispatch, editor, }) => {
3157
3169
  return true;
3158
3170
  }
3159
3171
  const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null;
3160
- const newTypeAttributes = getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs);
3161
- const newNextTypeAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs);
3172
+ const newTypeAttributes = {
3173
+ ...getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs),
3174
+ ...overrideAttrs,
3175
+ };
3176
+ const newNextTypeAttributes = {
3177
+ ...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
3178
+ ...overrideAttrs,
3179
+ };
3162
3180
  tr.delete($from.pos, $to.pos);
3163
3181
  const types = nextType
3164
3182
  ? [
@@ -3960,6 +3978,10 @@ class Editor extends EventEmitter {
3960
3978
  constructor(options = {}) {
3961
3979
  super();
3962
3980
  this.isFocused = false;
3981
+ /**
3982
+ * The editor is considered initialized after the `create` event has been emitted.
3983
+ */
3984
+ this.isInitialized = false;
3963
3985
  this.extensionStorage = {};
3964
3986
  this.options = {
3965
3987
  element: document.createElement('div'),
@@ -4010,6 +4032,7 @@ class Editor extends EventEmitter {
4010
4032
  }
4011
4033
  this.commands.focus(this.options.autofocus);
4012
4034
  this.emit('create', { editor: this });
4035
+ this.isInitialized = true;
4013
4036
  }, 0);
4014
4037
  }
4015
4038
  /**
@@ -4977,14 +5000,16 @@ function nodePasteRule(config) {
4977
5000
  find: config.find,
4978
5001
  handler({ match, chain, range, pasteEvent, }) {
4979
5002
  const attributes = callOrReturn(config.getAttributes, undefined, match, pasteEvent);
5003
+ const content = callOrReturn(config.getContent, undefined, attributes);
4980
5004
  if (attributes === false || attributes === null) {
4981
5005
  return null;
4982
5006
  }
5007
+ const node = { type: config.type.name, attrs: attributes };
5008
+ if (content) {
5009
+ node.content = content;
5010
+ }
4983
5011
  if (match.input) {
4984
- chain().deleteRange(range).insertContentAt(range.from, {
4985
- type: config.type.name,
4986
- attrs: attributes,
4987
- });
5012
+ chain().deleteRange(range).insertContentAt(range.from, node);
4988
5013
  }
4989
5014
  },
4990
5015
  });