@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/PasteRule.d.ts.map +1 -1
- package/dist/commands/focus.d.ts.map +1 -1
- package/dist/commands/selectAll.d.ts.map +1 -1
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/rewriteUnknownContent.d.ts +46 -0
- package/dist/helpers/rewriteUnknownContent.d.ts.map +1 -0
- package/dist/index.cjs +122 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +123 -27
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +122 -25
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
- package/src/NodeView.ts +2 -2
- package/src/PasteRule.ts +29 -0
- package/src/commands/focus.ts +1 -6
- package/src/commands/selectAll.ts +10 -5
- package/src/helpers/index.ts +1 -0
- package/src/helpers/rewriteUnknownContent.ts +148 -0
package/dist/index.umd.js
CHANGED
|
@@ -994,6 +994,8 @@
|
|
|
994
994
|
const success = handlers.every(handler => handler !== null);
|
|
995
995
|
return success;
|
|
996
996
|
}
|
|
997
|
+
// When dragging across editors, must get another editor instance to delete selection content.
|
|
998
|
+
let tiptapDragFromOtherEditor = null;
|
|
997
999
|
const createClipboardPasteEvent = (text) => {
|
|
998
1000
|
var _a;
|
|
999
1001
|
const event = new ClipboardEvent('paste', {
|
|
@@ -1056,11 +1058,21 @@
|
|
|
1056
1058
|
dragSourceElement = ((_a = view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.contains(event.target))
|
|
1057
1059
|
? view.dom.parentElement
|
|
1058
1060
|
: null;
|
|
1061
|
+
if (dragSourceElement) {
|
|
1062
|
+
tiptapDragFromOtherEditor = editor;
|
|
1063
|
+
}
|
|
1064
|
+
};
|
|
1065
|
+
const handleDragend = () => {
|
|
1066
|
+
if (tiptapDragFromOtherEditor) {
|
|
1067
|
+
tiptapDragFromOtherEditor = null;
|
|
1068
|
+
}
|
|
1059
1069
|
};
|
|
1060
1070
|
window.addEventListener('dragstart', handleDragstart);
|
|
1071
|
+
window.addEventListener('dragend', handleDragend);
|
|
1061
1072
|
return {
|
|
1062
1073
|
destroy() {
|
|
1063
1074
|
window.removeEventListener('dragstart', handleDragstart);
|
|
1075
|
+
window.removeEventListener('dragend', handleDragend);
|
|
1064
1076
|
},
|
|
1065
1077
|
};
|
|
1066
1078
|
},
|
|
@@ -1069,6 +1081,18 @@
|
|
|
1069
1081
|
drop: (view, event) => {
|
|
1070
1082
|
isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement;
|
|
1071
1083
|
dropEvent = event;
|
|
1084
|
+
if (!isDroppedFromProseMirror) {
|
|
1085
|
+
const dragFromOtherEditor = tiptapDragFromOtherEditor;
|
|
1086
|
+
if (dragFromOtherEditor) {
|
|
1087
|
+
// setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0
|
|
1088
|
+
setTimeout(() => {
|
|
1089
|
+
const selection = dragFromOtherEditor.state.selection;
|
|
1090
|
+
if (selection) {
|
|
1091
|
+
dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to });
|
|
1092
|
+
}
|
|
1093
|
+
}, 10);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1072
1096
|
return false;
|
|
1073
1097
|
},
|
|
1074
1098
|
paste: (_view, event) => {
|
|
@@ -1827,30 +1851,13 @@
|
|
|
1827
1851
|
return state.TextSelection.create(doc, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos));
|
|
1828
1852
|
}
|
|
1829
1853
|
|
|
1830
|
-
function isiOS() {
|
|
1831
|
-
return [
|
|
1832
|
-
'iPad Simulator',
|
|
1833
|
-
'iPhone Simulator',
|
|
1834
|
-
'iPod Simulator',
|
|
1835
|
-
'iPad',
|
|
1836
|
-
'iPhone',
|
|
1837
|
-
'iPod',
|
|
1838
|
-
].includes(navigator.platform)
|
|
1839
|
-
// iPad on iOS 13 detection
|
|
1840
|
-
|| (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
|
|
1841
|
-
}
|
|
1842
|
-
|
|
1843
1854
|
const focus = (position = null, options = {}) => ({ editor, view, tr, dispatch, }) => {
|
|
1844
1855
|
options = {
|
|
1845
1856
|
scrollIntoView: true,
|
|
1846
1857
|
...options,
|
|
1847
1858
|
};
|
|
1848
1859
|
const delayedFocus = () => {
|
|
1849
|
-
|
|
1850
|
-
// so we have to call this
|
|
1851
|
-
if (isiOS()) {
|
|
1852
|
-
view.dom.focus();
|
|
1853
|
-
}
|
|
1860
|
+
view.dom.focus();
|
|
1854
1861
|
// For React we have to focus asynchronously. Otherwise wild things happen.
|
|
1855
1862
|
// see: https://github.com/ueberdosis/tiptap/issues/1520
|
|
1856
1863
|
requestAnimationFrame(() => {
|
|
@@ -2181,6 +2188,19 @@
|
|
|
2181
2188
|
return commands$1.joinTextblockForward(state, dispatch);
|
|
2182
2189
|
};
|
|
2183
2190
|
|
|
2191
|
+
function isiOS() {
|
|
2192
|
+
return [
|
|
2193
|
+
'iPad Simulator',
|
|
2194
|
+
'iPhone Simulator',
|
|
2195
|
+
'iPod Simulator',
|
|
2196
|
+
'iPad',
|
|
2197
|
+
'iPhone',
|
|
2198
|
+
'iPod',
|
|
2199
|
+
].includes(navigator.platform)
|
|
2200
|
+
// iPad on iOS 13 detection
|
|
2201
|
+
|| (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2184
2204
|
function isMacOS() {
|
|
2185
2205
|
return typeof navigator !== 'undefined'
|
|
2186
2206
|
? /Mac/.test(navigator.platform)
|
|
@@ -2391,11 +2411,12 @@
|
|
|
2391
2411
|
return true;
|
|
2392
2412
|
};
|
|
2393
2413
|
|
|
2394
|
-
const selectAll = () => ({ tr,
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
}
|
|
2414
|
+
const selectAll = () => ({ tr, dispatch }) => {
|
|
2415
|
+
if (dispatch) {
|
|
2416
|
+
const selection = new state.AllSelection(tr.doc);
|
|
2417
|
+
tr.setSelection(selection);
|
|
2418
|
+
}
|
|
2419
|
+
return true;
|
|
2399
2420
|
};
|
|
2400
2421
|
|
|
2401
2422
|
const selectNodeBackward = () => ({ state, dispatch }) => {
|
|
@@ -3082,6 +3103,81 @@
|
|
|
3082
3103
|
};
|
|
3083
3104
|
}
|
|
3084
3105
|
|
|
3106
|
+
/**
|
|
3107
|
+
* The actual implementation of the rewriteUnknownContent function
|
|
3108
|
+
*/
|
|
3109
|
+
function rewriteUnknownContentInner({ json, validMarks, validNodes, options, rewrittenContent = [], }) {
|
|
3110
|
+
if (json.marks && Array.isArray(json.marks)) {
|
|
3111
|
+
json.marks = json.marks.filter(mark => {
|
|
3112
|
+
const name = typeof mark === 'string' ? mark : mark.type;
|
|
3113
|
+
if (validMarks.has(name)) {
|
|
3114
|
+
return true;
|
|
3115
|
+
}
|
|
3116
|
+
rewrittenContent.push({
|
|
3117
|
+
original: JSON.parse(JSON.stringify(mark)),
|
|
3118
|
+
unsupported: name,
|
|
3119
|
+
});
|
|
3120
|
+
// Just ignore any unknown marks
|
|
3121
|
+
return false;
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
if (json.content && Array.isArray(json.content)) {
|
|
3125
|
+
json.content = json.content
|
|
3126
|
+
.map(value => rewriteUnknownContentInner({
|
|
3127
|
+
json: value,
|
|
3128
|
+
validMarks,
|
|
3129
|
+
validNodes,
|
|
3130
|
+
options,
|
|
3131
|
+
rewrittenContent,
|
|
3132
|
+
}).json)
|
|
3133
|
+
.filter(a => a !== null && a !== undefined);
|
|
3134
|
+
}
|
|
3135
|
+
if (json.type && !validNodes.has(json.type)) {
|
|
3136
|
+
rewrittenContent.push({
|
|
3137
|
+
original: JSON.parse(JSON.stringify(json)),
|
|
3138
|
+
unsupported: json.type,
|
|
3139
|
+
});
|
|
3140
|
+
if (json.content && Array.isArray(json.content) && ((options === null || options === void 0 ? void 0 : options.fallbackToParagraph) !== false)) {
|
|
3141
|
+
// Just treat it like a paragraph and hope for the best
|
|
3142
|
+
json.type = 'paragraph';
|
|
3143
|
+
return {
|
|
3144
|
+
json,
|
|
3145
|
+
rewrittenContent,
|
|
3146
|
+
};
|
|
3147
|
+
}
|
|
3148
|
+
// or just omit it entirely
|
|
3149
|
+
return {
|
|
3150
|
+
json: null,
|
|
3151
|
+
rewrittenContent,
|
|
3152
|
+
};
|
|
3153
|
+
}
|
|
3154
|
+
return { json, rewrittenContent };
|
|
3155
|
+
}
|
|
3156
|
+
/**
|
|
3157
|
+
* Rewrite unknown nodes and marks within JSON content
|
|
3158
|
+
* Allowing for user within the editor
|
|
3159
|
+
*/
|
|
3160
|
+
function rewriteUnknownContent(
|
|
3161
|
+
/**
|
|
3162
|
+
* The JSON content to clean of unknown nodes and marks
|
|
3163
|
+
*/
|
|
3164
|
+
json,
|
|
3165
|
+
/**
|
|
3166
|
+
* The schema to use for validation
|
|
3167
|
+
*/
|
|
3168
|
+
schema,
|
|
3169
|
+
/**
|
|
3170
|
+
* Options for the cleaning process
|
|
3171
|
+
*/
|
|
3172
|
+
options) {
|
|
3173
|
+
return rewriteUnknownContentInner({
|
|
3174
|
+
json,
|
|
3175
|
+
validNodes: new Set(Object.keys(schema.nodes)),
|
|
3176
|
+
validMarks: new Set(Object.keys(schema.marks)),
|
|
3177
|
+
options,
|
|
3178
|
+
});
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3085
3181
|
function canSetMark(state, tr, newMarkType) {
|
|
3086
3182
|
var _a;
|
|
3087
3183
|
const { selection } = tr;
|
|
@@ -5077,10 +5173,10 @@ img.ProseMirror-separator {
|
|
|
5077
5173
|
// ProseMirror tries to drag selectable nodes
|
|
5078
5174
|
// even if `draggable` is set to `false`
|
|
5079
5175
|
// this fix prevents that
|
|
5080
|
-
if (!isDraggable && isSelectable && isDragEvent) {
|
|
5176
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
5081
5177
|
event.preventDefault();
|
|
5082
5178
|
}
|
|
5083
|
-
if (isDraggable && isDragEvent && !isDragging) {
|
|
5179
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
5084
5180
|
event.preventDefault();
|
|
5085
5181
|
return false;
|
|
5086
5182
|
}
|
|
@@ -5406,6 +5502,7 @@ img.ProseMirror-separator {
|
|
|
5406
5502
|
exports.posToDOMRect = posToDOMRect;
|
|
5407
5503
|
exports.removeDuplicates = removeDuplicates;
|
|
5408
5504
|
exports.resolveFocusPosition = resolveFocusPosition;
|
|
5505
|
+
exports.rewriteUnknownContent = rewriteUnknownContent;
|
|
5409
5506
|
exports.selectionToInsertionEnd = selectionToInsertionEnd;
|
|
5410
5507
|
exports.splitExtensions = splitExtensions;
|
|
5411
5508
|
exports.textInputRule = textInputRule;
|