@lobehub/editor 4.24.0 → 4.25.0

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.
Files changed (144) hide show
  1. package/es/codemirror/style.js +42 -0
  2. package/es/editor-kernel/kernel.js +3 -0
  3. package/es/editor-kernel/react/useDecorators.js +2 -4
  4. package/es/headless/collapsible-plugin.js +74 -0
  5. package/es/headless/index.js +2 -0
  6. package/es/headless.d.ts +18 -0
  7. package/es/headless.js +2479 -71
  8. package/es/index.d.ts +26 -3
  9. package/es/index.js +17 -2
  10. package/es/locale/index.d.ts +14 -0
  11. package/es/locale/index.js +14 -0
  12. package/es/plugins/block/command/index.js +24 -0
  13. package/es/plugins/block/plugin/index.js +7 -5
  14. package/es/plugins/block/react/ReactBlockPlugin.js +43 -1
  15. package/es/plugins/block/react/core/menu-position.js +20 -0
  16. package/es/plugins/block/react/drag/drag-session.js +3 -2
  17. package/es/plugins/block/react/drag/drag-utils.js +13 -1
  18. package/es/plugins/codemirror-block/index.d.ts +2 -1
  19. package/es/plugins/codemirror-block/plugin/index.js +2 -0
  20. package/es/plugins/codemirror-block/react/CodemirrorNode.js +95 -5
  21. package/es/plugins/codemirror-block/react/useCodemirrorEditLock.js +33 -0
  22. package/es/plugins/codemirror-block/service/index.d.ts +40 -0
  23. package/es/plugins/codemirror-block/service/index.js +59 -0
  24. package/es/plugins/collapsible/command/index.d.ts +17 -0
  25. package/es/plugins/collapsible/command/index.js +72 -0
  26. package/es/plugins/collapsible/index.d.ts +7 -0
  27. package/es/plugins/collapsible/node/CollapsibleNode.d.ts +30 -0
  28. package/es/plugins/collapsible/node/CollapsibleNode.js +138 -0
  29. package/es/plugins/collapsible/plugin/index.d.ts +11 -0
  30. package/es/plugins/collapsible/plugin/index.js +535 -0
  31. package/es/plugins/collapsible/react/ReactCollapsiblePlugin.d.ts +6 -0
  32. package/es/plugins/collapsible/react/ReactCollapsiblePlugin.js +19 -0
  33. package/es/plugins/collapsible/react/index.d.ts +3 -0
  34. package/es/plugins/collapsible/react/style.js +67 -0
  35. package/es/plugins/collapsible/react/type.d.ts +6 -0
  36. package/es/plugins/common/plugin/index.js +3 -2
  37. package/es/plugins/common/plugin/progressive-select-all.js +81 -0
  38. package/es/plugins/common/plugin/register.js +73 -4
  39. package/es/plugins/link/command/index.js +26 -3
  40. package/es/plugins/link/conversion/index.js +237 -0
  41. package/es/plugins/link/index.d.ts +5 -3
  42. package/es/plugins/link/node/LinkBlockCardNode.d.ts +16 -0
  43. package/es/plugins/link/node/LinkBlockCardNode.js +66 -0
  44. package/es/plugins/link/node/LinkCardNode.d.ts +42 -0
  45. package/es/plugins/link/node/LinkCardNode.js +161 -0
  46. package/es/plugins/link/node/LinkIframeNode.d.ts +33 -0
  47. package/es/plugins/link/node/LinkIframeNode.js +131 -0
  48. package/es/plugins/link/node/LinkNode.d.ts +48 -2
  49. package/es/plugins/link/node/LinkNode.js +14 -6
  50. package/es/plugins/link/node/SchemaNode.d.ts +36 -0
  51. package/es/plugins/link/node/SchemaNode.js +149 -0
  52. package/es/plugins/link/normalization/index.d.ts +7 -0
  53. package/es/plugins/link/normalization/index.js +38 -0
  54. package/es/plugins/link/plugin/index.d.ts +26 -1
  55. package/es/plugins/link/plugin/index.js +124 -4
  56. package/es/plugins/link/react/ReactLinkPlugin.js +165 -7
  57. package/es/plugins/link/react/components/LinkCard.js +235 -0
  58. package/es/plugins/link/react/components/LinkEdit.js +93 -14
  59. package/es/plugins/link/react/components/LinkIframe.js +128 -0
  60. package/es/plugins/link/react/components/LinkToolbar.js +440 -111
  61. package/es/plugins/link/react/components/SchemaLink.js +49 -0
  62. package/es/plugins/link/react/index.d.ts +2 -2
  63. package/es/plugins/link/react/renderer-registry.d.ts +81 -0
  64. package/es/plugins/link/react/renderer-registry.js +80 -0
  65. package/es/plugins/link/react/style.js +63 -1
  66. package/es/plugins/link/react/type.d.ts +24 -1
  67. package/es/plugins/link/service/i-link-service.d.ts +156 -1
  68. package/es/plugins/link/service/i-link-service.js +258 -5
  69. package/es/plugins/list/plugin/index.js +9 -2
  70. package/es/plugins/litexml/command/diffCommand.js +94 -14
  71. package/es/plugins/litexml/command/index.js +187 -6
  72. package/es/plugins/litexml/diff-validation.js +237 -0
  73. package/es/plugins/litexml/node/DiffContentNode.js +67 -0
  74. package/es/plugins/litexml/node/DiffNode.d.ts +1 -1
  75. package/es/plugins/litexml/node/DiffNode.js +5 -2
  76. package/es/plugins/litexml/node/TableCellDiffNode.js +77 -0
  77. package/es/plugins/litexml/node/TableRowDiffNode.js +73 -0
  78. package/es/plugins/litexml/plugin/index.d.ts +2 -0
  79. package/es/plugins/litexml/plugin/index.js +62 -9
  80. package/es/plugins/litexml/react/DiffNodeToolbar/index.js +10 -12
  81. package/es/plugins/litexml/react/TableRowDiffToolbar.js +123 -0
  82. package/es/plugins/litexml/react/hooks/useHasDiffNode.js +5 -2
  83. package/es/plugins/litexml/react/index.js +6 -2
  84. package/es/plugins/litexml/react/style.js +18 -5
  85. package/es/plugins/litexml/table-cell-diff.js +153 -0
  86. package/es/plugins/litexml/table-row-diff.js +82 -0
  87. package/es/plugins/markdown/data-source/markdown/parse.js +25 -1
  88. package/es/plugins/markdown/plugin/index.js +5 -3
  89. package/es/plugins/slash/react/ReactSlashPlugin.js +22 -43
  90. package/es/plugins/slash/react/components/DefaultSlashMenu.js +76 -16
  91. package/es/plugins/slash/react/menu-utils.js +84 -0
  92. package/es/plugins/slash/service/i-slash-service.d.ts +3 -0
  93. package/es/plugins/table/plugin/index.js +4 -1
  94. package/es/plugins/table/plugin/single-cell-paste.js +79 -0
  95. package/es/plugins/table/react/TableController/hooks.js +7 -4
  96. package/es/plugins/table/react/hooks.js +2 -2
  97. package/es/plugins/table/react/index.js +2 -0
  98. package/es/plugins/table/react/style.js +15 -5
  99. package/es/plugins/table/react/useScrollFocusedTableCellIntoView.js +46 -0
  100. package/es/plugins/toc/index.d.ts +10 -0
  101. package/es/plugins/toc/plugin/index.d.ts +8 -0
  102. package/es/plugins/toc/plugin/index.js +56 -0
  103. package/es/plugins/toc/react/ReactTocPlugin.d.ts +6 -0
  104. package/es/plugins/toc/react/ReactTocPlugin.js +36 -0
  105. package/es/plugins/toc/react/getNearestScrollContainer.d.ts +6 -0
  106. package/es/plugins/toc/react/getNearestScrollContainer.js +18 -0
  107. package/es/plugins/toc/react/hooks/useActiveHeading.js +59 -0
  108. package/es/plugins/toc/react/hooks/useTocItems.js +50 -0
  109. package/es/plugins/toc/react/index.d.ts +5 -0
  110. package/es/plugins/toc/react/type.d.ts +30 -0
  111. package/es/plugins/toc/react/useToc.d.ts +5 -0
  112. package/es/plugins/toc/react/useToc.js +41 -0
  113. package/es/plugins/toc/service/i-toc-service.d.ts +39 -0
  114. package/es/plugins/toc/service/i-toc-service.js +125 -0
  115. package/es/plugins/toc/service/index.d.ts +3 -0
  116. package/es/plugins/toc/types.d.ts +23 -0
  117. package/es/plugins/toc/utils/index.d.ts +6 -0
  118. package/es/plugins/toc/utils/index.js +30 -0
  119. package/es/plugins/toolbar/react/index.js +26 -12
  120. package/es/plugins/toolbar/react/style.js +3 -2
  121. package/es/plugins/virtual-block/plugin/register.js +34 -12
  122. package/es/plugins/yjs/index.d.ts +6 -0
  123. package/es/plugins/yjs/plugin/index.d.ts +7 -0
  124. package/es/plugins/yjs/plugin/index.js +191 -0
  125. package/es/plugins/yjs/plugin/types.d.ts +16 -0
  126. package/es/plugins/yjs/plugin/utils/awareness.js +9 -0
  127. package/es/plugins/yjs/plugin/utils/editor-state.js +47 -0
  128. package/es/plugins/yjs/plugin/utils/history.js +31 -0
  129. package/es/plugins/yjs/plugin/utils/node-properties.js +39 -0
  130. package/es/plugins/yjs/plugin/utils/sync.js +24 -0
  131. package/es/plugins/yjs/react/codemirrorEditLockProvider.js +59 -0
  132. package/es/plugins/yjs/react/index.d.ts +23 -0
  133. package/es/plugins/yjs/react/index.js +200 -0
  134. package/es/plugins/yjs/service/index.d.ts +47 -0
  135. package/es/plugins/yjs/service/index.js +84 -0
  136. package/es/plugins/yjs/websocket-provider.d.ts +78 -0
  137. package/es/plugins/yjs/websocket-provider.js +263 -0
  138. package/es/renderer/LexicalRenderer.js +9 -2
  139. package/es/renderer/engine/render-builtin-node.js +17 -8
  140. package/es/types/kernel.d.ts +4 -0
  141. package/es/utils/updatePosition.js +5 -2
  142. package/package.json +3 -1
  143. package/patches/@lexical__yjs@0.42.0.patch +42 -0
  144. package/scripts/postinstall-lexical-patch.cjs +62 -36
@@ -50,6 +50,48 @@ const styles = createStaticStyles(({ css, cssVar }) => css`
50
50
  transition: all 0.3s;
51
51
  }
52
52
 
53
+ &.collab-locked {
54
+ cursor: not-allowed;
55
+ }
56
+
57
+ &.collab-locked::after {
58
+ pointer-events: none;
59
+ content: '';
60
+
61
+ position: absolute;
62
+ z-index: 11;
63
+ inset: 0;
64
+
65
+ background: ${cssVar.colorFillSecondary};
66
+ }
67
+
68
+ &.collab-locked .cm-container {
69
+ opacity: 0.72;
70
+ }
71
+
72
+ .cm-collab-lock {
73
+ position: absolute;
74
+ z-index: 12;
75
+ inset-block-start: 8px;
76
+ inset-inline-end: 8px;
77
+
78
+ overflow: hidden;
79
+
80
+ max-width: min(240px, calc(100% - 16px));
81
+ padding-block: 2px;
82
+ padding-inline: 6px;
83
+ border-radius: 6px;
84
+
85
+ font-size: 12px;
86
+ line-height: 18px;
87
+ color: ${cssVar.colorTextSecondary};
88
+ text-overflow: ellipsis;
89
+ white-space: nowrap;
90
+
91
+ background: ${cssVar.colorBgElevated};
92
+ box-shadow: ${cssVar.boxShadowTertiary};
93
+ }
94
+
53
95
  .cm-container {
54
96
  position: relative;
55
97
  width: 100%;
@@ -246,6 +246,9 @@ var init_kernel = __esmMin((() => {
246
246
  this.historyState.current = null;
247
247
  }
248
248
  datasource.read(this.editor, content, options);
249
+ this.pluginsInstances.forEach((plugin) => {
250
+ plugin.onDocumentChange?.(type, content, options);
251
+ });
249
252
  this.emit("documentChange", type, content);
250
253
  this.logger.debug(`📥 Set ${type} document`);
251
254
  }
@@ -1,7 +1,7 @@
1
1
  import { CAN_USE_DOM } from "../../common/canUseDOM.js";
2
2
  import { Suspense, useEffect, useLayoutEffect, useMemo, useState } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
- import { createPortal, flushSync } from "react-dom";
4
+ import { createPortal } from "react-dom";
5
5
  //#region src/editor-kernel/react/useDecorators.tsx
6
6
  const useLayoutEffectImpl = CAN_USE_DOM ? useLayoutEffect : useEffect;
7
7
  function useDecorators(editor, ErrorBoundary) {
@@ -12,9 +12,7 @@ function useDecorators(editor, ErrorBoundary) {
12
12
  const initialDecorators = editor.getDecorators();
13
13
  setDecorators(initialDecorators);
14
14
  clears.push(editor.registerDecoratorListener((nextDecorators) => {
15
- flushSync(() => {
16
- setDecorators(nextDecorators);
17
- });
15
+ setDecorators(nextDecorators);
18
16
  }));
19
17
  };
20
18
  const lexicalEditor = editor.getLexicalEditor();
@@ -0,0 +1,74 @@
1
+ import { INodeHelper, init_helper } from "../editor-kernel/inode/helper.js";
2
+ import { KernelPlugin, init_plugin } from "../editor-kernel/plugin.js";
3
+ import { ILitexmlService } from "../plugins/litexml/service/litexml-service.js";
4
+ import { IMarkdownShortCutService } from "../plugins/markdown/service/shortcut.js";
5
+ import { $isCollapsibleNode, CollapsibleNode } from "../plugins/collapsible/node/CollapsibleNode.js";
6
+ //#region src/headless/collapsible-plugin.ts
7
+ init_helper();
8
+ init_plugin();
9
+ const HeadlessCollapsiblePlugin = class extends KernelPlugin {
10
+ static {
11
+ this.pluginName = "HeadlessCollapsiblePlugin";
12
+ }
13
+ constructor(kernel) {
14
+ super();
15
+ this.kernel = kernel;
16
+ kernel.registerNodes([CollapsibleNode]);
17
+ }
18
+ onInit(_editor) {
19
+ const markdownService = this.kernel.requireService(IMarkdownShortCutService);
20
+ markdownService?.registerMarkdownWriter(CollapsibleNode.getType(), (ctx, node) => {
21
+ if (!$isCollapsibleNode(node)) return false;
22
+ ctx.appendLine(`<details${node.isCollapsed() ? "" : " open"}>\n`);
23
+ ctx.appendLine(`<summary>${escapeHtml(node.getTitle())}</summary>\n\n`);
24
+ node.getChildren().slice(1).forEach((child) => ctx.processChild(ctx, child));
25
+ ctx.appendLine("\n</details>\n");
26
+ return true;
27
+ });
28
+ markdownService?.registerMarkdownReader("html", (node, children) => {
29
+ const tag = getHtmlTagName(node.value);
30
+ if (tag === "summary") return INodeHelper.createTypeNode("__collapsible_summary", { text: getNodeText(children) });
31
+ if (tag !== "details") return false;
32
+ const summaryNode = children.find((child) => child.type === "__collapsible_summary");
33
+ const contentChildren = children.filter((child) => child.type !== "__collapsible_summary");
34
+ const title = summaryNode && "text" in summaryNode && typeof summaryNode.text === "string" ? summaryNode.text : extractSummaryTitle(node.value) || "Details";
35
+ return INodeHelper.createElementNode(CollapsibleNode.getType(), {
36
+ children: ensureTitleChildren(contentChildren, title),
37
+ collapsed: !/\sopen(?:\s|>|$)/i.test(node.value),
38
+ title
39
+ });
40
+ });
41
+ const litexmlService = this.kernel.requireService(ILitexmlService);
42
+ litexmlService?.registerXMLWriter(CollapsibleNode.getType(), (node, ctx) => {
43
+ if (!$isCollapsibleNode(node)) return false;
44
+ return ctx.createXmlNode("collapsible", {
45
+ collapsed: String(node.isCollapsed()),
46
+ title: node.getTitle()
47
+ });
48
+ });
49
+ litexmlService?.registerXMLReader("collapsible", (xmlNode, children) => {
50
+ const title = xmlNode.getAttribute("title") || "Details";
51
+ return INodeHelper.createElementNode(CollapsibleNode.getType(), {
52
+ children: ensureTitleChildren(children, title),
53
+ collapsed: xmlNode.getAttribute("collapsed") === "true",
54
+ title
55
+ });
56
+ });
57
+ }
58
+ };
59
+ const getHtmlTagName = (value) => value.match(/^<\/?\s*([\da-z-]+)/i)?.[1]?.toLowerCase() || "";
60
+ const escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;");
61
+ const extractSummaryTitle = (value) => value.match(/<summary\b[^>]*>([\S\s]*?)<\/summary>/i)?.[1]?.trim() || "";
62
+ const getNodeText = (children) => children.map((child) => {
63
+ if (!child || typeof child !== "object") return "";
64
+ if ("text" in child && typeof child.text === "string") return child.text;
65
+ if ("children" in child && Array.isArray(child.children)) return getNodeText(child.children);
66
+ return "";
67
+ }).join("");
68
+ const ensureTitleChildren = (children, title) => {
69
+ const trimmedTitle = title.trim();
70
+ if (!trimmedTitle || getNodeText(children.slice(0, 1)).trim() === trimmedTitle) return children;
71
+ return [INodeHelper.createParagraph({ children: [INodeHelper.createTextNode(title)] }), ...children];
72
+ };
73
+ //#endregion
74
+ export { HeadlessCollapsiblePlugin };
@@ -15,6 +15,7 @@ import { ListPlugin } from "../plugins/list/plugin/index.js";
15
15
  import { MathPlugin } from "../plugins/math/plugin/index.js";
16
16
  import { MentionPlugin } from "../plugins/mention/plugin/index.js";
17
17
  import { TablePlugin } from "../plugins/table/plugin/index.js";
18
+ import { HeadlessCollapsiblePlugin } from "./collapsible-plugin.js";
18
19
  import { extractMediaFromEditorState } from "./extract-media-from-editor-state.js";
19
20
  //#region src/headless/index.ts
20
21
  init_utils();
@@ -118,6 +119,7 @@ const DEFAULT_HEADLESS_EDITOR_PLUGINS = [
118
119
  HRPlugin,
119
120
  ListPlugin,
120
121
  TablePlugin,
122
+ HeadlessCollapsiblePlugin,
121
123
  LitexmlPlugin
122
124
  ];
123
125
  var HeadlessEditor = class {
package/es/headless.d.ts CHANGED
@@ -79,6 +79,12 @@ declare const _default: {
79
79
  replace: string;
80
80
  };
81
81
  link: {
82
+ copy: string;
83
+ copySuccess: string;
84
+ convertToCard: string;
85
+ convertToIframe: string;
86
+ convertToLink: string;
87
+ convertToSchema: string;
82
88
  edit: string;
83
89
  editLinkTitle: string;
84
90
  editTextTitle: string;
@@ -112,6 +118,14 @@ declare const _default: {
112
118
  insertRowAbove: string;
113
119
  insertRowBelow: string;
114
120
  };
121
+ toc: {
122
+ ariaLabel: string;
123
+ empty: string;
124
+ expand: string;
125
+ pin: string;
126
+ title: string;
127
+ unpin: string;
128
+ };
115
129
  };
116
130
  //#endregion
117
131
  //#region src/types/locale.d.ts
@@ -458,6 +472,10 @@ interface IEditorPlugin<IConfig> {
458
472
  * Editor destruction
459
473
  */
460
474
  destroy(): void;
475
+ /**
476
+ * After editor document content is written by setDocument
477
+ */
478
+ onDocumentChange?(type: string, content: any, options?: IDocumentOptions): void;
461
479
  /**
462
480
  * After Lexical editor instantiation
463
481
  * @param editor Lexical editor instance