@ctzhian/tiptap 2.1.13 → 2.1.15

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.
@@ -6,9 +6,9 @@ import { Editor, EditorThemeProvider, EditorToolbar, useTiptap } from "./..";
6
6
  import { Box } from '@mui/material';
7
7
  import React from 'react';
8
8
  import "../index.css";
9
- var EDITABLE = true;
9
+ var EDITABLE = false;
10
10
  var DEFAULT_CONTENT_TYPE = 'html';
11
- var DEFAULT_HTML_CONTENT = "<p></p>\n<iframe class=\"iframe-wrapper\" src=\"//player.bilibili.com/player.html?isOutside=true&amp;aid=115377065630872&amp;bvid=BV1SQ4izBERf&amp;cid=33090306788&amp;p=1\" frameborder=\"0\" allowfullscreen=\"true\" autoplay=\"0\" loop=\"0\"></iframe>\n<table style=\"min-width: 400px;\"><colgroup><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"></colgroup><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\">\n <table style=\"min-width: 200px;\"><colgroup><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"></colgroup><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td></tr></tbody></table>\n</td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td></tr></tbody></table>\n<table style=\"min-width: 200px;\"><colgroup><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"></colgroup><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td></tr></tbody></table>\n<ol class=\"ordered-list\" data-type=\"orderedList\"><li><p>\u653E\u5047\u6740\u4EBA\u7684\u65B9\u5F0F\u963F\u51E1\u8FBE</p></li><li><p>\u53D1\u70E7\u5927\u6DA6\u53D1\u770B\u89C1</p><ol class=\"ordered-list\" data-type=\"orderedList\"><li><p>\u53D1\u5C31\u7B97\u4E86\u5FEB\u9012\u8D39</p><ol class=\"ordered-list\" data-type=\"orderedList\"><li><p>\u653E\u5047\u554A\u4F46\u662F\u4F60\u770B\u653E\u5047\u554A\u867D\u7136\u653E</p></li></ol></li></ol></li></ol>\n<ul class=\"bullet-list\" data-type=\"bulletList\"><li><p>\u53D1\u5BB6\u53F2\u4F60\u7684\u770B\u6CD5</p></li><li><p>\u53D1\u751F\u7684\u6FC0\u70C8\u53CD\u6297\u5565\u7684\u5C31\u53D1\u7684\u662F\u653E\u5047\u4E86</p><ul class=\"bullet-list\" data-type=\"bulletList\"><li><p>\u53D1\u70E7\u7684\u798F\u5229\u80AF\u5B9A\u6492\u9152\u75AF\u90A3\u53EF\u662F\u6253\u98DE\u673A\u554A\u662F\u4F60\u7684\u5BA2\u670D\u5C31\u662F\u5927\u6DA6\u53D1</p></li><li><p>\u53D1\u751F\u7684\u6D6A\u8D39\u7A7A\u95F4\u5565\u7684\u5357\u65B9\u5DE8\u517D\u9F99\u7684\u770B\u6CD5\u9759\u5B89\u5BFA\u5E97\u7406\u53D1\u5E08\u89E3\u653E\u4E1C\u8DEF</p><ul class=\"bullet-list\" data-type=\"bulletList\"><li><p>\u53D1\u751F\u7684\u53D1\u53D1\u987A\u4E30\u90A3\u53EF\u662F\u6253\u98DE\u673A\u554A\u867D\u7136\u5BA2\u670D</p></li></ul></li></ul></li></ul>\n<ul data-type=\"taskList\"><li class=\"task-item\" data-type=\"taskItem\" data-checked=\"false\"><label><input type=\"checkbox\"><span></span></label><div><p>\u53D1\u5565\u7684</p></div></li><li class=\"task-item\" data-type=\"taskItem\" data-checked=\"true\"><label><input type=\"checkbox\" checked=\"checked\"><span></span></label><div><p>\u53D1\u5565\u5446\u4F60</p><ul data-type=\"taskList\"><li class=\"task-item\" data-type=\"taskItem\" data-checked=\"false\"><label><input type=\"checkbox\"><span></span></label><div><p>\u53D1\u5927\u4E86</p><ul data-type=\"taskList\"><li class=\"task-item\" data-type=\"taskItem\" data-checked=\"false\"><label><input type=\"checkbox\"><span></span></label><div><p>\u53D1\u7684\u65F6\u95F4\u6765\u770B</p></div></li></ul></div></li></ul></div></li></ul>\n<pre data-title=\"\u5B89\u88C5\u76EE\u5F55\"><code>var a = 1;</code></pre>\n<p><img src=\"https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg\" width=\"100\"></p>\n<p><img src=\"https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg\" width=\"100\"></p>\n<h6 id=\"4b8d8c4e-29dc-4674-928b-b9ded0e363ae\" data-toc-id=\"4b8d8c4e-29dc-4674-928b-b9ded0e363ae\"><span data-name=\"watch\" data-type=\"emoji\">\u231A</span> \u8868\u683C\u64CD\u4F5C</h6>\n<table><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u94FE\u63A5</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u590D\u6742\u6587\u672C</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u56FE\u7247</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u9644\u4EF6</p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><a target=\"_blank\" class=\"MuiBox-root css-1ivg9gg\" type=\"icon\" rel=\"noopener noreferrer\" title=\"\u70B9\u51FB\u6B64\u5904\u8DF3\u8F6C\" href=\"http://localhost:8000/components/editor\">\u70B9\u51FB\u6B64\u5904\u8DF3\u8F6C</a></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><code>\u77E5</code><span style=\"background-color: rgb(255, 204, 188); color: rgb(90, 141, 218);\">\u529B</span><span style=\"color: rgb(90, 141, 218);\">\u4F9B</span><sup>\u5386</sup><sub>\u53F2</sub><u>\u52A8</u><s>\u5927</s><span style=\"background-color: rgb(172, 84, 84);\">\u501F</span><mark>\u7B54</mark></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><img src=\"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg\" width=\"100\"></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><span data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA.txt\" data-size=\"18.27 KB\"></span></p></td></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" controls=\"true\" width=\"75%\"></video></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p><audio src=\"http://vjs.zencdn.net/v/oceans.mp4\" controls=\"true\"></audio></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p></td></tr></tbody></table>\n<p><img src=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" width=\"100\"></p>\n<h6 id=\"a025f782-910f-4f17-9d0b-8f31f9cde175\" data-toc-id=\"a025f782-910f-4f17-9d0b-8f31f9cde175\"><span data-name=\"page_facing_up\" data-type=\"emoji\">\uD83D\uDCC4</span> \u6587\u672C\u5904\u7406</h6>\n<p>PandaWiki \u662F\u4E00\u6B3E AI \u5927\u6A21<code>\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D</code>\u5EFA\u7CFB\u7EDF\uFF0CF<strong>AQ \u3001 \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI </strong>\u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u501F<span style=\"color: rgb(90, 141, 218);\">\u52A9\u5927\u6A21\u578B\u7684</span><span style=\"background-color: rgb(255, 204, 188); color: rgb(90, 141, 218);\">\u529B\u91CF\u4E3A\u4F60\u63D0</span><span style=\"color: rgb(90, 141, 218);\">\u4F9B AI \u521B</span>\u4F5C\u80FD\u529B\u3002PandaWiki \u662F<u>\u4E00\u6B3E AI \u5927\u6A21\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D\u5EFA\u7CFB\u7EDF\uFF0C\u5E2E</u>\u52A9\u4F60\u5FEB\u901F\u6784\u5EFA\u667A\u80FD\u5316\u7684 <s><u>\u4EA7\u54C1\u6587\u6863\u3001\u6280\u672F</u></s>\u6587\u6863\u3001FAQ \u3001<s> \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684</s>\u529B\u91CF\u7CFB\u7EDF \uFF0C<span style=\"background-color: rgb(172, 84, 84);\">\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE</span>\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u7684\u529B\u91CF\u4E3A<mark>\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001</mark> AI \u641C\u7D22\u3002</p>\n<a target=\"_blank\" type=\"block\" href=\"http://localhost:8000/components/editor\" title=\"\u770B\u98CE\u666F\">\u770B\u98CE\u666F</a>\n<h6>\uD83D\uDCCE \u9644\u4EF6</h6>\n<div data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA\uFF1F\u8C01\u662F\u6211\u4EEC\u7684\u670B\u53CB\uFF1F\u8FD9\u4E2A\u95EE\u9898\u662F\u9769\u547D\u7684\u9996\u8981\u95EE\u9898\u3002\u4E2D\u56FD\u8FC7\u53BB\u4E00\u5207\u9769\u547D\u6597\u4E89\u6210.txt\" data-size=\"18.27 KB\"></div>\n<p>\u884C\u5185\u9644\u4EF6\uFF1A<span data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"font_4856251_qynqqohzdp.js\" data-size=\"412.34 KB\"></span><span data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u96F7\u6C60\u9879\u76EE\u8BBE\u8BA1\u65B9\u6848.docx\" data-size=\"635.74 KB\"></span></p>\n<div data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"b0f4a3e0-639f-4c09-ab33-ea9417939f87.tiff\" data-size=\"3.03 MB\"></div>\n<div data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u957F\u4EAD\u79D1\u6280\u516C\u53F8\u4ECB\u7ECDPPT-25.07.007_\u526F\u672C.pptx\" data-size=\"40.18 MB\"></div>\n<h6><span data-name=\"loudspeaker\" data-type=\"emoji\">\uD83D\uDCE2</span> \u97F3\u9891</h6>\n<audio src=\"http://vjs.zencdn.net/v/oceans.mp4\" controls=\"true\"></audio>\n<h6 id=\"1739ed5e-f03c-4c2f-b763-37505601c935\" data-toc-id=\"1739ed5e-f03c-4c2f-b763-37505601c935\"><span data-name=\"video_camera\" data-type=\"emoji\">\uD83D\uDCF9</span> \u89C6\u9891</h6>\n<video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" controls=\"true\" width=\"400\" data-align=\"center\"></video>\n<h6 id=\"746ea233-0e30-44a6-849a-090202217299\" data-toc-id=\"746ea233-0e30-44a6-849a-090202217299\">\u26A0\uFE0F \u8B66\u544A\u5757</h6>\n<div data-id=\"alert_5ysakwbhvqv\" data-variant=\"warning\" data-type=\"icon\" data-node=\"alert\"><p>\u6B64\u65F6\u8FD9\u662F\u4E00\u4E2A\u8B66\u544A\u5757\u3002</p></div>\n<h6 id=\"ebb64062-9efb-4de8-887f-7f8b7f9e54ca\" data-toc-id=\"ebb64062-9efb-4de8-887f-7f8b7f9e54ca\"><span data-name=\"bar_chart\" data-type=\"emoji\">\uD83D\uDCCA</span> \u6D41\u7A0B\u56FE\u64CD\u4F5C</h6>\n<div data-type=\"flow\" data-code=\"mindmap\n root((mindmap))\n Origins\n Long history\n ::icon(fa fa-book)\n Popularisation\n British popular psychology author Tony Buzan\n Research\n On effectiveness&lt;br/&gt;and features\n On Automatic creation\n Uses\n Creative techniques\n Strategic planning\n Argument mapping\n Tools\n Pen and paper\n Mermaid\" data-width=\"246px\"></div>\n";
11
+ var DEFAULT_HTML_CONTENT = "<p></p>\n<iframe class=\"iframe-wrapper\" width=\"50%\" height=\"400\" data-type=\"iframe\" data-align=\"right\" src=\"//player.bilibili.com/player.html?isOutside=true&amp;aid=115377065630872&amp;bvid=BV1SQ4izBERf&amp;cid=33090306788&amp;p=1\" frameborder=\"0\" allowfullscreen=\"true\" autoplay=\"0\" loop=\"0\"></iframe>\n<table style=\"min-width: 400px;\"><colgroup><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"></colgroup><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\">\n <table style=\"min-width: 200px;\"><colgroup><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"></colgroup><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td></tr></tbody></table>\n</td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td></tr></tbody></table>\n<table style=\"min-width: 200px;\"><colgroup><col style=\"min-width: 100px;\"><col style=\"min-width: 100px;\"></colgroup><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td><td colspan=\"1\" rowspan=\"1\" style=\"\"><p></p></td></tr></tbody></table>\n<ol class=\"ordered-list\" data-type=\"orderedList\"><li><p>\u653E\u5047\u6740\u4EBA\u7684\u65B9\u5F0F\u963F\u51E1\u8FBE</p></li><li><p>\u53D1\u70E7\u5927\u6DA6\u53D1\u770B\u89C1</p><ol class=\"ordered-list\" data-type=\"orderedList\"><li><p>\u53D1\u5C31\u7B97\u4E86\u5FEB\u9012\u8D39</p><ol class=\"ordered-list\" data-type=\"orderedList\"><li><p>\u653E\u5047\u554A\u4F46\u662F\u4F60\u770B\u653E\u5047\u554A\u867D\u7136\u653E</p></li></ol></li></ol></li></ol>\n<ul class=\"bullet-list\" data-type=\"bulletList\"><li><p>\u53D1\u5BB6\u53F2\u4F60\u7684\u770B\u6CD5</p></li><li><p>\u53D1\u751F\u7684\u6FC0\u70C8\u53CD\u6297\u5565\u7684\u5C31\u53D1\u7684\u662F\u653E\u5047\u4E86</p><ul class=\"bullet-list\" data-type=\"bulletList\"><li><p>\u53D1\u70E7\u7684\u798F\u5229\u80AF\u5B9A\u6492\u9152\u75AF\u90A3\u53EF\u662F\u6253\u98DE\u673A\u554A\u662F\u4F60\u7684\u5BA2\u670D\u5C31\u662F\u5927\u6DA6\u53D1</p></li><li><p>\u53D1\u751F\u7684\u6D6A\u8D39\u7A7A\u95F4\u5565\u7684\u5357\u65B9\u5DE8\u517D\u9F99\u7684\u770B\u6CD5\u9759\u5B89\u5BFA\u5E97\u7406\u53D1\u5E08\u89E3\u653E\u4E1C\u8DEF</p><ul class=\"bullet-list\" data-type=\"bulletList\"><li><p>\u53D1\u751F\u7684\u53D1\u53D1\u987A\u4E30\u90A3\u53EF\u662F\u6253\u98DE\u673A\u554A\u867D\u7136\u5BA2\u670D</p></li></ul></li></ul></li></ul>\n<ul data-type=\"taskList\"><li class=\"task-item\" data-type=\"taskItem\" data-checked=\"false\"><label><input type=\"checkbox\"><span></span></label><div><p>\u53D1\u5565\u7684</p></div></li><li class=\"task-item\" data-type=\"taskItem\" data-checked=\"true\"><label><input type=\"checkbox\" checked=\"checked\"><span></span></label><div><p>\u53D1\u5565\u5446\u4F60</p><ul data-type=\"taskList\"><li class=\"task-item\" data-type=\"taskItem\" data-checked=\"false\"><label><input type=\"checkbox\"><span></span></label><div><p>\u53D1\u5927\u4E86</p><ul data-type=\"taskList\"><li class=\"task-item\" data-type=\"taskItem\" data-checked=\"false\"><label><input type=\"checkbox\"><span></span></label><div><p>\u53D1\u7684\u65F6\u95F4\u6765\u770B</p></div></li></ul></div></li></ul></div></li></ul>\n<pre data-title=\"\u5B89\u88C5\u76EE\u5F55\"><code>var a = 1;</code></pre>\n<p><img src=\"https://fuss10.elemecdn.com/8/27/f01c15bb73e1ef3793e64e6b7bbccjpeg.jpeg\" width=\"100\"></p>\n<p><img src=\"https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg\" width=\"100\"></p>\n<h6 id=\"4b8d8c4e-29dc-4674-928b-b9ded0e363ae\" data-toc-id=\"4b8d8c4e-29dc-4674-928b-b9ded0e363ae\"><span data-name=\"watch\" data-type=\"emoji\">\u231A</span> \u8868\u683C\u64CD\u4F5C</h6>\n<table><tbody><tr class=\"table-row\"><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u94FE\u63A5</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u590D\u6742\u6587\u672C</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u56FE\u7247</p></th><th class=\"table-header\" colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p>\u9644\u4EF6</p></th></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><a target=\"_blank\" class=\"MuiBox-root css-1ivg9gg\" type=\"icon\" rel=\"noopener noreferrer\" title=\"\u70B9\u51FB\u6B64\u5904\u8DF3\u8F6C\" href=\"http://localhost:8000/components/editor\">\u70B9\u51FB\u6B64\u5904\u8DF3\u8F6C</a></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><code>\u77E5</code><span style=\"background-color: rgb(255, 204, 188); color: rgb(90, 141, 218);\">\u529B</span><span style=\"color: rgb(90, 141, 218);\">\u4F9B</span><sup>\u5386</sup><sub>\u53F2</sub><u>\u52A8</u><s>\u5927</s><span style=\"background-color: rgb(172, 84, 84);\">\u501F</span><mark>\u7B54</mark></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><img src=\"https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg\" width=\"100\"></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" data-vertical-align=\"middle\" style=\"text-align: center; vertical-align: middle;\"><p><span data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA.txt\" data-size=\"18.27 KB\"></span></p></td></tr><tr class=\"table-row\"><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" controls=\"true\" width=\"75%\"></video></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p><audio src=\"http://vjs.zencdn.net/v/oceans.mp4\" controls=\"true\"></audio></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p></td><td colspan=\"1\" rowspan=\"1\" data-background-color=\"\" data-text-align=\"center\" style=\"text-align: center;\"><p></p></td></tr></tbody></table>\n<p><img src=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" width=\"100\"></p>\n<h6 id=\"a025f782-910f-4f17-9d0b-8f31f9cde175\" data-toc-id=\"a025f782-910f-4f17-9d0b-8f31f9cde175\"><span data-name=\"page_facing_up\" data-type=\"emoji\">\uD83D\uDCC4</span> \u6587\u672C\u5904\u7406</h6>\n<p>PandaWiki \u662F\u4E00\u6B3E AI \u5927\u6A21<code>\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D</code>\u5EFA\u7CFB\u7EDF\uFF0CF<strong>AQ \u3001 \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI </strong>\u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u501F<span style=\"color: rgb(90, 141, 218);\">\u52A9\u5927\u6A21\u578B\u7684</span><span style=\"background-color: rgb(255, 204, 188); color: rgb(90, 141, 218);\">\u529B\u91CF\u4E3A\u4F60\u63D0</span><span style=\"color: rgb(90, 141, 218);\">\u4F9B AI \u521B</span>\u4F5C\u80FD\u529B\u3002PandaWiki \u662F<u>\u4E00\u6B3E AI \u5927\u6A21\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D\u5EFA\u7CFB\u7EDF\uFF0C\u5E2E</u>\u52A9\u4F60\u5FEB\u901F\u6784\u5EFA\u667A\u80FD\u5316\u7684 <s><u>\u4EA7\u54C1\u6587\u6863\u3001\u6280\u672F</u></s>\u6587\u6863\u3001FAQ \u3001<s> \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684</s>\u529B\u91CF\u7CFB\u7EDF \uFF0C<span style=\"background-color: rgb(172, 84, 84);\">\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE</span>\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u7684\u529B\u91CF\u4E3A<mark>\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001</mark> AI \u641C\u7D22\u3002</p>\n<a target=\"_blank\" type=\"block\" href=\"http://localhost:8000/components/editor\" title=\"\u770B\u98CE\u666F\">\u770B\u98CE\u666F</a>\n<h6>\uD83D\uDCCE \u9644\u4EF6</h6>\n<div data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA\uFF1F\u8C01\u662F\u6211\u4EEC\u7684\u670B\u53CB\uFF1F\u8FD9\u4E2A\u95EE\u9898\u662F\u9769\u547D\u7684\u9996\u8981\u95EE\u9898\u3002\u4E2D\u56FD\u8FC7\u53BB\u4E00\u5207\u9769\u547D\u6597\u4E89\u6210.txt\" data-size=\"18.27 KB\"></div>\n<p>\u884C\u5185\u9644\u4EF6\uFF1A<span data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"font_4856251_qynqqohzdp.js\" data-size=\"412.34 KB\"></span><span data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u96F7\u6C60\u9879\u76EE\u8BBE\u8BA1\u65B9\u6848.docx\" data-size=\"635.74 KB\"></span></p>\n<div data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"b0f4a3e0-639f-4c09-ab33-ea9417939f87.tiff\" data-size=\"3.03 MB\"></div>\n<div data-tag=\"attachment\" url=\"\" title=\"\" size=\"0\" data-url=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" data-title=\"\u957F\u4EAD\u79D1\u6280\u516C\u53F8\u4ECB\u7ECDPPT-25.07.007_\u526F\u672C.pptx\" data-size=\"40.18 MB\"></div>\n<h6><span data-name=\"loudspeaker\" data-type=\"emoji\">\uD83D\uDCE2</span> \u97F3\u9891</h6>\n<audio src=\"http://vjs.zencdn.net/v/oceans.mp4\" controls=\"true\"></audio>\n<h6 id=\"1739ed5e-f03c-4c2f-b763-37505601c935\" data-toc-id=\"1739ed5e-f03c-4c2f-b763-37505601c935\"><span data-name=\"video_camera\" data-type=\"emoji\">\uD83D\uDCF9</span> \u89C6\u9891</h6>\n<video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" controls=\"true\" width=\"400\" data-align=\"center\"></video>\n<h6 id=\"746ea233-0e30-44a6-849a-090202217299\" data-toc-id=\"746ea233-0e30-44a6-849a-090202217299\">\u26A0\uFE0F \u8B66\u544A\u5757</h6>\n<div data-id=\"alert_5ysakwbhvqv\" data-variant=\"warning\" data-type=\"icon\" data-node=\"alert\"><p>\u6B64\u65F6\u8FD9\u662F\u4E00\u4E2A\u8B66\u544A\u5757\u3002</p></div>\n<h6 id=\"ebb64062-9efb-4de8-887f-7f8b7f9e54ca\" data-toc-id=\"ebb64062-9efb-4de8-887f-7f8b7f9e54ca\"><span data-name=\"bar_chart\" data-type=\"emoji\">\uD83D\uDCCA</span> \u6D41\u7A0B\u56FE\u64CD\u4F5C</h6>\n<div data-type=\"flow\" data-code=\"mindmap\n root((mindmap))\n Origins\n Long history\n ::icon(fa fa-book)\n Popularisation\n British popular psychology author Tony Buzan\n Research\n On effectiveness&lt;br/&gt;and features\n On Automatic creation\n Uses\n Creative techniques\n Strategic planning\n Argument mapping\n Tools\n Pen and paper\n Mermaid\" data-width=\"246px\"></div>\n";
12
12
  var DEFAULT_MARKDOWN_CONTENT = "###### :page_facing_up: \u6587\u672C\u5904\u7406\n\nPandaWiki \u662F\u4E00\u6B3E AI \u5927\u6A21`\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D`\u5EFA\u7CFB\u7EDF\uFF0CF**AQ \u3001 \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI **\u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI \u521B\u4F5C\u80FD\u529B\u3002PandaWiki \u662F++\u4E00\u6B3E AI \u5927\u6A21\u578B\u9A71\u52A8\u7684\u5F00\u6E90\u77E5\u8BC6\u5E93\u642D\u5EFA\u7CFB\u7EDF\uFF0C\u5E2E++\u52A9\u4F60\u5FEB\u901F\u6784\u5EFA\u667A\u80FD\u5316\u7684 ++~~\u4EA7\u54C1\u6587\u6863\u3001\u6280\u672F~~++\u6587\u6863\u3001FAQ \u3001~~ \u535A\u5BA2\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684~~\u529B\u91CF\u7CFB\u7EDF \uFF0C\u501F\u52A9\u5927\u6A21\u578B\u7684\u529B\u91CF\u4E3A\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001 AI \u641C\u7D22 \u7B49\u80FD\u529B\u3002\u7684\u529B\u91CF\u4E3A==\u4F60\u63D0\u4F9B AI \u521B\u4F5C \u3001 AI \u95EE\u7B54 \u3001== AI \u641C\u7D22\u3002\n\n###### :video_camera: \u89C6\u9891\n\n<video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" width=\"400\" controls ></video>\n\n###### \u26A0\uFE0F \u8B66\u544A\u5757\n\n:::alert {#alert_5ysakwbhvqv indent=\"0\" variant=\"warning\" type=\"icon\"}\n\n\u6B64\u65F6\u8FD9\u662F\u4E00\u4E2A\u8B66\u544A\u5757\u3002\n\n:::\n\n###### :bar_chart: \u6D41\u7A0B\u56FE\u64CD\u4F5C\n\n```mermaid\nmindmap\n root((mindmap))\n Origins\n Long history\n ::icon(fa fa-book)\n Popularisation\n British popular psychology author Tony Buzan\n Research\n On effectiveness<br/>and features\n On Automatic creation\n Uses\n Creative techniques\n Strategic planning\n Argument mapping\n Tools\n Pen and paper\n Mermaid\n```\n\n###### :watch: \u8868\u683C\u64CD\u4F5C\n\n\n| \u94FE\u63A5 | \u590D\u6742\u6587\u672C | \u56FE\u7247 | \u9644\u4EF6 |\n| ------------------------------------------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |\n| [\u70B9\u51FB\u6B64\u5904\u8DF3\u8F6C](http://localhost:8000/components/editor) | `\u77E5`\u529B\u4F9B^\u5386^~\u53F2~++\u52A8++~~\u5927~~\u501F==\u7B54== | ![](https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg) | <a href=\"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg\" target=\"_blank\" download=\"\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA.txt\">\u8C01\u662F\u6211\u4EEC\u7684\u654C\u4EBA.txt</a> |\n| <video src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\" width=\"75%\" controls ></video> | \x1F | | |\n\n\n";
13
13
  var Reader = function Reader() {
14
14
  // @ts-ignore
@@ -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("本文用以记录 Gitlab 相关问题及解答\n\n## 我在使用 `git@git.in.chaitin.net:ns/repo` 时可以访问仓库,但是 `https://git.in.chaitin.net/ns/repo` 无法访问\n\n问题通常出现 git clone 与其他依赖 git 进行的操作,如 `go get` 等,具体报错可能为 `Permission Denied`.\n\n在使用 curl 借助 `CI_JOB_TOKEN` 获取其他仓库 cicd job 产物或者 generic package 时,其具体报错为 `404 Not Found` 的问题.\n\n原因是在使用 `git@git.in.chaitin.net` 时,使用的是 ssh 协议,此时默认使用的是 `~/.ssh` 下的私钥进行认证你在 gitlab 中添加的 `SSH Keys`。而使用 `https://git.in.chaitin.net/ns/repo` 时,使用的是 http 协议,此时默认使用的是 `~/.netrc` 认证你在 gitlab 中申请的 `Access tokens`。部分软件如 `go get` 默认使用的便是 http 来拉取代码,因此需要额外配置。\n\n这里推荐两种解决方案:\n\n1. 配置 `~/.netrc` 文件(推荐)\n\n 在 ~/.netrc 文件中添加以下配置:\n\n ```text\n machine git.in.chaitin.net login git password <your access token>\n ```\n\n 在 gitlab cicd job 中遇到拉取其他仓库时遇到权限问题可以使用本配置,比如可以在 job 的 `before_script` 阶段添加以下命令:\n\n ```shell\n echo \"machine git.in.chaitin.net login git password $CI_JOB_TOKEN\" >> ~/.netrc\n ```\n\n 注意: 其中 `$CI_JOB_TOKEN` 是 job 运行期间生成的 token,其权限与 trigger 用户相同,详见 [CI Job Token](https://docs.gitlab.com/ci/jobs/ci_job_token/)。其 Token 权限由 `pipeline 触发者`权限以及`目标仓库权限`共同决定。因此被拉取的目标仓库也需要保证其 `Setting -> CI/CD -> Job token permissions` 配置正确,允许源仓库的 CI/CD 能够访问到该仓库,否则依然会出现如 `404 Not Found`, `403 Forbidden` 的权限问题。(如果你是 pipeline 触发者,可以手动在浏览器通过 gitlab api 访问目标仓库的 generic package 或者 job artifact 如果可以正常下载,说明是 `Job token permissions` 问题)\n\n2. 配置 `git url replace`\n\n 在 ~/.gitconfig 文件中添加以下配置:\n\n ```ini\n [url \"git@git.in.chaitin.net:\"]\n insteadOf = https://git.in.chaitin.net/\n ```\n\n 这个配置可以将所有 `https://git.in.chaitin.net/` 请求替换为 `git@git.in.chaitin.net:` 使用 ssh 来拉取代码仓库\n\n## 我在 clone gitlab 仓库时没问题,但是 lfs 遇到了 EOF 问题\n\nEOF 在大多数情况下由代理导致,如果代理不允许客户端访问某个网站,行为可能是提早结束连接,导致 `EOF` 错误。如\n\n> 在 ubunu 虚拟机里无法拉取 safeline-aliyun 项目里的 lfs 文件怎么处理?\n\n```bash\nroot@OPS-5108:~/proj/safeline-aliyun# git lfs fetch --all\nfetch: 34 object(s) found, done.\nfetch: Fetching all references...\nbatch response: Post https://git.in.chaitin.net/patronus/safeline-aliyun.git/info/lfs/objects/batch: EOF\nerror: failed to fetch some objects from 'https://git.in.chaitin.net/patronus/safeline-aliyun.git/info/lfs'\n```\n\n可以看到返回了 EOF 问题,经查代理未配置在 git config 中。从 `env` 中可以看到用户配置了 *_proxy 但其中发现 `no_proxy` 配置不正确:\n\n```shell\nroot@OPS-5108:~/proj/safeline-aliyun# env | grep pro\nno_proxy=localhost, 127.0.0.1, ::1\nPWD=/root/proj/safeline-aliyun\nftp_proxy=http://proxy.in.chaitin.net:8123\nhttps_proxy=http://proxy.in.chaitin.net:8123\nproxy=http://proxy.in.chaitin.net:8123\nhttp_proxy=http://proxy.in.chaitin.net:8123\nOLDPWD=/root/proj\n```\n\n需要按照 [代理配置](https://info.chaitin.net/colab-editor/page/%E7%A0%94%E5%8F%91%E4%BD%93%E7%B3%BB%2F%E7%A0%94%E5%8F%91%E6%94%AF%E6%8C%81%2F%E4%BB%A3%E7%90%86%E6%89%AB%E7%9B%B2) 进行正确配置后,重新执行操作,发现 EOF 问题被解决。\n\n## 我在访问公司内部服务时报错 `x509: certificate signed by unknown authority`\n\n公司部分内部服务采用自签名证书,导致客户端在访问这些服务时会遇到 `x509: certificate signed by unknown authority` 错误。为了确保客户端能够信任这些自签名证书,你需要配置信任自签名证书即 CA。\n\n以 debian 系系统举例:\n\n```shell\ncurl -o /usr/local/share/ca-certificates/chaitin_ca.crt -L https://chaitin-ops-public.cn-beijing.oss.aliyuncs.com/Chaitin_Ltd_Root_CA.pem\nupdate-ca-certificates\n```\n\n如果无法访问外网,可以尝试 `http://s3-ephemeral.in.chaitin.net/dev/Chaitin_Ltd_Root_CA.pem`\n\n其他系统 CA 证书安装请参考 [安装CA证书](https://info.chaitin.net/colab-editor/page/IT%E5%8A%9E%E5%85%AC/%E5%8A%9E%E5%85%AC%E7%BD%91%E7%BB%9C/windows%E7%94%A8%E6%88%B7/%E5%A4%87%E9%80%89%E6%96%B9%E6%A1%88%EF%BC%88Windows%EF%BC%89/%E8%AF%81%E4%B9%A6%E5%AE%89%E8%A3%85%28windows%29/%E9%95%BF%E4%BA%AD%E6%A0%B9%E8%AF%81%E4%B9%A6%E5%AE%89%E8%A3%85%28windows%29)\n"),
16
+ var _useState = useState("本文用以记录 Gitlab 相关问题及解答\n\n![https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg](https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg)\n\n## 我在使用 `git@git.in.chaitin.net:ns/repo` 时可以访问仓库,但是 `https://git.in.chaitin.net/ns/repo` 无法访问\n\n问题通常出现 git clone 与其他依赖 git 进行的操作,如 `go get` 等,具体报错可能为 `Permission Denied`.\n\n在使用 curl 借助 `CI_JOB_TOKEN` 获取其他仓库 cicd job 产物或者 generic package 时,其具体报错为 `404 Not Found` 的问题.\n\n原因是在使用 `git@git.in.chaitin.net` 时,使用的是 ssh 协议,此时默认使用的是 `~/.ssh` 下的私钥进行认证你在 gitlab 中添加的 `SSH Keys`。而使用 `https://git.in.chaitin.net/ns/repo` 时,使用的是 http 协议,此时默认使用的是 `~/.netrc` 认证你在 gitlab 中申请的 `Access tokens`。部分软件如 `go get` 默认使用的便是 http 来拉取代码,因此需要额外配置。\n\n这里推荐两种解决方案:\n\n1. 配置 `~/.netrc` 文件(推荐)\n\n 在 ~/.netrc 文件中添加以下配置:\n\n ```text\n machine git.in.chaitin.net login git password <your access token>\n ```\n\n 在 gitlab cicd job 中遇到拉取其他仓库时遇到权限问题可以使用本配置,比如可以在 job 的 `before_script` 阶段添加以下命令:\n\n ```shell\n echo \"machine git.in.chaitin.net login git password $CI_JOB_TOKEN\" >> ~/.netrc\n ```\n\n 注意: 其中 `$CI_JOB_TOKEN` 是 job 运行期间生成的 token,其权限与 trigger 用户相同,详见 [CI Job Token](https://docs.gitlab.com/ci/jobs/ci_job_token/)。其 Token 权限由 `pipeline 触发者`权限以及`目标仓库权限`共同决定。因此被拉取的目标仓库也需要保证其 `Setting -> CI/CD -> Job token permissions` 配置正确,允许源仓库的 CI/CD 能够访问到该仓库,否则依然会出现如 `404 Not Found`, `403 Forbidden` 的权限问题。(如果你是 pipeline 触发者,可以手动在浏览器通过 gitlab api 访问目标仓库的 generic package 或者 job artifact 如果可以正常下载,说明是 `Job token permissions` 问题)\n\n2. 配置 `git url replace`\n\n 在 ~/.gitconfig 文件中添加以下配置:\n\n ```ini\n [url \"git@git.in.chaitin.net:\"]\n insteadOf = https://git.in.chaitin.net/\n ```\n\n 这个配置可以将所有 `https://git.in.chaitin.net/` 请求替换为 `git@git.in.chaitin.net:` 使用 ssh 来拉取代码仓库\n\n## 我在 clone gitlab 仓库时没问题,但是 lfs 遇到了 EOF 问题\n\nEOF 在大多数情况下由代理导致,如果代理不允许客户端访问某个网站,行为可能是提早结束连接,导致 `EOF` 错误。如\n\n> 在 ubunu 虚拟机里无法拉取 safeline-aliyun 项目里的 lfs 文件怎么处理?\n\n```bash\nroot@OPS-5108:~/proj/safeline-aliyun# git lfs fetch --all\nfetch: 34 object(s) found, done.\nfetch: Fetching all references...\nbatch response: Post https://git.in.chaitin.net/patronus/safeline-aliyun.git/info/lfs/objects/batch: EOF\nerror: failed to fetch some objects from 'https://git.in.chaitin.net/patronus/safeline-aliyun.git/info/lfs'\n```\n\n可以看到返回了 EOF 问题,经查代理未配置在 git config 中。从 `env` 中可以看到用户配置了 *_proxy 但其中发现 `no_proxy` 配置不正确:\n\n```shell\nroot@OPS-5108:~/proj/safeline-aliyun# env | grep pro\nno_proxy=localhost, 127.0.0.1, ::1\nPWD=/root/proj/safeline-aliyun\nftp_proxy=http://proxy.in.chaitin.net:8123\nhttps_proxy=http://proxy.in.chaitin.net:8123\nproxy=http://proxy.in.chaitin.net:8123\nhttp_proxy=http://proxy.in.chaitin.net:8123\nOLDPWD=/root/proj\n```\n\n需要按照 [代理配置](https://info.chaitin.net/colab-editor/page/%E7%A0%94%E5%8F%91%E4%BD%93%E7%B3%BB%2F%E7%A0%94%E5%8F%91%E6%94%AF%E6%8C%81%2F%E4%BB%A3%E7%90%86%E6%89%AB%E7%9B%B2) 进行正确配置后,重新执行操作,发现 EOF 问题被解决。\n\n## 我在访问公司内部服务时报错 `x509: certificate signed by unknown authority`\n\n公司部分内部服务采用自签名证书,导致客户端在访问这些服务时会遇到 `x509: certificate signed by unknown authority` 错误。为了确保客户端能够信任这些自签名证书,你需要配置信任自签名证书即 CA。\n\n以 debian 系系统举例:\n\n```shell\ncurl -o /usr/local/share/ca-certificates/chaitin_ca.crt -L https://chaitin-ops-public.cn-beijing.oss.aliyuncs.com/Chaitin_Ltd_Root_CA.pem\nupdate-ca-certificates\n```\n\n如果无法访问外网,可以尝试 `http://s3-ephemeral.in.chaitin.net/dev/Chaitin_Ltd_Root_CA.pem`\n\n其他系统 CA 证书安装请参考 [安装CA证书](https://info.chaitin.net/colab-editor/page/IT%E5%8A%9E%E5%85%AC/%E5%8A%9E%E5%85%AC%E7%BD%91%E7%BB%9C/windows%E7%94%A8%E6%88%B7/%E5%A4%87%E9%80%89%E6%96%B9%E6%A1%88%EF%BC%88Windows%EF%BC%89/%E8%AF%81%E4%B9%A6%E5%AE%89%E8%A3%85%28windows%29/%E9%95%BF%E4%BA%AD%E6%A0%B9%E8%AF%81%E4%B9%A6%E5%AE%89%E8%A3%85%28windows%29)\n"),
17
17
  _useState2 = _slicedToArray(_useState, 2),
18
18
  mdContent = _useState2[0],
19
19
  setMdContent = _useState2[1];
@@ -1,8 +1,11 @@
1
1
  import { Box } from '@mui/material';
2
+ import { NodeViewWrapper } from '@tiptap/react';
2
3
  import React from 'react';
3
4
  var ReadonlyIframe = function ReadonlyIframe(_ref) {
4
5
  var attrs = _ref.attrs;
5
- return /*#__PURE__*/React.createElement(Box, {
6
+ return /*#__PURE__*/React.createElement(NodeViewWrapper, {
7
+ className: "iframe-wrapper"
8
+ }, /*#__PURE__*/React.createElement(Box, {
6
9
  sx: {
7
10
  textAlign: attrs.align || undefined
8
11
  }
@@ -11,13 +14,13 @@ var ReadonlyIframe = function ReadonlyIframe(_ref) {
11
14
  width: typeof attrs.width === 'number' ? attrs.width : undefined,
12
15
  height: attrs.height,
13
16
  style: {
14
- display: 'block',
17
+ display: 'inline-block',
15
18
  border: 0,
16
19
  width: typeof attrs.width === 'string' && attrs.width.endsWith('%') ? attrs.width : undefined,
17
20
  maxWidth: '100%'
18
21
  },
19
22
  frameBorder: "0",
20
23
  allowFullScreen: true
21
- }));
24
+ })));
22
25
  };
23
26
  export default ReadonlyIframe;
@@ -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)) {
@@ -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;
@@ -1,30 +1,30 @@
1
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
4
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
5
1
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
6
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."); }
7
3
  function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
8
4
  function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
5
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
8
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
9
9
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
10
10
  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); }
11
11
  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; }
12
12
  import { generateJSON } from '@tiptap/html';
13
13
  import DiffMatchPatch from 'diff-match-patch';
14
-
15
- // 创建diff-match-patch实例
16
14
  var dmp = new DiffMatchPatch();
17
-
18
- // 类型定义
19
-
20
- /**
21
- * 将HTML转换为ProseMirror文档结构
22
- * @param {string} html - HTML字符串
23
- * @param {Array} extensions - Tiptap扩展数组
24
- * @returns {Object} ProseMirror文档对象
25
- */
26
15
  export function parseHtmlToDoc(html, extensions) {
27
- return generateJSON(html, extensions);
16
+ try {
17
+ if (!html || typeof html !== 'string') {
18
+ throw new Error('HTML 内容无效');
19
+ }
20
+ if (!extensions || extensions.length === 0) {
21
+ throw new Error('扩展数组不能为空');
22
+ }
23
+ return generateJSON(html, extensions);
24
+ } catch (error) {
25
+ console.error('解析 HTML 到文档结构时出错:', error);
26
+ throw error;
27
+ }
28
28
  }
29
29
  function haveSameMarks(a, b) {
30
30
  var arrA = a || [];
@@ -48,191 +48,6 @@ function haveSameMarks(a, b) {
48
48
  }
49
49
  return true;
50
50
  }
51
-
52
- /**
53
- * 对比两个ProseMirror文档节点
54
- * @param {Object} nodeA - 旧文档节点
55
- * @param {Object} nodeB - 新文档节点
56
- * @param {Array} path - 当前节点路径
57
- * @returns {Array} 差异数组
58
- */
59
- function compareNodes(nodeA, nodeB) {
60
- var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
61
- var diffs = [];
62
-
63
- // 如果节点类型不同,标记整个节点为变更
64
- if ((nodeA === null || nodeA === void 0 ? void 0 : nodeA.type) !== (nodeB === null || nodeB === void 0 ? void 0 : nodeB.type)) {
65
- if (nodeA) {
66
- diffs.push({
67
- type: 'delete',
68
- path: _toConsumableArray(path),
69
- node: nodeA
70
- });
71
- }
72
- if (nodeB) {
73
- diffs.push({
74
- type: 'insert',
75
- path: _toConsumableArray(path),
76
- node: nodeB
77
- });
78
- }
79
- return diffs;
80
- }
81
-
82
- // 如果是文本节点,进行文本级别的diff
83
- if ((nodeA === null || nodeA === void 0 ? void 0 : nodeA.type) === 'text' && (nodeB === null || nodeB === void 0 ? void 0 : nodeB.type) === 'text') {
84
- if (nodeA.text !== nodeB.text) {
85
- // 计算文本差异
86
- var textDiffs = dmp.diff_main(nodeA.text || '', nodeB.text || '');
87
- dmp.diff_cleanupSemantic(textDiffs);
88
-
89
- // 检查是否有文本差异
90
- // if (textDiffs.length > 1) {
91
- // console.log('发现文本差异:', { oldText: nodeA.text, newText: nodeB.text, path });
92
- // }
93
-
94
- var textOffset = 0; // offset in the NEW text node
95
-
96
- textDiffs.forEach(function (_ref) {
97
- var _ref2 = _slicedToArray(_ref, 2),
98
- operation = _ref2[0],
99
- text = _ref2[1];
100
- if (operation === -1) {
101
- // Delete
102
- // The widget should be placed at the current position in the new text.
103
- var diffItem = {
104
- type: 'delete',
105
- path: _toConsumableArray(path),
106
- textDiff: {
107
- offset: textOffset,
108
- length: text.length,
109
- text: text,
110
- operation: operation
111
- }
112
- };
113
- diffs.push(diffItem);
114
- // DO NOT advance textOffset
115
- } else if (operation === 1) {
116
- // Insert
117
- var _diffItem = {
118
- type: 'insert',
119
- path: _toConsumableArray(path),
120
- textDiff: {
121
- offset: textOffset,
122
- length: text.length,
123
- text: text,
124
- operation: operation
125
- }
126
- };
127
- diffs.push(_diffItem);
128
- textOffset += text.length; // DO advance textOffset
129
- } else {
130
- // Equal
131
- textOffset += text.length; // DO advance textOffset
132
- }
133
- });
134
- }
135
- // 文本相等或不相等时都可检查 marks 差异(粗粒度:节点级)
136
- if (!haveSameMarks(nodeA.marks, nodeB.marks)) {
137
- diffs.push({
138
- type: 'modify',
139
- path: _toConsumableArray(path),
140
- attrChange: {
141
- key: 'marks',
142
- oldValue: nodeA.marks || [],
143
- newValue: nodeB.marks || []
144
- }
145
- });
146
- }
147
- return diffs;
148
- }
149
-
150
- // 优先:段落/标题等内联容器执行字符级 diff 和 marks 区间对比
151
- if (nodeA && nodeB && isInlineContainer(nodeA) && isInlineContainer(nodeB)) {
152
- // 文本与 marks 的字符级 diff
153
- diffs.push.apply(diffs, _toConsumableArray(compareInlineContainer(nodeA, nodeB, path)));
154
- // 非文本内联节点(如行内数学、行内公式等)的结构化对比
155
- diffs.push.apply(diffs, _toConsumableArray(compareInlineContainerChildren(nodeA, nodeB, path)));
156
- return diffs;
157
- }
158
-
159
- // 对比节点属性
160
- var attrsA = (nodeA === null || nodeA === void 0 ? void 0 : nodeA.attrs) || {};
161
- var attrsB = (nodeB === null || nodeB === void 0 ? void 0 : nodeB.attrs) || {};
162
- var allAttrKeys = new Set([].concat(_toConsumableArray(Object.keys(attrsA)), _toConsumableArray(Object.keys(attrsB))));
163
- for (var _i = 0, _Array$from = Array.from(allAttrKeys); _i < _Array$from.length; _i++) {
164
- var key = _Array$from[_i];
165
- if (attrsA[key] !== attrsB[key]) {
166
- diffs.push({
167
- type: 'modify',
168
- path: _toConsumableArray(path),
169
- attrChange: {
170
- key: key,
171
- oldValue: attrsA[key],
172
- newValue: attrsB[key]
173
- }
174
- });
175
- }
176
- }
177
-
178
- // 使用 LCS 对齐子节点,减少错配
179
- var contentA = (nodeA === null || nodeA === void 0 ? void 0 : nodeA.content) || [];
180
- var contentB = (nodeB === null || nodeB === void 0 ? void 0 : nodeB.content) || [];
181
- var pairs = lcsAlign(contentA, contentB, nodesEqualForAlign);
182
- var ai = 0;
183
- var bi = 0;
184
- for (var _i2 = 0, _pairs = pairs; _i2 < _pairs.length; _i2++) {
185
- var _pairs$_i = _slicedToArray(_pairs[_i2], 2),
186
- i = _pairs$_i[0],
187
- j = _pairs$_i[1];
188
- // 先处理 A 中未匹配(删除),以 B 的当前位置作为锚点
189
- while (ai < i) {
190
- var delNode = contentA[ai];
191
- diffs.push({
192
- type: 'delete',
193
- path: [].concat(_toConsumableArray(path), [bi]),
194
- node: delNode
195
- });
196
- ai++;
197
- }
198
- // 再处理 B 中未匹配(插入)
199
- while (bi < j) {
200
- var insNode = contentB[bi];
201
- diffs.push({
202
- type: 'insert',
203
- path: [].concat(_toConsumableArray(path), [bi]),
204
- node: insNode
205
- });
206
- bi++;
207
- }
208
- // 匹配上的成对递归,路径以新文档索引为准
209
- var childA = contentA[i];
210
- var childB = contentB[j];
211
- diffs.push.apply(diffs, _toConsumableArray(compareNodes(childA, childB, [].concat(_toConsumableArray(path), [j]))));
212
- ai = i + 1;
213
- bi = j + 1;
214
- }
215
- // 处理尾部剩余未匹配项
216
- while (ai < contentA.length) {
217
- var _delNode = contentA[ai];
218
- diffs.push({
219
- type: 'delete',
220
- path: [].concat(_toConsumableArray(path), [bi]),
221
- node: _delNode
222
- });
223
- ai++;
224
- }
225
- while (bi < contentB.length) {
226
- var _insNode = contentB[bi];
227
- diffs.push({
228
- type: 'insert',
229
- path: [].concat(_toConsumableArray(path), [bi]),
230
- node: _insNode
231
- });
232
- bi++;
233
- }
234
- return diffs;
235
- }
236
51
  function isInlineContainer(node) {
237
52
  return node.type === 'paragraph' || node.type === 'heading';
238
53
  }
@@ -275,13 +90,12 @@ function compareInlineContainer(nodeA, nodeB, path) {
275
90
  dmp.diff_cleanupSemantic(blocks);
276
91
  var oldOffset = 0;
277
92
  var newOffset = 0;
278
- for (var _i3 = 0, _arr = blocks; _i3 < _arr.length; _i3++) {
279
- var _arr$_i = _slicedToArray(_arr[_i3], 2),
93
+ for (var _i = 0, _arr = blocks; _i < _arr.length; _i++) {
94
+ var _arr$_i = _slicedToArray(_arr[_i], 2),
280
95
  operation = _arr$_i[0],
281
96
  text = _arr$_i[1];
282
97
  var len = text.length;
283
98
  if (operation === -1) {
284
- // 删除:在新文本当前位置放置删除widget
285
99
  diffs.push({
286
100
  type: 'delete',
287
101
  path: _toConsumableArray(path),
@@ -294,7 +108,6 @@ function compareInlineContainer(nodeA, nodeB, path) {
294
108
  });
295
109
  oldOffset += len;
296
110
  } else if (operation === 1) {
297
- // 插入:直接在新文本当前位置标注
298
111
  diffs.push({
299
112
  type: 'insert',
300
113
  path: _toConsumableArray(path),
@@ -307,7 +120,6 @@ function compareInlineContainer(nodeA, nodeB, path) {
307
120
  });
308
121
  newOffset += len;
309
122
  } else {
310
- // 相等:检测 marks 差异并生成区间级 modify
311
123
  var runStart = null;
312
124
  for (var i = 0; i < len; i++) {
313
125
  var oldIdx = oldOffset + i;
@@ -331,16 +143,16 @@ function compareInlineContainer(nodeA, nodeB, path) {
331
143
  }
332
144
  }
333
145
  if (runStart !== null) {
334
- var _i4 = len;
146
+ var _i2 = len;
335
147
  diffs.push({
336
148
  type: 'modify',
337
149
  path: _toConsumableArray(path),
338
150
  attrChange: {
339
151
  key: 'marks',
340
- oldValue: oldMarks.slice(oldOffset + runStart, oldOffset + _i4),
341
- newValue: newMarks.slice(newOffset + runStart, newOffset + _i4),
152
+ oldValue: oldMarks.slice(oldOffset + runStart, oldOffset + _i2),
153
+ newValue: newMarks.slice(newOffset + runStart, newOffset + _i2),
342
154
  fromOffset: newOffset + runStart,
343
- toOffset: newOffset + _i4
155
+ toOffset: newOffset + _i2
344
156
  }
345
157
  });
346
158
  }
@@ -350,31 +162,6 @@ function compareInlineContainer(nodeA, nodeB, path) {
350
162
  }
351
163
  return diffs;
352
164
  }
353
- function nodesEqualForAlign(a, b) {
354
- if (!a || !b) return false;
355
- if (a.type !== b.type) return false;
356
- // 对部分结构节点使用关键属性辅助匹配
357
- if (a.type === 'heading') {
358
- var _a$attrs$level, _a$attrs, _b$attrs$level, _b$attrs;
359
- return ((_a$attrs$level = (_a$attrs = a.attrs) === null || _a$attrs === void 0 ? void 0 : _a$attrs.level) !== null && _a$attrs$level !== void 0 ? _a$attrs$level : null) === ((_b$attrs$level = (_b$attrs = b.attrs) === null || _b$attrs === void 0 ? void 0 : _b$attrs.level) !== null && _b$attrs$level !== void 0 ? _b$attrs$level : null);
360
- }
361
- if (a.type === 'codeBlock' || a.type === 'code_block') {
362
- var _ref3, _a$attrs$language, _a$attrs2, _a$attrs3, _ref4, _b$attrs$language, _b$attrs2, _b$attrs3;
363
- var langA = (_ref3 = (_a$attrs$language = (_a$attrs2 = a.attrs) === null || _a$attrs2 === void 0 ? void 0 : _a$attrs2.language) !== null && _a$attrs$language !== void 0 ? _a$attrs$language : (_a$attrs3 = a.attrs) === null || _a$attrs3 === void 0 ? void 0 : _a$attrs3.lang) !== null && _ref3 !== void 0 ? _ref3 : null;
364
- var langB = (_ref4 = (_b$attrs$language = (_b$attrs2 = b.attrs) === null || _b$attrs2 === void 0 ? void 0 : _b$attrs2.language) !== null && _b$attrs$language !== void 0 ? _b$attrs$language : (_b$attrs3 = b.attrs) === null || _b$attrs3 === void 0 ? void 0 : _b$attrs3.lang) !== null && _ref4 !== void 0 ? _ref4 : null;
365
- return langA === langB;
366
- }
367
- if (a.type === 'table_cell' || a.type === 'tableHeader' || a.type === 'table_header') {
368
- var _a$attrs$colspan, _a$attrs4, _b$attrs$colspan, _b$attrs4, _a$attrs$rowspan, _a$attrs5, _b$attrs$rowspan, _b$attrs5;
369
- var colspanA = (_a$attrs$colspan = (_a$attrs4 = a.attrs) === null || _a$attrs4 === void 0 ? void 0 : _a$attrs4.colspan) !== null && _a$attrs$colspan !== void 0 ? _a$attrs$colspan : 1;
370
- var colspanB = (_b$attrs$colspan = (_b$attrs4 = b.attrs) === null || _b$attrs4 === void 0 ? void 0 : _b$attrs4.colspan) !== null && _b$attrs$colspan !== void 0 ? _b$attrs$colspan : 1;
371
- var rowspanA = (_a$attrs$rowspan = (_a$attrs5 = a.attrs) === null || _a$attrs5 === void 0 ? void 0 : _a$attrs5.rowspan) !== null && _a$attrs$rowspan !== void 0 ? _a$attrs$rowspan : 1;
372
- var rowspanB = (_b$attrs$rowspan = (_b$attrs5 = b.attrs) === null || _b$attrs5 === void 0 ? void 0 : _b$attrs5.rowspan) !== null && _b$attrs$rowspan !== void 0 ? _b$attrs$rowspan : 1;
373
- return colspanA === colspanB && rowspanA === rowspanB;
374
- }
375
- // 默认仅按类型
376
- return true;
377
- }
378
165
  function compareInlineContainerChildren(nodeA, nodeB, path) {
379
166
  var diffs = [];
380
167
  var aList = (nodeA.content || []).map(function (n, idx) {
@@ -395,17 +182,15 @@ function compareInlineContainerChildren(nodeA, nodeB, path) {
395
182
  });
396
183
  var equals = function equals(x, y) {
397
184
  if (!x || !y) return false;
398
- // 仅按类型对齐,属性差异作为 modify 处理
399
185
  return x.n.type === y.n.type;
400
186
  };
401
187
  var pairs = lcsAlign(aList, bList, equals);
402
188
  var ai = 0,
403
189
  bi = 0;
404
- for (var _i5 = 0, _pairs2 = pairs; _i5 < _pairs2.length; _i5++) {
405
- var _pairs2$_i = _slicedToArray(_pairs2[_i5], 2),
406
- i = _pairs2$_i[0],
407
- j = _pairs2$_i[1];
408
- // 删除:使用新文档当前位置作为锚点路径
190
+ for (var _i3 = 0, _pairs = pairs; _i3 < _pairs.length; _i3++) {
191
+ var _pairs$_i = _slicedToArray(_pairs[_i3], 2),
192
+ i = _pairs$_i[0],
193
+ j = _pairs$_i[1];
409
194
  while (ai < i) {
410
195
  var del = aList[ai];
411
196
  var anchorIdx = bi < bList.length ? bList[bi].idx : nodeB.content ? nodeB.content.length : 0;
@@ -416,7 +201,6 @@ function compareInlineContainerChildren(nodeA, nodeB, path) {
416
201
  });
417
202
  ai++;
418
203
  }
419
- // 插入:直接使用新文档该节点的实际索引
420
204
  while (bi < j) {
421
205
  var ins = bList[bi];
422
206
  diffs.push({
@@ -426,7 +210,6 @@ function compareInlineContainerChildren(nodeA, nodeB, path) {
426
210
  });
427
211
  bi++;
428
212
  }
429
- // modify:同类型节点进行属性对比,路径指向新文档该内联节点索引
430
213
  var aItem = aList[i];
431
214
  var bItem = bList[j];
432
215
  if (aItem && bItem) {
@@ -447,8 +230,6 @@ function compareInlineContainerChildren(nodeA, nodeB, path) {
447
230
  ai = i + 1;
448
231
  bi = j + 1;
449
232
  }
450
-
451
- // 尾部删除
452
233
  while (ai < aList.length) {
453
234
  var _del = aList[ai++];
454
235
  var _anchorIdx = bi < bList.length ? bList[bi].idx : nodeB.content ? nodeB.content.length : 0;
@@ -458,7 +239,6 @@ function compareInlineContainerChildren(nodeA, nodeB, path) {
458
239
  node: _del.n
459
240
  });
460
241
  }
461
- // 尾部插入
462
242
  while (bi < bList.length) {
463
243
  var _ins = bList[bi++];
464
244
  diffs.push({
@@ -469,6 +249,29 @@ function compareInlineContainerChildren(nodeA, nodeB, path) {
469
249
  }
470
250
  return diffs;
471
251
  }
252
+ function nodesEqualForAlign(a, b) {
253
+ if (!a || !b) return false;
254
+ if (a.type !== b.type) return false;
255
+ if (a.type === 'heading') {
256
+ var _a$attrs$level, _a$attrs, _b$attrs$level, _b$attrs;
257
+ return ((_a$attrs$level = (_a$attrs = a.attrs) === null || _a$attrs === void 0 ? void 0 : _a$attrs.level) !== null && _a$attrs$level !== void 0 ? _a$attrs$level : null) === ((_b$attrs$level = (_b$attrs = b.attrs) === null || _b$attrs === void 0 ? void 0 : _b$attrs.level) !== null && _b$attrs$level !== void 0 ? _b$attrs$level : null);
258
+ }
259
+ if (a.type === 'codeBlock' || a.type === 'code_block') {
260
+ var _ref, _a$attrs$language, _a$attrs2, _a$attrs3, _ref2, _b$attrs$language, _b$attrs2, _b$attrs3;
261
+ var langA = (_ref = (_a$attrs$language = (_a$attrs2 = a.attrs) === null || _a$attrs2 === void 0 ? void 0 : _a$attrs2.language) !== null && _a$attrs$language !== void 0 ? _a$attrs$language : (_a$attrs3 = a.attrs) === null || _a$attrs3 === void 0 ? void 0 : _a$attrs3.lang) !== null && _ref !== void 0 ? _ref : null;
262
+ var langB = (_ref2 = (_b$attrs$language = (_b$attrs2 = b.attrs) === null || _b$attrs2 === void 0 ? void 0 : _b$attrs2.language) !== null && _b$attrs$language !== void 0 ? _b$attrs$language : (_b$attrs3 = b.attrs) === null || _b$attrs3 === void 0 ? void 0 : _b$attrs3.lang) !== null && _ref2 !== void 0 ? _ref2 : null;
263
+ return langA === langB;
264
+ }
265
+ if (a.type === 'table_cell' || a.type === 'tableHeader' || a.type === 'table_header') {
266
+ var _a$attrs$colspan, _a$attrs4, _b$attrs$colspan, _b$attrs4, _a$attrs$rowspan, _a$attrs5, _b$attrs$rowspan, _b$attrs5;
267
+ var colspanA = (_a$attrs$colspan = (_a$attrs4 = a.attrs) === null || _a$attrs4 === void 0 ? void 0 : _a$attrs4.colspan) !== null && _a$attrs$colspan !== void 0 ? _a$attrs$colspan : 1;
268
+ var colspanB = (_b$attrs$colspan = (_b$attrs4 = b.attrs) === null || _b$attrs4 === void 0 ? void 0 : _b$attrs4.colspan) !== null && _b$attrs$colspan !== void 0 ? _b$attrs$colspan : 1;
269
+ var rowspanA = (_a$attrs$rowspan = (_a$attrs5 = a.attrs) === null || _a$attrs5 === void 0 ? void 0 : _a$attrs5.rowspan) !== null && _a$attrs$rowspan !== void 0 ? _a$attrs$rowspan : 1;
270
+ var rowspanB = (_b$attrs$rowspan = (_b$attrs5 = b.attrs) === null || _b$attrs5 === void 0 ? void 0 : _b$attrs5.rowspan) !== null && _b$attrs$rowspan !== void 0 ? _b$attrs$rowspan : 1;
271
+ return colspanA === colspanB && rowspanA === rowspanB;
272
+ }
273
+ return true;
274
+ }
472
275
  function lcsAlign(a, b, equals) {
473
276
  var n = a.length;
474
277
  var m = b.length;
@@ -477,9 +280,9 @@ function lcsAlign(a, b, equals) {
477
280
  }, function () {
478
281
  return Array(m + 1).fill(0);
479
282
  });
480
- for (var _i6 = n - 1; _i6 >= 0; _i6--) {
283
+ for (var _i4 = n - 1; _i4 >= 0; _i4--) {
481
284
  for (var _j = m - 1; _j >= 0; _j--) {
482
- dp[_i6][_j] = equals(a[_i6], b[_j]) ? 1 + dp[_i6 + 1][_j + 1] : Math.max(dp[_i6 + 1][_j], dp[_i6][_j + 1]);
285
+ dp[_i4][_j] = equals(a[_i4], b[_j]) ? 1 + dp[_i4 + 1][_j + 1] : Math.max(dp[_i4 + 1][_j], dp[_i4][_j + 1]);
483
286
  }
484
287
  }
485
288
  var pairs = [];
@@ -498,51 +301,212 @@ function lcsAlign(a, b, equals) {
498
301
  }
499
302
  return pairs;
500
303
  }
501
-
502
- /**
503
- * 对比两个HTML文档并生成结构化差异
504
- * @param {string} oldHtml - 旧HTML
505
- * @param {string} newHtml - 新HTML
506
- * @param {Array} extensions - Tiptap扩展数组
507
- * @returns {Object} 包含差异信息的对象
508
- */
304
+ function compareNodes(nodeA, nodeB) {
305
+ var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
306
+ var diffs = [];
307
+ if ((nodeA === null || nodeA === void 0 ? void 0 : nodeA.type) !== (nodeB === null || nodeB === void 0 ? void 0 : nodeB.type)) {
308
+ if (nodeA) {
309
+ diffs.push({
310
+ type: 'delete',
311
+ path: _toConsumableArray(path),
312
+ node: nodeA
313
+ });
314
+ }
315
+ if (nodeB) {
316
+ diffs.push({
317
+ type: 'insert',
318
+ path: _toConsumableArray(path),
319
+ node: nodeB
320
+ });
321
+ }
322
+ return diffs;
323
+ }
324
+ if ((nodeA === null || nodeA === void 0 ? void 0 : nodeA.type) === 'text' && (nodeB === null || nodeB === void 0 ? void 0 : nodeB.type) === 'text') {
325
+ if (nodeA.text !== nodeB.text) {
326
+ var textDiffs = dmp.diff_main(nodeA.text || '', nodeB.text || '');
327
+ dmp.diff_cleanupSemantic(textDiffs);
328
+ var textOffset = 0;
329
+ textDiffs.forEach(function (_ref3) {
330
+ var _ref4 = _slicedToArray(_ref3, 2),
331
+ operation = _ref4[0],
332
+ text = _ref4[1];
333
+ if (operation === -1) {
334
+ var diffItem = {
335
+ type: 'delete',
336
+ path: _toConsumableArray(path),
337
+ textDiff: {
338
+ offset: textOffset,
339
+ length: text.length,
340
+ text: text,
341
+ operation: operation
342
+ }
343
+ };
344
+ diffs.push(diffItem);
345
+ } else if (operation === 1) {
346
+ var _diffItem = {
347
+ type: 'insert',
348
+ path: _toConsumableArray(path),
349
+ textDiff: {
350
+ offset: textOffset,
351
+ length: text.length,
352
+ text: text,
353
+ operation: operation
354
+ }
355
+ };
356
+ diffs.push(_diffItem);
357
+ textOffset += text.length;
358
+ } else {
359
+ textOffset += text.length;
360
+ }
361
+ });
362
+ }
363
+ if (!haveSameMarks(nodeA.marks, nodeB.marks)) {
364
+ diffs.push({
365
+ type: 'modify',
366
+ path: _toConsumableArray(path),
367
+ attrChange: {
368
+ key: 'marks',
369
+ oldValue: nodeA.marks || [],
370
+ newValue: nodeB.marks || []
371
+ }
372
+ });
373
+ }
374
+ return diffs;
375
+ }
376
+ if (nodeA && nodeB && isInlineContainer(nodeA) && isInlineContainer(nodeB)) {
377
+ diffs.push.apply(diffs, _toConsumableArray(compareInlineContainer(nodeA, nodeB, path)));
378
+ diffs.push.apply(diffs, _toConsumableArray(compareInlineContainerChildren(nodeA, nodeB, path)));
379
+ return diffs;
380
+ }
381
+ var attrsA = (nodeA === null || nodeA === void 0 ? void 0 : nodeA.attrs) || {};
382
+ var attrsB = (nodeB === null || nodeB === void 0 ? void 0 : nodeB.attrs) || {};
383
+ var allAttrKeys = new Set([].concat(_toConsumableArray(Object.keys(attrsA)), _toConsumableArray(Object.keys(attrsB))));
384
+ for (var _i5 = 0, _Array$from = Array.from(allAttrKeys); _i5 < _Array$from.length; _i5++) {
385
+ var key = _Array$from[_i5];
386
+ if (attrsA[key] !== attrsB[key]) {
387
+ diffs.push({
388
+ type: 'modify',
389
+ path: _toConsumableArray(path),
390
+ attrChange: {
391
+ key: key,
392
+ oldValue: attrsA[key],
393
+ newValue: attrsB[key]
394
+ }
395
+ });
396
+ }
397
+ }
398
+ var contentA = (nodeA === null || nodeA === void 0 ? void 0 : nodeA.content) || [];
399
+ var contentB = (nodeB === null || nodeB === void 0 ? void 0 : nodeB.content) || [];
400
+ var pairs = lcsAlign(contentA, contentB, nodesEqualForAlign);
401
+ var ai = 0;
402
+ var bi = 0;
403
+ var _iterator3 = _createForOfIteratorHelper(pairs),
404
+ _step3;
405
+ try {
406
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
407
+ var _step3$value = _slicedToArray(_step3.value, 2),
408
+ i = _step3$value[0],
409
+ j = _step3$value[1];
410
+ while (ai < i) {
411
+ var _delNode = contentA[ai];
412
+ diffs.push({
413
+ type: 'delete',
414
+ path: [].concat(_toConsumableArray(path), [bi]),
415
+ node: _delNode
416
+ });
417
+ ai++;
418
+ }
419
+ while (bi < j) {
420
+ var _insNode = contentB[bi];
421
+ diffs.push({
422
+ type: 'insert',
423
+ path: [].concat(_toConsumableArray(path), [bi]),
424
+ node: _insNode
425
+ });
426
+ bi++;
427
+ }
428
+ var childA = contentA[i];
429
+ var childB = contentB[j];
430
+ diffs.push.apply(diffs, _toConsumableArray(compareNodes(childA, childB, [].concat(_toConsumableArray(path), [j]))));
431
+ ai = i + 1;
432
+ bi = j + 1;
433
+ }
434
+ } catch (err) {
435
+ _iterator3.e(err);
436
+ } finally {
437
+ _iterator3.f();
438
+ }
439
+ while (ai < contentA.length) {
440
+ var delNode = contentA[ai];
441
+ diffs.push({
442
+ type: 'delete',
443
+ path: [].concat(_toConsumableArray(path), [bi]),
444
+ node: delNode
445
+ });
446
+ ai++;
447
+ }
448
+ while (bi < contentB.length) {
449
+ var insNode = contentB[bi];
450
+ diffs.push({
451
+ type: 'insert',
452
+ path: [].concat(_toConsumableArray(path), [bi]),
453
+ node: insNode
454
+ });
455
+ bi++;
456
+ }
457
+ return diffs;
458
+ }
509
459
  export function compareDocuments(oldHtml, newHtml, extensions) {
510
- var docA = parseHtmlToDoc(oldHtml, extensions);
511
- var docB = parseHtmlToDoc(newHtml, extensions);
512
- var diffs = compareNodes(docA, docB);
513
- return {
514
- oldDoc: docA,
515
- newDoc: docB,
516
- diffs: diffs,
517
- hasChanges: diffs.length > 0
518
- };
460
+ try {
461
+ var docA = parseHtmlToDoc(oldHtml, extensions);
462
+ var docB = parseHtmlToDoc(newHtml, extensions);
463
+ var diffs = compareNodes(docA, docB);
464
+ return {
465
+ oldDoc: docA,
466
+ newDoc: docB,
467
+ diffs: diffs,
468
+ hasChanges: diffs.length > 0
469
+ };
470
+ } catch (error) {
471
+ console.error('对比文档时出错:', error);
472
+ return {
473
+ oldDoc: null,
474
+ newDoc: null,
475
+ diffs: [],
476
+ hasChanges: false
477
+ };
478
+ }
519
479
  }
520
-
521
- /**
522
- * 将路径转换为ProseMirror位置
523
- * @param {Array} path - 节点路径
524
- * @param {Object} doc - ProseMirror文档
525
- * @returns {number} 文档位置
526
- */
527
480
  export function pathToPos(path, doc) {
481
+ if (!path || path.length === 0) {
482
+ return 0;
483
+ }
484
+ if (!doc) {
485
+ throw new Error('文档节点不能为空');
486
+ }
528
487
  var pos = 0;
529
488
  var current = doc;
530
489
  for (var i = 0; i < path.length; i++) {
531
- var _current$childCount;
490
+ var _current$type, _current$childCount;
532
491
  var index = path[i];
533
- var contentStartOffset = current.type.name === 'doc' ? 0 : 1;
492
+ var contentStartOffset = ((_current$type = current.type) === null || _current$type === void 0 ? void 0 : _current$type.name) === 'doc' ? 0 : 1;
534
493
  var resolvedPos = pos + contentStartOffset;
535
494
  var childCount = (_current$childCount = current.childCount) !== null && _current$childCount !== void 0 ? _current$childCount : 0;
536
495
  var effectiveIndex = Math.min(index, childCount);
537
496
  for (var j = 0; j < effectiveIndex; j++) {
538
497
  var child = current.child(j);
498
+ if (!child) {
499
+ break;
500
+ }
539
501
  resolvedPos += child.nodeSize;
540
502
  }
541
503
  pos = resolvedPos;
542
504
  if (index < childCount) {
543
505
  current = current.child(index);
506
+ if (!current) {
507
+ break;
508
+ }
544
509
  } else {
545
- // Path points past the end in this doc (likely a deletion). Stop descending
546
510
  break;
547
511
  }
548
512
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctzhian/tiptap",
3
- "version": "2.1.13",
3
+ "version": "2.1.15",
4
4
  "description": "基于 Tiptap 二次开发的编辑器组件",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",