@ctzhian/tiptap 2.12.7 → 2.12.8
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 +388 -113
- package/package.json +1 -1
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
2
|
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
3
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
4
|
-
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); }); }; }
|
|
5
3
|
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
6
4
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
7
5
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -13,12 +11,112 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
13
11
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
14
12
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
15
13
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
14
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
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
18
|
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
|
19
19
|
import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
20
20
|
import { generateJSON } from "@tiptap/html";
|
|
21
21
|
import ImageViewWrapper, { getImageDimensionsFromFile } from "../component/Image";
|
|
22
|
+
/** 从 URL 下载图片并转换为 File 对象 */
|
|
23
|
+
function downloadImageAsFile(_x, _x2) {
|
|
24
|
+
return _downloadImageAsFile.apply(this, arguments);
|
|
25
|
+
}
|
|
26
|
+
/** 解码 HTML 实体 */
|
|
27
|
+
function _downloadImageAsFile() {
|
|
28
|
+
_downloadImageAsFile = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(url, index) {
|
|
29
|
+
var response, blob, fileName, file;
|
|
30
|
+
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
31
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
32
|
+
case 0:
|
|
33
|
+
_context5.prev = 0;
|
|
34
|
+
console.log("[\u4E0B\u8F7D] \u5F00\u59CB\u4E0B\u8F7D\u56FE\u7247 ".concat(index + 1, ": ").concat(url.substring(0, 100)));
|
|
35
|
+
|
|
36
|
+
// 尝试不带 credentials 下载
|
|
37
|
+
_context5.next = 4;
|
|
38
|
+
return fetch(url, {
|
|
39
|
+
mode: 'cors',
|
|
40
|
+
credentials: 'omit'
|
|
41
|
+
});
|
|
42
|
+
case 4:
|
|
43
|
+
response = _context5.sent;
|
|
44
|
+
if (response.ok) {
|
|
45
|
+
_context5.next = 13;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
console.warn("[\u4E0B\u8F7D] \u56FE\u7247 ".concat(index + 1, " \u76F4\u63A5\u4E0B\u8F7D\u5931\u8D25 (").concat(response.status, ")\uFF0C\u5C1D\u8BD5\u65E0\u9650\u5236\u6A21\u5F0F"));
|
|
49
|
+
// 再试一次,允许跨域
|
|
50
|
+
_context5.next = 9;
|
|
51
|
+
return fetch(url, {
|
|
52
|
+
mode: 'no-cors'
|
|
53
|
+
});
|
|
54
|
+
case 9:
|
|
55
|
+
response = _context5.sent;
|
|
56
|
+
if (!(response.type === 'opaque')) {
|
|
57
|
+
_context5.next = 13;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
console.error("[\u4E0B\u8F7D] \u56FE\u7247 ".concat(index + 1, " \u88ABCORS\u963B\u6B62\uFF0C\u65E0\u6CD5\u4E0B\u8F7D"));
|
|
61
|
+
return _context5.abrupt("return", null);
|
|
62
|
+
case 13:
|
|
63
|
+
_context5.next = 15;
|
|
64
|
+
return response.blob();
|
|
65
|
+
case 15:
|
|
66
|
+
blob = _context5.sent;
|
|
67
|
+
if (!(blob.size === 0)) {
|
|
68
|
+
_context5.next = 19;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
console.error("[\u4E0B\u8F7D] \u56FE\u7247 ".concat(index + 1, " blob\u4E3A\u7A7A"));
|
|
72
|
+
return _context5.abrupt("return", null);
|
|
73
|
+
case 19:
|
|
74
|
+
fileName = "image-".concat(index + 1, ".").concat(blob.type.split('/')[1] || 'png');
|
|
75
|
+
file = new File([blob], fileName, {
|
|
76
|
+
type: blob.type
|
|
77
|
+
});
|
|
78
|
+
console.log("[\u4E0B\u8F7D] \u56FE\u7247 ".concat(index + 1, " \u4E0B\u8F7D\u6210\u529F:"), {
|
|
79
|
+
name: file.name,
|
|
80
|
+
type: file.type,
|
|
81
|
+
size: file.size
|
|
82
|
+
});
|
|
83
|
+
return _context5.abrupt("return", file);
|
|
84
|
+
case 25:
|
|
85
|
+
_context5.prev = 25;
|
|
86
|
+
_context5.t0 = _context5["catch"](0);
|
|
87
|
+
console.error("[\u4E0B\u8F7D] \u56FE\u7247 ".concat(index + 1, " \u4E0B\u8F7D\u5F02\u5E38:"), _context5.t0);
|
|
88
|
+
return _context5.abrupt("return", null);
|
|
89
|
+
case 29:
|
|
90
|
+
case "end":
|
|
91
|
+
return _context5.stop();
|
|
92
|
+
}
|
|
93
|
+
}, _callee5, null, [[0, 25]]);
|
|
94
|
+
}));
|
|
95
|
+
return _downloadImageAsFile.apply(this, arguments);
|
|
96
|
+
}
|
|
97
|
+
function decodeHTMLEntities(text) {
|
|
98
|
+
var textarea = document.createElement('textarea');
|
|
99
|
+
textarea.innerHTML = text;
|
|
100
|
+
return textarea.value;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** 从 HTML 中提取所有 img 标签的 src */
|
|
104
|
+
function extractImageUrls(html) {
|
|
105
|
+
var imgRegex = /<img[^>]+src=["']([^"']+)["'][^>]*>/gi;
|
|
106
|
+
var urls = [];
|
|
107
|
+
var match;
|
|
108
|
+
while ((match = imgRegex.exec(html)) !== null) {
|
|
109
|
+
var src = match[1];
|
|
110
|
+
// 解码HTML实体(如 & -> &)
|
|
111
|
+
src = decodeHTMLEntities(src);
|
|
112
|
+
// 过滤掉 base64 和无效 URL
|
|
113
|
+
if (src && !src.startsWith('data:') && (src.startsWith('http') || src.startsWith('//'))) {
|
|
114
|
+
urls.push(src.startsWith('//') ? "https:".concat(src) : src);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return urls;
|
|
118
|
+
}
|
|
119
|
+
|
|
22
120
|
/** 在 JSON 结构中用 progress 节点替换 image 节点,按顺序匹配 Files */
|
|
23
121
|
function replaceImagesWithProgressNodes(node, imageFiles, fileIndex, tempIds) {
|
|
24
122
|
if (node.type === 'image' && fileIndex.current < imageFiles.length) {
|
|
@@ -114,26 +212,56 @@ var customImage = function customImage(props) {
|
|
|
114
212
|
key: new PluginKey('imagePasteHandler'),
|
|
115
213
|
props: {
|
|
116
214
|
handlePaste: function handlePaste(view, event) {
|
|
117
|
-
var _event$clipboardData, _event$clipboardData2;
|
|
215
|
+
var _event$clipboardData, _event$clipboardData2, _event$clipboardData3;
|
|
118
216
|
if (!props.onUpload) return false;
|
|
119
217
|
var items = Array.from(((_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.items) || []);
|
|
218
|
+
console.log('=== 图片粘贴调试 ===');
|
|
219
|
+
console.log('1. clipboardData.items:', items.map(function (item) {
|
|
220
|
+
return {
|
|
221
|
+
kind: item.kind,
|
|
222
|
+
type: item.type
|
|
223
|
+
};
|
|
224
|
+
}));
|
|
120
225
|
var imageFiles = items.map(function (item) {
|
|
121
226
|
return item.getAsFile();
|
|
122
227
|
}).filter(function (file) {
|
|
123
228
|
return file !== null && getFileType(file) === 'image';
|
|
124
229
|
});
|
|
125
|
-
|
|
230
|
+
console.log('2. 提取到的图片文件:', imageFiles.map(function (f) {
|
|
231
|
+
return {
|
|
232
|
+
name: f.name,
|
|
233
|
+
type: f.type,
|
|
234
|
+
size: f.size
|
|
235
|
+
};
|
|
236
|
+
}));
|
|
126
237
|
var htmlData = (_event$clipboardData2 = event.clipboardData) === null || _event$clipboardData2 === void 0 ? void 0 : _event$clipboardData2.getData('text/html');
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
238
|
+
var textData = (_event$clipboardData3 = event.clipboardData) === null || _event$clipboardData3 === void 0 ? void 0 : _event$clipboardData3.getData('text/plain');
|
|
239
|
+
console.log('3. 完整 HTML 内容:');
|
|
240
|
+
console.log(htmlData || '(无)');
|
|
241
|
+
console.log('4. 完整纯文本内容:');
|
|
242
|
+
console.log(textData || '(无)');
|
|
243
|
+
|
|
244
|
+
// 从 HTML 中提取所有 img 标签
|
|
245
|
+
var imgMatches = (htmlData === null || htmlData === void 0 ? void 0 : htmlData.matchAll(/<img[^>]+>/gi)) || [];
|
|
246
|
+
var imgTags = Array.from(imgMatches);
|
|
247
|
+
console.log('5. HTML 中的 img 标签数量:', imgTags.length);
|
|
248
|
+
imgTags.forEach(function (match, i) {
|
|
249
|
+
var _srcMatch$;
|
|
250
|
+
var imgTag = match[0];
|
|
251
|
+
var srcMatch = imgTag.match(/src=["']([^"']+)["']/i);
|
|
252
|
+
console.log(" \u56FE\u7247 ".concat(i + 1, ":"), {
|
|
253
|
+
tag: imgTag.substring(0, 100),
|
|
254
|
+
src: (srcMatch === null || srcMatch === void 0 || (_srcMatch$ = srcMatch[1]) === null || _srcMatch$ === void 0 ? void 0 : _srcMatch$.substring(0, 100)) || '无src'
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// 提前声明变量和函数,避免在异步回调中出现 TDZ 错误
|
|
133
259
|
var _view$state$selection = view.state.selection,
|
|
134
260
|
from = _view$state$selection.from,
|
|
135
261
|
to = _view$state$selection.to;
|
|
136
262
|
var editor = _this2.editor;
|
|
263
|
+
|
|
264
|
+
// 定义辅助函数
|
|
137
265
|
var findNodePosition = function findNodePosition(typeName, tempId) {
|
|
138
266
|
var targetPos = null;
|
|
139
267
|
editor.state.doc.descendants(function (node, position) {
|
|
@@ -151,33 +279,39 @@ var customImage = function customImage(props) {
|
|
|
151
279
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
152
280
|
while (1) switch (_context.prev = _context.next) {
|
|
153
281
|
case 0:
|
|
154
|
-
|
|
282
|
+
console.log("[\u4E0A\u4F20] \u5F00\u59CB\u4E0A\u4F20: ".concat(file.name, ", tempId: ").concat(tempId));
|
|
283
|
+
_context.prev = 1;
|
|
155
284
|
progressPos = findNodePosition('inlineUploadProgress', tempId);
|
|
156
|
-
|
|
285
|
+
console.log("[\u4E0A\u4F20] \u627E\u5230 progress \u8282\u70B9\u4F4D\u7F6E: ".concat(progressPos));
|
|
286
|
+
_context.next = 6;
|
|
157
287
|
return props.onUpload(file, function (progressEvent) {
|
|
288
|
+
console.log("[\u4E0A\u4F20] ".concat(file.name, " \u8FDB\u5EA6: ").concat(Math.round(progressEvent.progress * 100), "%"));
|
|
158
289
|
editor.chain().updateInlineUploadProgress(tempId, progressEvent.progress).focus().run();
|
|
159
290
|
});
|
|
160
|
-
case
|
|
291
|
+
case 6:
|
|
161
292
|
url = _context.sent;
|
|
293
|
+
console.log("[\u4E0A\u4F20] ".concat(file.name, " \u4E0A\u4F20\u5B8C\u6210\uFF0CURL: ").concat(url));
|
|
162
294
|
editor.chain().removeInlineUploadProgress(tempId).focus().run();
|
|
163
295
|
chain = editor.chain().focus();
|
|
164
296
|
if (progressPos !== null) {
|
|
165
297
|
chain.setTextSelection(progressPos);
|
|
166
298
|
}
|
|
167
|
-
_context.prev =
|
|
168
|
-
_context.next =
|
|
299
|
+
_context.prev = 11;
|
|
300
|
+
_context.next = 14;
|
|
169
301
|
return getImageDimensionsFromFile(file);
|
|
170
|
-
case
|
|
302
|
+
case 14:
|
|
171
303
|
dimensions = _context.sent;
|
|
304
|
+
console.log("[\u4E0A\u4F20] ".concat(file.name, " \u5C3A\u5BF8: ").concat(dimensions.width, "x").concat(dimensions.height));
|
|
172
305
|
chain.setImage({
|
|
173
306
|
src: url,
|
|
174
307
|
width: Math.min(dimensions.width, 760)
|
|
175
308
|
}).run();
|
|
176
|
-
_context.next =
|
|
309
|
+
_context.next = 25;
|
|
177
310
|
break;
|
|
178
|
-
case
|
|
179
|
-
_context.prev =
|
|
180
|
-
_context.t0 = _context["catch"](
|
|
311
|
+
case 19:
|
|
312
|
+
_context.prev = 19;
|
|
313
|
+
_context.t0 = _context["catch"](11);
|
|
314
|
+
console.log("[\u4E0A\u4F20] ".concat(file.name, " \u83B7\u53D6\u5C3A\u5BF8\u5931\u8D25\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u5BBD\u5EA6"));
|
|
181
315
|
fallbackChain = editor.chain().focus();
|
|
182
316
|
if (progressPos !== null) {
|
|
183
317
|
fallbackChain.setTextSelection(progressPos);
|
|
@@ -186,12 +320,14 @@ var customImage = function customImage(props) {
|
|
|
186
320
|
src: url,
|
|
187
321
|
width: 760
|
|
188
322
|
}).run();
|
|
189
|
-
case
|
|
190
|
-
|
|
323
|
+
case 25:
|
|
324
|
+
console.log("[\u4E0A\u4F20] ".concat(file.name, " \u5B8C\u6210\u6240\u6709\u5904\u7406"));
|
|
325
|
+
_context.next = 36;
|
|
191
326
|
break;
|
|
192
|
-
case
|
|
193
|
-
_context.prev =
|
|
194
|
-
_context.t1 = _context["catch"](
|
|
327
|
+
case 28:
|
|
328
|
+
_context.prev = 28;
|
|
329
|
+
_context.t1 = _context["catch"](1);
|
|
330
|
+
console.error("[\u4E0A\u4F20] ".concat(file.name, " \u4E0A\u4F20\u5931\u8D25:"), _context.t1);
|
|
195
331
|
editor.chain().removeInlineUploadProgress(tempId).focus().run();
|
|
196
332
|
_progressPos = findNodePosition('inlineUploadProgress', tempId);
|
|
197
333
|
_chain = editor.chain().focus();
|
|
@@ -202,107 +338,246 @@ var customImage = function customImage(props) {
|
|
|
202
338
|
src: '',
|
|
203
339
|
width: 760
|
|
204
340
|
}).run();
|
|
205
|
-
case
|
|
341
|
+
case 36:
|
|
206
342
|
case "end":
|
|
207
343
|
return _context.stop();
|
|
208
344
|
}
|
|
209
|
-
}, _callee, null, [[
|
|
345
|
+
}, _callee, null, [[1, 28], [11, 19]]);
|
|
210
346
|
}));
|
|
211
|
-
return function uploadSingleImage(
|
|
347
|
+
return function uploadSingleImage(_x3, _x4) {
|
|
212
348
|
return _ref.apply(this, arguments);
|
|
213
349
|
};
|
|
214
350
|
}();
|
|
215
|
-
|
|
216
|
-
var
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
351
|
+
var processImagePaste = /*#__PURE__*/function () {
|
|
352
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(files, html, fromPos, toPos) {
|
|
353
|
+
var _htmlTrimmed$match, _htmlTrimmed$match2;
|
|
354
|
+
var htmlTrimmed, hasRichHtml, _parsed$content, extensions, parsed, tempIds, fileIndex, modifiedDoc, finalDoc, i, useSimpleInsert;
|
|
355
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
356
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
357
|
+
case 0:
|
|
358
|
+
useSimpleInsert = function _useSimpleInsert(files, fromPos, toPos) {
|
|
359
|
+
var baseTime = Date.now();
|
|
360
|
+
var content = files.map(function (file, i) {
|
|
361
|
+
return {
|
|
362
|
+
type: 'paragraph',
|
|
363
|
+
content: [{
|
|
364
|
+
type: 'inlineUploadProgress',
|
|
365
|
+
attrs: {
|
|
366
|
+
fileName: file.name,
|
|
367
|
+
fileType: 'image',
|
|
368
|
+
progress: 0,
|
|
369
|
+
tempId: "upload-".concat(baseTime, "-").concat(i)
|
|
370
|
+
}
|
|
371
|
+
}]
|
|
372
|
+
};
|
|
373
|
+
});
|
|
374
|
+
console.log('简单插入内容:', JSON.stringify(content, null, 2));
|
|
375
|
+
console.log('插入位置:', {
|
|
376
|
+
from: fromPos,
|
|
377
|
+
to: toPos
|
|
378
|
+
});
|
|
379
|
+
editor.chain().insertContentAt({
|
|
380
|
+
from: fromPos,
|
|
381
|
+
to: toPos
|
|
382
|
+
}, content).focus().run();
|
|
383
|
+
console.log('开始触发上传');
|
|
384
|
+
files.forEach(function (file, i) {
|
|
385
|
+
var tempId = "upload-".concat(baseTime, "-").concat(i);
|
|
386
|
+
console.log("\u89E6\u53D1\u4E0A\u4F20: ".concat(file.name, ", tempId: ").concat(tempId));
|
|
387
|
+
uploadSingleImage(file, tempId);
|
|
388
|
+
});
|
|
389
|
+
};
|
|
390
|
+
if (props.onUpload) {
|
|
391
|
+
_context2.next = 3;
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
return _context2.abrupt("return");
|
|
395
|
+
case 3:
|
|
396
|
+
htmlTrimmed = (html === null || html === void 0 ? void 0 : html.trim()) || '';
|
|
397
|
+
hasRichHtml = htmlTrimmed.length > 0 && (htmlTrimmed.includes('<p') || htmlTrimmed.includes('<div') || htmlTrimmed.includes('<br') || htmlTrimmed.includes('<span') || ((_htmlTrimmed$match = htmlTrimmed.match(/<img/gi)) === null || _htmlTrimmed$match === void 0 ? void 0 : _htmlTrimmed$match.length) !== 1);
|
|
398
|
+
console.log('hasRichHtml 判断:', {
|
|
399
|
+
htmlLength: htmlTrimmed.length,
|
|
400
|
+
hasPTag: htmlTrimmed.includes('<p'),
|
|
401
|
+
hasDivTag: htmlTrimmed.includes('<div'),
|
|
402
|
+
hasBrTag: htmlTrimmed.includes('<br'),
|
|
403
|
+
hasSpanTag: htmlTrimmed.includes('<span'),
|
|
404
|
+
imgCount: ((_htmlTrimmed$match2 = htmlTrimmed.match(/<img/gi)) === null || _htmlTrimmed$match2 === void 0 ? void 0 : _htmlTrimmed$match2.length) || 0,
|
|
405
|
+
result: hasRichHtml
|
|
236
406
|
});
|
|
407
|
+
if (!hasRichHtml) {
|
|
408
|
+
_context2.next = 40;
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
console.log('走富文本解析路径');
|
|
412
|
+
_context2.prev = 8;
|
|
413
|
+
extensions = editor.extensionManager.extensions;
|
|
414
|
+
parsed = generateJSON(htmlTrimmed, extensions);
|
|
415
|
+
console.log('解析后的 JSON:', JSON.stringify(parsed, null, 2));
|
|
416
|
+
if (parsed !== null && parsed !== void 0 && (_parsed$content = parsed.content) !== null && _parsed$content !== void 0 && _parsed$content.length) {
|
|
417
|
+
_context2.next = 14;
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
throw new Error('Empty parsed content');
|
|
421
|
+
case 14:
|
|
422
|
+
tempIds = [];
|
|
423
|
+
fileIndex = {
|
|
424
|
+
current: 0
|
|
425
|
+
};
|
|
426
|
+
modifiedDoc = replaceImagesWithProgressNodes(parsed, files, fileIndex, tempIds);
|
|
427
|
+
finalDoc = appendExtraImagesToDoc(modifiedDoc, files, fileIndex.current, tempIds);
|
|
428
|
+
console.log('替换后的文档:', JSON.stringify(finalDoc, null, 2));
|
|
429
|
+
console.log('tempIds:', tempIds);
|
|
430
|
+
console.log('开始插入内容');
|
|
237
431
|
editor.chain().insertContentAt({
|
|
238
|
-
from:
|
|
239
|
-
to:
|
|
240
|
-
},
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
432
|
+
from: fromPos,
|
|
433
|
+
to: toPos
|
|
434
|
+
}, finalDoc).focus().run();
|
|
435
|
+
console.log('开始上传图片');
|
|
436
|
+
i = 0;
|
|
437
|
+
case 24:
|
|
438
|
+
if (!(i < tempIds.length)) {
|
|
439
|
+
_context2.next = 31;
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
console.log("\u4E0A\u4F20\u7B2C ".concat(i + 1, "/").concat(tempIds.length, " \u5F20\u56FE\u7247, tempId: ").concat(tempIds[i]));
|
|
443
|
+
_context2.next = 28;
|
|
444
|
+
return uploadSingleImage(files[i], tempIds[i]);
|
|
445
|
+
case 28:
|
|
446
|
+
i++;
|
|
447
|
+
_context2.next = 24;
|
|
247
448
|
break;
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
htmlTrimmed = (htmlData === null || htmlData === void 0 ? void 0 : htmlData.trim()) || '';
|
|
252
|
-
hasRichHtml = htmlTrimmed.length > 0 && (htmlTrimmed.includes('<p') || htmlTrimmed.includes('<div') || htmlTrimmed.includes('<br') || htmlTrimmed.includes('<span') || ((_htmlTrimmed$match = htmlTrimmed.match(/<img/gi)) === null || _htmlTrimmed$match === void 0 ? void 0 : _htmlTrimmed$match.length) !== 1);
|
|
253
|
-
if (!hasRichHtml) {
|
|
254
|
-
_context2.next = 30;
|
|
449
|
+
case 31:
|
|
450
|
+
console.log('所有图片上传完成');
|
|
451
|
+
_context2.next = 38;
|
|
255
452
|
break;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
throw new Error('Empty parsed content');
|
|
265
|
-
case 11:
|
|
266
|
-
tempIds = [];
|
|
267
|
-
fileIndex = {
|
|
268
|
-
current: 0
|
|
269
|
-
};
|
|
270
|
-
modifiedDoc = replaceImagesWithProgressNodes(parsed, imageFiles, fileIndex, tempIds);
|
|
271
|
-
finalDoc = appendExtraImagesToDoc(modifiedDoc, imageFiles, fileIndex.current, tempIds);
|
|
272
|
-
editor.chain().insertContentAt({
|
|
273
|
-
from: from,
|
|
274
|
-
to: to
|
|
275
|
-
}, finalDoc).focus().run();
|
|
276
|
-
i = 0;
|
|
277
|
-
case 17:
|
|
278
|
-
if (!(i < tempIds.length)) {
|
|
279
|
-
_context2.next = 23;
|
|
453
|
+
case 34:
|
|
454
|
+
_context2.prev = 34;
|
|
455
|
+
_context2.t0 = _context2["catch"](8);
|
|
456
|
+
console.error('富文本解析失败,fallback 到简单插入:', _context2.t0);
|
|
457
|
+
useSimpleInsert(files, fromPos, toPos);
|
|
458
|
+
case 38:
|
|
459
|
+
_context2.next = 42;
|
|
280
460
|
break;
|
|
461
|
+
case 40:
|
|
462
|
+
console.log('走简单插入路径');
|
|
463
|
+
useSimpleInsert(files, fromPos, toPos);
|
|
464
|
+
case 42:
|
|
465
|
+
case "end":
|
|
466
|
+
return _context2.stop();
|
|
467
|
+
}
|
|
468
|
+
}, _callee2, null, [[8, 34]]);
|
|
469
|
+
}));
|
|
470
|
+
return function processImagePaste(_x5, _x6, _x7, _x8) {
|
|
471
|
+
return _ref2.apply(this, arguments);
|
|
472
|
+
};
|
|
473
|
+
}();
|
|
474
|
+
|
|
475
|
+
// 如果没有 File 对象,尝试从 HTML 中提取图片 URL
|
|
476
|
+
var finalImageFiles = imageFiles;
|
|
477
|
+
if (imageFiles.length === 0 && htmlData) {
|
|
478
|
+
console.log('6. 没有图片 File 对象');
|
|
479
|
+
var imageUrls = extractImageUrls(htmlData);
|
|
480
|
+
console.log('7. 从 HTML 中提取到的图片 URL:', imageUrls);
|
|
481
|
+
if (imageUrls.length > 0) {
|
|
482
|
+
console.log('8. 开始下载图片...');
|
|
483
|
+
event.preventDefault(); // 阻止默认粘贴行为
|
|
484
|
+
|
|
485
|
+
// 异步下载所有图片
|
|
486
|
+
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
487
|
+
var downloadedFiles, validFiles, _parsed$content2, extensions, parsed;
|
|
488
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
489
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
490
|
+
case 0:
|
|
491
|
+
_context3.next = 2;
|
|
492
|
+
return Promise.all(imageUrls.map(function (url, i) {
|
|
493
|
+
return downloadImageAsFile(url, i);
|
|
494
|
+
}));
|
|
495
|
+
case 2:
|
|
496
|
+
downloadedFiles = _context3.sent;
|
|
497
|
+
validFiles = downloadedFiles.filter(function (f) {
|
|
498
|
+
return f !== null;
|
|
499
|
+
});
|
|
500
|
+
console.log('9. 下载完成,有效文件数:', validFiles.length);
|
|
501
|
+
if (!(validFiles.length === 0)) {
|
|
502
|
+
_context3.next = 24;
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
console.log('10. 没有成功下载任何图片(可能是CORS限制)');
|
|
506
|
+
console.log('11. 降级方案:保留原图URL,不上传到服务器');
|
|
507
|
+
|
|
508
|
+
// 降级方案:直接粘贴原始HTML,使用原图URL
|
|
509
|
+
_context3.prev = 8;
|
|
510
|
+
extensions = editor.extensionManager.extensions;
|
|
511
|
+
parsed = generateJSON(htmlData, extensions);
|
|
512
|
+
if (!(parsed !== null && parsed !== void 0 && (_parsed$content2 = parsed.content) !== null && _parsed$content2 !== void 0 && _parsed$content2.length)) {
|
|
513
|
+
_context3.next = 16;
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
editor.chain().insertContentAt({
|
|
517
|
+
from: from,
|
|
518
|
+
to: to
|
|
519
|
+
}, parsed).focus().run();
|
|
520
|
+
console.log('12. 已插入原始内容,图片使用原URL');
|
|
521
|
+
_context3.next = 17;
|
|
522
|
+
break;
|
|
523
|
+
case 16:
|
|
524
|
+
throw new Error('解析失败');
|
|
525
|
+
case 17:
|
|
526
|
+
_context3.next = 23;
|
|
527
|
+
break;
|
|
528
|
+
case 19:
|
|
529
|
+
_context3.prev = 19;
|
|
530
|
+
_context3.t0 = _context3["catch"](8);
|
|
531
|
+
console.log('13. 解析失败,使用默认粘贴');
|
|
532
|
+
// 最后兜底:返回false让浏览器处理默认粘贴
|
|
533
|
+
return _context3.abrupt("return");
|
|
534
|
+
case 23:
|
|
535
|
+
return _context3.abrupt("return");
|
|
536
|
+
case 24:
|
|
537
|
+
// 使用下载的文件继续处理
|
|
538
|
+
finalImageFiles = validFiles;
|
|
539
|
+
console.log('11. 开始处理下载的图片');
|
|
540
|
+
_context3.next = 28;
|
|
541
|
+
return processImagePaste(validFiles, htmlData, from, to);
|
|
542
|
+
case 28:
|
|
543
|
+
case "end":
|
|
544
|
+
return _context3.stop();
|
|
281
545
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
546
|
+
}, _callee3, null, [[8, 19]]);
|
|
547
|
+
}))();
|
|
548
|
+
return true; // 已处理
|
|
549
|
+
} else {
|
|
550
|
+
console.log('8. HTML 中没有可下载的图片 URL,退出处理');
|
|
551
|
+
return false;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (imageFiles.length === 0) {
|
|
555
|
+
console.log('6. 没有图片,退出处理');
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
if (htmlData && htmlData.trim().length > 0) {
|
|
559
|
+
var htmlLower = htmlData.toLowerCase();
|
|
560
|
+
if (htmlLower.includes('<table') || htmlLower.includes('<tr') || htmlLower.includes('<td') || htmlLower.includes('<th')) {
|
|
561
|
+
console.log('检测到表格,退出处理');
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// 如果有 File 对象,直接处理
|
|
567
|
+
if (finalImageFiles.length > 0) {
|
|
568
|
+
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
|
|
569
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
570
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
571
|
+
case 0:
|
|
572
|
+
_context4.next = 2;
|
|
573
|
+
return processImagePaste(finalImageFiles, htmlData, from, to);
|
|
574
|
+
case 2:
|
|
575
|
+
case "end":
|
|
576
|
+
return _context4.stop();
|
|
577
|
+
}
|
|
578
|
+
}, _callee4);
|
|
579
|
+
}))();
|
|
580
|
+
}
|
|
306
581
|
return true;
|
|
307
582
|
}
|
|
308
583
|
}
|