@ctzhian/tiptap 1.13.0 → 1.13.1

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.
@@ -7,6 +7,9 @@ import { Box } from '@mui/material';
7
7
  import React from 'react';
8
8
  import "../index.css";
9
9
  var Reader = function Reader() {
10
+ var handleTocUpdate = function handleTocUpdate(toc) {
11
+ console.log('toc', toc);
12
+ };
10
13
  var _useTiptap = useTiptap({
11
14
  editable: true,
12
15
  exclude: ['invisibleCharacters'],
@@ -90,7 +93,7 @@ var Reader = function Reader() {
90
93
  }
91
94
  return onAiWritingGetSuggestion;
92
95
  }(),
93
- // onTocUpdate: handleTocUpdate,
96
+ onTocUpdate: handleTocUpdate,
94
97
  // onMentionFilter: async ({ query }: { query: string }) => {
95
98
  // return new Promise((resolve) => {
96
99
  // resolve([
@@ -152,7 +155,7 @@ var Reader = function Reader() {
152
155
  }
153
156
  return onUpload;
154
157
  }(),
155
- content: "<p>fadsjlfkas</p><div data-type=\"flow\" data-code=\"C4Context\n title System Context diagram for Internet Banking System\n Enterprise_Boundary(b0, &quot;BankBoundary0&quot;) {\n Person(customerA, &quot;Banking Customer A&quot;, &quot;A customer of the bank, with personal bank accounts.&quot;)\n Person(customerB, &quot;Banking Customer B&quot;)\n Person_Ext(customerC, &quot;Banking Customer C&quot;, &quot;desc&quot;)\n\n Person(customerD, &quot;Banking Customer D&quot;, &quot;A customer of the bank, &lt;br/&gt; with personal bank accounts.&quot;)\n\n System(SystemAA, &quot;Internet Banking System&quot;, &quot;Allows customers to view information about their bank accounts, and make payments.&quot;)\n\n Enterprise_Boundary(b1, &quot;BankBoundary&quot;) {\n SystemDb_Ext(SystemE, &quot;Mainframe Banking System&quot;, &quot;Stores all of the core banking information about customers, accounts, transactions, etc.&quot;)\n\n System_Boundary(b2, &quot;BankBoundary2&quot;) {\n System(SystemA, &quot;Banking System A&quot;)\n System(SystemB, &quot;Banking System B&quot;, &quot;A system of the bank, with personal bank accounts. next line.&quot;)\n }\n\n System_Ext(SystemC, &quot;E-mail system&quot;, &quot;The internal Microsoft Exchange e-mail system.&quot;)\n SystemDb(SystemD, &quot;Banking System D Database&quot;, &quot;A system of the bank, with personal bank accounts.&quot;)\n\n Boundary(b3, &quot;BankBoundary3&quot;, &quot;boundary&quot;) {\n SystemQueue(SystemF, &quot;Banking System F Queue&quot;, &quot;A system of the bank.&quot;)\n SystemQueue_Ext(SystemG, &quot;Banking System G Queue&quot;, &quot;A system of the bank, with personal bank accounts.&quot;)\n }\n }\n }\n\n BiRel(customerA, SystemAA, &quot;Uses&quot;)\n BiRel(SystemAA, SystemE, &quot;Uses&quot;)\n Rel(SystemAA, SystemC, &quot;Sends e-mails&quot;, &quot;SMTP&quot;)\n Rel(SystemC, customerA, &quot;Sends e-mails to&quot;)\" data-width=\"100%\" data-height=\"auto\"></div><p>fsajdlkfjadsl</p>"
158
+ content: "<pre><code>$$ sflsa $$\n\n$fsjadl$</code></pre><p></p><p><span data-latex=\"x+y=1\" data-type=\"inline-math\"></span></p><div data-latex=\"ssss\" data-type=\"block-math\"></div><p></p><p>fadsjlfkas</p><div data-type=\"flow\" data-code=\"C4Context\n title System Context diagram for Internet Banking System\n Enterprise_Boundary(b0, &quot;BankBoundary0&quot;) {\n Person(customerA, &quot;Banking Customer A&quot;, &quot;A customer of the bank, with personal bank accounts.&quot;)\n Person(customerB, &quot;Banking Customer B&quot;)\n Person_Ext(customerC, &quot;Banking Customer C&quot;, &quot;desc&quot;)\n\n Person(customerD, &quot;Banking Customer D&quot;, &quot;A customer of the bank, &lt;br/&gt; with personal bank accounts.&quot;)\n\n System(SystemAA, &quot;Internet Banking System&quot;, &quot;Allows customers to view information about their bank accounts, and make payments.&quot;)\n\n Enterprise_Boundary(b1, &quot;BankBoundary&quot;) {\n SystemDb_Ext(SystemE, &quot;Mainframe Banking System&quot;, &quot;Stores all of the core banking information about customers, accounts, transactions, etc.&quot;)\n\n System_Boundary(b2, &quot;BankBoundary2&quot;) {\n System(SystemA, &quot;Banking System A&quot;)\n System(SystemB, &quot;Banking System B&quot;, &quot;A system of the bank, with personal bank accounts. next line.&quot;)\n }\n\n System_Ext(SystemC, &quot;E-mail system&quot;, &quot;The internal Microsoft Exchange e-mail system.&quot;)\n SystemDb(SystemD, &quot;Banking System D Database&quot;, &quot;A system of the bank, with personal bank accounts.&quot;)\n\n Boundary(b3, &quot;BankBoundary3&quot;, &quot;boundary&quot;) {\n SystemQueue(SystemF, &quot;Banking System F Queue&quot;, &quot;A system of the bank.&quot;)\n SystemQueue_Ext(SystemG, &quot;Banking System G Queue&quot;, &quot;A system of the bank, with personal bank accounts.&quot;)\n }\n }\n }\n\n BiRel(customerA, SystemAA, &quot;Uses&quot;)\n BiRel(SystemAA, SystemE, &quot;Uses&quot;)\n Rel(SystemAA, SystemC, &quot;Sends e-mails&quot;, &quot;SMTP&quot;)\n Rel(SystemC, customerA, &quot;Sends e-mails to&quot;)\" data-width=\"100%\" data-height=\"auto\"></div><p>fsajdlkfjadsl</p>"
156
159
  }),
157
160
  editor = _useTiptap.editor;
158
161
  return /*#__PURE__*/React.createElement(EditorThemeProvider, {
@@ -13,7 +13,7 @@ import { Box } from '@mui/material';
13
13
  import React, { useCallback, useEffect, useState } from 'react';
14
14
  import "../index.css";
15
15
  var Reader = function Reader() {
16
- var _useState = useState(''),
16
+ var _useState = useState('![ss](/ss)'),
17
17
  _useState2 = _slicedToArray(_useState, 2),
18
18
  mdContent = _useState2[0],
19
19
  setMdContent = _useState2[1];
@@ -123,6 +123,9 @@ var Reader = function Reader() {
123
123
  // contentType: 'markdown'
124
124
  // }).run()
125
125
  },
126
+ onTocUpdate: function onTocUpdate(toc) {
127
+ console.log('toc', toc);
128
+ },
126
129
  content: mdContent
127
130
  }),
128
131
  editor = _useTiptap.editor;
@@ -13,6 +13,8 @@ interface EditorMarkdownProps {
13
13
  editor: Editor;
14
14
  value?: string;
15
15
  readOnly?: string;
16
+ showAutocomplete?: boolean;
17
+ highlightActiveLine?: boolean;
16
18
  placeholder?: string;
17
19
  height: number | string;
18
20
  onUpload?: UploadFunction;
@@ -37,6 +37,10 @@ var EditorMarkdown = /*#__PURE__*/forwardRef(function (_ref, ref) {
37
37
  readOnly = _ref$readOnly === void 0 ? false : _ref$readOnly,
38
38
  _ref$splitMode = _ref.splitMode,
39
39
  splitMode = _ref$splitMode === void 0 ? false : _ref$splitMode,
40
+ _ref$showAutocomplete = _ref.showAutocomplete,
41
+ showAutocomplete = _ref$showAutocomplete === void 0 ? true : _ref$showAutocomplete,
42
+ _ref$highlightActiveL = _ref.highlightActiveLine,
43
+ highlightActiveLine = _ref$highlightActiveL === void 0 ? true : _ref$highlightActiveL,
40
44
  _ref$defaultDisplayMo = _ref.defaultDisplayMode,
41
45
  defaultDisplayMode = _ref$defaultDisplayMo === void 0 ? 'edit' : _ref$defaultDisplayMo,
42
46
  _ref$showToolbar = _ref.showToolbar,
@@ -57,14 +61,18 @@ var EditorMarkdown = /*#__PURE__*/forwardRef(function (_ref, ref) {
57
61
  _useState6 = _slicedToArray(_useState5, 2),
58
62
  loading = _useState6[0],
59
63
  setLoading = _useState6[1];
60
- var _useState7 = useState(0),
64
+ var _useState7 = useState(false),
61
65
  _useState8 = _slicedToArray(_useState7, 2),
62
- progress = _useState8[0],
63
- setProgress = _useState8[1];
64
- var _useState9 = useState(''),
66
+ isComposing = _useState8[0],
67
+ setIsComposing = _useState8[1];
68
+ var _useState9 = useState(0),
65
69
  _useState10 = _slicedToArray(_useState9, 2),
66
- fileName = _useState10[0],
67
- setFileName = _useState10[1];
70
+ progress = _useState10[0],
71
+ setProgress = _useState10[1];
72
+ var _useState11 = useState(''),
73
+ _useState12 = _slicedToArray(_useState11, 2),
74
+ fileName = _useState12[0],
75
+ setFileName = _useState12[1];
68
76
  var EditorHeight = useMemo(function () {
69
77
  return isExpend ? 'calc(100vh - 45px)' : height;
70
78
  }, [isExpend, height]);
@@ -357,6 +365,25 @@ var EditorMarkdown = /*#__PURE__*/forwardRef(function (_ref, ref) {
357
365
  editor.setEditable(false);
358
366
  }
359
367
  }, [editor]);
368
+ useEffect(function () {
369
+ var _aceEditor$textInput;
370
+ if (!aceEditorRef.current) return;
371
+ var aceEditor = aceEditorRef.current.editor;
372
+ var textarea = (_aceEditor$textInput = aceEditor.textInput) === null || _aceEditor$textInput === void 0 ? void 0 : _aceEditor$textInput.getElement();
373
+ if (!textarea) return;
374
+ var handleCompositionStart = function handleCompositionStart() {
375
+ setIsComposing(true);
376
+ };
377
+ var handleCompositionEnd = function handleCompositionEnd() {
378
+ setIsComposing(false);
379
+ };
380
+ textarea.addEventListener('compositionstart', handleCompositionStart);
381
+ textarea.addEventListener('compositionend', handleCompositionEnd);
382
+ return function () {
383
+ textarea.removeEventListener('compositionstart', handleCompositionStart);
384
+ textarea.removeEventListener('compositionend', handleCompositionEnd);
385
+ };
386
+ }, [displayMode]);
360
387
  return /*#__PURE__*/React.createElement(Box, {
361
388
  sx: _objectSpread({
362
389
  position: 'relative',
@@ -472,14 +499,15 @@ var EditorMarkdown = /*#__PURE__*/forwardRef(function (_ref, ref) {
472
499
  onDrop: handleDrop,
473
500
  sx: {
474
501
  flex: 1,
475
- fontFamily: 'monospace',
476
- '.ace_placeholder': {
502
+ '.ace_placeholder': _objectSpread({
477
503
  transform: 'scale(1)',
478
504
  height: '100%',
479
505
  overflow: 'auto',
480
506
  width: '100%',
481
507
  fontStyle: 'normal'
482
- }
508
+ }, isComposing && {
509
+ display: 'none'
510
+ })
483
511
  }
484
512
  }, /*#__PURE__*/React.createElement(AceEditor, {
485
513
  ref: aceEditorRef,
@@ -497,10 +525,12 @@ var EditorMarkdown = /*#__PURE__*/forwardRef(function (_ref, ref) {
497
525
  $blockScrolling: true
498
526
  },
499
527
  setOptions: {
500
- enableBasicAutocompletion: true,
501
- enableLiveAutocompletion: true,
528
+ tabSize: 2,
529
+ showGutter: showLineNumbers,
502
530
  showLineNumbers: showLineNumbers,
503
- tabSize: 2
531
+ enableBasicAutocompletion: showAutocomplete,
532
+ enableLiveAutocompletion: showAutocomplete,
533
+ highlightActiveLine: highlightActiveLine
504
534
  },
505
535
  style: {
506
536
  width: '100%',
@@ -15,7 +15,7 @@ import { PLACEHOLDER } from "../contants/placeholder";
15
15
  import { AiWritingExtension, SlashCommands, StructuredDiffExtension } from "./extension";
16
16
  import { CodeExtension } from "./mark/Code";
17
17
  import CustomLink from "./mark/Link";
18
- import { AlertExtension, AudioExtension, BlockAttachmentExtension, BlockLinkExtension, CodeBlockLowlightExtension, CustomBlockMathExtension, CustomHorizontalRule, CustomInlineMathExtension, CustomSubscript, CustomSuperscript, DetailsContentExtension, DetailsExtension, DetailsSummaryExtension, EmojiExtension, FileHandlerExtension, FlowExtension, IframeExtension, ImageExtension, Indent, InlineAttachmentExtension, InlineLinkExtension, InlineUploadProgressExtension, ListExtension, MentionExtension, TableExtension, TableOfContents, UploadProgressExtension, VerticalAlign, VideoExtension, YamlFormat, YoutubeExtension } from "./node";
18
+ import { AlertExtension, AudioExtension, BlockAttachmentExtension, BlockLinkExtension, CodeBlockLowlightExtension, CustomBlockMathExtension, CustomHorizontalRule, CustomInlineMathExtension, CustomSubscript, CustomSuperscript, DetailsContentExtension, DetailsExtension, DetailsSummaryExtension, EmojiExtension, FileHandlerExtension, FlowExtension, IframeExtension, ImageExtension, Indent, InlineAttachmentExtension, InlineLinkExtension, InlineUploadProgressExtension, ListExtension, MentionExtension, TableExtension, TableOfContentsExtension, UploadProgressExtension, VerticalAlign, VideoExtension, YamlFormat, YoutubeExtension } from "./node";
19
19
  export var getExtensions = function getExtensions(_ref) {
20
20
  var contentType = _ref.contentType,
21
21
  limit = _ref.limit,
@@ -57,7 +57,7 @@ export var getExtensions = function getExtensions(_ref) {
57
57
  onValidateUrl: onValidateUrl
58
58
  })].concat(_toConsumableArray(TableExtension({
59
59
  editable: editable
60
- })), [TableOfContents({
60
+ })), [TableOfContentsExtension({
61
61
  onTocUpdate: onTocUpdate
62
62
  }), ImageExtension({
63
63
  onUpload: onUpload,
@@ -1,9 +1,4 @@
1
- import { Extension } from '@tiptap/core';
2
1
  import { TocList } from "../../../type";
3
- import type { TableOfContentsOptions, TableOfContentsStorage } from './type';
4
- export * from './type';
5
- export declare const TableOfContentsExtension: Extension<TableOfContentsOptions, TableOfContentsStorage>;
6
- export declare const TableOfContents: ({ onTocUpdate }: {
2
+ export declare const TableOfContentsExtension: ({ onTocUpdate }: {
7
3
  onTocUpdate?: ((toc: TocList) => void) | undefined;
8
- }) => Extension<TableOfContentsOptions, TableOfContentsStorage>;
9
- export default TableOfContents;
4
+ }) => import("@tiptap/core").Extension<import("@tiptap/extension-table-of-contents").TableOfContentsOptions, import("@tiptap/extension-table-of-contents").TableOfContentsStorage>;
@@ -1,374 +1,7 @@
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 _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; }
5
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
- 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); }
7
- import { Extension } from '@tiptap/core';
8
- import { v4 as uuidv4 } from 'uuid';
9
- import { TableOfContentsPlugin } from "./plugin";
10
- import { getHeadlineLevel, getHierarchicalIndexes, getLinearIndexes } from "./utils";
11
- export * from "./type";
12
-
13
- // 全局组合状态管理,避免在 IME 组合期间触发 TOC 更新
14
- var globalCompositionState = false;
15
- var globalCompositionEndTimer = null;
16
- var globalInputTimer = null;
17
- var lastInputTime = 0;
18
-
19
- // 全局监听组合状态和输入事件
20
- if (typeof document !== 'undefined') {
21
- document.addEventListener('compositionstart', function () {
22
- globalCompositionState = true;
23
- }, {
24
- passive: true
25
- });
26
- document.addEventListener('compositionend', function () {
27
- globalCompositionState = false;
28
- // 组合结束后,延迟刷新所有 TOC 实例
29
- if (globalCompositionEndTimer) {
30
- clearTimeout(globalCompositionEndTimer);
31
- }
32
- globalCompositionEndTimer = setTimeout(function () {
33
- // 这里会通过 editor 实例来触发刷新
34
- // 具体实现在 onTransaction 中处理
35
- }, 200);
36
- }, {
37
- passive: true
38
- });
39
-
40
- // 监听所有输入事件,记录最后输入时间
41
- document.addEventListener('input', function () {
42
- lastInputTime = Date.now();
43
- }, {
44
- passive: true
45
- });
46
- document.addEventListener('keydown', function () {
47
- lastInputTime = Date.now();
48
- }, {
49
- passive: true
50
- });
51
- }
52
- var addTocActiveStatesAndGetItems = function addTocActiveStatesAndGetItems(content, options) {
53
- var editor = options.editor;
54
- var headlines = [];
55
- var scrolledOverIds = [];
56
- var activeId = null;
57
- if (editor.isDestroyed) {
58
- return content;
59
- }
60
- editor.state.doc.descendants(function (node, pos) {
61
- var _options$anchorTypes;
62
- var isValidType = (_options$anchorTypes = options.anchorTypes) === null || _options$anchorTypes === void 0 ? void 0 : _options$anchorTypes.includes(node.type.name);
63
- if (!isValidType) {
64
- return;
65
- }
66
- headlines.push({
67
- node: node,
68
- pos: pos
69
- });
70
- });
71
- headlines.forEach(function (headline) {
72
- var domElement = editor.view.domAtPos(headline.pos + 1).node;
73
- var scrolledOver = options.storage.scrollPosition >= domElement.offsetTop;
74
- if (scrolledOver) {
75
- activeId = headline.node.attrs.id;
76
- scrolledOverIds.push(headline.node.attrs.id);
77
- }
78
- });
79
- return content.map(function (heading) {
80
- return _objectSpread(_objectSpread({}, heading), {}, {
81
- isActive: heading.id === activeId,
82
- isScrolledOver: scrolledOverIds.includes(heading.id)
83
- });
84
- });
85
- };
86
- var setTocData = function setTocData(options) {
87
- var editor = options.editor,
88
- onUpdate = options.onUpdate;
89
- if (editor.isDestroyed) {
90
- return;
91
- }
92
- var headlines = [];
93
- var anchors = [];
94
- var anchorEls = [];
95
- editor.state.doc.descendants(function (node, pos) {
96
- var _options$anchorTypes2;
97
- var isValidType = (_options$anchorTypes2 = options.anchorTypes) === null || _options$anchorTypes2 === void 0 ? void 0 : _options$anchorTypes2.includes(node.type.name);
98
- if (!isValidType) {
99
- return;
100
- }
101
- headlines.push({
102
- node: node,
103
- pos: pos
104
- });
105
- });
106
- headlines.forEach(function (headline, i) {
107
- if (headline.node.textContent.length === 0) {
108
- return;
109
- }
110
- var domElement = editor.view.domAtPos(headline.pos + 1).node;
111
- var scrolledOver = options.storage.scrollPosition >= domElement.offsetTop;
112
- anchorEls.push(domElement);
113
- var originalLevel = headline.node.attrs.level;
114
- var level = options.getLevelFn(headline, anchors);
115
- var itemIndex = options.getIndexFn(headline, anchors, level);
116
- anchors.push({
117
- itemIndex: itemIndex,
118
- id: headline.node.attrs.id || options.getId(headline.node.textContent),
119
- originalLevel: originalLevel,
120
- level: level,
121
- textContent: headline.node.textContent,
122
- pos: headline.pos,
123
- editor: editor,
124
- isActive: false,
125
- isScrolledOver: scrolledOver,
126
- node: headline.node,
127
- dom: domElement
128
- });
129
- });
130
-
131
- // 计算 active 和 scrolledOver 状态
132
- anchors = addTocActiveStatesAndGetItems(anchors, {
133
- editor: options.editor,
134
- anchorTypes: options.anchorTypes,
135
- storage: options.storage
136
- });
137
-
138
- // 更新存储
139
- options.storage.anchors = anchorEls;
140
- options.storage.content = anchors;
141
-
142
- // 调用回调
143
- if (onUpdate) {
144
- var isInitialCreation = options.storage.content.length === 0;
145
- onUpdate(anchors, isInitialCreation);
146
- }
147
- };
148
- export var TableOfContentsExtension = Extension.create({
149
- name: 'tableOfContents',
150
- addStorage: function addStorage() {
151
- return {
152
- content: [],
153
- anchors: [],
154
- scrollHandler: function scrollHandler() {
155
- return null;
156
- },
157
- scrollPosition: 0
158
- };
159
- },
160
- addGlobalAttributes: function addGlobalAttributes() {
161
- return [{
162
- types: this.options.anchorTypes || ['heading'],
163
- attributes: {
164
- id: {
165
- default: null,
166
- renderHTML: function renderHTML(attributes) {
167
- return {
168
- id: attributes.id
169
- };
170
- },
171
- parseHTML: function parseHTML(element) {
172
- return element.id || null;
173
- }
174
- }
175
- }
176
- }];
177
- },
178
- addOptions: function addOptions() {
179
- var defaultScrollParent = typeof window !== 'undefined' ? function () {
180
- return window;
181
- } : undefined;
182
- return {
183
- // eslint-disable-next-line
184
- onUpdate: function onUpdate() {},
185
- // eslint-disable-next-line
186
- getId: function getId(_textContent) {
187
- return uuidv4();
188
- },
189
- scrollParent: defaultScrollParent,
190
- anchorTypes: ['heading']
191
- };
192
- },
193
- addCommands: function addCommands() {
194
- var _this = this;
195
- return {
196
- updateTableOfContents: function updateTableOfContents() {
197
- return function (_ref) {
198
- var dispatch = _ref.dispatch;
199
- if (dispatch) {
200
- var _this$options$onUpdat;
201
- setTocData({
202
- editor: _this.editor,
203
- storage: _this.storage,
204
- onUpdate: (_this$options$onUpdat = _this.options.onUpdate) === null || _this$options$onUpdat === void 0 ? void 0 : _this$options$onUpdat.bind(_this),
205
- getIndexFn: _this.options.getIndex || getLinearIndexes,
206
- getLevelFn: _this.options.getLevel || getHeadlineLevel,
207
- anchorTypes: _this.options.anchorTypes,
208
- getId: _this.options.getId || function (textContent) {
209
- return uuidv4();
210
- }
211
- });
212
- }
213
- return true;
214
- };
215
- }
216
- };
217
- },
218
- onTransaction: function onTransaction(_ref2) {
219
- var _this2 = this;
220
- var transaction = _ref2.transaction;
221
- if (!transaction.docChanged) return;
222
- var now = Date.now();
223
- var timeSinceLastInput = now - lastInputTime;
224
-
225
- // 组合期间完全不处理 TOC 更新,避免打断输入
226
- if (globalCompositionState || this.editor.view.composing) {
227
- return;
228
- }
229
-
230
- // 如果最近有输入(1秒内),延迟处理
231
- if (timeSinceLastInput < 1000) {
232
- if (globalInputTimer) {
233
- clearTimeout(globalInputTimer);
234
- }
235
- globalInputTimer = setTimeout(function () {
236
- // 再次检查组合状态
237
- if (!globalCompositionState && !_this2.editor.view.composing) {
238
- var _this2$options$onUpda;
239
- setTocData({
240
- editor: _this2.editor,
241
- storage: _this2.storage,
242
- onUpdate: (_this2$options$onUpda = _this2.options.onUpdate) === null || _this2$options$onUpda === void 0 ? void 0 : _this2$options$onUpda.bind(_this2),
243
- getIndexFn: _this2.options.getIndex || getLinearIndexes,
244
- getLevelFn: _this2.options.getLevel || getHeadlineLevel,
245
- anchorTypes: _this2.options.anchorTypes,
246
- getId: _this2.options.getId || function (textContent) {
247
- return uuidv4();
248
- }
249
- });
250
- }
251
- }, 1000 - timeSinceLastInput + 200);
252
- return;
253
- }
254
-
255
- // 非组合期间且无最近输入,使用 setTimeout 确保有足够延迟
256
- setTimeout(function () {
257
- // 再次检查,确保组合状态没有变化
258
- if (!globalCompositionState && !_this2.editor.view.composing) {
259
- var _this2$options$onUpda2;
260
- setTocData({
261
- editor: _this2.editor,
262
- storage: _this2.storage,
263
- onUpdate: (_this2$options$onUpda2 = _this2.options.onUpdate) === null || _this2$options$onUpda2 === void 0 ? void 0 : _this2$options$onUpda2.bind(_this2),
264
- getIndexFn: _this2.options.getIndex || getLinearIndexes,
265
- getLevelFn: _this2.options.getLevel || getHeadlineLevel,
266
- anchorTypes: _this2.options.anchorTypes,
267
- getId: _this2.options.getId || function (textContent) {
268
- return uuidv4();
269
- }
270
- });
271
- }
272
- }, 100);
273
- },
274
- onCreate: function onCreate() {
275
- var _this3 = this;
276
- var tr = this.editor.state.tr;
277
- var existingIds = [];
278
- if (this.options.scrollParent && typeof this.options.scrollParent !== 'function') {
279
- console.warn("[Tiptap Table of Contents Deprecation Notice]: The 'scrollParent' option must now be provided as a callback function that returns the 'scrollParent' element. The ability to pass this option directly will be deprecated in future releases.");
280
- }
281
-
282
- // 异步处理初始 ID 分配,避免与初始输入竞争
283
- requestAnimationFrame(function () {
284
- _this3.editor.state.doc.descendants(function (node, pos) {
285
- var _this3$options$anchor;
286
- var nodeId = node.attrs.id;
287
- var isValidType = (_this3$options$anchor = _this3.options.anchorTypes) === null || _this3$options$anchor === void 0 ? void 0 : _this3$options$anchor.includes(node.type.name);
288
- if (!isValidType || node.textContent.length === 0) {
289
- return;
290
- }
291
- if (nodeId === null || nodeId === undefined || existingIds.includes(nodeId)) {
292
- var id = '';
293
- if (_this3.options.getId) {
294
- id = _this3.options.getId(node.textContent);
295
- } else {
296
- id = uuidv4();
297
- }
298
- tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, node.attrs), {}, {
299
- id: id
300
- }));
301
- }
302
- existingIds.push(nodeId);
303
- });
304
- _this3.editor.view.dispatch(tr);
305
-
306
- // 延迟初始化 TOC 数据
307
- setTimeout(function () {
308
- var _this3$options$onUpda;
309
- setTocData({
310
- editor: _this3.editor,
311
- storage: _this3.storage,
312
- onUpdate: (_this3$options$onUpda = _this3.options.onUpdate) === null || _this3$options$onUpda === void 0 ? void 0 : _this3$options$onUpda.bind(_this3),
313
- getIndexFn: _this3.options.getIndex || getLinearIndexes,
314
- getLevelFn: _this3.options.getLevel || getHeadlineLevel,
315
- anchorTypes: _this3.options.anchorTypes,
316
- getId: _this3.options.getId || function (textContent) {
317
- return uuidv4();
318
- }
319
- });
320
- }, 100);
321
- });
322
-
323
- // 防抖的 scroll handler,避免滚动期间频繁触发回调
324
- var scrollTimer = null;
325
- this.storage.scrollHandler = function () {
326
- if (!_this3.options.scrollParent) {
327
- return;
328
- }
329
- var scrollParent = typeof _this3.options.scrollParent === 'function' ? _this3.options.scrollParent() : _this3.options.scrollParent;
330
- var scrollPosition = scrollParent instanceof HTMLElement ? scrollParent.scrollTop : scrollParent.scrollY;
331
- _this3.storage.scrollPosition = scrollPosition || 0;
332
- if (scrollTimer) clearTimeout(scrollTimer);
333
- scrollTimer = setTimeout(function () {
334
- var _this3$options$onUpda2, _this3$options;
335
- var updatedItems = addTocActiveStatesAndGetItems(_this3.storage.content, {
336
- editor: _this3.editor,
337
- anchorTypes: _this3.options.anchorTypes,
338
- storage: _this3.storage
339
- });
340
- _this3.storage.content = updatedItems;
341
- // 调用 onUpdate 回调
342
- (_this3$options$onUpda2 = (_this3$options = _this3.options).onUpdate) === null || _this3$options$onUpda2 === void 0 || _this3$options$onUpda2.call(_this3$options, updatedItems, false);
343
- }, 100);
344
- };
345
-
346
- // 添加滚动监听
347
- if (this.options.scrollParent) {
348
- var scrollParent = typeof this.options.scrollParent === 'function' ? this.options.scrollParent() : this.options.scrollParent;
349
- if (scrollParent) {
350
- scrollParent.addEventListener('scroll', this.storage.scrollHandler);
351
- }
352
- }
353
- },
354
- onDestroy: function onDestroy() {
355
- if (this.options.scrollParent) {
356
- var scrollParent = typeof this.options.scrollParent === 'function' ? this.options.scrollParent() : this.options.scrollParent;
357
- if (scrollParent) {
358
- scrollParent.removeEventListener('scroll', this.storage.scrollHandler);
359
- }
360
- }
361
- },
362
- addProseMirrorPlugins: function addProseMirrorPlugins() {
363
- return [TableOfContentsPlugin({
364
- getId: this.options.getId,
365
- anchorTypes: this.options.anchorTypes
366
- })];
367
- }
368
- });
369
- export var TableOfContents = function TableOfContents(_ref3) {
370
- var onTocUpdate = _ref3.onTocUpdate;
371
- return TableOfContentsExtension.configure({
1
+ import { getHierarchicalIndexes, TableOfContents } from '@tiptap/extension-table-of-contents';
2
+ export var TableOfContentsExtension = function TableOfContentsExtension(_ref) {
3
+ var onTocUpdate = _ref.onTocUpdate;
4
+ return TableOfContents.configure({
372
5
  getIndex: getHierarchicalIndexes,
373
6
  onUpdate: function onUpdate(data) {
374
7
  setTimeout(function () {
@@ -387,5 +20,4 @@ export var TableOfContents = function TableOfContents(_ref3) {
387
20
  }, 0);
388
21
  }
389
22
  });
390
- };
391
- export default TableOfContents;
23
+ };
@@ -8,7 +8,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
8
8
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
9
9
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
10
10
  import { getExtensions } from "../extension";
11
- import { migrateMathStrings } from "../util";
11
+ import { migrateMathStrings } from '@tiptap/extension-mathematics';
12
12
  import { useEditor } from '@tiptap/react';
13
13
  import { renderToMarkdown } from '@tiptap/static-renderer/pm/markdown';
14
14
  var useTiptap = function useTiptap(_ref) {
@@ -2,7 +2,6 @@ export * from './fileDownload';
2
2
  export * from './fileHandler';
3
3
  export * from './floating';
4
4
  export * from './linewiseConvert';
5
- export * from './migrateMathStrings';
6
5
  export * from './resourceExtractor';
7
6
  export * from './shortcutKey';
8
7
  import { Node } from '@tiptap/pm/model';
@@ -2,7 +2,6 @@ export * from "./fileDownload";
2
2
  export * from "./fileHandler";
3
3
  export * from "./floating";
4
4
  export * from "./linewiseConvert";
5
- export * from "./migrateMathStrings";
6
5
  export * from "./resourceExtractor";
7
6
  export * from "./shortcutKey";
8
7
  export var formatFileSize = function formatFileSize(bytes) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctzhian/tiptap",
3
- "version": "1.13.0",
3
+ "version": "1.13.1",
4
4
  "description": "基于 Tiptap 二次开发的编辑器组件",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -81,38 +81,38 @@
81
81
  },
82
82
  "dependencies": {
83
83
  "@floating-ui/dom": "^1.7.2",
84
- "@tiptap/core": "^3.10.5",
85
- "@tiptap/extension-bubble-menu": "^3.10.5",
86
- "@tiptap/extension-code": "^3.10.5",
87
- "@tiptap/extension-code-block-lowlight": "^3.10.5",
88
- "@tiptap/extension-details": "^3.10.5",
89
- "@tiptap/extension-drag-handle-react": "^3.10.5",
90
- "@tiptap/extension-emoji": "^3.10.5",
91
- "@tiptap/extension-file-handler": "^3.10.5",
92
- "@tiptap/extension-highlight": "^3.10.5",
93
- "@tiptap/extension-horizontal-rule": "^3.10.5",
94
- "@tiptap/extension-image": "^3.10.5",
95
- "@tiptap/extension-invisible-characters": "^3.10.5",
96
- "@tiptap/extension-link": "^3.10.5",
97
- "@tiptap/extension-list": "^3.10.5",
98
- "@tiptap/extension-mathematics": "^3.10.5",
99
- "@tiptap/extension-mention": "^3.10.5",
100
- "@tiptap/extension-subscript": "^3.10.5",
101
- "@tiptap/extension-superscript": "^3.10.5",
102
- "@tiptap/extension-table": "^3.10.5",
103
- "@tiptap/extension-table-of-contents": "^3.10.5",
104
- "@tiptap/extension-text-align": "^3.10.5",
105
- "@tiptap/extension-text-style": "^3.10.5",
106
- "@tiptap/extension-unique-id": "^3.10.5",
107
- "@tiptap/extension-youtube": "^3.10.5",
108
- "@tiptap/extensions": "^3.10.5",
109
- "@tiptap/html": "^3.10.5",
110
- "@tiptap/markdown": "^3.10.5",
111
- "@tiptap/pm": "^3.10.5",
112
- "@tiptap/react": "^3.10.5",
113
- "@tiptap/starter-kit": "^3.10.5",
114
- "@tiptap/static-renderer": "^3.10.5",
115
- "@tiptap/suggestion": "^3.10.5",
84
+ "@tiptap/core": "^3.10.7",
85
+ "@tiptap/extension-bubble-menu": "^3.10.7",
86
+ "@tiptap/extension-code": "^3.10.7",
87
+ "@tiptap/extension-code-block-lowlight": "^3.10.7",
88
+ "@tiptap/extension-details": "^3.10.7",
89
+ "@tiptap/extension-drag-handle-react": "^3.10.7",
90
+ "@tiptap/extension-emoji": "^3.10.7",
91
+ "@tiptap/extension-file-handler": "^3.10.7",
92
+ "@tiptap/extension-highlight": "^3.10.7",
93
+ "@tiptap/extension-horizontal-rule": "^3.10.7",
94
+ "@tiptap/extension-image": "^3.10.7",
95
+ "@tiptap/extension-invisible-characters": "^3.10.7",
96
+ "@tiptap/extension-link": "^3.10.7",
97
+ "@tiptap/extension-list": "^3.10.7",
98
+ "@tiptap/extension-mathematics": "^3.10.7",
99
+ "@tiptap/extension-mention": "^3.10.7",
100
+ "@tiptap/extension-subscript": "^3.10.7",
101
+ "@tiptap/extension-superscript": "^3.10.7",
102
+ "@tiptap/extension-table": "^3.10.7",
103
+ "@tiptap/extension-table-of-contents": "^3.10.7",
104
+ "@tiptap/extension-text-align": "^3.10.7",
105
+ "@tiptap/extension-text-style": "^3.10.7",
106
+ "@tiptap/extension-unique-id": "^3.10.7",
107
+ "@tiptap/extension-youtube": "^3.10.7",
108
+ "@tiptap/extensions": "^3.10.7",
109
+ "@tiptap/html": "^3.10.7",
110
+ "@tiptap/markdown": "^3.10.7",
111
+ "@tiptap/pm": "^3.10.7",
112
+ "@tiptap/react": "^3.10.7",
113
+ "@tiptap/starter-kit": "^3.10.7",
114
+ "@tiptap/static-renderer": "^3.10.7",
115
+ "@tiptap/suggestion": "^3.10.7",
116
116
  "ace-builds": "^1.43.4",
117
117
  "core-js": "^3.46.0",
118
118
  "diff-match-patch": "^1.0.5",
@@ -1,6 +0,0 @@
1
- import type { NodeType } from '@tiptap/pm/model';
2
- import { Plugin } from '@tiptap/pm/state';
3
- export declare const TableOfContentsPlugin: ({ getId, anchorTypes, }: {
4
- getId?: ((textContent: string) => string) | undefined;
5
- anchorTypes?: (string | NodeType)[] | undefined;
6
- }) => Plugin<any>;
@@ -1,58 +0,0 @@
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 _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; }
5
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
- 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); }
7
- import { Plugin, PluginKey } from '@tiptap/pm/state';
8
- import { v4 as uuidv4 } from 'uuid';
9
- export var TableOfContentsPlugin = function TableOfContentsPlugin(_ref) {
10
- var getId = _ref.getId,
11
- _ref$anchorTypes = _ref.anchorTypes,
12
- anchorTypes = _ref$anchorTypes === void 0 ? ['heading'] : _ref$anchorTypes;
13
- return new Plugin({
14
- key: new PluginKey('tableOfContent'),
15
- appendTransaction: function appendTransaction(transactions, oldState, newState) {
16
- var _view;
17
- // 若处于组合输入,完全避免在此事务中写入 id,交由扩展层异步生成
18
- if ((_view = newState.view) !== null && _view !== void 0 && _view.composing || typeof document !== 'undefined' && document.composing || typeof window !== 'undefined' && window.compositionState) {
19
- return null;
20
- }
21
-
22
- // 检查是否有任何事务包含组合相关的变化
23
- var hasCompositionChanges = transactions.some(function (tr) {
24
- return tr.getMeta('composition') || tr.getMeta('compositionend') || tr.getMeta('compositionstart');
25
- });
26
- if (hasCompositionChanges) {
27
- return null;
28
- }
29
- var tr = newState.tr;
30
- var modified = false;
31
- if (transactions.some(function (transaction) {
32
- return transaction.docChanged;
33
- }) && !oldState.doc.eq(newState.doc)) {
34
- var existingIds = [];
35
- newState.doc.descendants(function (node, pos) {
36
- var nodeId = node.attrs.id;
37
- if (!anchorTypes.includes(node.type.name) || node.textContent.length === 0) {
38
- return;
39
- }
40
- if (nodeId === null || nodeId === undefined || existingIds.includes(nodeId)) {
41
- var id = '';
42
- if (getId) {
43
- id = getId(node.textContent);
44
- } else {
45
- id = uuidv4();
46
- }
47
- tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, node.attrs), {}, {
48
- id: id
49
- }));
50
- modified = true;
51
- }
52
- existingIds.push(nodeId);
53
- });
54
- }
55
- return modified ? tr : null;
56
- }
57
- });
58
- };
@@ -1,45 +0,0 @@
1
- import type { Editor } from '@tiptap/core';
2
- import type { Node } from '@tiptap/pm/model';
3
- export type GetTableOfContentLevelFunction = (headline: {
4
- node: Node;
5
- pos: number;
6
- }, previousItems: TableOfContentDataItem[]) => number;
7
- export type GetTableOfContentIndexFunction = (headline: {
8
- node: Node;
9
- pos: number;
10
- }, previousItems: TableOfContentDataItem[], currentLevel?: number) => number;
11
- export type TableOfContentsOptions = {
12
- getId?: (textContent: string) => string;
13
- onUpdate?: (data: TableOfContentData, isCreate?: boolean) => void;
14
- getLevel?: GetTableOfContentLevelFunction;
15
- getIndex?: GetTableOfContentIndexFunction;
16
- scrollParent?: (() => HTMLElement | Window) | HTMLElement | Window;
17
- anchorTypes?: Array<string>;
18
- };
19
- export type TableOfContentsStorage = {
20
- content: TableOfContentData;
21
- anchors: Array<HTMLHeadingElement | HTMLElement>;
22
- scrollHandler: () => void;
23
- scrollPosition: number;
24
- };
25
- export type TableOfContentData = Array<TableOfContentDataItem>;
26
- export type TableOfContentDataItem = {
27
- dom: HTMLHeadingElement;
28
- editor: Editor;
29
- id: string;
30
- isActive: boolean;
31
- isScrolledOver: boolean;
32
- itemIndex: number;
33
- level: number;
34
- node: Node;
35
- originalLevel: number;
36
- pos: number;
37
- textContent: string;
38
- };
39
- declare module '@tiptap/core' {
40
- interface Commands<ReturnType> {
41
- tableOfContents: {
42
- updateTableOfContents: () => ReturnType;
43
- };
44
- }
45
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,6 +0,0 @@
1
- import type { GetTableOfContentIndexFunction, GetTableOfContentLevelFunction, TableOfContentDataItem } from './type';
2
- export declare const getLastHeadingOnLevel: (headings: TableOfContentDataItem[], level: number) => TableOfContentDataItem | undefined;
3
- export declare const getHeadlineLevel: GetTableOfContentLevelFunction;
4
- export declare const getLinearIndexes: GetTableOfContentIndexFunction;
5
- export declare const getHierarchicalIndexes: GetTableOfContentIndexFunction;
6
- export declare function debounce(func: (...args: any[]) => void, wait: number): (...args: any[]) => void;
@@ -1,70 +0,0 @@
1
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
- 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."); }
3
- 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); }
4
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
- 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; }
7
- export var getLastHeadingOnLevel = function getLastHeadingOnLevel(headings, level) {
8
- var heading = headings.filter(function (currentHeading) {
9
- return currentHeading.level === level;
10
- }).pop();
11
- if (level === 0) {
12
- return undefined;
13
- }
14
- if (!heading) {
15
- heading = getLastHeadingOnLevel(headings, level - 1);
16
- }
17
- return heading;
18
- };
19
- export var getHeadlineLevel = function getHeadlineLevel(headline, previousItems) {
20
- var level = 1;
21
- var previousHeadline = previousItems.at(-1);
22
- var highestHeadlineAbove = _toConsumableArray(previousItems).reverse().find(function (h) {
23
- return h.originalLevel <= headline.node.attrs.level;
24
- });
25
- var highestLevelAbove = (highestHeadlineAbove === null || highestHeadlineAbove === void 0 ? void 0 : highestHeadlineAbove.level) || 1;
26
- if (headline.node.attrs.level > ((previousHeadline === null || previousHeadline === void 0 ? void 0 : previousHeadline.originalLevel) || 1)) {
27
- level = ((previousHeadline === null || previousHeadline === void 0 ? void 0 : previousHeadline.level) || 1) + 1;
28
- } else if (headline.node.attrs.level < ((previousHeadline === null || previousHeadline === void 0 ? void 0 : previousHeadline.originalLevel) || 1)) {
29
- level = highestLevelAbove;
30
- } else {
31
- level = (previousHeadline === null || previousHeadline === void 0 ? void 0 : previousHeadline.level) || 1;
32
- }
33
- return level;
34
- };
35
- export var getLinearIndexes = function getLinearIndexes(_headline, previousHeadlines) {
36
- var previousHeadline = previousHeadlines.at(-1);
37
- if (!previousHeadline) {
38
- return 1;
39
- }
40
- return ((previousHeadline === null || previousHeadline === void 0 ? void 0 : previousHeadline.itemIndex) || 1) + 1;
41
- };
42
- export var getHierarchicalIndexes = function getHierarchicalIndexes(headline, previousHeadlines, currentLevel) {
43
- var _previousHeadlinesOnL;
44
- var level = currentLevel || headline.node.attrs.level || 1;
45
- var itemIndex = 1;
46
- var previousHeadlinesOnLevelOrBelow = previousHeadlines.filter(function (h) {
47
- return h.level <= level;
48
- });
49
- if (((_previousHeadlinesOnL = previousHeadlinesOnLevelOrBelow.at(-1)) === null || _previousHeadlinesOnL === void 0 ? void 0 : _previousHeadlinesOnL.level) === level) {
50
- var _previousHeadlinesOnL2;
51
- itemIndex = (((_previousHeadlinesOnL2 = previousHeadlinesOnLevelOrBelow.at(-1)) === null || _previousHeadlinesOnL2 === void 0 ? void 0 : _previousHeadlinesOnL2.itemIndex) || 1) + 1;
52
- } else {
53
- itemIndex = 1;
54
- }
55
- return itemIndex;
56
- };
57
- export function debounce(func, wait) {
58
- var timeout = null;
59
- return function () {
60
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
61
- args[_key] = arguments[_key];
62
- }
63
- if (timeout) {
64
- clearTimeout(timeout);
65
- }
66
- timeout = setTimeout(function () {
67
- func.apply(void 0, args);
68
- }, wait);
69
- };
70
- }
@@ -1,73 +0,0 @@
1
- import type { Editor } from '@tiptap/core';
2
- import type { Transaction } from '@tiptap/pm/state';
3
- /**
4
- * Regular expression to match LaTeX math strings wrapped in single dollar signs.
5
- * This should not catch dollar signs which are not part of a math expression,
6
- * like those used for currency or other purposes.
7
- * It ensures that the dollar signs are not preceded or followed by digits,
8
- * allowing for proper identification of inline math expressions.
9
- *
10
- * - `$x^2 + y^2 = z^2$` will match
11
- * - `This is $inline math$ in text.` will match
12
- * - `This is $100$ dollars.` will not match (as it is not a math expression)
13
- * - `This is $x^2 + y^2 = z^2$ and $100$ dollars.` will match both math expressions
14
- * - `$$\frac{a}{b}$$` will NOT match (block math should be handled separately)
15
- */
16
- export declare const mathMigrationRegex: RegExp;
17
- /**
18
- * Regular expression to match LaTeX math strings wrapped in double dollar signs.
19
- * This matches block-level math expressions that should be displayed on their own line.
20
- *
21
- * - `$$\frac{a}{b}$$` will match
22
- * - `$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$` will match
23
- * - `$$100$$ dollars` will not match (as it is not a math expression)
24
- */
25
- export declare const blockMathMigrationRegex: RegExp;
26
- /**
27
- * Alternative approach: First find all math patterns, then classify them
28
- * This is more reliable than trying to use complex regex patterns
29
- */
30
- export declare const allMathPatternsRegex: RegExp;
31
- /**
32
- * Creates a transaction that migrates existing math strings in the document to new math nodes.
33
- * This function traverses the document and replaces LaTeX math syntax with proper math nodes,
34
- * preserving the mathematical content. It handles both inline and block math expressions.
35
- *
36
- * Note: Math formulas inside <pre> and <code> tags are ignored to preserve code formatting.
37
- *
38
- * @param editor - The editor instance containing the schema and configuration
39
- * @param tr - The transaction to modify with the migration operations
40
- * @returns The modified transaction with math string replacements
41
- *
42
- * @example
43
- * ```typescript
44
- * const editor = new Editor({ ... })
45
- * const tr = editor.state.tr
46
- * const updatedTr = createMathMigrateTransaction(editor, tr)
47
- * editor.view.dispatch(updatedTr)
48
- * ```
49
- */
50
- export declare function createMathMigrateTransaction(editor: Editor, tr: Transaction): Transaction;
51
- /**
52
- * Migrates existing math strings in the editor document to math nodes.
53
- * This function creates and dispatches a transaction that converts LaTeX math syntax
54
- * into proper math nodes. It handles both inline math (single dollar signs) and
55
- * block math (double dollar signs). The migration happens immediately and is not
56
- * added to the editor's history.
57
- *
58
- * Note: Math formulas inside <pre> and <code> tags are ignored to preserve code formatting.
59
- *
60
- * @param editor - The editor instance to perform the migration on
61
- *
62
- * @example
63
- * ```typescript
64
- * const editor = new Editor({
65
- * extensions: [Mathematics],
66
- * content: 'This is inline math: $x^2 + y^2 = z^2$ and block math: $$\frac{a}{b}$$'
67
- * })
68
- *
69
- * // Math strings will be automatically migrated to math nodes
70
- * migrateMathStrings(editor)
71
- * ```
72
- */
73
- export declare function migrateMathStrings(editor: Editor): void;
@@ -1,192 +0,0 @@
1
- /**
2
- * Regular expression to match LaTeX math strings wrapped in single dollar signs.
3
- * This should not catch dollar signs which are not part of a math expression,
4
- * like those used for currency or other purposes.
5
- * It ensures that the dollar signs are not preceded or followed by digits,
6
- * allowing for proper identification of inline math expressions.
7
- *
8
- * - `$x^2 + y^2 = z^2$` will match
9
- * - `This is $inline math$ in text.` will match
10
- * - `This is $100$ dollars.` will not match (as it is not a math expression)
11
- * - `This is $x^2 + y^2 = z^2$ and $100$ dollars.` will match both math expressions
12
- * - `$$\frac{a}{b}$$` will NOT match (block math should be handled separately)
13
- */
14
- export var mathMigrationRegex = /\$(?!\d+\$)(?!\$)(.+?)(?<!\$)\$(?!\d)(?!\$)/g;
15
-
16
- /**
17
- * Regular expression to match LaTeX math strings wrapped in double dollar signs.
18
- * This matches block-level math expressions that should be displayed on their own line.
19
- *
20
- * - `$$\frac{a}{b}$$` will match
21
- * - `$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$` will match
22
- * - `$$100$$ dollars` will not match (as it is not a math expression)
23
- */
24
- export var blockMathMigrationRegex = /\$\$([^$]+)\$\$/g;
25
-
26
- /**
27
- * Alternative approach: First find all math patterns, then classify them
28
- * This is more reliable than trying to use complex regex patterns
29
- */
30
- export var allMathPatternsRegex = /\$\$?[^$]*\$\$?/g;
31
-
32
- /**
33
- * Creates a transaction that migrates existing math strings in the document to new math nodes.
34
- * This function traverses the document and replaces LaTeX math syntax with proper math nodes,
35
- * preserving the mathematical content. It handles both inline and block math expressions.
36
- *
37
- * Note: Math formulas inside <pre> and <code> tags are ignored to preserve code formatting.
38
- *
39
- * @param editor - The editor instance containing the schema and configuration
40
- * @param tr - The transaction to modify with the migration operations
41
- * @returns The modified transaction with math string replacements
42
- *
43
- * @example
44
- * ```typescript
45
- * const editor = new Editor({ ... })
46
- * const tr = editor.state.tr
47
- * const updatedTr = createMathMigrateTransaction(editor, tr)
48
- * editor.view.dispatch(updatedTr)
49
- * ```
50
- */
51
- export function createMathMigrateTransaction(editor, tr) {
52
- var inlineMathNode = editor.schema.nodes.inlineMath;
53
- var blockMathNode = editor.schema.nodes.blockMath;
54
-
55
- // 收集所有需要处理的数学公式,按位置排序
56
- var allMathReplacements = [];
57
-
58
- // 第一遍:收集所有数学公式信息
59
- tr.doc.descendants(function (node, pos) {
60
- // 跳过代码块和预格式化文本
61
- if (node.marks.some(function (mark) {
62
- return mark.type.name === 'codeBlock' || mark.type.name === 'code';
63
- })) {
64
- return;
65
- }
66
- if (!node.isText || !node.text || !node.text.includes('$')) {
67
- return;
68
- }
69
- var text = node.text;
70
-
71
- // 使用更可靠的方法:先找到所有可能的数学模式,然后分类
72
- var allMatches = text.match(allMathPatternsRegex);
73
- if (!allMatches) {
74
- return;
75
- }
76
-
77
- // 按位置排序,从后往前处理,避免位置偏移问题
78
- var sortedMatches = allMatches.map(function (match) {
79
- var isBlock = match.startsWith('$$') && match.endsWith('$$');
80
- var type = isBlock ? 'block' : 'inline';
81
- return {
82
- match: match,
83
- start: text.indexOf(match),
84
- end: text.indexOf(match) + match.length,
85
- type: type
86
- };
87
- }).sort(function (a, b) {
88
- return b.start - a.start;
89
- }); // 从后往前排序
90
-
91
- sortedMatches.forEach(function (_ref) {
92
- var match = _ref.match,
93
- start = _ref.start,
94
- end = _ref.end,
95
- type = _ref.type;
96
- var from = tr.mapping.map(pos + start);
97
- var to = tr.mapping.map(pos + end);
98
- var $from = tr.doc.resolve(from);
99
- var parent = $from.parent;
100
- var index = $from.index();
101
- var latex;
102
- if (type === 'block') {
103
- latex = match.slice(2, -2); // 移除 $$ 符号
104
- } else {
105
- latex = match.slice(1, -1); // 移除 $ 符号
106
- }
107
- allMathReplacements.push({
108
- pos: from,
109
- match: match,
110
- type: type,
111
- latex: latex,
112
- parent: parent,
113
- index: index
114
- });
115
- });
116
- });
117
-
118
- // 按位置从后往前排序,避免位置偏移问题
119
- allMathReplacements.sort(function (a, b) {
120
- return b.pos - a.pos;
121
- });
122
-
123
- // 第二遍:执行替换
124
- allMathReplacements.forEach(function (_ref2) {
125
- var pos = _ref2.pos,
126
- match = _ref2.match,
127
- type = _ref2.type,
128
- latex = _ref2.latex,
129
- parent = _ref2.parent,
130
- index = _ref2.index;
131
- var mathNode;
132
- if (type === 'block') {
133
- // 块级数学公式
134
- mathNode = blockMathNode;
135
- } else {
136
- // 行内数学公式
137
- mathNode = inlineMathNode;
138
- }
139
- if (type === 'block') {
140
- // 对于块级数学公式,需要特殊处理
141
- // 1. 先删除原始文本
142
- var endPos = pos + match.length;
143
- tr.delete(pos, endPos);
144
-
145
- // 2. 在删除位置插入块级数学节点
146
- tr.insert(pos, mathNode.create({
147
- latex: latex
148
- }));
149
- } else {
150
- // 对于行内数学公式,在段落内部替换
151
- if (!parent.canReplaceWith(index, index + 1, mathNode)) {
152
- console.warn("\u65E0\u6CD5\u66FF\u6362\u884C\u5185\u6570\u5B66\u516C\u5F0F:", match);
153
- return;
154
- }
155
- var _endPos = pos + match.length;
156
- tr.replaceWith(pos, _endPos, mathNode.create({
157
- latex: latex
158
- }));
159
- }
160
- });
161
-
162
- // don't add to history
163
- tr.setMeta('addToHistory', false);
164
- return tr;
165
- }
166
-
167
- /**
168
- * Migrates existing math strings in the editor document to math nodes.
169
- * This function creates and dispatches a transaction that converts LaTeX math syntax
170
- * into proper math nodes. It handles both inline math (single dollar signs) and
171
- * block math (double dollar signs). The migration happens immediately and is not
172
- * added to the editor's history.
173
- *
174
- * Note: Math formulas inside <pre> and <code> tags are ignored to preserve code formatting.
175
- *
176
- * @param editor - The editor instance to perform the migration on
177
- *
178
- * @example
179
- * ```typescript
180
- * const editor = new Editor({
181
- * extensions: [Mathematics],
182
- * content: 'This is inline math: $x^2 + y^2 = z^2$ and block math: $$\frac{a}{b}$$'
183
- * })
184
- *
185
- * // Math strings will be automatically migrated to math nodes
186
- * migrateMathStrings(editor)
187
- * ```
188
- */
189
- export function migrateMathStrings(editor) {
190
- var tr = createMathMigrateTransaction(editor, editor.state.tr);
191
- editor.view.dispatch(tr);
192
- }