@tiptap/core 2.5.0-beta.3 → 2.5.0-beta.5

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.umd.js CHANGED
@@ -462,6 +462,7 @@
462
462
  selectable: callOrReturn(getExtensionField(extension, 'selectable', context)),
463
463
  draggable: callOrReturn(getExtensionField(extension, 'draggable', context)),
464
464
  code: callOrReturn(getExtensionField(extension, 'code', context)),
465
+ whitespace: callOrReturn(getExtensionField(extension, 'whitespace', context)),
465
466
  defining: callOrReturn(getExtensionField(extension, 'defining', context)),
466
467
  isolating: callOrReturn(getExtensionField(extension, 'isolating', context)),
467
468
  attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => {
@@ -1079,7 +1080,7 @@
1079
1080
  const addKeyboardShortcuts = getExtensionField(extension, 'addKeyboardShortcuts', context);
1080
1081
  let defaultBindings = {};
1081
1082
  // bind exit handling
1082
- if (extension.type === 'mark' && extension.config.exitable) {
1083
+ if (extension.type === 'mark' && getExtensionField(extension, 'exitable', context)) {
1083
1084
  defaultBindings.ArrowRight = () => Mark.handleExit({ editor, mark: extension });
1084
1085
  }
1085
1086
  if (addKeyboardShortcuts) {
@@ -1285,13 +1286,17 @@
1285
1286
  configure(options = {}) {
1286
1287
  // return a new instance so we can use the same extension
1287
1288
  // with different calls of `configure`
1288
- const extension = this.extend();
1289
+ const extension = this.extend({
1290
+ ...this.config,
1291
+ addOptions() {
1292
+ var _a;
1293
+ return mergeDeep(((_a = this.parent) === null || _a === void 0 ? void 0 : _a.call(this)) || {}, options);
1294
+ },
1295
+ });
1296
+ // Always preserve the current name
1297
+ extension.name = this.name;
1298
+ // Set the parent to be our parent
1289
1299
  extension.parent = this.parent;
1290
- extension.options = mergeDeep(this.options, options);
1291
- extension.storage = callOrReturn(getExtensionField(extension, 'addStorage', {
1292
- name: extension.name,
1293
- options: extension.options,
1294
- }));
1295
1300
  return extension;
1296
1301
  }
1297
1302
  extend(extendedConfig = {}) {
@@ -1299,7 +1304,7 @@
1299
1304
  extension.parent = this;
1300
1305
  this.child = extension;
1301
1306
  extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name;
1302
- if (extendedConfig.defaultOptions) {
1307
+ if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {
1303
1308
  console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`);
1304
1309
  }
1305
1310
  extension.options = callOrReturn(getExtensionField(extension, 'addOptions', {
@@ -1773,6 +1778,7 @@
1773
1778
  if (isTextContent) {
1774
1779
  let schemaToUse = schema;
1775
1780
  let hasInvalidContent = false;
1781
+ let invalidContent = '';
1776
1782
  // Only ever check for invalid content if we're supposed to throw an error
1777
1783
  if (options.errorOnInvalidContent) {
1778
1784
  schemaToUse = new model.Schema({
@@ -1787,9 +1793,11 @@
1787
1793
  parseDOM: [
1788
1794
  {
1789
1795
  tag: '*',
1790
- getAttrs: () => {
1796
+ getAttrs: e => {
1791
1797
  // If this is ever called, we know that the content has something that we don't know how to handle in the schema
1792
1798
  hasInvalidContent = true;
1799
+ // Try to stringify the element for a more helpful error message
1800
+ invalidContent = typeof e === 'string' ? e : e.outerHTML;
1793
1801
  return null;
1794
1802
  },
1795
1803
  },
@@ -1803,7 +1811,7 @@
1803
1811
  ? parser.parseSlice(elementFromString(content), options.parseOptions).content
1804
1812
  : parser.parse(elementFromString(content), options.parseOptions);
1805
1813
  if (options.errorOnInvalidContent && hasInvalidContent) {
1806
- throw new Error('[tiptap error]: Invalid HTML content');
1814
+ throw new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) });
1807
1815
  }
1808
1816
  return response;
1809
1817
  }
@@ -1856,10 +1864,6 @@
1856
1864
  catch (e) {
1857
1865
  return false;
1858
1866
  }
1859
- // don’t dispatch an empty fragment because this can lead to strange errors
1860
- if (content.toString() === '<>') {
1861
- return true;
1862
- }
1863
1867
  let { from, to } = typeof position === 'number' ? { from: position, to: position } : { from: position.from, to: position.to };
1864
1868
  let isOnlyTextContent = true;
1865
1869
  let isOnlyBlockContent = true;
@@ -2229,22 +2233,27 @@
2229
2233
  });
2230
2234
  }
2231
2235
 
2232
- const setContent = (content, emitUpdate = false, parseOptions = {}, options = {}) => ({ tr, editor, dispatch }) => {
2233
- var _a;
2236
+ const setContent = (content, emitUpdate = false, parseOptions = {}, options = {}) => ({ editor, tr, dispatch, commands, }) => {
2237
+ var _a, _b;
2234
2238
  const { doc } = tr;
2235
- let document;
2236
- try {
2237
- document = createDocument(content, editor.schema, parseOptions, {
2239
+ // This is to keep backward compatibility with the previous behavior
2240
+ // TODO remove this in the next major version
2241
+ if (parseOptions.preserveWhitespace !== 'full') {
2242
+ const document = createDocument(content, editor.schema, parseOptions, {
2238
2243
  errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck,
2239
2244
  });
2240
- }
2241
- catch (e) {
2242
- return false;
2245
+ if (dispatch) {
2246
+ tr.replaceWith(0, doc.content.size, document).setMeta('preventUpdate', !emitUpdate);
2247
+ }
2248
+ return true;
2243
2249
  }
2244
2250
  if (dispatch) {
2245
- tr.replaceWith(0, doc.content.size, document).setMeta('preventUpdate', !emitUpdate);
2251
+ tr.setMeta('preventUpdate', !emitUpdate);
2246
2252
  }
2247
- return true;
2253
+ return commands.insertContentAt({ from: 0, to: doc.content.size }, content, {
2254
+ parseOptions,
2255
+ errorOnInvalidContent: (_b = options.errorOnInvalidContent) !== null && _b !== void 0 ? _b : editor.options.enableContentCheck,
2256
+ });
2248
2257
  };
2249
2258
 
2250
2259
  function getMarkAttributes(state, typeOrName) {
@@ -3348,40 +3357,30 @@
3348
3357
  markType = getMarkType(typeOrName, state.schema);
3349
3358
  }
3350
3359
  if (dispatch) {
3351
- let lastPos;
3352
- let lastNode;
3353
- let trimmedFrom;
3354
- let trimmedTo;
3355
- tr.selection.ranges.forEach((range) => {
3360
+ tr.selection.ranges.forEach(range => {
3356
3361
  const from = range.$from.pos;
3357
3362
  const to = range.$to.pos;
3358
3363
  state.doc.nodesBetween(from, to, (node, pos) => {
3359
3364
  if (nodeType && nodeType === node.type) {
3360
- trimmedFrom = Math.max(pos, from);
3361
- trimmedTo = Math.min(pos + node.nodeSize, to);
3362
- lastPos = pos;
3363
- lastNode = node;
3365
+ tr.setNodeMarkup(pos, undefined, {
3366
+ ...node.attrs,
3367
+ ...attributes,
3368
+ });
3369
+ }
3370
+ if (markType && node.marks.length) {
3371
+ node.marks.forEach(mark => {
3372
+ if (markType === mark.type) {
3373
+ const trimmedFrom = Math.max(pos, from);
3374
+ const trimmedTo = Math.min(pos + node.nodeSize, to);
3375
+ tr.addMark(trimmedFrom, trimmedTo, markType.create({
3376
+ ...mark.attrs,
3377
+ ...attributes,
3378
+ }));
3379
+ }
3380
+ });
3364
3381
  }
3365
3382
  });
3366
3383
  });
3367
- if (lastNode) {
3368
- if (lastPos !== undefined) {
3369
- tr.setNodeMarkup(lastPos, undefined, {
3370
- ...lastNode.attrs,
3371
- ...attributes,
3372
- });
3373
- }
3374
- if (markType && lastNode.marks.length) {
3375
- lastNode.marks.forEach((mark) => {
3376
- if (markType === mark.type) {
3377
- tr.addMark(trimmedFrom, trimmedTo, markType.create({
3378
- ...mark.attrs,
3379
- ...attributes,
3380
- }));
3381
- }
3382
- });
3383
- }
3384
- }
3385
3384
  }
3386
3385
  return true;
3387
3386
  };
@@ -3637,7 +3636,7 @@
3637
3636
  new state.Plugin({
3638
3637
  key: new state.PluginKey('tabindex'),
3639
3638
  props: {
3640
- attributes: this.editor.isEditable ? { tabindex: '0' } : {},
3639
+ attributes: () => (this.editor.isEditable ? { tabindex: '0' } : {}),
3641
3640
  },
3642
3641
  }),
3643
3642
  ];
@@ -4552,20 +4551,25 @@ img.ProseMirror-separator {
4552
4551
  configure(options = {}) {
4553
4552
  // return a new instance so we can use the same extension
4554
4553
  // with different calls of `configure`
4555
- const extension = this.extend();
4556
- extension.options = mergeDeep(this.options, options);
4557
- extension.storage = callOrReturn(getExtensionField(extension, 'addStorage', {
4558
- name: extension.name,
4559
- options: extension.options,
4560
- }));
4554
+ const extension = this.extend({
4555
+ ...this.config,
4556
+ addOptions() {
4557
+ var _a;
4558
+ return mergeDeep(((_a = this.parent) === null || _a === void 0 ? void 0 : _a.call(this)) || {}, options);
4559
+ },
4560
+ });
4561
+ // Always preserve the current name
4562
+ extension.name = this.name;
4563
+ // Set the parent to be our parent
4564
+ extension.parent = this.parent;
4561
4565
  return extension;
4562
4566
  }
4563
4567
  extend(extendedConfig = {}) {
4564
- const extension = new Mark({ ...this.config, ...extendedConfig });
4568
+ const extension = new Mark(extendedConfig);
4565
4569
  extension.parent = this;
4566
4570
  this.child = extension;
4567
4571
  extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name;
4568
- if (extendedConfig.defaultOptions) {
4572
+ if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {
4569
4573
  console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`);
4570
4574
  }
4571
4575
  extension.options = callOrReturn(getExtensionField(extension, 'addOptions', {
@@ -4639,20 +4643,25 @@ img.ProseMirror-separator {
4639
4643
  configure(options = {}) {
4640
4644
  // return a new instance so we can use the same extension
4641
4645
  // with different calls of `configure`
4642
- const extension = this.extend();
4643
- extension.options = mergeDeep(this.options, options);
4644
- extension.storage = callOrReturn(getExtensionField(extension, 'addStorage', {
4645
- name: extension.name,
4646
- options: extension.options,
4647
- }));
4646
+ const extension = this.extend({
4647
+ ...this.config,
4648
+ addOptions() {
4649
+ var _a;
4650
+ return mergeDeep(((_a = this.parent) === null || _a === void 0 ? void 0 : _a.call(this)) || {}, options);
4651
+ },
4652
+ });
4653
+ // Always preserve the current name
4654
+ extension.name = this.name;
4655
+ // Set the parent to be our parent
4656
+ extension.parent = this.parent;
4648
4657
  return extension;
4649
4658
  }
4650
4659
  extend(extendedConfig = {}) {
4651
- const extension = new Node({ ...this.config, ...extendedConfig });
4660
+ const extension = new Node(extendedConfig);
4652
4661
  extension.parent = this;
4653
4662
  this.child = extension;
4654
4663
  extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name;
4655
- if (extendedConfig.defaultOptions) {
4664
+ if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {
4656
4665
  console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`);
4657
4666
  }
4658
4667
  extension.options = callOrReturn(getExtensionField(extension, 'addOptions', {