@tiptap/core 2.10.4 → 2.11.1
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/Editor.d.ts +1 -1
- package/dist/Editor.d.ts.map +1 -1
- package/dist/EventEmitter.d.ts.map +1 -1
- package/dist/Mark.d.ts.map +1 -1
- package/dist/Node.d.ts.map +1 -1
- 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 +128 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +129 -32
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +128 -30
- package/dist/index.umd.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utilities/isFunction.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/Editor.ts +2 -1
- package/src/EventEmitter.ts +1 -1
- package/src/Mark.ts +1 -0
- package/src/Node.ts +1 -0
- package/src/NodeView.ts +2 -2
- package/src/PasteRule.ts +31 -2
- package/src/commands/focus.ts +1 -6
- package/src/commands/joinItemBackward.ts +1 -1
- package/src/commands/joinItemForward.ts +1 -1
- package/src/commands/selectAll.ts +10 -5
- package/src/helpers/getSchemaByResolvedExtensions.ts +1 -1
- package/src/helpers/index.ts +1 -0
- package/src/helpers/rewriteUnknownContent.ts +148 -0
- package/src/types.ts +1 -1
- package/src/utilities/isFunction.ts +1 -0
- package/src/utilities/mergeAttributes.ts +1 -1
package/dist/index.umd.js
CHANGED
|
@@ -318,7 +318,7 @@
|
|
|
318
318
|
return;
|
|
319
319
|
}
|
|
320
320
|
if (key === 'class') {
|
|
321
|
-
const valueClasses = value ? value.split(' ') : [];
|
|
321
|
+
const valueClasses = value ? String(value).split(' ') : [];
|
|
322
322
|
const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(' ') : [];
|
|
323
323
|
const insertClasses = valueClasses.filter(valueClass => !existingClasses.includes(valueClass));
|
|
324
324
|
mergedAttributes[key] = [...existingClasses, ...insertClasses].join(' ');
|
|
@@ -360,6 +360,7 @@
|
|
|
360
360
|
.reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {});
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
363
364
|
function isFunction(value) {
|
|
364
365
|
return typeof value === 'function';
|
|
365
366
|
}
|
|
@@ -994,6 +995,8 @@
|
|
|
994
995
|
const success = handlers.every(handler => handler !== null);
|
|
995
996
|
return success;
|
|
996
997
|
}
|
|
998
|
+
// When dragging across editors, must get another editor instance to delete selection content.
|
|
999
|
+
let tiptapDragFromOtherEditor = null;
|
|
997
1000
|
const createClipboardPasteEvent = (text) => {
|
|
998
1001
|
var _a;
|
|
999
1002
|
const event = new ClipboardEvent('paste', {
|
|
@@ -1017,7 +1020,7 @@
|
|
|
1017
1020
|
try {
|
|
1018
1021
|
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
|
|
1019
1022
|
}
|
|
1020
|
-
catch
|
|
1023
|
+
catch {
|
|
1021
1024
|
dropEvent = null;
|
|
1022
1025
|
}
|
|
1023
1026
|
const processEvent = ({ state, from, to, rule, pasteEvt, }) => {
|
|
@@ -1041,7 +1044,7 @@
|
|
|
1041
1044
|
try {
|
|
1042
1045
|
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
|
|
1043
1046
|
}
|
|
1044
|
-
catch
|
|
1047
|
+
catch {
|
|
1045
1048
|
dropEvent = null;
|
|
1046
1049
|
}
|
|
1047
1050
|
pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null;
|
|
@@ -1056,11 +1059,21 @@
|
|
|
1056
1059
|
dragSourceElement = ((_a = view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.contains(event.target))
|
|
1057
1060
|
? view.dom.parentElement
|
|
1058
1061
|
: null;
|
|
1062
|
+
if (dragSourceElement) {
|
|
1063
|
+
tiptapDragFromOtherEditor = editor;
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
const handleDragend = () => {
|
|
1067
|
+
if (tiptapDragFromOtherEditor) {
|
|
1068
|
+
tiptapDragFromOtherEditor = null;
|
|
1069
|
+
}
|
|
1059
1070
|
};
|
|
1060
1071
|
window.addEventListener('dragstart', handleDragstart);
|
|
1072
|
+
window.addEventListener('dragend', handleDragend);
|
|
1061
1073
|
return {
|
|
1062
1074
|
destroy() {
|
|
1063
1075
|
window.removeEventListener('dragstart', handleDragstart);
|
|
1076
|
+
window.removeEventListener('dragend', handleDragend);
|
|
1064
1077
|
},
|
|
1065
1078
|
};
|
|
1066
1079
|
},
|
|
@@ -1069,6 +1082,18 @@
|
|
|
1069
1082
|
drop: (view, event) => {
|
|
1070
1083
|
isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement;
|
|
1071
1084
|
dropEvent = event;
|
|
1085
|
+
if (!isDroppedFromProseMirror) {
|
|
1086
|
+
const dragFromOtherEditor = tiptapDragFromOtherEditor;
|
|
1087
|
+
if (dragFromOtherEditor) {
|
|
1088
|
+
// setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0
|
|
1089
|
+
setTimeout(() => {
|
|
1090
|
+
const selection = dragFromOtherEditor.state.selection;
|
|
1091
|
+
if (selection) {
|
|
1092
|
+
dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to });
|
|
1093
|
+
}
|
|
1094
|
+
}, 10);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1072
1097
|
return false;
|
|
1073
1098
|
},
|
|
1074
1099
|
paste: (_view, event) => {
|
|
@@ -1827,30 +1852,13 @@
|
|
|
1827
1852
|
return state.TextSelection.create(doc, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos));
|
|
1828
1853
|
}
|
|
1829
1854
|
|
|
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
1855
|
const focus = (position = null, options = {}) => ({ editor, view, tr, dispatch, }) => {
|
|
1844
1856
|
options = {
|
|
1845
1857
|
scrollIntoView: true,
|
|
1846
1858
|
...options,
|
|
1847
1859
|
};
|
|
1848
1860
|
const delayedFocus = () => {
|
|
1849
|
-
|
|
1850
|
-
// so we have to call this
|
|
1851
|
-
if (isiOS()) {
|
|
1852
|
-
view.dom.focus();
|
|
1853
|
-
}
|
|
1861
|
+
view.dom.focus();
|
|
1854
1862
|
// For React we have to focus asynchronously. Otherwise wild things happen.
|
|
1855
1863
|
// see: https://github.com/ueberdosis/tiptap/issues/1520
|
|
1856
1864
|
requestAnimationFrame(() => {
|
|
@@ -2151,7 +2159,7 @@
|
|
|
2151
2159
|
}
|
|
2152
2160
|
return true;
|
|
2153
2161
|
}
|
|
2154
|
-
catch
|
|
2162
|
+
catch {
|
|
2155
2163
|
return false;
|
|
2156
2164
|
}
|
|
2157
2165
|
};
|
|
@@ -2168,7 +2176,7 @@
|
|
|
2168
2176
|
}
|
|
2169
2177
|
return true;
|
|
2170
2178
|
}
|
|
2171
|
-
catch
|
|
2179
|
+
catch {
|
|
2172
2180
|
return false;
|
|
2173
2181
|
}
|
|
2174
2182
|
};
|
|
@@ -2181,6 +2189,19 @@
|
|
|
2181
2189
|
return commands$1.joinTextblockForward(state, dispatch);
|
|
2182
2190
|
};
|
|
2183
2191
|
|
|
2192
|
+
function isiOS() {
|
|
2193
|
+
return [
|
|
2194
|
+
'iPad Simulator',
|
|
2195
|
+
'iPhone Simulator',
|
|
2196
|
+
'iPod Simulator',
|
|
2197
|
+
'iPad',
|
|
2198
|
+
'iPhone',
|
|
2199
|
+
'iPod',
|
|
2200
|
+
].includes(navigator.platform)
|
|
2201
|
+
// iPad on iOS 13 detection
|
|
2202
|
+
|| (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2184
2205
|
function isMacOS() {
|
|
2185
2206
|
return typeof navigator !== 'undefined'
|
|
2186
2207
|
? /Mac/.test(navigator.platform)
|
|
@@ -2391,11 +2412,12 @@
|
|
|
2391
2412
|
return true;
|
|
2392
2413
|
};
|
|
2393
2414
|
|
|
2394
|
-
const selectAll = () => ({ tr,
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
}
|
|
2415
|
+
const selectAll = () => ({ tr, dispatch }) => {
|
|
2416
|
+
if (dispatch) {
|
|
2417
|
+
const selection = new state.AllSelection(tr.doc);
|
|
2418
|
+
tr.setSelection(selection);
|
|
2419
|
+
}
|
|
2420
|
+
return true;
|
|
2399
2421
|
};
|
|
2400
2422
|
|
|
2401
2423
|
const selectNodeBackward = () => ({ state, dispatch }) => {
|
|
@@ -3082,6 +3104,81 @@
|
|
|
3082
3104
|
};
|
|
3083
3105
|
}
|
|
3084
3106
|
|
|
3107
|
+
/**
|
|
3108
|
+
* The actual implementation of the rewriteUnknownContent function
|
|
3109
|
+
*/
|
|
3110
|
+
function rewriteUnknownContentInner({ json, validMarks, validNodes, options, rewrittenContent = [], }) {
|
|
3111
|
+
if (json.marks && Array.isArray(json.marks)) {
|
|
3112
|
+
json.marks = json.marks.filter(mark => {
|
|
3113
|
+
const name = typeof mark === 'string' ? mark : mark.type;
|
|
3114
|
+
if (validMarks.has(name)) {
|
|
3115
|
+
return true;
|
|
3116
|
+
}
|
|
3117
|
+
rewrittenContent.push({
|
|
3118
|
+
original: JSON.parse(JSON.stringify(mark)),
|
|
3119
|
+
unsupported: name,
|
|
3120
|
+
});
|
|
3121
|
+
// Just ignore any unknown marks
|
|
3122
|
+
return false;
|
|
3123
|
+
});
|
|
3124
|
+
}
|
|
3125
|
+
if (json.content && Array.isArray(json.content)) {
|
|
3126
|
+
json.content = json.content
|
|
3127
|
+
.map(value => rewriteUnknownContentInner({
|
|
3128
|
+
json: value,
|
|
3129
|
+
validMarks,
|
|
3130
|
+
validNodes,
|
|
3131
|
+
options,
|
|
3132
|
+
rewrittenContent,
|
|
3133
|
+
}).json)
|
|
3134
|
+
.filter(a => a !== null && a !== undefined);
|
|
3135
|
+
}
|
|
3136
|
+
if (json.type && !validNodes.has(json.type)) {
|
|
3137
|
+
rewrittenContent.push({
|
|
3138
|
+
original: JSON.parse(JSON.stringify(json)),
|
|
3139
|
+
unsupported: json.type,
|
|
3140
|
+
});
|
|
3141
|
+
if (json.content && Array.isArray(json.content) && ((options === null || options === void 0 ? void 0 : options.fallbackToParagraph) !== false)) {
|
|
3142
|
+
// Just treat it like a paragraph and hope for the best
|
|
3143
|
+
json.type = 'paragraph';
|
|
3144
|
+
return {
|
|
3145
|
+
json,
|
|
3146
|
+
rewrittenContent,
|
|
3147
|
+
};
|
|
3148
|
+
}
|
|
3149
|
+
// or just omit it entirely
|
|
3150
|
+
return {
|
|
3151
|
+
json: null,
|
|
3152
|
+
rewrittenContent,
|
|
3153
|
+
};
|
|
3154
|
+
}
|
|
3155
|
+
return { json, rewrittenContent };
|
|
3156
|
+
}
|
|
3157
|
+
/**
|
|
3158
|
+
* Rewrite unknown nodes and marks within JSON content
|
|
3159
|
+
* Allowing for user within the editor
|
|
3160
|
+
*/
|
|
3161
|
+
function rewriteUnknownContent(
|
|
3162
|
+
/**
|
|
3163
|
+
* The JSON content to clean of unknown nodes and marks
|
|
3164
|
+
*/
|
|
3165
|
+
json,
|
|
3166
|
+
/**
|
|
3167
|
+
* The schema to use for validation
|
|
3168
|
+
*/
|
|
3169
|
+
schema,
|
|
3170
|
+
/**
|
|
3171
|
+
* Options for the cleaning process
|
|
3172
|
+
*/
|
|
3173
|
+
options) {
|
|
3174
|
+
return rewriteUnknownContentInner({
|
|
3175
|
+
json,
|
|
3176
|
+
validNodes: new Set(Object.keys(schema.nodes)),
|
|
3177
|
+
validMarks: new Set(Object.keys(schema.marks)),
|
|
3178
|
+
options,
|
|
3179
|
+
});
|
|
3180
|
+
}
|
|
3181
|
+
|
|
3085
3182
|
function canSetMark(state, tr, newMarkType) {
|
|
3086
3183
|
var _a;
|
|
3087
3184
|
const { selection } = tr;
|
|
@@ -5077,10 +5174,10 @@ img.ProseMirror-separator {
|
|
|
5077
5174
|
// ProseMirror tries to drag selectable nodes
|
|
5078
5175
|
// even if `draggable` is set to `false`
|
|
5079
5176
|
// this fix prevents that
|
|
5080
|
-
if (!isDraggable && isSelectable && isDragEvent) {
|
|
5177
|
+
if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {
|
|
5081
5178
|
event.preventDefault();
|
|
5082
5179
|
}
|
|
5083
|
-
if (isDraggable && isDragEvent && !isDragging) {
|
|
5180
|
+
if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {
|
|
5084
5181
|
event.preventDefault();
|
|
5085
5182
|
return false;
|
|
5086
5183
|
}
|
|
@@ -5406,6 +5503,7 @@ img.ProseMirror-separator {
|
|
|
5406
5503
|
exports.posToDOMRect = posToDOMRect;
|
|
5407
5504
|
exports.removeDuplicates = removeDuplicates;
|
|
5408
5505
|
exports.resolveFocusPosition = resolveFocusPosition;
|
|
5506
|
+
exports.rewriteUnknownContent = rewriteUnknownContent;
|
|
5409
5507
|
exports.selectionToInsertionEnd = selectionToInsertionEnd;
|
|
5410
5508
|
exports.splitExtensions = splitExtensions;
|
|
5411
5509
|
exports.textInputRule = textInputRule;
|