@tiptap/core 2.10.4 → 2.11.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
@@ -1,4 +1,4 @@
1
- import { Plugin, PluginKey, TextSelection, Selection, NodeSelection, EditorState } from '@tiptap/pm/state';
1
+ import { Plugin, PluginKey, TextSelection, Selection, AllSelection, NodeSelection, EditorState } from '@tiptap/pm/state';
2
2
  import { EditorView } from '@tiptap/pm/view';
3
3
  import { keymap } from '@tiptap/pm/keymap';
4
4
  import { Schema, DOMSerializer, Fragment, Node as Node$1, DOMParser, Slice } from '@tiptap/pm/model';
@@ -996,6 +996,8 @@ function run(config) {
996
996
  const success = handlers.every(handler => handler !== null);
997
997
  return success;
998
998
  }
999
+ // When dragging across editors, must get another editor instance to delete selection content.
1000
+ let tiptapDragFromOtherEditor = null;
999
1001
  const createClipboardPasteEvent = (text) => {
1000
1002
  var _a;
1001
1003
  const event = new ClipboardEvent('paste', {
@@ -1058,11 +1060,21 @@ function pasteRulesPlugin(props) {
1058
1060
  dragSourceElement = ((_a = view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.contains(event.target))
1059
1061
  ? view.dom.parentElement
1060
1062
  : null;
1063
+ if (dragSourceElement) {
1064
+ tiptapDragFromOtherEditor = editor;
1065
+ }
1066
+ };
1067
+ const handleDragend = () => {
1068
+ if (tiptapDragFromOtherEditor) {
1069
+ tiptapDragFromOtherEditor = null;
1070
+ }
1061
1071
  };
1062
1072
  window.addEventListener('dragstart', handleDragstart);
1073
+ window.addEventListener('dragend', handleDragend);
1063
1074
  return {
1064
1075
  destroy() {
1065
1076
  window.removeEventListener('dragstart', handleDragstart);
1077
+ window.removeEventListener('dragend', handleDragend);
1066
1078
  },
1067
1079
  };
1068
1080
  },
@@ -1071,6 +1083,18 @@ function pasteRulesPlugin(props) {
1071
1083
  drop: (view, event) => {
1072
1084
  isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement;
1073
1085
  dropEvent = event;
1086
+ if (!isDroppedFromProseMirror) {
1087
+ const dragFromOtherEditor = tiptapDragFromOtherEditor;
1088
+ if (dragFromOtherEditor) {
1089
+ // setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0
1090
+ setTimeout(() => {
1091
+ const selection = dragFromOtherEditor.state.selection;
1092
+ if (selection) {
1093
+ dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to });
1094
+ }
1095
+ }, 10);
1096
+ }
1097
+ }
1074
1098
  return false;
1075
1099
  },
1076
1100
  paste: (_view, event) => {
@@ -1829,30 +1853,13 @@ function resolveFocusPosition(doc, position = null) {
1829
1853
  return TextSelection.create(doc, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos));
1830
1854
  }
1831
1855
 
1832
- function isiOS() {
1833
- return [
1834
- 'iPad Simulator',
1835
- 'iPhone Simulator',
1836
- 'iPod Simulator',
1837
- 'iPad',
1838
- 'iPhone',
1839
- 'iPod',
1840
- ].includes(navigator.platform)
1841
- // iPad on iOS 13 detection
1842
- || (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
1843
- }
1844
-
1845
1856
  const focus = (position = null, options = {}) => ({ editor, view, tr, dispatch, }) => {
1846
1857
  options = {
1847
1858
  scrollIntoView: true,
1848
1859
  ...options,
1849
1860
  };
1850
1861
  const delayedFocus = () => {
1851
- // focus within `requestAnimationFrame` breaks focus on iOS
1852
- // so we have to call this
1853
- if (isiOS()) {
1854
- view.dom.focus();
1855
- }
1862
+ view.dom.focus();
1856
1863
  // For React we have to focus asynchronously. Otherwise wild things happen.
1857
1864
  // see: https://github.com/ueberdosis/tiptap/issues/1520
1858
1865
  requestAnimationFrame(() => {
@@ -2183,6 +2190,19 @@ const joinTextblockForward = () => ({ state, dispatch }) => {
2183
2190
  return joinTextblockForward$1(state, dispatch);
2184
2191
  };
2185
2192
 
2193
+ function isiOS() {
2194
+ return [
2195
+ 'iPad Simulator',
2196
+ 'iPhone Simulator',
2197
+ 'iPod Simulator',
2198
+ 'iPad',
2199
+ 'iPhone',
2200
+ 'iPod',
2201
+ ].includes(navigator.platform)
2202
+ // iPad on iOS 13 detection
2203
+ || (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
2204
+ }
2205
+
2186
2206
  function isMacOS() {
2187
2207
  return typeof navigator !== 'undefined'
2188
2208
  ? /Mac/.test(navigator.platform)
@@ -2393,11 +2413,12 @@ const scrollIntoView = () => ({ tr, dispatch }) => {
2393
2413
  return true;
2394
2414
  };
2395
2415
 
2396
- const selectAll = () => ({ tr, commands }) => {
2397
- return commands.setTextSelection({
2398
- from: 0,
2399
- to: tr.doc.content.size,
2400
- });
2416
+ const selectAll = () => ({ tr, dispatch }) => {
2417
+ if (dispatch) {
2418
+ const selection = new AllSelection(tr.doc);
2419
+ tr.setSelection(selection);
2420
+ }
2421
+ return true;
2401
2422
  };
2402
2423
 
2403
2424
  const selectNodeBackward = () => ({ state, dispatch }) => {
@@ -3084,6 +3105,81 @@ function posToDOMRect(view, from, to) {
3084
3105
  };
3085
3106
  }
3086
3107
 
3108
+ /**
3109
+ * The actual implementation of the rewriteUnknownContent function
3110
+ */
3111
+ function rewriteUnknownContentInner({ json, validMarks, validNodes, options, rewrittenContent = [], }) {
3112
+ if (json.marks && Array.isArray(json.marks)) {
3113
+ json.marks = json.marks.filter(mark => {
3114
+ const name = typeof mark === 'string' ? mark : mark.type;
3115
+ if (validMarks.has(name)) {
3116
+ return true;
3117
+ }
3118
+ rewrittenContent.push({
3119
+ original: JSON.parse(JSON.stringify(mark)),
3120
+ unsupported: name,
3121
+ });
3122
+ // Just ignore any unknown marks
3123
+ return false;
3124
+ });
3125
+ }
3126
+ if (json.content && Array.isArray(json.content)) {
3127
+ json.content = json.content
3128
+ .map(value => rewriteUnknownContentInner({
3129
+ json: value,
3130
+ validMarks,
3131
+ validNodes,
3132
+ options,
3133
+ rewrittenContent,
3134
+ }).json)
3135
+ .filter(a => a !== null && a !== undefined);
3136
+ }
3137
+ if (json.type && !validNodes.has(json.type)) {
3138
+ rewrittenContent.push({
3139
+ original: JSON.parse(JSON.stringify(json)),
3140
+ unsupported: json.type,
3141
+ });
3142
+ if (json.content && Array.isArray(json.content) && ((options === null || options === void 0 ? void 0 : options.fallbackToParagraph) !== false)) {
3143
+ // Just treat it like a paragraph and hope for the best
3144
+ json.type = 'paragraph';
3145
+ return {
3146
+ json,
3147
+ rewrittenContent,
3148
+ };
3149
+ }
3150
+ // or just omit it entirely
3151
+ return {
3152
+ json: null,
3153
+ rewrittenContent,
3154
+ };
3155
+ }
3156
+ return { json, rewrittenContent };
3157
+ }
3158
+ /**
3159
+ * Rewrite unknown nodes and marks within JSON content
3160
+ * Allowing for user within the editor
3161
+ */
3162
+ function rewriteUnknownContent(
3163
+ /**
3164
+ * The JSON content to clean of unknown nodes and marks
3165
+ */
3166
+ json,
3167
+ /**
3168
+ * The schema to use for validation
3169
+ */
3170
+ schema,
3171
+ /**
3172
+ * Options for the cleaning process
3173
+ */
3174
+ options) {
3175
+ return rewriteUnknownContentInner({
3176
+ json,
3177
+ validNodes: new Set(Object.keys(schema.nodes)),
3178
+ validMarks: new Set(Object.keys(schema.marks)),
3179
+ options,
3180
+ });
3181
+ }
3182
+
3087
3183
  function canSetMark(state, tr, newMarkType) {
3088
3184
  var _a;
3089
3185
  const { selection } = tr;
@@ -5079,10 +5175,10 @@ class NodeView {
5079
5175
  // ProseMirror tries to drag selectable nodes
5080
5176
  // even if `draggable` is set to `false`
5081
5177
  // this fix prevents that
5082
- if (!isDraggable && isSelectable && isDragEvent) {
5178
+ if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
5083
5179
  event.preventDefault();
5084
5180
  }
5085
- if (isDraggable && isDragEvent && !isDragging) {
5181
+ if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
5086
5182
  event.preventDefault();
5087
5183
  return false;
5088
5184
  }
@@ -5323,5 +5419,5 @@ class Tracker {
5323
5419
  }
5324
5420
  }
5325
5421
 
5326
- export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodePos, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, createChainableState, createDocument, createNodeFromContent, createStyleTag, defaultBlockAt, deleteProps, elementFromString, escapeForRegEx, index as extensions, findChildren, findChildrenInRange, findDuplicates, findParentNode, findParentNodeClosestToPos, fromString, generateHTML, generateJSON, generateText, getAttributes, getAttributesFromExtensions, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAtPosition, getNodeAttributes, getNodeType, getRenderedAttributes, getSchema, getSchemaByResolvedExtensions, getSchemaTypeByName, getSchemaTypeNameByName, getSplittedAttributes, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, injectExtensionAttributesToParseRule, inputRulesPlugin, isActive, isAtEndOfNode, isAtStartOfNode, isEmptyObject, isExtensionRulesEnabled, isFunction, isList, isMacOS, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isNumber, isPlainObject, isRegExp, isString, isTextSelection, isiOS, markInputRule, markPasteRule, mergeAttributes, mergeDeep, minMax, nodeInputRule, nodePasteRule, objectIncludes, pasteRulesPlugin, posToDOMRect, removeDuplicates, resolveFocusPosition, selectionToInsertionEnd, splitExtensions, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
5422
+ export { CommandManager, Editor, Extension, InputRule, Mark, Node, NodePos, NodeView, PasteRule, Tracker, callOrReturn, combineTransactionSteps, createChainableState, createDocument, createNodeFromContent, createStyleTag, defaultBlockAt, deleteProps, elementFromString, escapeForRegEx, index as extensions, findChildren, findChildrenInRange, findDuplicates, findParentNode, findParentNodeClosestToPos, fromString, generateHTML, generateJSON, generateText, getAttributes, getAttributesFromExtensions, getChangedRanges, getDebugJSON, getExtensionField, getHTMLFromFragment, getMarkAttributes, getMarkRange, getMarkType, getMarksBetween, getNodeAtPosition, getNodeAttributes, getNodeType, getRenderedAttributes, getSchema, getSchemaByResolvedExtensions, getSchemaTypeByName, getSchemaTypeNameByName, getSplittedAttributes, getText, getTextBetween, getTextContentFromNodes, getTextSerializersFromSchema, injectExtensionAttributesToParseRule, inputRulesPlugin, isActive, isAtEndOfNode, isAtStartOfNode, isEmptyObject, isExtensionRulesEnabled, isFunction, isList, isMacOS, isMarkActive, isNodeActive, isNodeEmpty, isNodeSelection, isNumber, isPlainObject, isRegExp, isString, isTextSelection, isiOS, markInputRule, markPasteRule, mergeAttributes, mergeDeep, minMax, nodeInputRule, nodePasteRule, objectIncludes, pasteRulesPlugin, posToDOMRect, removeDuplicates, resolveFocusPosition, rewriteUnknownContent, selectionToInsertionEnd, splitExtensions, textInputRule, textPasteRule, textblockTypeInputRule, wrappingInputRule };
5327
5423
  //# sourceMappingURL=index.js.map