@mdxeditor/editor 4.0.4 → 4.1.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.
Files changed (40) hide show
  1. package/dist/MDXEditor.js +138 -53
  2. package/dist/RealmWithPlugins.js +27 -9
  3. package/dist/exportMarkdownFromLexical.js +1 -1
  4. package/dist/index.d.ts +12 -10
  5. package/dist/index.js +6 -6
  6. package/dist/mdastUtilHtmlComment.js +2 -1
  7. package/dist/plugins/codeblock/CodeBlockNode.js +4 -5
  8. package/dist/plugins/codeblock/index.js +1 -1
  9. package/dist/plugins/codemirror/CodeMirrorEditor.js +1 -1
  10. package/dist/plugins/core/GenericHTMLNode.js +2 -5
  11. package/dist/plugins/core/NestedLexicalEditor.js +58 -38
  12. package/dist/plugins/core/index.js +26 -30
  13. package/dist/plugins/core/lexicalExtensions.js +143 -0
  14. package/dist/plugins/diff-source/SourceEditor.js +1 -1
  15. package/dist/plugins/directives/DirectiveNode.js +1 -4
  16. package/dist/plugins/frontmatter/FrontmatterNode.js +1 -4
  17. package/dist/plugins/frontmatter/index.js +1 -1
  18. package/dist/plugins/headings/index.js +2 -1
  19. package/dist/plugins/image/ImageDialog.js +1 -2
  20. package/dist/plugins/image/ImageEditor.js +1 -2
  21. package/dist/plugins/image/ImageNode.js +1 -4
  22. package/dist/plugins/image/index.js +4 -6
  23. package/dist/plugins/jsx/LexicalJsxNode.js +1 -4
  24. package/dist/plugins/jsx/LexicalMdxExpressionNode.js +1 -4
  25. package/dist/plugins/link-dialog/LinkDialog.js +3 -3
  26. package/dist/plugins/link-dialog/index.js +16 -4
  27. package/dist/plugins/lists/index.js +3 -3
  28. package/dist/plugins/markdown-shortcut/index.js +1 -1
  29. package/dist/plugins/search/index.js +259 -179
  30. package/dist/plugins/table/TableEditor.js +38 -24
  31. package/dist/plugins/table/TableNode.js +1 -4
  32. package/dist/plugins/thematic-break/LexicalThematicBreakVisitor.js +2 -2
  33. package/dist/plugins/toolbar/components/KitchenSinkToolbar.js +1 -1
  34. package/dist/plugins/toolbar/primitives/toolbar.js +1 -1
  35. package/dist/realmSession.js +38 -0
  36. package/dist/style.css +1511 -1525
  37. package/dist/utils/lexicalHelpers.js +53 -74
  38. package/package.json +23 -12
  39. package/dist/plugins/core/SharedHistoryPlugin.js +0 -10
  40. package/dist/styles/globals.css.js +0 -1
@@ -1,10 +1,10 @@
1
1
  import { realmPlugin } from "../../RealmWithPlugins.js";
2
- import { createEmptyHistoryState } from "@lexical/react/LexicalHistoryPlugin.js";
2
+ import { createEmptyHistoryState } from "@lexical/history";
3
3
  import { $isHeadingNode } from "@lexical/rich-text";
4
4
  import { $setBlocksType } from "@lexical/selection";
5
5
  import { $findMatchingParent, $wrapNodeInElement, $insertNodeToNearestRoot } from "@lexical/utils";
6
- import { Cell, Signal, withLatestFrom, filter, map, useCellValue, scan } from "@mdxeditor/gurx";
7
- import { createCommand, FORMAT_TEXT_COMMAND, $isRootOrShadowRoot, $getRoot, $setSelection, $getSelection, $insertNodes, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, DecoratorNode, $createParagraphNode, FOCUS_COMMAND, BLUR_COMMAND, $isRangeSelection, createEditor, ParagraphNode, TextNode } from "lexical";
6
+ import { Signal, Cell, withLatestFrom, map, filter, useCellValue, scan } from "@mdxeditor/gurx";
7
+ import { createCommand, FORMAT_TEXT_COMMAND, $getSelection, $isRangeSelection, BLUR_COMMAND, COMMAND_PRIORITY_CRITICAL, SELECTION_CHANGE_COMMAND, $getRoot, DecoratorNode, $createParagraphNode, FOCUS_COMMAND, $isRootOrShadowRoot, $insertNodes, $setSelection, ParagraphNode, TextNode } from "lexical";
8
8
  import { gfmStrikethrough } from "micromark-extension-gfm-strikethrough";
9
9
  import { gfmStrikethroughToMarkdown, gfmStrikethroughFromMarkdown } from "mdast-util-gfm-strikethrough";
10
10
  import { highlightMarkToMarkdown, highlightMarkFromMarkdown } from "mdast-util-highlight-mark";
@@ -28,9 +28,10 @@ import { MdastHTMLVisitor } from "./MdastHTMLVisitor.js";
28
28
  import { MdastParagraphVisitor } from "./MdastParagraphVisitor.js";
29
29
  import { MdastRootVisitor } from "./MdastRootVisitor.js";
30
30
  import { MdastTextVisitor } from "./MdastTextVisitor.js";
31
- import { SharedHistoryPlugin } from "./SharedHistoryPlugin.js";
32
31
  import { comment, commentFromMarkdown } from "../../mdastUtilHtmlComment.js";
33
32
  import { lexicalTheme } from "../../styles/lexicalTheme.js";
33
+ import { registerRealmCleanup } from "../../realmSession.js";
34
+ import { createExtensionEditor } from "./lexicalExtensions.js";
34
35
  const NESTED_EDITOR_UPDATED_COMMAND = createCommand("NESTED_EDITOR_UPDATED_COMMAND");
35
36
  const rootEditor$ = Cell(null);
36
37
  const activeEditor$ = Cell(null);
@@ -536,6 +537,7 @@ const corePlugin = realmPlugin({
536
537
  [placeholder$]: params == null ? void 0 : params.placeholder,
537
538
  [readOnly$]: params == null ? void 0 : params.readOnly,
538
539
  [translation$]: params == null ? void 0 : params.translation,
540
+ [historyState$]: createEmptyHistoryState(),
539
541
  [addMdastExtension$]: [gfmStrikethroughFromMarkdown(), highlightMarkFromMarkdown],
540
542
  [addSyntaxExtension$]: [gfmStrikethrough(), highlightMark()],
541
543
  [addToMarkdownExtension$]: [mdxJsxToMarkdown(), gfmStrikethroughToMarkdown(), highlightMarkToMarkdown],
@@ -553,39 +555,33 @@ const corePlugin = realmPlugin({
553
555
  [addImportVisitor$]: MdastHTMLVisitor
554
556
  });
555
557
  }
556
- if (!(params == null ? void 0 : params.suppressSharedHistory)) {
557
- r.pub(addComposerChild$, SharedHistoryPlugin);
558
- }
559
558
  },
560
559
  postInit(r, params) {
561
- const newEditor = createEditor({
562
- // ...(params?.editorState ? { editorState: params.editorState } : {}),
560
+ const newEditor = createExtensionEditor({
561
+ name: "@mdxeditor/root",
563
562
  editable: (params == null ? void 0 : params.readOnly) !== true,
564
563
  namespace: (params == null ? void 0 : params.lexicalEditorNamespace) ?? "MDXEditor",
565
564
  nodes: [...r.getValue(usedLexicalNodes$), ...(params == null ? void 0 : params.additionalLexicalNodes) ?? []],
566
- onError: (error) => {
567
- throw error;
568
- },
569
- theme: r.getValue(lexicalTheme$)
570
- });
571
- if ((params == null ? void 0 : params.editorState) !== null) {
572
- newEditor.update(() => {
565
+ theme: r.getValue(lexicalTheme$),
566
+ historyMode: (params == null ? void 0 : params.suppressSharedHistory) ? "none" : "root-shared",
567
+ historyState: r.getValue(historyState$),
568
+ initialEditorState: (params == null ? void 0 : params.editorState) === null ? null : () => {
573
569
  const markdown = (params == null ? void 0 : params.initialMarkdown.trim()) ?? "";
574
570
  tryImportingMarkdown(r, $getRoot(), markdown);
575
- const autoFocusValue = params == null ? void 0 : params.autoFocus;
576
- if (autoFocusValue) {
577
- if (autoFocusValue === true) {
578
- setTimeout(() => {
579
- newEditor.focus(noop, { defaultSelection: "rootStart" });
580
- });
581
- return;
582
- }
583
- setTimeout(() => {
584
- newEditor.focus(noop, {
585
- defaultSelection: autoFocusValue.defaultSelection ?? "rootStart"
586
- });
587
- });
588
- }
571
+ }
572
+ });
573
+ registerRealmCleanup(r, () => {
574
+ newEditor.dispose();
575
+ });
576
+ const autoFocusValue = params == null ? void 0 : params.autoFocus;
577
+ if ((params == null ? void 0 : params.editorState) !== null && autoFocusValue) {
578
+ const autoFocusTimer = setTimeout(() => {
579
+ newEditor.focus(noop, {
580
+ defaultSelection: autoFocusValue === true ? "rootStart" : autoFocusValue.defaultSelection ?? "rootStart"
581
+ });
582
+ });
583
+ registerRealmCleanup(r, () => {
584
+ clearTimeout(autoFocusTimer);
589
585
  });
590
586
  }
591
587
  r.pub(rootEditor$, newEditor);
@@ -0,0 +1,143 @@
1
+ import { InitialStateExtension, NestedEditorExtension, buildEditorFromExtensions, getPeerDependencyFromEditor } from "@lexical/extension";
2
+ import { SharedHistoryExtension, HistoryExtension } from "@lexical/history";
3
+ import { ReactExtension } from "@lexical/react/ReactExtension";
4
+ import { ReactProviderExtension } from "@lexical/react/ReactProviderExtension";
5
+ import { configExtension, HISTORIC_TAG, defineExtension, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, FOCUS_COMMAND, COMMAND_PRIORITY_LOW, RootNode, TextNode, LineBreakNode, TabNode, ParagraphNode } from "lexical";
6
+ const editorsWithSharedHistory = /* @__PURE__ */ new WeakSet();
7
+ const editorHistoryStates = /* @__PURE__ */ new WeakMap();
8
+ const extensionBuiltinNodes = /* @__PURE__ */ new Set([RootNode, TextNode, LineBreakNode, TabNode, ParagraphNode]);
9
+ const meaningfulHistoryEntries = /* @__PURE__ */ new WeakMap();
10
+ function externalHistoryExtension(historyState) {
11
+ return configExtension(HistoryExtension, {
12
+ createInitialHistoryState: () => historyState,
13
+ disabled: false
14
+ });
15
+ }
16
+ function createExtensionEditor({
17
+ name,
18
+ namespace,
19
+ nodes,
20
+ theme,
21
+ editable = true,
22
+ parentEditor,
23
+ historyMode,
24
+ historyState,
25
+ initialEditorState,
26
+ onError = (error) => {
27
+ throw error;
28
+ }
29
+ }) {
30
+ const dependencies = [
31
+ ReactProviderExtension,
32
+ configExtension(ReactExtension, { contentEditable: null }),
33
+ configExtension(InitialStateExtension, {
34
+ setOptions: { tag: HISTORIC_TAG },
35
+ updateOptions: { tag: HISTORIC_TAG }
36
+ })
37
+ ];
38
+ if (parentEditor) {
39
+ dependencies.push(
40
+ configExtension(NestedEditorExtension, {
41
+ $getParentEditor: () => parentEditor,
42
+ inheritEditableFromParent: true
43
+ })
44
+ );
45
+ }
46
+ if (historyMode === "nested-shared") {
47
+ dependencies.push(SharedHistoryExtension);
48
+ } else if (historyMode === "root-shared" || historyMode === "nested-external") {
49
+ if (!historyState) {
50
+ throw new Error(`${historyMode} requires a historyState`);
51
+ }
52
+ dependencies.push(externalHistoryExtension(historyState));
53
+ } else if (historyMode === "table-local") {
54
+ dependencies.push(configExtension(HistoryExtension, { disabled: false }));
55
+ }
56
+ const editorExtension = defineExtension({
57
+ name,
58
+ namespace,
59
+ // InitialStateExtension already declares Lexical's built-ins. Filtering
60
+ // them here also prevents Vite's optimized extension bundle from seeing
61
+ // the same built-in constructor through two module facades.
62
+ nodes: nodes == null ? void 0 : nodes.filter((node) => !extensionBuiltinNodes.has(node)),
63
+ theme,
64
+ editable,
65
+ $initialEditorState: initialEditorState,
66
+ onError,
67
+ dependencies
68
+ });
69
+ const editor = buildEditorFromExtensions(editorExtension);
70
+ const historyDependency = getPeerDependencyFromEditor(editor, HistoryExtension.name);
71
+ const editorHistoryState = historyDependency == null ? void 0 : historyDependency.output.historyState.value;
72
+ if (editorHistoryState) {
73
+ editorHistoryStates.set(editor, editorHistoryState);
74
+ }
75
+ if (editorHistoryState) {
76
+ if (!meaningfulHistoryEntries.has(editorHistoryState)) {
77
+ meaningfulHistoryEntries.set(editorHistoryState, editorHistoryState.current);
78
+ }
79
+ }
80
+ const unregisterHistoryFocusGuard = editorHistoryState ? editor.registerUpdateListener(({ dirtyElements, dirtyLeaves, tags }) => {
81
+ const current = editorHistoryState.current;
82
+ if (tags.has(HISTORIC_TAG)) {
83
+ meaningfulHistoryEntries.set(editorHistoryState, current);
84
+ return;
85
+ }
86
+ if (dirtyElements.size > 0 || dirtyLeaves.size > 0) {
87
+ meaningfulHistoryEntries.set(editorHistoryState, current);
88
+ return;
89
+ }
90
+ const meaningfulEntry = meaningfulHistoryEntries.get(editorHistoryState);
91
+ if ((current == null ? void 0 : current.editor) === editor && meaningfulEntry && meaningfulEntry.editor !== editor) {
92
+ editorHistoryState.undoStack.push({ ...meaningfulEntry });
93
+ editorHistoryState.redoStack = [];
94
+ editor.dispatchCommand(CAN_UNDO_COMMAND, true);
95
+ editor.dispatchCommand(CAN_REDO_COMMAND, false);
96
+ meaningfulHistoryEntries.set(editorHistoryState, current);
97
+ } else {
98
+ meaningfulHistoryEntries.set(editorHistoryState, current);
99
+ }
100
+ }) : () => void 0;
101
+ const availabilityTimers = /* @__PURE__ */ new Set();
102
+ const unregisterHistoryAvailability = editorHistoryState ? editor.registerCommand(
103
+ FOCUS_COMMAND,
104
+ () => {
105
+ const timer = setTimeout(() => {
106
+ availabilityTimers.delete(timer);
107
+ editor.dispatchCommand(CAN_UNDO_COMMAND, editorHistoryState.undoStack.length > 0);
108
+ editor.dispatchCommand(CAN_REDO_COMMAND, editorHistoryState.redoStack.length > 0);
109
+ });
110
+ availabilityTimers.add(timer);
111
+ return false;
112
+ },
113
+ COMMAND_PRIORITY_LOW
114
+ ) : () => void 0;
115
+ const dispose = editor.dispose.bind(editor);
116
+ let disposed = false;
117
+ editor.dispose = () => {
118
+ if (disposed) {
119
+ return;
120
+ }
121
+ disposed = true;
122
+ availabilityTimers.forEach(clearTimeout);
123
+ availabilityTimers.clear();
124
+ unregisterHistoryAvailability();
125
+ unregisterHistoryFocusGuard();
126
+ dispose();
127
+ };
128
+ if (historyMode === "root-shared") {
129
+ editorsWithSharedHistory.add(editor);
130
+ }
131
+ return editor;
132
+ }
133
+ function editorHasSharedHistory(editor) {
134
+ return editorsWithSharedHistory.has(editor);
135
+ }
136
+ function editorUsesHistoryState(editor, historyState) {
137
+ return editorHistoryStates.get(editor) === historyState;
138
+ }
139
+ export {
140
+ createExtensionEditor,
141
+ editorHasSharedHistory,
142
+ editorUsesHistoryState
143
+ };
@@ -1,6 +1,6 @@
1
1
  import { markdown } from "@codemirror/lang-markdown";
2
2
  import { EditorState } from "@codemirror/state";
3
- import { lineNumbers, EditorView } from "@codemirror/view";
3
+ import { EditorView, lineNumbers } from "@codemirror/view";
4
4
  import { basicLight } from "cm6-theme-basic-light";
5
5
  import { basicSetup } from "codemirror";
6
6
  import React__default from "react";
@@ -1,9 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
4
  import React__default from "react";
8
5
  import { DecoratorNode } from "lexical";
9
6
  import { NestedEditorsContext } from "../core/NestedLexicalEditor.js";
@@ -1,9 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
4
  import { DecoratorNode } from "lexical";
8
5
  import React__default from "react";
9
6
  import { FrontmatterEditor } from "./FrontmatterEditor.js";
@@ -1,5 +1,5 @@
1
1
  import { realmPlugin } from "../../RealmWithPlugins.js";
2
- import { rootEditor$, createRootEditorSubscription$, addToMarkdownExtension$, addExportVisitor$, addImportVisitor$, addLexicalNode$, addSyntaxExtension$, addMdastExtension$ } from "../core/index.js";
2
+ import { createRootEditorSubscription$, rootEditor$, addToMarkdownExtension$, addExportVisitor$, addImportVisitor$, addLexicalNode$, addSyntaxExtension$, addMdastExtension$ } from "../core/index.js";
3
3
  import { Cell, Action, withLatestFrom } from "@mdxeditor/gurx";
4
4
  import { $getRoot, KEY_DOWN_COMMAND, $getSelection, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_CRITICAL } from "lexical";
5
5
  import { frontmatterToMarkdown, frontmatterFromMarkdown } from "mdast-util-frontmatter";
@@ -44,13 +44,14 @@ const allowedHeadingLevels$ = Cell(ALL_HEADING_LEVELS, (r) => {
44
44
  });
45
45
  });
46
46
  const headingsPlugin = realmPlugin({
47
- init(realm) {
47
+ init(realm, params) {
48
48
  realm.pubIn({
49
49
  [addActivePlugin$]: "headings",
50
50
  [addImportVisitor$]: MdastHeadingVisitor,
51
51
  [addLexicalNode$]: HeadingNode,
52
52
  [addExportVisitor$]: LexicalHeadingVisitor
53
53
  });
54
+ realm.pub(allowedHeadingLevels$, (params == null ? void 0 : params.allowedHeadingLevels) ?? ALL_HEADING_LEVELS);
54
55
  },
55
56
  update(realm, params) {
56
57
  realm.pub(allowedHeadingLevels$, (params == null ? void 0 : params.allowedHeadingLevels) ?? ALL_HEADING_LEVELS);
@@ -25,8 +25,7 @@ const ImageDialog = () => {
25
25
  const resetFormState = () => {
26
26
  reset({ src: "", title: "", altText: "", width: void 0, height: void 0 });
27
27
  };
28
- if (state.type === "inactive")
29
- return null;
28
+ if (state.type === "inactive") return null;
30
29
  return /* @__PURE__ */ React__default.createElement(
31
30
  Dialog.Root,
32
31
  {
@@ -132,8 +132,7 @@ function ImageEditor({ src, title, alt, nodeKey, width, height, rest }) {
132
132
  React__default.useEffect(() => {
133
133
  if (imagePreviewHandler) {
134
134
  const callPreviewHandler = async () => {
135
- if (!initialImagePath)
136
- setInitialImagePath(src);
135
+ if (!initialImagePath) setInitialImagePath(src);
137
136
  const updatedSrc = await imagePreviewHandler(src);
138
137
  setImageSource(updatedSrc);
139
138
  };
@@ -1,9 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
4
  import React__default from "react";
8
5
  import { DecoratorNode } from "lexical";
9
6
  import { ImageEditor } from "./ImageEditor.js";
@@ -1,13 +1,13 @@
1
1
  import { ImagePlaceholder } from "./ImagePlaceholder.js";
2
2
  import { mergeRegister, $wrapNodeInElement } from "@lexical/utils";
3
- import { Signal, Cell, Action, withLatestFrom, mapTo, map } from "@mdxeditor/gurx";
3
+ import { Cell, Action, mapTo, withLatestFrom, Signal, map } from "@mdxeditor/gurx";
4
4
  import { createCommand, $getNodeByKey, $insertNodes, $isRootOrShadowRoot, $createParagraphNode, COMMAND_PRIORITY_EDITOR, DRAGSTART_COMMAND, COMMAND_PRIORITY_HIGH, DRAGOVER_COMMAND, COMMAND_PRIORITY_LOW, DROP_COMMAND, PASTE_COMMAND, COMMAND_PRIORITY_CRITICAL, $createRangeSelection, $setSelection, $getSelection, $isNodeSelection } from "lexical";
5
5
  import { realmPlugin } from "../../RealmWithPlugins.js";
6
6
  import { CAN_USE_DOM } from "../../utils/detectMac.js";
7
7
  import { activeEditor$, createActiveEditorSubscription$, addComposerChild$, addExportVisitor$, addLexicalNode$, addImportVisitor$ } from "../core/index.js";
8
8
  import { EditImageToolbar } from "./EditImageToolbar.js";
9
9
  import { ImageDialog } from "./ImageDialog.js";
10
- import { $createImageNode, ImageNode, $isImageNode } from "./ImageNode.js";
10
+ import { $createImageNode, $isImageNode, ImageNode } from "./ImageNode.js";
11
11
  import { LexicalImageVisitor } from "./LexicalImageVisitor.js";
12
12
  import { MdastImageVisitor, MdastHtmlImageVisitor, MdastJsxImageVisitor } from "./MdastImageVisitor.js";
13
13
  const internalInsertImage$ = Signal((r) => {
@@ -129,8 +129,7 @@ const imageDialogState$ = Cell(
129
129
  }
130
130
  const cbPayload = Array.from(((_b = event.clipboardData) == null ? void 0 : _b.items) ?? []);
131
131
  const isMixedPayload = cbPayload.some((item) => !item.type.includes("image"));
132
- if (isMixedPayload)
133
- return false;
132
+ if (isMixedPayload) return false;
134
133
  if (!cbPayload.length || cbPayload.length === 0) {
135
134
  return false;
136
135
  }
@@ -173,8 +172,7 @@ const allowSetImageDimensions$ = Cell(false);
173
172
  const saveImage$ = Signal();
174
173
  const editImageToolbarComponent$ = Cell(EditImageToolbar);
175
174
  const parseImageDimension = (value) => {
176
- if (typeof value === "undefined")
177
- return void 0;
175
+ if (typeof value === "undefined") return void 0;
178
176
  const parsed = parseInt(String(value), 10);
179
177
  return Number.isNaN(parsed) ? void 0 : parsed;
180
178
  };
@@ -1,9 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
4
  import { DecoratorNode } from "lexical";
8
5
  import React__default from "react";
9
6
  import { NestedEditorsContext } from "../core/NestedLexicalEditor.js";
@@ -1,9 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
4
  import React__default from "react";
8
5
  import { DecoratorNode, $applyNodeReplacement } from "lexical";
9
6
  import lexicalThemeStyles from "../../styles/lexical-theme.module.css.js";
@@ -128,8 +128,7 @@ const LinkDialog = () => {
128
128
  }, [activeEditor, publishWindowChange]);
129
129
  const [copyUrlTooltipOpen, setCopyUrlTooltipOpen] = React__default.useState(false);
130
130
  const t = useTranslation();
131
- if (linkDialogState.type === "inactive")
132
- return null;
131
+ if (linkDialogState.type === "inactive") return null;
133
132
  const theRect = linkDialogState.rectangle;
134
133
  const urlIsExternal = linkDialogState.type === "preview" && linkDialogState.url.startsWith("http");
135
134
  return /* @__PURE__ */ React__default.createElement(RadixPopover.Root, { open: true }, /* @__PURE__ */ React__default.createElement(
@@ -171,7 +170,8 @@ const LinkDialog = () => {
171
170
  "a",
172
171
  {
173
172
  className: styles.linkDialogPreviewAnchor,
174
- href: linkDialogState.url,
173
+ "data-testid": "link-dialog-preview",
174
+ href: linkDialogState.href ?? "about:blank",
175
175
  ...urlIsExternal ? { target: "_blank", rel: "noreferrer" } : {},
176
176
  onClick: (e) => {
177
177
  if (onClickLinkCallback !== null) {
@@ -1,5 +1,5 @@
1
1
  import { $isLinkNode, $createLinkNode, $isAutoLinkNode, TOGGLE_LINK_COMMAND, LinkNode } from "@lexical/link";
2
- import { Signal, Cell, Action, withLatestFrom, map, filter } from "@mdxeditor/gurx";
2
+ import { Action, Cell, withLatestFrom, map, Signal, filter } from "@mdxeditor/gurx";
3
3
  import { KEY_ESCAPE_COMMAND, COMMAND_PRIORITY_LOW, KEY_DOWN_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_HIGH, $getNodeByKey, $createTextNode, $insertNodes, $isTextNode, $getNearestNodeFromDOMNode } from "lexical";
4
4
  import { realmPlugin } from "../../RealmWithPlugins.js";
5
5
  import { IS_APPLE } from "../../utils/detectMac.js";
@@ -23,6 +23,16 @@ function getLinkNodeInSelection(selection) {
23
23
  }
24
24
  return null;
25
25
  }
26
+ function getPreviewHref(editor, linkNodeKey, url) {
27
+ if (!editor) return "about:blank";
28
+ return editor.getEditorState().read(() => {
29
+ const keyedNode = linkNodeKey === "" ? null : $getNodeByKey(linkNodeKey);
30
+ const selection = $getSelection();
31
+ const selectedNode = $isRangeSelection(selection) ? getLinkNodeInSelection(selection) : null;
32
+ const linkNode = $isLinkNode(keyedNode) ? keyedNode : selectedNode;
33
+ return (linkNode == null ? void 0 : linkNode.sanitizeUrl(url)) ?? "about:blank";
34
+ });
35
+ }
26
36
  const onWindowChange$ = Signal();
27
37
  const linkDialogState$ = Cell({ type: "inactive" }, (r) => {
28
38
  r.pub(createActiveEditorSubscription$, (editor) => {
@@ -129,7 +139,8 @@ const linkDialogState$ = Cell({ type: "inactive" }, (r) => {
129
139
  linkNodeKey: state.linkNodeKey,
130
140
  rectangle: state.rectangle,
131
141
  title,
132
- url
142
+ url,
143
+ href: getPreviewHref(editor, state.linkNodeKey ?? "", url)
133
144
  });
134
145
  } else {
135
146
  if (state.type === "edit" && state.initialUrl !== "") {
@@ -155,6 +166,7 @@ const linkDialogState$ = Cell({ type: "inactive" }, (r) => {
155
166
  return {
156
167
  type: "preview",
157
168
  url: state.initialUrl,
169
+ href: getPreviewHref(editor, state.linkNodeKey, state.initialUrl),
158
170
  linkNodeKey: state.linkNodeKey,
159
171
  rectangle: state.rectangle
160
172
  };
@@ -173,8 +185,7 @@ const linkDialogState$ = Cell({ type: "inactive" }, (r) => {
173
185
  map(([[selection], activeEditor, _, readOnly]) => {
174
186
  if ($isRangeSelection(selection) && activeEditor && !readOnly) {
175
187
  const node = getLinkNodeInSelection(selection);
176
- if (!selection.isCollapsed())
177
- return { type: "inactive" };
188
+ if (!selection.isCollapsed()) return { type: "inactive" };
178
189
  if (node) {
179
190
  const rect = getSelectionRectangle(activeEditor);
180
191
  if (!rect) {
@@ -183,6 +194,7 @@ const linkDialogState$ = Cell({ type: "inactive" }, (r) => {
183
194
  return {
184
195
  type: "preview",
185
196
  url: node.getURL(),
197
+ href: node.sanitizeUrl(node.getURL()),
186
198
  linkNodeKey: node.getKey(),
187
199
  title: node.getTitle(),
188
200
  rectangle: rect
@@ -1,9 +1,9 @@
1
- import { currentSelection$, activeEditor$, rootEditor$, addNestedEditorChild$, addComposerChild$, addToMarkdownExtension$, addExportVisitor$, addLexicalNode$, addImportVisitor$, addSyntaxExtension$, addMdastExtension$, addActivePlugin$ } from "../core/index.js";
1
+ import { activeEditor$, currentSelection$, rootEditor$, addNestedEditorChild$, addComposerChild$, addToMarkdownExtension$, addExportVisitor$, addLexicalNode$, addImportVisitor$, addSyntaxExtension$, addMdastExtension$, addActivePlugin$ } from "../core/index.js";
2
2
  import { MdastListVisitor } from "./MdastListVisitor.js";
3
3
  import { MdastListItemVisitor } from "./MdastListItemVisitor.js";
4
4
  import { LexicalListVisitor } from "./LexicalListVisitor.js";
5
5
  import { LexicalListItemVisitor } from "./LexicalListItemVisitor.js";
6
- import { $isListNode, ListNode, ListItemNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, REMOVE_LIST_COMMAND, $getListDepth, $isListItemNode } from "@lexical/list";
6
+ import { $isListNode, ListNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, REMOVE_LIST_COMMAND, ListItemNode, $getListDepth, $isListItemNode } from "@lexical/list";
7
7
  import { $isRootOrShadowRoot, INDENT_CONTENT_COMMAND, COMMAND_PRIORITY_CRITICAL, $getSelection, $isRangeSelection, $isElementNode } from "lexical";
8
8
  import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin.js";
9
9
  import { CheckListPlugin } from "@lexical/react/LexicalCheckListPlugin.js";
@@ -11,7 +11,7 @@ import { ListPlugin } from "@lexical/react/LexicalListPlugin.js";
11
11
  import { $findMatchingParent, $getNearestNodeOfType } from "@lexical/utils";
12
12
  import { gfmTaskListItem } from "micromark-extension-gfm-task-list-item";
13
13
  import { gfmTaskListItemToMarkdown, gfmTaskListItemFromMarkdown } from "mdast-util-gfm-task-list-item";
14
- import { Cell, Signal, withLatestFrom } from "@mdxeditor/gurx";
14
+ import { Signal, withLatestFrom, Cell } from "@mdxeditor/gurx";
15
15
  import { realmPlugin } from "../../RealmWithPlugins.js";
16
16
  const ListTypeCommandMap = /* @__PURE__ */ new Map([
17
17
  ["number", INSERT_ORDERED_LIST_COMMAND],
@@ -1,5 +1,5 @@
1
1
  import React__default from "react";
2
- import { BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, INLINE_CODE, ITALIC_STAR, ITALIC_UNDERSCORE, QUOTE, LINK, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST, CODE } from "@lexical/markdown";
2
+ import { ORDERED_LIST, UNORDERED_LIST, CHECK_LIST, BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, INLINE_CODE, ITALIC_STAR, ITALIC_UNDERSCORE, QUOTE, LINK, CODE } from "@lexical/markdown";
3
3
  import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
4
4
  import { HeadingNode, $isHeadingNode, $createHeadingNode } from "@lexical/rich-text";
5
5
  import { realmPlugin } from "../../RealmWithPlugins.js";