@tiptap/core 2.0.0-beta.162 → 2.0.0-beta.166

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.
@@ -18,6 +18,7 @@ export * from './inputRules/wrappingInputRule';
18
18
  export * from './pasteRules/markPasteRule';
19
19
  export * from './pasteRules/textPasteRule';
20
20
  export * from './utilities/callOrReturn';
21
+ export * from './utilities/escapeForRegEx';
21
22
  export * from './utilities/mergeAttributes';
22
23
  export * from './helpers/combineTransactionSteps';
23
24
  export * from './helpers/defaultBlockAt';
@@ -0,0 +1 @@
1
+ export declare function escapeForRegEx(string: string): string;
@@ -210,8 +210,12 @@ const ClipboardTextSerializer = Extension.create({
210
210
 
211
211
  const blur = () => ({ editor, view }) => {
212
212
  requestAnimationFrame(() => {
213
+ var _a;
213
214
  if (!editor.isDestroyed) {
214
215
  view.dom.blur();
216
+ // Browsers should remove the caret on blur but safari does not.
217
+ // See: https://github.com/ueberdosis/tiptap/issues/2405
218
+ (_a = window === null || window === void 0 ? void 0 : window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
215
219
  }
216
220
  });
217
221
  return true;
@@ -670,6 +674,7 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
670
674
  let { from, to } = typeof position === 'number'
671
675
  ? { from: position, to: position }
672
676
  : position;
677
+ let isOnlyTextContent = true;
673
678
  let isOnlyBlockContent = true;
674
679
  const nodes = isFragment(content)
675
680
  ? content
@@ -677,6 +682,9 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
677
682
  nodes.forEach(node => {
678
683
  // check if added node is valid
679
684
  node.check();
685
+ isOnlyTextContent = isOnlyTextContent
686
+ ? node.isText && node.marks.length === 0
687
+ : false;
680
688
  isOnlyBlockContent = isOnlyBlockContent
681
689
  ? node.isBlock
682
690
  : false;
@@ -696,7 +704,14 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
696
704
  to += 1;
697
705
  }
698
706
  }
699
- tr.replaceWith(from, to, content);
707
+ // if there is only plain text we have to use `insertText`
708
+ // because this will keep the current marks
709
+ if (isOnlyTextContent) {
710
+ tr.insertText(value, from, to);
711
+ }
712
+ else {
713
+ tr.replaceWith(from, to, content);
714
+ }
700
715
  // set cursor at end of inserted content
701
716
  if (options.updateSelection) {
702
717
  selectionToInsertionEnd(tr, tr.steps.length - 1, -1);
@@ -2455,21 +2470,45 @@ function run(config) {
2455
2470
  */
2456
2471
  function pasteRulesPlugin(props) {
2457
2472
  const { editor, rules } = props;
2458
- let isProseMirrorHTML = false;
2473
+ let dragSourceElement = null;
2474
+ let isPastedFromProseMirror = false;
2475
+ let isDroppedFromProseMirror = false;
2459
2476
  const plugins = rules.map(rule => {
2460
2477
  return new prosemirrorState.Plugin({
2461
- props: {
2462
- handlePaste: (view, event) => {
2478
+ // we register a global drag handler to track the current drag source element
2479
+ view(view) {
2480
+ const handleDragstart = (event) => {
2463
2481
  var _a;
2464
- const html = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/html');
2465
- isProseMirrorHTML = !!(html === null || html === void 0 ? void 0 : html.includes('data-pm-slice'));
2466
- return false;
2482
+ dragSourceElement = ((_a = view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.contains(event.target))
2483
+ ? view.dom.parentElement
2484
+ : null;
2485
+ };
2486
+ window.addEventListener('dragstart', handleDragstart);
2487
+ return {
2488
+ destroy() {
2489
+ window.removeEventListener('dragstart', handleDragstart);
2490
+ },
2491
+ };
2492
+ },
2493
+ props: {
2494
+ handleDOMEvents: {
2495
+ drop: view => {
2496
+ isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement;
2497
+ return false;
2498
+ },
2499
+ paste: (view, event) => {
2500
+ var _a;
2501
+ const html = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text/html');
2502
+ isPastedFromProseMirror = !!(html === null || html === void 0 ? void 0 : html.includes('data-pm-slice'));
2503
+ return false;
2504
+ },
2467
2505
  },
2468
2506
  },
2469
2507
  appendTransaction: (transactions, oldState, state) => {
2470
2508
  const transaction = transactions[0];
2471
- // stop if there is not a paste event
2472
- if (!transaction.getMeta('paste') || isProseMirrorHTML) {
2509
+ const isPaste = transaction.getMeta('uiEvent') === 'paste' && !isPastedFromProseMirror;
2510
+ const isDrop = transaction.getMeta('uiEvent') === 'drop' && !isDroppedFromProseMirror;
2511
+ if (!isPaste && !isDrop) {
2473
2512
  return;
2474
2513
  }
2475
2514
  // stop if there is no changed range
@@ -4083,6 +4122,11 @@ function textPasteRule(config) {
4083
4122
  });
4084
4123
  }
4085
4124
 
4125
+ // source: https://stackoverflow.com/a/6969486
4126
+ function escapeForRegEx(string) {
4127
+ return string.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
4128
+ }
4129
+
4086
4130
  /**
4087
4131
  * Returns a new `Transform` based on all steps of the passed transactions.
4088
4132
  */
@@ -4338,6 +4382,7 @@ exports.Tracker = Tracker;
4338
4382
  exports.callOrReturn = callOrReturn;
4339
4383
  exports.combineTransactionSteps = combineTransactionSteps;
4340
4384
  exports.defaultBlockAt = defaultBlockAt;
4385
+ exports.escapeForRegEx = escapeForRegEx;
4341
4386
  exports.extensions = extensions;
4342
4387
  exports.findChildren = findChildren;
4343
4388
  exports.findChildrenInRange = findChildrenInRange;