@ctzhian/tiptap 2.1.12 → 2.1.14

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.
@@ -25,7 +25,7 @@ var SlashCommandsList = /*#__PURE__*/forwardRef(function (_ref, ref) {
25
25
  }, /*#__PURE__*/React.createElement(Stack, {
26
26
  direction: 'row',
27
27
  flexWrap: 'wrap'
28
- }, items.slice(0, 18).map(function (item, index) {
28
+ }, items.slice(0, 16).map(function (item, index) {
29
29
  return /*#__PURE__*/React.createElement(ToolbarItem, {
30
30
  key: index,
31
31
  shortcutKey: (item === null || item === void 0 ? void 0 : item.shortcutKey) || [],
@@ -9,7 +9,13 @@ declare module '@tiptap/core' {
9
9
  };
10
10
  }
11
11
  }
12
- export declare const StructuredDiffExtension: Extension<any, any>;
12
+ import { GetExtensionsProps } from '../../type';
13
+ export interface StructuredDiffOptions {
14
+ getExtensionConfig?: () => Omit<GetExtensionsProps, 'editable'> & {
15
+ editable: false;
16
+ };
17
+ }
18
+ export declare const StructuredDiffExtension: Extension<StructuredDiffOptions, any>;
13
19
  export { diffPluginKey };
14
20
  export declare function getDiffState(editor: Editor): {
15
21
  isActive: any;
@@ -1,4 +1,12 @@
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
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
5
+ 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."); }
6
+ 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); }
7
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
8
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
9
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
2
10
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3
11
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
4
12
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
@@ -9,6 +17,7 @@ import { Extension } from '@tiptap/core';
9
17
  import { Plugin, PluginKey } from '@tiptap/pm/state';
10
18
  import { createDecorationsFromDiffs, createEmptyDecorationSet } from "../../util/decorations";
11
19
  import { compareDocuments } from "../../util/structuredDiff";
20
+ import { getExtensions } from "../index";
12
21
  var diffPluginKey = new PluginKey('structuredDiff');
13
22
  var DiffPluginState = /*#__PURE__*/function () {
14
23
  function DiffPluginState(decorations) {
@@ -44,20 +53,40 @@ var DiffPluginState = /*#__PURE__*/function () {
44
53
  }
45
54
  }], [{
46
55
  key: "init",
47
- value: function init(config, state) {
56
+ value: function init(_config, state) {
48
57
  return new DiffPluginState(createEmptyDecorationSet(state.doc), [], false);
49
58
  }
50
59
  }]);
51
60
  return DiffPluginState;
52
61
  }();
62
+ function getExtensionsForParsing(editor, getExtensionConfig) {
63
+ if (getExtensionConfig) {
64
+ var config = getExtensionConfig();
65
+ if (config) {
66
+ var exclude = [].concat(_toConsumableArray(config.exclude || []), ['structuredDiff']);
67
+ return getExtensions(_objectSpread(_objectSpread({}, config), {}, {
68
+ exclude: exclude,
69
+ editable: false
70
+ }));
71
+ }
72
+ }
73
+ return editor.extensionManager.extensions.filter(function (ext) {
74
+ return ext.name !== 'structuredDiff';
75
+ });
76
+ }
53
77
  export var StructuredDiffExtension = Extension.create({
54
78
  name: 'structuredDiff',
79
+ addOptions: function addOptions() {
80
+ return {
81
+ getExtensionConfig: undefined
82
+ };
83
+ },
55
84
  addProseMirrorPlugins: function addProseMirrorPlugins() {
56
85
  return [new Plugin({
57
86
  key: diffPluginKey,
58
87
  state: {
59
88
  init: DiffPluginState.init,
60
- apply: DiffPluginState.prototype.apply
89
+ apply: DiffPluginState.prototype.apply.bind(DiffPluginState.prototype)
61
90
  },
62
91
  props: {
63
92
  decorations: function decorations(state) {
@@ -68,6 +97,7 @@ export var StructuredDiffExtension = Extension.create({
68
97
  })];
69
98
  },
70
99
  addCommands: function addCommands() {
100
+ var _this = this;
71
101
  return {
72
102
  showStructuredDiff: function showStructuredDiff(oldHtml, newHtml) {
73
103
  return function (_ref) {
@@ -76,8 +106,8 @@ export var StructuredDiffExtension = Extension.create({
76
106
  dispatch = _ref.dispatch,
77
107
  editor = _ref.editor;
78
108
  try {
79
- var extensions = editor.extensionManager.extensions;
80
- var comparison = compareDocuments(oldHtml, newHtml, extensions);
109
+ var extensionsForParsing = getExtensionsForParsing(editor, _this.options.getExtensionConfig);
110
+ var comparison = compareDocuments(oldHtml, newHtml, extensionsForParsing);
81
111
  if (!comparison.hasChanges) {
82
112
  return false;
83
113
  }
@@ -150,7 +150,26 @@ export var getExtensions = function getExtensions(_ref) {
150
150
  } else {
151
151
  // 只读模式
152
152
  if (!(exclude !== null && exclude !== void 0 && exclude.includes('structuredDiff'))) {
153
- defaultExtensions.push(StructuredDiffExtension);
153
+ defaultExtensions.push(StructuredDiffExtension.configure({
154
+ getExtensionConfig: function getExtensionConfig() {
155
+ return {
156
+ contentType: contentType,
157
+ limit: limit,
158
+ exclude: [].concat(_toConsumableArray(exclude || []), ['structuredDiff']),
159
+ extensions: extensionsProps,
160
+ youtube: youtube,
161
+ editable: false,
162
+ mentionItems: mentionItems,
163
+ onMentionFilter: onMentionFilter,
164
+ onUpload: onUpload,
165
+ onError: onError,
166
+ onTocUpdate: onTocUpdate,
167
+ onAiWritingGetSuggestion: onAiWritingGetSuggestion,
168
+ onValidateUrl: onValidateUrl,
169
+ placeholder: _placeholder
170
+ };
171
+ }
172
+ }));
154
173
  }
155
174
  }
156
175
  if (!(exclude !== null && exclude !== void 0 && exclude.includes('mention')) && (mentionItems && mentionItems.length > 0 || onMentionFilter)) {
@@ -1,4 +1,4 @@
1
1
  import { UploadFunction } from "../../type";
2
2
  export declare const FileHandlerExtension: (props: {
3
3
  onUpload?: UploadFunction;
4
- }) => import("@tiptap/core").Extension<Omit<import("@tiptap/extension-file-handler").FileHandlePluginOptions, "editor" | "key">, any>;
4
+ }) => import("@tiptap/core").Extension<Omit<import("@tiptap/extension-file-handler").FileHandlePluginOptions, "key" | "editor">, any>;
@@ -4,9 +4,11 @@ declare module '@tiptap/core' {
4
4
  interface Commands<ReturnType> {
5
5
  iframe: {
6
6
  setIframe: (options: {
7
+ type?: 'iframe' | 'bilibili';
7
8
  src: string;
8
- width?: number;
9
+ width?: number | string;
9
10
  height?: number;
11
+ align?: 'left' | 'center' | 'right';
10
12
  }) => ReturnType;
11
13
  };
12
14
  }
@@ -35,10 +35,15 @@ export var IframeExtension = function IframeExtension(props) {
35
35
  }
36
36
  },
37
37
  width: {
38
- default: 760,
38
+ default: '100%',
39
39
  parseHTML: function parseHTML(element) {
40
40
  var width = element.getAttribute('width');
41
- return width ? parseInt(width, 10) : 760;
41
+ if (width) {
42
+ if (width.endsWith('%')) return width;
43
+ var numWidth = parseInt(width, 10);
44
+ return isNaN(numWidth) ? '100%' : numWidth;
45
+ }
46
+ return '100%';
42
47
  },
43
48
  renderHTML: function renderHTML(attributes) {
44
49
  return {
@@ -57,6 +62,29 @@ export var IframeExtension = function IframeExtension(props) {
57
62
  height: attributes.height
58
63
  };
59
64
  }
65
+ },
66
+ type: {
67
+ default: 'iframe',
68
+ parseHTML: function parseHTML(element) {
69
+ return element.getAttribute('data-type');
70
+ },
71
+ renderHTML: function renderHTML(attributes) {
72
+ return {
73
+ 'data-type': attributes.type
74
+ };
75
+ }
76
+ },
77
+ align: {
78
+ default: null,
79
+ parseHTML: function parseHTML(element) {
80
+ return element.getAttribute('data-align');
81
+ },
82
+ renderHTML: function renderHTML(attributes) {
83
+ if (!attributes.align) return {};
84
+ return {
85
+ 'data-align': attributes.align
86
+ };
87
+ }
60
88
  }
61
89
  };
62
90
  },
@@ -67,12 +95,24 @@ export var IframeExtension = function IframeExtension(props) {
67
95
  if (!(dom instanceof HTMLElement)) return false;
68
96
  var src = dom.getAttribute('src');
69
97
  if (!src) return false;
70
- var width = dom.getAttribute('width') ? parseInt(dom.getAttribute('width'), 10) : dom.style.width ? parseInt(dom.style.width, 10) : 760;
98
+ var widthAttr = dom.getAttribute('width');
99
+ var width = '100%';
100
+ if (widthAttr) {
101
+ // 如果是百分比,保留字符串格式
102
+ if (widthAttr.endsWith('%')) {
103
+ width = widthAttr;
104
+ } else {
105
+ // 否则解析为数字
106
+ var numWidth = parseInt(widthAttr, 10);
107
+ width = isNaN(numWidth) ? '100%' : numWidth;
108
+ }
109
+ }
71
110
  var height = dom.getAttribute('height') ? parseInt(dom.getAttribute('height'), 10) : dom.style.height ? parseInt(dom.style.height, 10) : 400;
72
111
  return {
73
112
  src: src,
74
113
  width: width,
75
- height: height
114
+ height: height,
115
+ align: dom.getAttribute('data-align') || dom.getAttribute('align')
76
116
  };
77
117
  }
78
118
  }];
@@ -94,9 +134,10 @@ export var IframeExtension = function IframeExtension(props) {
94
134
  var _ref3 = node.attrs,
95
135
  src = _ref3.src,
96
136
  width = _ref3.width,
97
- height = _ref3.height;
137
+ height = _ref3.height,
138
+ align = _ref3['data-align'];
98
139
  if (!src || src.trim() === '') return '';
99
- return "<iframe src=\"".concat(src, "\" ").concat(width ? "width=\"".concat(width, "\"") : '', " ").concat(height ? "height=\"".concat(height, "\"") : '', " frameborder=\"0\" allowfullscreen=\"true\" autoplay=\"0\" loop=\"0\"></iframe>");
140
+ return "<iframe src=\"".concat(src, "\" ").concat(width ? "width=\"".concat(width, "\"") : '', " ").concat(height ? "height=\"".concat(height, "\"") : '', " ").concat(align ? "data-align=\"".concat(align, "\"") : '', " frameborder=\"0\" allowfullscreen=\"true\" autoplay=\"0\" loop=\"0\"></iframe>");
100
141
  },
101
142
  addCommands: function addCommands() {
102
143
  var _this = this;
@@ -107,9 +148,11 @@ export var IframeExtension = function IframeExtension(props) {
107
148
  return commands.insertContent({
108
149
  type: _this.name,
109
150
  attrs: {
151
+ type: options.type || 'iframe',
110
152
  src: options.src,
111
- width: options.width || 760,
112
- height: options.height || 400
153
+ width: options.width || '100%',
154
+ height: options.height || 400,
155
+ align: options.align || null
113
156
  }
114
157
  });
115
158
  };
@@ -1,5 +1,5 @@
1
1
  import { Extension } from '@tiptap/core';
2
2
  export declare const TableExtension: ({ editable }: {
3
3
  editable: boolean;
4
- }) => (import("@tiptap/core").Node<import("@tiptap/extension-table").TableOptions, any> | import("@tiptap/core").Node<import("@tiptap/extension-table").TableHeaderOptions, any> | Extension<any, any>)[];
4
+ }) => (Extension<any, any> | import("@tiptap/core").Node<import("@tiptap/extension-table").TableOptions, any> | import("@tiptap/core").Node<import("@tiptap/extension-table").TableHeaderOptions, any>)[];
5
5
  export default TableExtension;
package/dist/index.css CHANGED
@@ -448,7 +448,6 @@
448
448
  overflow-x: auto;
449
449
  overflow-y: hidden;
450
450
  position: relative;
451
- margin: 20px 0;
452
451
  }
453
452
 
454
453
  .tiptap.ProseMirror[contenteditable="true"] .tableWrapper {
@@ -22,3 +22,4 @@ export declare const getLinkTitle: (href: string) => string;
22
22
  export declare const getLinkAttributesWithSelectedText: (editor: Editor) => {
23
23
  title?: string;
24
24
  };
25
+ export declare const extractSrcFromIframe: (input: string) => string;
@@ -88,4 +88,12 @@ export var getLinkAttributesWithSelectedText = function getLinkAttributesWithSel
88
88
  };
89
89
  }
90
90
  return {};
91
+ };
92
+ export var extractSrcFromIframe = function extractSrcFromIframe(input) {
93
+ var trimmed = input.trim();
94
+ var iframeMatch = trimmed.match(/<iframe[^>]*\ssrc\s*=\s*["']([^"']+)["'][^>]*>/i) || trimmed.match(/<iframe[^>]*\ssrc\s*=\s*([^\s>]+)[^>]*>/i);
95
+ if (iframeMatch && iframeMatch[1]) {
96
+ return iframeMatch[1].trim();
97
+ }
98
+ return trimmed;
91
99
  };
@@ -35,25 +35,6 @@ export interface ProseMirrorNode {
35
35
  attrs?: Record<string, any>;
36
36
  }>;
37
37
  }
38
- /**
39
- * 将HTML转换为ProseMirror文档结构
40
- * @param {string} html - HTML字符串
41
- * @param {Array} extensions - Tiptap扩展数组
42
- * @returns {Object} ProseMirror文档对象
43
- */
44
38
  export declare function parseHtmlToDoc(html: string, extensions: Extensions): any;
45
- /**
46
- * 对比两个HTML文档并生成结构化差异
47
- * @param {string} oldHtml - 旧HTML
48
- * @param {string} newHtml - 新HTML
49
- * @param {Array} extensions - Tiptap扩展数组
50
- * @returns {Object} 包含差异信息的对象
51
- */
52
39
  export declare function compareDocuments(oldHtml: string, newHtml: string, extensions: Extensions): DocumentComparison;
53
- /**
54
- * 将路径转换为ProseMirror位置
55
- * @param {Array} path - 节点路径
56
- * @param {Object} doc - ProseMirror文档
57
- * @returns {number} 文档位置
58
- */
59
40
  export declare function pathToPos(path: number[], doc: any): number;