@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.
@@ -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实体(如 &amp; -> &)
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
- if (imageFiles.length === 0) return false;
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
- if (htmlData && htmlData.trim().length > 0) {
128
- var htmlLower = htmlData.toLowerCase();
129
- if (htmlLower.includes('<table') || htmlLower.includes('<tr') || htmlLower.includes('<td') || htmlLower.includes('<th')) {
130
- return false;
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
- _context.prev = 0;
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
- _context.next = 4;
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 4:
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 = 8;
168
- _context.next = 11;
299
+ _context.prev = 11;
300
+ _context.next = 14;
169
301
  return getImageDimensionsFromFile(file);
170
- case 11:
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 = 20;
309
+ _context.next = 25;
177
310
  break;
178
- case 15:
179
- _context.prev = 15;
180
- _context.t0 = _context["catch"](8);
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 20:
190
- _context.next = 29;
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 22:
193
- _context.prev = 22;
194
- _context.t1 = _context["catch"](0);
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 29:
341
+ case 36:
206
342
  case "end":
207
343
  return _context.stop();
208
344
  }
209
- }, _callee, null, [[0, 22], [8, 15]]);
345
+ }, _callee, null, [[1, 28], [11, 19]]);
210
346
  }));
211
- return function uploadSingleImage(_x, _x2) {
347
+ return function uploadSingleImage(_x3, _x4) {
212
348
  return _ref.apply(this, arguments);
213
349
  };
214
350
  }();
215
- _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
216
- var _htmlTrimmed$match;
217
- var htmlTrimmed, hasRichHtml, _parsed$content, extensions, parsed, tempIds, fileIndex, modifiedDoc, finalDoc, i, useSimpleInsert;
218
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
219
- while (1) switch (_context2.prev = _context2.next) {
220
- case 0:
221
- useSimpleInsert = function _useSimpleInsert() {
222
- var baseTime = Date.now();
223
- var content = imageFiles.map(function (file, i) {
224
- return {
225
- type: 'paragraph',
226
- content: [{
227
- type: 'inlineUploadProgress',
228
- attrs: {
229
- fileName: file.name,
230
- fileType: 'image',
231
- progress: 0,
232
- tempId: "upload-".concat(baseTime, "-").concat(i)
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: from,
239
- to: to
240
- }, content).focus().run();
241
- imageFiles.forEach(function (file, i) {
242
- uploadSingleImage(file, "upload-".concat(baseTime, "-").concat(i));
243
- });
244
- };
245
- if (props.onUpload) {
246
- _context2.next = 3;
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
- return _context2.abrupt("return");
250
- case 3:
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
- _context2.prev = 6;
258
- extensions = editor.extensionManager.extensions;
259
- parsed = generateJSON(htmlTrimmed, extensions);
260
- if (parsed !== null && parsed !== void 0 && (_parsed$content = parsed.content) !== null && _parsed$content !== void 0 && _parsed$content.length) {
261
- _context2.next = 11;
262
- break;
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
- _context2.next = 20;
283
- return uploadSingleImage(imageFiles[i], tempIds[i]);
284
- case 20:
285
- i++;
286
- _context2.next = 17;
287
- break;
288
- case 23:
289
- _context2.next = 28;
290
- break;
291
- case 25:
292
- _context2.prev = 25;
293
- _context2.t0 = _context2["catch"](6);
294
- useSimpleInsert();
295
- case 28:
296
- _context2.next = 31;
297
- break;
298
- case 30:
299
- useSimpleInsert();
300
- case 31:
301
- case "end":
302
- return _context2.stop();
303
- }
304
- }, _callee2, null, [[6, 25]]);
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctzhian/tiptap",
3
- "version": "2.12.7",
3
+ "version": "2.12.8",
4
4
  "description": "基于 Tiptap 二次开发的编辑器组件",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",