@ctzhian/tiptap 2.13.4 → 2.13.6

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.
@@ -10,15 +10,16 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
10
10
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
11
11
  import { FloatingPopover } from "../../../component/FloatingPopover";
12
12
  import { IframeTypeEnums } from "../../../contants/enums";
13
- import { extractSrcFromIframe } from "../../../util";
13
+ import { extractSrcFromIframe, normalizeBilibiliAutoplay } from "../../../util";
14
14
  import { Box, Button, Stack, TextField } from "@mui/material";
15
15
  import { NodeViewWrapper } from "@tiptap/react";
16
16
  import React, { useState } from "react";
17
17
  var InsertIframe = function InsertIframe(_ref) {
18
+ var _attrs$src;
18
19
  var attrs = _ref.attrs,
19
20
  updateAttributes = _ref.updateAttributes,
20
21
  onValidateUrl = _ref.onValidateUrl;
21
- var _useState = useState(attrs.src || ''),
22
+ var _useState = useState((_attrs$src = attrs.src) !== null && _attrs$src !== void 0 ? _attrs$src : ''),
22
23
  _useState2 = _slicedToArray(_useState, 2),
23
24
  editUrl = _useState2[0],
24
25
  setEditUrl = _useState2[1];
@@ -55,6 +56,9 @@ var InsertIframe = function InsertIframe(_ref) {
55
56
  case 7:
56
57
  validatedUrl = _context.sent;
57
58
  case 8:
59
+ if (attrs.type === 'bilibili') {
60
+ validatedUrl = normalizeBilibiliAutoplay(validatedUrl);
61
+ }
58
62
  updateAttributes({
59
63
  src: validatedUrl,
60
64
  width: attrs.width,
@@ -63,16 +67,16 @@ var InsertIframe = function InsertIframe(_ref) {
63
67
  type: attrs.type
64
68
  });
65
69
  handleClosePopover();
66
- _context.next = 14;
70
+ _context.next = 15;
67
71
  break;
68
- case 12:
69
- _context.prev = 12;
72
+ case 13:
73
+ _context.prev = 13;
70
74
  _context.t0 = _context["catch"](2);
71
- case 14:
75
+ case 15:
72
76
  case "end":
73
77
  return _context.stop();
74
78
  }
75
- }, _callee, null, [[2, 12]]);
79
+ }, _callee, null, [[2, 13]]);
76
80
  }));
77
81
  return function handleInsert() {
78
82
  return _ref2.apply(this, arguments);
@@ -16,13 +16,14 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
16
  import { ActionDropdown, FloatingPopover, HoverPopover } from "../../../component";
17
17
  import { AlignCenterIcon, AlignLeftIcon, AlignRightIcon, DeleteLineIcon, EditLineIcon } from "../../../component/Icons";
18
18
  import { ToolbarItem } from "../../../component/Toolbar";
19
- import { extractSrcFromIframe } from "../../../util";
19
+ import { extractSrcFromIframe, normalizeBilibiliAutoplay } from "../../../util";
20
20
  import { alpha, Box, Button, Divider, Stack, TextField, useTheme } from "@mui/material";
21
21
  import { NodeViewWrapper } from '@tiptap/react';
22
22
  import React, { useCallback, useEffect, useRef, useState } from "react";
23
23
  import InsertIframe from "./Insert";
24
24
  import ReadonlyIframe from "./Readonly";
25
25
  var IframeViewWrapper = function IframeViewWrapper(_ref) {
26
+ var _attrs$src;
26
27
  var editor = _ref.editor,
27
28
  node = _ref.node,
28
29
  updateAttributes = _ref.updateAttributes,
@@ -51,7 +52,7 @@ var IframeViewWrapper = function IframeViewWrapper(_ref) {
51
52
  var dragStartWidthRef = useRef(0);
52
53
  var dragStartHeightRef = useRef(0);
53
54
  var maxWidthRef = useRef(0);
54
- var _useState7 = useState(attrs.src),
55
+ var _useState7 = useState((_attrs$src = attrs.src) !== null && _attrs$src !== void 0 ? _attrs$src : ''),
55
56
  _useState8 = _slicedToArray(_useState7, 2),
56
57
  editSrc = _useState8[0],
57
58
  setEditSrc = _useState8[1];
@@ -64,6 +65,8 @@ var IframeViewWrapper = function IframeViewWrapper(_ref) {
64
65
  keepHoverPopoverOpen = _useState12[0],
65
66
  setKeepHoverPopoverOpen = _useState12[1];
66
67
  var handleShowPopover = function handleShowPopover() {
68
+ var _attrs$src2;
69
+ setEditSrc((_attrs$src2 = attrs.src) !== null && _attrs$src2 !== void 0 ? _attrs$src2 : '');
67
70
  setKeepHoverPopoverOpen(true);
68
71
  setAnchorEl(editButtonRef.current);
69
72
  };
@@ -179,7 +182,8 @@ var IframeViewWrapper = function IframeViewWrapper(_ref) {
179
182
  setDragCorner(null);
180
183
  }, []);
181
184
  useEffect(function () {
182
- setEditSrc(attrs.src);
185
+ var _attrs$src3;
186
+ setEditSrc((_attrs$src3 = attrs.src) !== null && _attrs$src3 !== void 0 ? _attrs$src3 : '');
183
187
  }, [attrs.src]);
184
188
  useEffect(function () {
185
189
  if (isDragging) {
@@ -212,13 +216,15 @@ var IframeViewWrapper = function IframeViewWrapper(_ref) {
212
216
  case 6:
213
217
  validatedUrl = _context.sent;
214
218
  case 7:
219
+ if (attrs.type === 'bilibili') {
220
+ validatedUrl = normalizeBilibiliAutoplay(validatedUrl);
221
+ }
215
222
  updateAttributes({
216
223
  src: validatedUrl,
217
224
  width: attrs.width,
218
225
  height: attrs.height,
219
226
  align: attrs.align
220
227
  });
221
- setEditSrc(validatedUrl);
222
228
  _context.next = 13;
223
229
  break;
224
230
  case 11:
@@ -438,7 +438,7 @@ var customImage = function customImage(props) {
438
438
  if (imageUrls.length > 0) {
439
439
  event.preventDefault();
440
440
  _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
441
- var downloadedFiles, validFiles;
441
+ var downloadedFiles, validFiles, _parsed$content2, extensions, parsed;
442
442
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
443
443
  while (1) switch (_context3.prev = _context3.next) {
444
444
  case 0:
@@ -452,14 +452,27 @@ var customImage = function customImage(props) {
452
452
  return f !== null;
453
453
  });
454
454
  if (!(validFiles.length === 0)) {
455
- _context3.next = 6;
455
+ _context3.next = 7;
456
456
  break;
457
457
  }
458
+ // 下载失败:回退为直接粘贴原始 HTML(保留原始图片 URL)
459
+ try {
460
+ extensions = editor.extensionManager.extensions;
461
+ parsed = generateJSON(htmlData, extensions);
462
+ if (parsed !== null && parsed !== void 0 && (_parsed$content2 = parsed.content) !== null && _parsed$content2 !== void 0 && _parsed$content2.length) {
463
+ editor.chain().insertContentAt({
464
+ from: from,
465
+ to: to
466
+ }, parsed).focus().run();
467
+ }
468
+ } catch (error) {
469
+ // 解析失败则不再处理,交给默认粘贴逻辑
470
+ }
458
471
  return _context3.abrupt("return");
459
- case 6:
460
- _context3.next = 8;
472
+ case 7:
473
+ _context3.next = 9;
461
474
  return processImagePaste(validFiles, htmlData, from, to);
462
- case 8:
475
+ case 9:
463
476
  case "end":
464
477
  return _context3.stop();
465
478
  }
@@ -471,12 +484,12 @@ var customImage = function customImage(props) {
471
484
  // 没有图片 URL,尝试处理 HTML 或纯文本
472
485
  // 先尝试使用 generateJSON 解析 HTML
473
486
  try {
474
- var _parsed$content2;
487
+ var _parsed$content3;
475
488
  var extensions = editor.extensionManager.extensions;
476
489
  var parsed = generateJSON(htmlData, extensions);
477
490
 
478
491
  // 检查解析后的内容是否包含有效文本
479
- if (parsed !== null && parsed !== void 0 && (_parsed$content2 = parsed.content) !== null && _parsed$content2 !== void 0 && _parsed$content2.length && hasValidTextContent(parsed.content)) {
492
+ if (parsed !== null && parsed !== void 0 && (_parsed$content3 = parsed.content) !== null && _parsed$content3 !== void 0 && _parsed$content3.length && hasValidTextContent(parsed.content)) {
480
493
  event.preventDefault();
481
494
  editor.chain().insertContentAt({
482
495
  from: from,
@@ -25,3 +25,11 @@ export declare const getLinkAttributesWithSelectedText: (editor: Editor) => {
25
25
  title?: string;
26
26
  };
27
27
  export declare const extractSrcFromIframe: (input: string) => string;
28
+ /**
29
+ * 将 B 站链接的 autoplay 统一为 0,避免默认自动播放
30
+ * - autoplay=1 改为 0
31
+ * - autoplay=0 不处理
32
+ * - 无 autoplay 参数则添加 &autoplay=0
33
+ * 支持协议相对地址(//player.bilibili.com/...),会先转为 https: 再解析
34
+ */
35
+ export declare const normalizeBilibiliAutoplay: (url: string) => string;
@@ -134,4 +134,32 @@ export var extractSrcFromIframe = function extractSrcFromIframe(input) {
134
134
  return iframeMatch[1].trim();
135
135
  }
136
136
  return trimmed;
137
+ };
138
+
139
+ /**
140
+ * 将 B 站链接的 autoplay 统一为 0,避免默认自动播放
141
+ * - autoplay=1 改为 0
142
+ * - autoplay=0 不处理
143
+ * - 无 autoplay 参数则添加 &autoplay=0
144
+ * 支持协议相对地址(//player.bilibili.com/...),会先转为 https: 再解析
145
+ */
146
+ export var normalizeBilibiliAutoplay = function normalizeBilibiliAutoplay(url) {
147
+ var trimmed = url.trim();
148
+ if (!trimmed) return trimmed;
149
+ try {
150
+ // 处理协议相对地址(//player.bilibili.com/...)和相对路径
151
+ var urlToParse = trimmed.startsWith('//') ? 'https:' + trimmed : /^https?:\/\//i.test(trimmed) ? trimmed : 'https://' + trimmed;
152
+ var u = new URL(urlToParse);
153
+ var host = u.hostname.toLowerCase();
154
+ if (!host.includes('bilibili.com') && !host.includes('b23.tv')) {
155
+ return trimmed;
156
+ }
157
+ var autoplay = u.searchParams.get('autoplay');
158
+ if (autoplay !== '0') {
159
+ u.searchParams.set('autoplay', '0');
160
+ }
161
+ return u.toString();
162
+ } catch (_unused) {
163
+ return trimmed;
164
+ }
137
165
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctzhian/tiptap",
3
- "version": "2.13.4",
3
+ "version": "2.13.6",
4
4
  "description": "基于 Tiptap 二次开发的编辑器组件",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",