@ctzhian/tiptap 2.13.3 → 2.13.4
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/extension/node/Image.js +95 -64
- package/package.json +1 -1
|
@@ -15,11 +15,10 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try
|
|
|
15
15
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
16
16
|
import { getFileType, removeBaseUrl, withBaseUrl } from "../../util";
|
|
17
17
|
import Image from "@tiptap/extension-image";
|
|
18
|
+
import { generateJSON } from "@tiptap/html";
|
|
18
19
|
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
|
19
20
|
import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
20
|
-
import { generateJSON } from "@tiptap/html";
|
|
21
21
|
import ImageViewWrapper, { getImageDimensionsFromFile } from "../component/Image";
|
|
22
|
-
/** 从 URL 下载图片并转换为 File 对象 */
|
|
23
22
|
function downloadImageAsFile(_x, _x2) {
|
|
24
23
|
return _downloadImageAsFile.apply(this, arguments);
|
|
25
24
|
}
|
|
@@ -69,7 +68,7 @@ function _downloadImageAsFile() {
|
|
|
69
68
|
fileName = "image-".concat(index + 1, ".").concat(blob.type.split('/')[1] || 'png');
|
|
70
69
|
file = new File([blob], fileName, {
|
|
71
70
|
type: blob.type
|
|
72
|
-
});
|
|
71
|
+
});
|
|
73
72
|
return _context5.abrupt("return", file);
|
|
74
73
|
case 22:
|
|
75
74
|
_context5.prev = 22;
|
|
@@ -202,7 +201,7 @@ var customImage = function customImage(props) {
|
|
|
202
201
|
key: new PluginKey('imagePasteHandler'),
|
|
203
202
|
props: {
|
|
204
203
|
handlePaste: function handlePaste(view, event) {
|
|
205
|
-
var _event$clipboardData, _event$clipboardData2;
|
|
204
|
+
var _event$clipboardData, _event$clipboardData2, _event$clipboardData3;
|
|
206
205
|
if (!props.onUpload) return false;
|
|
207
206
|
var items = Array.from(((_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.items) || []);
|
|
208
207
|
var imageFiles = items.map(function (item) {
|
|
@@ -211,13 +210,44 @@ var customImage = function customImage(props) {
|
|
|
211
210
|
return file !== null && getFileType(file) === 'image';
|
|
212
211
|
});
|
|
213
212
|
var htmlData = (_event$clipboardData2 = event.clipboardData) === null || _event$clipboardData2 === void 0 ? void 0 : _event$clipboardData2.getData('text/html');
|
|
214
|
-
|
|
215
|
-
// 提前声明变量和函数,避免在异步回调中出现 TDZ 错误
|
|
213
|
+
var plainText = (_event$clipboardData3 = event.clipboardData) === null || _event$clipboardData3 === void 0 ? void 0 : _event$clipboardData3.getData('text/plain');
|
|
216
214
|
var _view$state$selection = view.state.selection,
|
|
217
215
|
from = _view$state$selection.from,
|
|
218
216
|
to = _view$state$selection.to;
|
|
219
217
|
var editor = _this2.editor;
|
|
220
218
|
|
|
219
|
+
// 辅助函数:检查内容是否包含有效文本
|
|
220
|
+
var hasValidTextContent = function hasValidTextContent(content) {
|
|
221
|
+
var _content$some;
|
|
222
|
+
return (_content$some = content === null || content === void 0 ? void 0 : content.some(function (node) {
|
|
223
|
+
if (node.type === 'text' || node.text && node.text.trim()) {
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
if (node.content && Array.isArray(node.content)) {
|
|
227
|
+
return hasValidTextContent(node.content);
|
|
228
|
+
}
|
|
229
|
+
return false;
|
|
230
|
+
})) !== null && _content$some !== void 0 ? _content$some : false;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// 辅助函数:插入纯文本内容
|
|
234
|
+
var insertPlainText = function insertPlainText(text) {
|
|
235
|
+
event.preventDefault();
|
|
236
|
+
editor.chain().insertContentAt({
|
|
237
|
+
from: from,
|
|
238
|
+
to: to
|
|
239
|
+
}, {
|
|
240
|
+
type: 'doc',
|
|
241
|
+
content: [{
|
|
242
|
+
type: 'paragraph',
|
|
243
|
+
content: [{
|
|
244
|
+
type: 'text',
|
|
245
|
+
text: text
|
|
246
|
+
}]
|
|
247
|
+
}]
|
|
248
|
+
}).focus().run();
|
|
249
|
+
};
|
|
250
|
+
|
|
221
251
|
// 定义辅助函数
|
|
222
252
|
var findNodePosition = function findNodePosition(typeName, tempId) {
|
|
223
253
|
var targetPos = null;
|
|
@@ -397,16 +427,18 @@ var customImage = function customImage(props) {
|
|
|
397
427
|
};
|
|
398
428
|
}();
|
|
399
429
|
|
|
400
|
-
//
|
|
401
|
-
|
|
402
|
-
|
|
430
|
+
// 如果没有图片文件,尝试从 HTML 中提取图片 URL 或处理文本粘贴
|
|
431
|
+
if (imageFiles.length === 0) {
|
|
432
|
+
if (!htmlData) {
|
|
433
|
+
return false; // 没有 HTML 数据,让默认粘贴处理
|
|
434
|
+
}
|
|
403
435
|
var imageUrls = extractImageUrls(htmlData);
|
|
404
|
-
if (imageUrls.length > 0) {
|
|
405
|
-
event.preventDefault(); // 阻止默认粘贴行为
|
|
406
436
|
|
|
407
|
-
|
|
437
|
+
// 如果找到图片 URL,下载并处理图片
|
|
438
|
+
if (imageUrls.length > 0) {
|
|
439
|
+
event.preventDefault();
|
|
408
440
|
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
409
|
-
var downloadedFiles, validFiles
|
|
441
|
+
var downloadedFiles, validFiles;
|
|
410
442
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
411
443
|
while (1) switch (_context3.prev = _context3.next) {
|
|
412
444
|
case 0:
|
|
@@ -420,72 +452,71 @@ var customImage = function customImage(props) {
|
|
|
420
452
|
return f !== null;
|
|
421
453
|
});
|
|
422
454
|
if (!(validFiles.length === 0)) {
|
|
423
|
-
_context3.next =
|
|
455
|
+
_context3.next = 6;
|
|
424
456
|
break;
|
|
425
457
|
}
|
|
426
|
-
_context3.prev = 5;
|
|
427
|
-
extensions = editor.extensionManager.extensions;
|
|
428
|
-
parsed = generateJSON(htmlData, extensions);
|
|
429
|
-
if (!(parsed !== null && parsed !== void 0 && (_parsed$content2 = parsed.content) !== null && _parsed$content2 !== void 0 && _parsed$content2.length)) {
|
|
430
|
-
_context3.next = 12;
|
|
431
|
-
break;
|
|
432
|
-
}
|
|
433
|
-
editor.chain().insertContentAt({
|
|
434
|
-
from: from,
|
|
435
|
-
to: to
|
|
436
|
-
}, parsed).focus().run();
|
|
437
|
-
_context3.next = 13;
|
|
438
|
-
break;
|
|
439
|
-
case 12:
|
|
440
|
-
throw new Error('解析失败');
|
|
441
|
-
case 13:
|
|
442
|
-
_context3.next = 18;
|
|
443
|
-
break;
|
|
444
|
-
case 15:
|
|
445
|
-
_context3.prev = 15;
|
|
446
|
-
_context3.t0 = _context3["catch"](5);
|
|
447
|
-
return _context3.abrupt("return");
|
|
448
|
-
case 18:
|
|
449
458
|
return _context3.abrupt("return");
|
|
450
|
-
case
|
|
451
|
-
_context3.next =
|
|
459
|
+
case 6:
|
|
460
|
+
_context3.next = 8;
|
|
452
461
|
return processImagePaste(validFiles, htmlData, from, to);
|
|
453
|
-
case
|
|
462
|
+
case 8:
|
|
454
463
|
case "end":
|
|
455
464
|
return _context3.stop();
|
|
456
465
|
}
|
|
457
|
-
}, _callee3
|
|
466
|
+
}, _callee3);
|
|
458
467
|
}))();
|
|
459
|
-
return true;
|
|
460
|
-
} else {
|
|
461
|
-
return false;
|
|
468
|
+
return true;
|
|
462
469
|
}
|
|
470
|
+
|
|
471
|
+
// 没有图片 URL,尝试处理 HTML 或纯文本
|
|
472
|
+
// 先尝试使用 generateJSON 解析 HTML
|
|
473
|
+
try {
|
|
474
|
+
var _parsed$content2;
|
|
475
|
+
var extensions = editor.extensionManager.extensions;
|
|
476
|
+
var parsed = generateJSON(htmlData, extensions);
|
|
477
|
+
|
|
478
|
+
// 检查解析后的内容是否包含有效文本
|
|
479
|
+
if (parsed !== null && parsed !== void 0 && (_parsed$content2 = parsed.content) !== null && _parsed$content2 !== void 0 && _parsed$content2.length && hasValidTextContent(parsed.content)) {
|
|
480
|
+
event.preventDefault();
|
|
481
|
+
editor.chain().insertContentAt({
|
|
482
|
+
from: from,
|
|
483
|
+
to: to
|
|
484
|
+
}, parsed).focus().run();
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
} catch (error) {
|
|
488
|
+
// HTML 解析失败,继续尝试纯文本
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// HTML 解析失败或内容无效(如包含特殊格式 data-clipboard-cangjie),使用纯文本
|
|
492
|
+
if (plainText !== null && plainText !== void 0 && plainText.trim()) {
|
|
493
|
+
insertPlainText(plainText.trim());
|
|
494
|
+
return true;
|
|
495
|
+
}
|
|
496
|
+
return false; // 让默认粘贴处理
|
|
463
497
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if (htmlData && htmlData.trim()
|
|
498
|
+
|
|
499
|
+
// 有图片文件,直接处理
|
|
500
|
+
// 如果包含表格,让默认粘贴处理
|
|
501
|
+
if (htmlData !== null && htmlData !== void 0 && htmlData.trim()) {
|
|
468
502
|
var htmlLower = htmlData.toLowerCase();
|
|
469
503
|
if (htmlLower.includes('<table') || htmlLower.includes('<tr') || htmlLower.includes('<td') || htmlLower.includes('<th')) {
|
|
470
504
|
return false;
|
|
471
505
|
}
|
|
472
506
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}, _callee4);
|
|
487
|
-
}))();
|
|
488
|
-
}
|
|
507
|
+
event.preventDefault();
|
|
508
|
+
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
|
|
509
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
510
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
511
|
+
case 0:
|
|
512
|
+
_context4.next = 2;
|
|
513
|
+
return processImagePaste(imageFiles, htmlData, from, to);
|
|
514
|
+
case 2:
|
|
515
|
+
case "end":
|
|
516
|
+
return _context4.stop();
|
|
517
|
+
}
|
|
518
|
+
}, _callee4);
|
|
519
|
+
}))();
|
|
489
520
|
return true;
|
|
490
521
|
}
|
|
491
522
|
}
|