@lexical/code-core 0.44.1-nightly.20260519.0 → 0.45.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.
@@ -6,8 +6,9 @@
6
6
  *
7
7
  */
8
8
 
9
- import { getTextDirection, $isElementNode, $isTabNode, $isLineBreakNode, $getSiblingCaret, $create, ElementNode, addClassNamesToElement, setDOMStyleFromCSS, $getEditor, $isTextNode, $createTabNode, $createLineBreakNode, $createParagraphNode, isHTMLElement, $applyNodeReplacement, TextNode, removeClassNamesFromElement, defineExtension, KEY_ENTER_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_LOW, safeCast, mergeRegister, KEY_TAB_COMMAND, INSERT_TAB_COMMAND, $insertNodes, INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ARROW_DOWN_COMMAND, MOVE_TO_START, MOVE_TO_END, $createPoint, $setSelectionFromCaretRange, $getCaretRangeInDirection, $getCaretRange, $getTextPointCaret, $normalizeCaret } from 'lexical';
9
+ import { getTextDirection, $isElementNode, $isTabNode, $isLineBreakNode, $createLineBreakNode, $createTabNode, $getSiblingCaret, $create, ElementNode, addClassNamesToElement, setDOMStyleFromCSS, $getEditor, $isTextNode, $createParagraphNode, isHTMLElement, $applyNodeReplacement, TextNode, removeClassNamesFromElement, defineExtension, KEY_ENTER_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_LOW, configExtension, isDOMDocumentNode, isDOMTextNode, $generateNodesFromRawText, safeCast, mergeRegister, KEY_TAB_COMMAND, INSERT_TAB_COMMAND, $insertNodes, INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ARROW_DOWN_COMMAND, MOVE_TO_START, MOVE_TO_END, $createPoint, $setSelectionFromCaretRange, $getCaretRangeInDirection, $getCaretRange, $getTextPointCaret, $normalizeCaret } from 'lexical';
10
10
  import { getPeerDependencyFromEditor, effect, namedSignals } from '@lexical/extension';
11
+ import { CoreImportExtension, DOMImportExtension, defineImportRule, sel, ImportOverlays, defineOverlayRules } from '@lexical/html';
11
12
 
12
13
  /**
13
14
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -17,6 +18,7 @@ import { getPeerDependencyFromEditor, effect, namedSignals } from '@lexical/exte
17
18
  *
18
19
  */
19
20
 
21
+
20
22
  /*@__INLINE__*/
21
23
  function warnOnlyOnce(message) {
22
24
  {
@@ -190,6 +192,34 @@ function $getEndOfCodeInLine(anchor) {
190
192
  return lastNode;
191
193
  }
192
194
 
195
+ /**
196
+ * Plain split of code text into CodeHighlightNodes (with no highlight
197
+ * type) + LineBreakNodes + TabNodes. Used when the tokenizer opts out
198
+ * of a default language so a previously highlighted block still
199
+ * renders its `\n` / `\t` as real line breaks / tabs, while staying
200
+ * compatible with the indent / shift-lines handlers that only accept
201
+ * CodeHighlightNode + TabNode + LineBreakNode inside a CodeNode.
202
+ */
203
+ function $plainifyCodeContent(text) {
204
+ const out = [];
205
+ const lines = text.split('\n');
206
+ lines.forEach((line, lineIdx) => {
207
+ if (lineIdx > 0) {
208
+ out.push($createLineBreakNode());
209
+ }
210
+ const tabParts = line.split('\t');
211
+ tabParts.forEach((part, partIdx) => {
212
+ if (partIdx > 0) {
213
+ out.push($createTabNode());
214
+ }
215
+ if (part.length > 0) {
216
+ out.push($createCodeHighlightNode(part));
217
+ }
218
+ });
219
+ });
220
+ return out;
221
+ }
222
+
193
223
  /**
194
224
  * Strip up to `tabSize` leading spaces from a {@link CodeHighlightNode} that
195
225
  * starts a code line, to support outdenting space-indented code lines (e.g.
@@ -236,6 +266,7 @@ function $outdentLeadingSpaces(node, tabSize, selection) {
236
266
  */
237
267
 
238
268
  const DEFAULT_CODE_LANGUAGE = 'javascript';
269
+ /** @internal Configurable through the extensions. */
239
270
  const getDefaultCodeLanguage = () => DEFAULT_CODE_LANGUAGE;
240
271
  function hasChildDOMNodeTag(node, tagName) {
241
272
  for (const child of node.childNodes) {
@@ -248,7 +279,7 @@ function hasChildDOMNodeTag(node, tagName) {
248
279
  }
249
280
  return false;
250
281
  }
251
- const LANGUAGE_DATA_ATTRIBUTE = 'data-language';
282
+ const LANGUAGE_DATA_ATTRIBUTE$1 = 'data-language';
252
283
  const HIGHLIGHT_LANGUAGE_DATA_ATTRIBUTE = 'data-highlight-language';
253
284
  const THEME_DATA_ATTRIBUTE = 'data-theme';
254
285
  const noExtensionDeprecation = warnOnlyOnce('Using CodeNode without CodeExtension is deprecated');
@@ -287,7 +318,7 @@ class CodeNode extends ElementNode {
287
318
  element.setAttribute('spellcheck', 'false');
288
319
  const language = this.getLanguage();
289
320
  if (language) {
290
- element.setAttribute(LANGUAGE_DATA_ATTRIBUTE, language);
321
+ element.setAttribute(LANGUAGE_DATA_ATTRIBUTE$1, language);
291
322
  if (this.getIsSyntaxHighlightSupported()) {
292
323
  element.setAttribute(HIGHLIGHT_LANGUAGE_DATA_ATTRIBUTE, language);
293
324
  }
@@ -307,10 +338,10 @@ class CodeNode extends ElementNode {
307
338
  const prevLanguage = prevNode.__language;
308
339
  if (language) {
309
340
  if (language !== prevLanguage) {
310
- dom.setAttribute(LANGUAGE_DATA_ATTRIBUTE, language);
341
+ dom.setAttribute(LANGUAGE_DATA_ATTRIBUTE$1, language);
311
342
  }
312
343
  } else if (prevLanguage) {
313
- dom.removeAttribute(LANGUAGE_DATA_ATTRIBUTE);
344
+ dom.removeAttribute(LANGUAGE_DATA_ATTRIBUTE$1);
314
345
  }
315
346
  const isSyntaxHighlightSupported = this.__isSyntaxHighlightSupported;
316
347
  const prevIsSyntaxHighlightSupported = prevNode.__isSyntaxHighlightSupported;
@@ -347,7 +378,7 @@ class CodeNode extends ElementNode {
347
378
  element.setAttribute('spellcheck', 'false');
348
379
  const language = this.getLanguage();
349
380
  if (language) {
350
- element.setAttribute(LANGUAGE_DATA_ATTRIBUTE, language);
381
+ element.setAttribute(LANGUAGE_DATA_ATTRIBUTE$1, language);
351
382
  if (this.getIsSyntaxHighlightSupported()) {
352
383
  element.setAttribute(HIGHLIGHT_LANGUAGE_DATA_ATTRIBUTE, language);
353
384
  }
@@ -546,7 +577,7 @@ function $isCodeNode(node) {
546
577
  return node instanceof CodeNode;
547
578
  }
548
579
  function $convertPreElement(domNode) {
549
- const language = domNode.getAttribute(LANGUAGE_DATA_ATTRIBUTE);
580
+ const language = domNode.getAttribute(LANGUAGE_DATA_ATTRIBUTE$1);
550
581
  return {
551
582
  node: $createCodeNode(language)
552
583
  };
@@ -734,6 +765,331 @@ const CodeExtension = defineExtension({
734
765
  }
735
766
  });
736
767
 
768
+ /**
769
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
770
+ *
771
+ * This source code is licensed under the MIT license found in the
772
+ * LICENSE file in the root directory of this source tree.
773
+ *
774
+ */
775
+
776
+ const LANGUAGE_DATA_ATTRIBUTE = 'data-language';
777
+
778
+ /**
779
+ * True for elements whose `font-family` mentions `monospace` — the
780
+ * heuristic the legacy `<div>` rule uses to spot copy-pasted code blocks
781
+ * (e.g. Google Docs serializes a code block as a styled `<div>`).
782
+ */
783
+ function isMonospaceElement(el) {
784
+ return el.style.fontFamily.match('monospace') !== null;
785
+ }
786
+ function isMonospaceDescendant(node) {
787
+ let parent = node.parentElement;
788
+ while (parent !== null) {
789
+ if (isMonospaceElement(parent)) {
790
+ return true;
791
+ }
792
+ parent = parent.parentElement;
793
+ }
794
+ return false;
795
+ }
796
+
797
+ /**
798
+ * Overlay rules active only while {@link GitHubCodeTableRule} is
799
+ * processing its children. Inside the code-table subtree, every `<tr>`
800
+ * and `<td>` unwraps unconditionally — they never become table-row /
801
+ * table-cell nodes (even when `@lexical/table` registers its rules for
802
+ * those tags). Outside the subtree, this overlay isn't installed, so
803
+ * the cost of these rules is never paid against unrelated `<tr>` /
804
+ * `<td>` pastes.
805
+ */
806
+ const GitHubCodeTableOverlayRules = defineOverlayRules([defineImportRule({
807
+ $import: (ctx, el) => ctx.$importChildren(el),
808
+ match: sel.tag('tr', 'td'),
809
+ name: '@lexical/code/github-code-table/unwrap'
810
+ })]);
811
+ const PreRule = defineImportRule({
812
+ $import: (ctx, el) => [$createCodeNode(el.getAttribute(LANGUAGE_DATA_ATTRIBUTE)).splice(0, 0, ctx.$importChildren(el))],
813
+ match: sel.tag('pre'),
814
+ name: '@lexical/code/pre'
815
+ });
816
+
817
+ /**
818
+ * Multi-line `<code>` (containing newlines or `<br>`) is treated as a
819
+ * block code element — mirrors the legacy behavior. Single-line `<code>`
820
+ * defers to the inline-format rule from `CoreImportExtension` so it
821
+ * becomes a TextNode with IS_CODE.
822
+ */
823
+ const MultilineCodeRule = defineImportRule({
824
+ $import: (ctx, el, $next) => {
825
+ const text = el.textContent || '';
826
+ const isMultiLine = /\r?\n/.test(text) || el.querySelector('br') !== null;
827
+ if (!isMultiLine) {
828
+ return $next();
829
+ }
830
+ return [$createCodeNode(el.getAttribute(LANGUAGE_DATA_ATTRIBUTE)).splice(0, 0, ctx.$importChildren(el))];
831
+ },
832
+ match: sel.tag('code'),
833
+ name: '@lexical/code/code-multiline'
834
+ });
835
+
836
+ /**
837
+ * True for elements carrying BOTH `font-family: …monospace…` and
838
+ * `white-space: pre*` inline — the shape VS Code uses for every line
839
+ * of a copied code block (on every per-line `<div>` on Safari, on
840
+ * the single outer wrapper on Chrome).
841
+ */
842
+ function isMonospacePreElement(el) {
843
+ if (!isHTMLElement(el)) {
844
+ return false;
845
+ }
846
+ const ff = el.style.fontFamily;
847
+ const ws = el.style.whiteSpace;
848
+ return typeof ff === 'string' && /monospace/i.test(ff) && typeof ws === 'string' && ws.startsWith('pre');
849
+ }
850
+
851
+ /**
852
+ * Split a monospace-pre wrapper element into logical code lines:
853
+ * `<div>` children contribute their text content as one line,
854
+ * `<br>` children contribute an empty line, inline children (spans
855
+ * and bare text) accumulate into the current line until the next
856
+ * block child.
857
+ *
858
+ * Returns `null` if `el` has no block children (i.e. it's a leaf
859
+ * line, not a wrapper) so the caller can leave it to the
860
+ * sibling-run pass.
861
+ */
862
+ function splitMonospaceWrapperLines(el) {
863
+ let hasBlockChild = false;
864
+ const lines = [];
865
+ let acc = '';
866
+ let hasAcc = false;
867
+ const flush = () => {
868
+ if (hasAcc) {
869
+ lines.push(acc);
870
+ acc = '';
871
+ hasAcc = false;
872
+ }
873
+ };
874
+ for (const child of Array.from(el.childNodes)) {
875
+ if (isHTMLElement(child)) {
876
+ if (child.tagName === 'DIV') {
877
+ flush();
878
+ lines.push(child.textContent || '');
879
+ hasBlockChild = true;
880
+ } else if (child.tagName === 'BR') {
881
+ flush();
882
+ lines.push('');
883
+ hasBlockChild = true;
884
+ } else {
885
+ acc += child.textContent || '';
886
+ hasAcc = true;
887
+ }
888
+ } else if (isDOMTextNode(child)) {
889
+ const t = child.textContent || '';
890
+ if (t.length > 0) {
891
+ acc += t;
892
+ hasAcc = true;
893
+ }
894
+ }
895
+ }
896
+ flush();
897
+ return hasBlockChild ? lines : null;
898
+ }
899
+
900
+ /**
901
+ * Returns `true` if `root` contains the structural signature of a
902
+ * VS Code code-block paste:
903
+ *
904
+ * - a monospace+pre `<div>` wrapper with at least one block (`<div>` /
905
+ * `<br>`) child — the Chrome shape, or
906
+ * - two or more consecutive monospace+pre siblings — the Safari shape.
907
+ *
908
+ * Walked once in preprocess; the matching overlay is only installed
909
+ * when this returns `true` so an unrelated paste doesn't pay for the
910
+ * detection or rule cost.
911
+ */
912
+ function looksLikeVscodePaste(root) {
913
+ for (const child of Array.from(root.children)) {
914
+ if (isHTMLElement(child) && isMonospacePreElement(child)) {
915
+ const lines = splitMonospaceWrapperLines(child);
916
+ if (lines !== null) {
917
+ return true;
918
+ }
919
+ const next = child.nextElementSibling;
920
+ if (next && isMonospacePreElement(next)) {
921
+ return true;
922
+ }
923
+ continue;
924
+ }
925
+ if (looksLikeVscodePaste(child)) {
926
+ return true;
927
+ }
928
+ }
929
+ return false;
930
+ }
931
+
932
+ /**
933
+ * Match a monospace+pre `<div>` whose direct children include block
934
+ * (`<div>` / `<br>`) elements — the Chrome shape, one outer wrapper
935
+ * around per-line `<div>`s and `<br>`s. Emits a single CodeNode whose
936
+ * text is the wrapper's lines joined by `\n`.
937
+ */
938
+ const VscodeWrapperRule = defineImportRule({
939
+ $import: (_ctx, el, $next) => {
940
+ if (!isMonospacePreElement(el) || isMonospaceDescendant(el)) {
941
+ return $next();
942
+ }
943
+ const lines = splitMonospaceWrapperLines(el);
944
+ if (lines === null || lines.length === 0) {
945
+ return $next();
946
+ }
947
+ return [$createCodeNode().splice(0, 0, $generateNodesFromRawText(lines.join('\n')))];
948
+ },
949
+ match: sel.tag('div'),
950
+ name: '@lexical/code/vscode-wrapper'
951
+ });
952
+
953
+ /**
954
+ * Match the first of a run of consecutive monospace+pre `<div>` /
955
+ * `<br>` siblings (the Safari shape) and emit one CodeNode for the
956
+ * whole run. When the framework's per-child dispatch lands on a
957
+ * subsequent sibling in the same run, the prev-sibling check below
958
+ * returns `[]` so the run is only emitted once.
959
+ */
960
+ const VscodeLineRunRule = defineImportRule({
961
+ $import: (_ctx, el, $next) => {
962
+ if (!isMonospacePreElement(el) || isMonospaceDescendant(el)) {
963
+ return $next();
964
+ }
965
+ const prev = el.previousElementSibling;
966
+ if (prev && isMonospacePreElement(prev)) {
967
+ // An earlier sibling's walk already absorbed `el` into its run.
968
+ return [];
969
+ }
970
+ const lines = [];
971
+ let cur = el;
972
+ while (cur && isMonospacePreElement(cur)) {
973
+ lines.push(cur.tagName === 'BR' ? '' : cur.textContent || '');
974
+ cur = cur.nextElementSibling;
975
+ }
976
+ if (lines.length < 2) {
977
+ return $next();
978
+ }
979
+ return [$createCodeNode().splice(0, 0, $generateNodesFromRawText(lines.join('\n')))];
980
+ },
981
+ match: sel.tag('div', 'br'),
982
+ name: '@lexical/code/vscode-line-run'
983
+ });
984
+ const VscodeCodePasteOverlay = defineOverlayRules([VscodeWrapperRule, VscodeLineRunRule]);
985
+
986
+ /**
987
+ * VS Code → browser code-block pastes ship the block as either:
988
+ *
989
+ * - **Chrome**: one outer
990
+ * `<div style="font-family: …monospace…; white-space: pre">…</div>`
991
+ * wrapping per-line `<div>`s and `<br>`s.
992
+ * - **Safari**: a flat run of sibling
993
+ * `<div style="…monospace…; white-space: pre">…</div>` and
994
+ * `<br style="…monospace…; …">` elements with no wrapping
995
+ * monospace ancestor (the styles are duplicated onto every
996
+ * element).
997
+ *
998
+ * The legacy `<div>` rule (and {@link DivRule}) produces one CodeNode
999
+ * per `<div>` on Safari and concatenates inner divs without
1000
+ * separating `\n`s on Chrome. This preprocess scans once for the
1001
+ * structural signature and, only when it matches, pushes
1002
+ * {@link VscodeCodePasteOverlay} onto {@link ImportOverlays} so the
1003
+ * VS Code-specific rules participate in the walk. Pastes from other
1004
+ * sources pay only the detection cost.
1005
+ *
1006
+ * @experimental
1007
+ */
1008
+ const $installVscodeCodePasteOverlay = (dom, ctx, $next) => {
1009
+ const root = isDOMDocumentNode(dom) ? dom.body : dom;
1010
+ if (looksLikeVscodePaste(root)) {
1011
+ ctx.session.update(ImportOverlays, prev => [...prev, VscodeCodePasteOverlay]);
1012
+ }
1013
+ $next();
1014
+ };
1015
+
1016
+ /**
1017
+ * A `<div style="font-family: …monospace…">` (Google-Docs-style code
1018
+ * block) creates a CodeNode. Descendant elements inside a monospace
1019
+ * wrapper just unwrap so their text content flows into the surrounding
1020
+ * CodeNode.
1021
+ */
1022
+ const DivRule = defineImportRule({
1023
+ $import: (ctx, el, $next) => {
1024
+ if (isMonospaceElement(el)) {
1025
+ return [$createCodeNode().splice(0, 0, ctx.$importChildren(el))];
1026
+ }
1027
+ if (isMonospaceDescendant(el)) {
1028
+ // Unwrap so children flow into the enclosing CodeNode.
1029
+ return ctx.$importChildren(el);
1030
+ }
1031
+ return $next();
1032
+ },
1033
+ match: sel.tag('div'),
1034
+ name: '@lexical/code/div'
1035
+ });
1036
+
1037
+ /**
1038
+ * GitHub raw-file-view `<table class="js-file-line-container">` becomes
1039
+ * a CodeNode. Walking the table's children pushes an overlay (see
1040
+ * {@link GitHubCodeTableOverlayRules}) so `<tr>` / `<td>` inside this
1041
+ * subtree unwrap unconditionally — without paying the predicate cost
1042
+ * on every other `<tr>` / `<td>` paste elsewhere.
1043
+ */
1044
+ const GitHubCodeTableRule = defineImportRule({
1045
+ $import: (ctx, el) => [$createCodeNode().splice(0, 0, ctx.$importChildren(el, {
1046
+ rules: GitHubCodeTableOverlayRules
1047
+ }))],
1048
+ match: sel.tag('table').classAll('js-file-line-container'),
1049
+ name: '@lexical/code/github-code-table'
1050
+ });
1051
+
1052
+ /**
1053
+ * Stray `<td class="js-file-line">` (cell with the explicit GitHub code-
1054
+ * line class but no surrounding code-table wrapper) — unwrap so the
1055
+ * descendant text flows up into whatever context the cell is in. The
1056
+ * class is part of the selector itself, so no runtime guard.
1057
+ */
1058
+ const GitHubCodeCellByClassRule = defineImportRule({
1059
+ $import: (ctx, el) => ctx.$importChildren(el),
1060
+ match: sel.tag('td').classAll('js-file-line'),
1061
+ name: '@lexical/code/github-code-cell-by-class'
1062
+ });
1063
+
1064
+ /**
1065
+ * Import rules for {@link CodeNode}.
1066
+ *
1067
+ * Specific class-restricted rules (GitHub raw-file-view detectors) are
1068
+ * registered before the generic `<table>` / `<tr>` / `<td>` rules so
1069
+ * they win dispatch.
1070
+ *
1071
+ * @experimental
1072
+ */
1073
+ const CodeImportRules = [
1074
+ // Higher-priority (more-specific) rules first:
1075
+ GitHubCodeTableRule, GitHubCodeCellByClassRule, MultilineCodeRule, PreRule, DivRule];
1076
+
1077
+ /**
1078
+ * Bundles {@link CodeImportRules} (plus {@link CoreImportExtension}) into
1079
+ * a single dependency. The legacy {@link CodeNode.importDOM} continues to
1080
+ * work in parallel; depend on this extension to opt into the new
1081
+ * pipeline.
1082
+ *
1083
+ * @experimental
1084
+ */
1085
+ const CodeImportExtension = defineExtension({
1086
+ dependencies: [CoreImportExtension, CodeExtension, configExtension(DOMImportExtension, {
1087
+ preprocess: [$installVscodeCodePasteOverlay],
1088
+ rules: CodeImportRules
1089
+ })],
1090
+ name: '@lexical/code/Import'
1091
+ });
1092
+
737
1093
  function $isSelectionInCode(selection) {
738
1094
  if (!$isRangeSelection(selection)) {
739
1095
  return false;
@@ -1027,6 +1383,15 @@ function $handleMoveTo(type, event) {
1027
1383
  const focusLineNode = focusNode;
1028
1384
  const direction = $getCodeLineDirection(focusLineNode);
1029
1385
  const moveToStart = direction === 'rtl' ? !isMoveToStart : isMoveToStart;
1386
+
1387
+ // Shift variant: let the non-shift branches resolve the target via
1388
+ // framework helpers (`selectNext` / `selectStart` / `setTextNodeRange` /
1389
+ // `node.select`), then restore the original anchor so we end up with an
1390
+ // extended selection rather than a collapsed caret. This keeps point
1391
+ // shapes (text vs. element) consistent between shift and non-shift.
1392
+ const originalAnchorKey = anchor.key;
1393
+ const originalAnchorOffset = anchor.offset;
1394
+ const originalAnchorType = anchor.type;
1030
1395
  if (moveToStart) {
1031
1396
  const start = $getStartOfCodeInLine(focusLineNode, focus.offset);
1032
1397
  if (start !== null) {
@@ -1046,6 +1411,9 @@ function $handleMoveTo(type, event) {
1046
1411
  const node = $getEndOfCodeInLine(focusLineNode);
1047
1412
  node.select();
1048
1413
  }
1414
+ if (event.shiftKey) {
1415
+ selection.anchor.set(originalAnchorKey, originalAnchorOffset, originalAnchorType);
1416
+ }
1049
1417
  event.preventDefault();
1050
1418
  event.stopPropagation();
1051
1419
  return true;
@@ -1150,4 +1518,4 @@ const CodeIndentExtension = defineExtension({
1150
1518
  }
1151
1519
  });
1152
1520
 
1153
- export { $createCodeHighlightNode, $createCodeNode, $getCodeLineDirection, $getEndOfCodeInLine, $getFirstCodeNodeOfLine, $getLastCodeNodeOfLine, $getStartOfCodeInLine, $isCodeHighlightNode, $isCodeNode, $outdentLeadingSpaces, CodeExtension, CodeHighlightNode, CodeIndentExtension, CodeNode, DEFAULT_CODE_LANGUAGE, getDefaultCodeLanguage, registerCodeIndentation };
1521
+ export { $createCodeHighlightNode, $createCodeNode, $getCodeLineDirection, $getEndOfCodeInLine, $getFirstCodeNodeOfLine, $getLastCodeNodeOfLine, $getStartOfCodeInLine, $isCodeHighlightNode, $isCodeNode, $outdentLeadingSpaces, $plainifyCodeContent, CodeExtension, CodeHighlightNode, CodeImportExtension, CodeImportRules, CodeIndentExtension, CodeNode, DEFAULT_CODE_LANGUAGE, getDefaultCodeLanguage, registerCodeIndentation };
@@ -79,6 +79,8 @@ declare export function $outdentLeadingSpaces(
79
79
  selection: RangeSelection,
80
80
  ): boolean;
81
81
 
82
+ declare export function $plainifyCodeContent(text: string): LexicalNode[];
83
+
82
84
  /**
83
85
  * CodeNode
84
86
  */
@@ -19,8 +19,11 @@ export const $getStartOfCodeInLine = mod.$getStartOfCodeInLine;
19
19
  export const $isCodeHighlightNode = mod.$isCodeHighlightNode;
20
20
  export const $isCodeNode = mod.$isCodeNode;
21
21
  export const $outdentLeadingSpaces = mod.$outdentLeadingSpaces;
22
+ export const $plainifyCodeContent = mod.$plainifyCodeContent;
22
23
  export const CodeExtension = mod.CodeExtension;
23
24
  export const CodeHighlightNode = mod.CodeHighlightNode;
25
+ export const CodeImportExtension = mod.CodeImportExtension;
26
+ export const CodeImportRules = mod.CodeImportRules;
24
27
  export const CodeIndentExtension = mod.CodeIndentExtension;
25
28
  export const CodeNode = mod.CodeNode;
26
29
  export const DEFAULT_CODE_LANGUAGE = mod.DEFAULT_CODE_LANGUAGE;
@@ -17,8 +17,11 @@ export const $getStartOfCodeInLine = mod.$getStartOfCodeInLine;
17
17
  export const $isCodeHighlightNode = mod.$isCodeHighlightNode;
18
18
  export const $isCodeNode = mod.$isCodeNode;
19
19
  export const $outdentLeadingSpaces = mod.$outdentLeadingSpaces;
20
+ export const $plainifyCodeContent = mod.$plainifyCodeContent;
20
21
  export const CodeExtension = mod.CodeExtension;
21
22
  export const CodeHighlightNode = mod.CodeHighlightNode;
23
+ export const CodeImportExtension = mod.CodeImportExtension;
24
+ export const CodeImportRules = mod.CodeImportRules;
22
25
  export const CodeIndentExtension = mod.CodeIndentExtension;
23
26
  export const CodeNode = mod.CodeNode;
24
27
  export const DEFAULT_CODE_LANGUAGE = mod.DEFAULT_CODE_LANGUAGE;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ "use strict";var e=require("lexical"),t=require("@lexical/extension"),n=require("@lexical/html");function r(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function i(t,n){let r=t;for(let i=e.$getSiblingCaret(t,n);i&&(A(i.origin)||e.$isTabNode(i.origin));i=i.getAdjacentCaret())r=i.origin;return r}function o(e){return i(e,"previous")}function s(e){return i(e,"next")}function l(t){const n=o(t),r=s(t);let i=n;for(;null!==i;){if(A(i)){const t=e.getTextDirection(i.getTextContent());if(null!==t)return t}if(i===r)break;i=i.getNextSibling()}const l=n.getParent();if(e.$isElementNode(l)){const e=l.getDirection();if("ltr"===e||"rtl"===e)return e}return null}function a(t,n){let i=null,o=null,s=t,l=n,a=t.getTextContent();for(;;){if(0===l){if(s=s.getPreviousSibling(),null===s)break;if(A(s)||e.$isTabNode(s)||e.$isLineBreakNode(s)||r(167),e.$isLineBreakNode(s)){i={node:s,offset:1};break}l=Math.max(0,s.getTextContentSize()-1),a=s.getTextContent()}else l--;const t=a[l];A(s)&&" "!==t&&(o={node:s,offset:l})}if(null!==o)return o;let c=null;if(n<t.getTextContentSize())A(t)&&(c=t.getTextContent()[n]);else{const e=t.getNextSibling();A(e)&&(c=e.getTextContent()[0])}if(null!==c&&" "!==c)return i;{const r=function(t,n){let r=t,i=n,o=t.getTextContent(),s=t.getTextContentSize();for(;;){if(!A(r)||i===s){if(r=r.getNextSibling(),null===r||e.$isLineBreakNode(r))return null;A(r)&&(i=0,o=r.getTextContent(),s=r.getTextContentSize())}if(A(r)){if(" "!==o[i])return{node:r,offset:i};i++}}}(t,n);return null!==r?r:i}}function c(t){const n=s(t);return e.$isLineBreakNode(n)&&r(168),n}function u(e,t,n){if(!Number.isInteger(t)||t<=0)return!1;const r=e.getTextContent(),i=/^ +/.exec(r);if(!i)return!1;const o=Math.min(t,i[0].length),s=e.getKey(),l=n.anchor.key===s&&"text"===n.anchor.type?n.anchor.offset:null,a=n.focus.key===s&&"text"===n.focus.type?n.focus.offset:null;return e.spliceText(0,o,""),null!==l&&n.anchor.set(s,Math.max(0,l-o),"text"),null!==a&&n.focus.set(s,Math.max(0,a-o),"text"),!0}const g="javascript";function d(t,n){for(const r of t.childNodes){if(e.isHTMLElement(r)&&r.tagName===n)return!0;if(d(r,n))return!0}return!1}const f="data-language",h="data-highlight-language",p="data-theme",N=()=>{};class m extends e.ElementNode{__language;__theme;__isSyntaxHighlightSupported;static getType(){return"code"}static clone(e){return new m(e.__language,e.__key)}constructor(e,t){super(t),this.__language=e||void 0,this.__isSyntaxHighlightSupported=!1,this.__theme=void 0}afterCloneFrom(e){super.afterCloneFrom(e),this.__language=e.__language,this.__theme=e.__theme,this.__isSyntaxHighlightSupported=e.__isSyntaxHighlightSupported}createDOM(t){const n=document.createElement("code");e.addClassNamesToElement(n,t.theme.code),n.setAttribute("spellcheck","false");const r=this.getLanguage();r&&(n.setAttribute(f,r),this.getIsSyntaxHighlightSupported()&&n.setAttribute(h,r));const i=this.getTheme();i&&n.setAttribute(p,i);const o=this.getStyle();return o&&e.setDOMStyleFromCSS(n.style,o),n}updateDOM(t,n,r){const i=this.__language,o=t.__language;i?i!==o&&n.setAttribute(f,i):o&&n.removeAttribute(f);const s=this.__isSyntaxHighlightSupported;t.__isSyntaxHighlightSupported&&o?s&&i?i!==o&&n.setAttribute(h,i):n.removeAttribute(h):s&&i&&n.setAttribute(h,i);const l=this.__theme,a=t.__theme;l?l!==a&&n.setAttribute(p,l):a&&n.removeAttribute(p);const c=this.__style,u=t.__style;return c!==u&&e.setDOMStyleFromCSS(n.style,c,u),!1}exportDOM(t){const n=document.createElement("pre");e.addClassNamesToElement(n,t._config.theme.code),n.setAttribute("spellcheck","false");const r=this.getLanguage();r&&(n.setAttribute(f,r),this.getIsSyntaxHighlightSupported()&&n.setAttribute(h,r));const i=this.getTheme();i&&n.setAttribute(p,i);const o=this.getStyle();return o&&e.setDOMStyleFromCSS(n.style,o),{element:n}}static importDOM(){return{code:e=>null!=e.textContent&&(/\r?\n/.test(e.textContent)||d(e,"BR"))?{conversion:x,priority:1}:null,div:()=>({conversion:C,priority:1}),pre:()=>({conversion:x,priority:0}),table:e=>b(e)?{conversion:O,priority:3}:null,td:e=>{const t=e,n=t.closest("table");return t.classList.contains("js-file-line")||n&&b(n)?{conversion:S,priority:3}:null},tr:e=>{const t=e.closest("table");return t&&b(t)?{conversion:S,priority:3}:null}}}static importJSON(e){return _().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setLanguage(e.language).setTheme(e.theme)}exportJSON(){return{...super.exportJSON(),language:this.getLanguage(),theme:this.getTheme()}}insertNewAfter(n,r=!0){if(!t.getPeerDependencyFromEditor(e.$getEditor(),"@lexical/code")){N();const e=M(n);if(e)return e}const{anchor:i,focus:s}=n,l=(i.isBefore(s)?i:s).getNode();if(e.$isTextNode(l)){let t=o(l);const n=[];for(;;)if(e.$isTabNode(t))n.push(e.$createTabNode()),t=t.getNextSibling();else{if(!A(t))break;{let e=0;const r=t.getTextContent(),i=t.getTextContentSize();for(;e<i&&" "===r[e];)e++;if(0!==e&&n.push(D(" ".repeat(e))),e!==i)break;t=t.getNextSibling()}}const r=l.splitText(i.offset)[0],s=0===i.offset?0:1,a=r.getIndexWithinParent()+s,c=l.getParentOrThrow(),u=[e.$createLineBreakNode(),...n];c.splice(a,0,u);const g=n[n.length-1];g?g.select():0===i.offset?r.selectPrevious():r.getNextSibling().selectNext(0,0)}if(T(l)){const{offset:t}=n.anchor;l.splice(t,0,[e.$createLineBreakNode()]),l.select(t+1,t+1)}return null}canIndent(){return!1}collapseAtStart(){const t=e.$createParagraphNode();return this.getChildren().forEach(e=>t.append(e)),this.replace(t),!0}setLanguage(e){const t=this.getWritable();return t.__language=e||void 0,t}getLanguage(){return this.getLatest().__language}setIsSyntaxHighlightSupported(e){const t=this.getWritable();return t.__isSyntaxHighlightSupported=e,t}getIsSyntaxHighlightSupported(){return this.getLatest().__isSyntaxHighlightSupported}setTheme(e){const t=this.getWritable();return t.__theme=e||void 0,t}getTheme(){return this.getLatest().__theme}}function _(t,n){return e.$create(m).setLanguage(t).setTheme(n)}function T(e){return e instanceof m}function x(e){return{node:_(e.getAttribute(f))}}function C(e){const t=e,n=$(t);return n||function(e){let t=e.parentElement;for(;null!==t;){if($(t))return!0;t=t.parentElement}return!1}(t)?{node:n?_():null}:{node:null}}function O(){return{node:_()}}function S(){return{node:null}}function $(e){return null!==e.style.fontFamily.match("monospace")}function b(e){return e.classList.contains("js-file-line-container")}function M(t){const{anchor:n}=t;if(t.isCollapsed()&&"element"===n.type){const t=n.getNode();if(T(t)){const r=t.getChildrenSize();if(r>=2&&n.offset===r){const n=t.getLastChild();if(e.$isLineBreakNode(n)&&e.$isLineBreakNode(n.getPreviousSibling())){const n=e.$createParagraphNode();return t.splice(r-2,2,[]).insertAfter(n,!1),n.select(),n}}}}return null}class y extends e.TextNode{__highlightType;constructor(e="",t,n){super(e,n),this.__highlightType=t}static getType(){return"code-highlight"}static clone(e){return new y(e.__text,e.__highlightType||void 0,e.__key)}afterCloneFrom(e){super.afterCloneFrom(e),this.__highlightType=e.__highlightType}getHighlightType(){return this.getLatest().__highlightType}setHighlightType(e){const t=this.getWritable();return t.__highlightType=e||void 0,t}canHaveFormat(){return!1}createDOM(t){const n=super.createDOM(t),r=E(t.theme,this.__highlightType);return e.addClassNamesToElement(n,r),n}updateDOM(t,n,r){const i=super.updateDOM(t,n,r),o=E(r.theme,t.__highlightType),s=E(r.theme,this.__highlightType);return o!==s&&(o&&e.removeClassNamesFromElement(n,o),s&&e.addClassNamesToElement(n,s)),i}static importJSON(e){return D().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setHighlightType(e.highlightType)}exportJSON(){return{...super.exportJSON(),highlightType:this.getHighlightType()}}setFormat(e){return this}isParentRequired(){return!0}createParentElementNode(){return _()}}function E(e,t){return t&&e&&e.codeHighlight&&e.codeHighlight[t]}function D(t="",n){return e.$applyNodeReplacement(new y(t,n))}function A(e){return e instanceof y}const R=e.defineExtension({name:"@lexical/code",nodes:()=>[m,y],register:t=>t.registerCommand(e.KEY_ENTER_COMMAND,t=>{const n=e.$getSelection();return!(!e.$isRangeSelection(n)||!M(n))&&(t.preventDefault(),!0)},e.COMMAND_PRIORITY_LOW)}),v="data-language";function L(e){return null!==e.style.fontFamily.match("monospace")}function I(e){let t=e.parentElement;for(;null!==t;){if(L(t))return!0;t=t.parentElement}return!1}const P=n.defineOverlayRules([n.defineImportRule({$import:(e,t)=>e.$importChildren(t),match:n.sel.tag("tr","td"),name:"@lexical/code/github-code-table/unwrap"})]),B=n.defineImportRule({$import:(e,t)=>[_(t.getAttribute(v)).splice(0,0,e.$importChildren(t))],match:n.sel.tag("pre"),name:"@lexical/code/pre"}),k=n.defineImportRule({$import:(e,t,n)=>{const r=t.textContent||"";return/\r?\n/.test(r)||null!==t.querySelector("br")?[_(t.getAttribute(v)).splice(0,0,e.$importChildren(t))]:n()},match:n.sel.tag("code"),name:"@lexical/code/code-multiline"});function H(t){if(!e.isHTMLElement(t))return!1;const n=t.style.fontFamily,r=t.style.whiteSpace;return"string"==typeof n&&/monospace/i.test(n)&&"string"==typeof r&&r.startsWith("pre")}function F(t){let n=!1;const r=[];let i="",o=!1;const s=()=>{o&&(r.push(i),i="",o=!1)};for(const l of Array.from(t.childNodes))if(e.isHTMLElement(l))"DIV"===l.tagName?(s(),r.push(l.textContent||""),n=!0):"BR"===l.tagName?(s(),r.push(""),n=!0):(i+=l.textContent||"",o=!0);else if(e.isDOMTextNode(l)){const e=l.textContent||"";e.length>0&&(i+=e,o=!0)}return s(),n?r:null}function w(t){for(const n of Array.from(t.children)){if(e.isHTMLElement(n)&&H(n)){if(null!==F(n))return!0;const e=n.nextElementSibling;if(e&&H(e))return!0;continue}if(w(n))return!0}return!1}const W=n.defineImportRule({$import:(t,n,r)=>{if(!H(n)||I(n))return r();const i=F(n);return null===i||0===i.length?r():[_().splice(0,0,e.$generateNodesFromRawText(i.join("\n")))]},match:n.sel.tag("div"),name:"@lexical/code/vscode-wrapper"}),K=n.defineImportRule({$import:(t,n,r)=>{if(!H(n)||I(n))return r();const i=n.previousElementSibling;if(i&&H(i))return[];const o=[];let s=n;for(;s&&H(s);)o.push("BR"===s.tagName?"":s.textContent||""),s=s.nextElementSibling;return o.length<2?r():[_().splice(0,0,e.$generateNodesFromRawText(o.join("\n")))]},match:n.sel.tag("div","br"),name:"@lexical/code/vscode-line-run"}),Y=n.defineOverlayRules([W,K]),z=n.defineImportRule({$import:(e,t,n)=>L(t)?[_().splice(0,0,e.$importChildren(t))]:I(t)?e.$importChildren(t):n(),match:n.sel.tag("div"),name:"@lexical/code/div"}),J=[n.defineImportRule({$import:(e,t)=>[_().splice(0,0,e.$importChildren(t,{rules:P}))],match:n.sel.tag("table").classAll("js-file-line-container"),name:"@lexical/code/github-code-table"}),n.defineImportRule({$import:(e,t)=>e.$importChildren(t),match:n.sel.tag("td").classAll("js-file-line"),name:"@lexical/code/github-code-cell-by-class"}),k,B,z],U=e.defineExtension({dependencies:[n.CoreImportExtension,R,e.configExtension(n.DOMImportExtension,{preprocess:[(t,r,i)=>{w(e.isDOMDocumentNode(t)?t.body:t)&&r.session.update(n.ImportOverlays,e=>[...e,Y]),i()}],rules:J})],name:"@lexical/code/Import"});function j(t){if(!e.$isRangeSelection(t))return!1;const n=t.anchor.getNode(),r=T(n)?n:n.getParent(),i=t.focus.getNode(),o=T(i)?i:i.getParent();return T(r)&&r.is(o)}function V(t){const n=t.getNodes(),i=[];if(1===n.length&&T(n[0]))return i;let o=[];for(let t=0;t<n.length;t++){const s=n[t];A(s)||e.$isTabNode(s)||e.$isLineBreakNode(s)||r(169),e.$isLineBreakNode(s)?o.length>0&&(i.push(o),o=[]):o.push(s)}if(o.length>0){const n=t.isBackward()?t.anchor:t.focus,r=e.$createPoint(o[0].getKey(),0,"text");n.is(r)||i.push(o)}return i}function q(t,n){const r=e.$getSelection();if(!e.$isRangeSelection(r)||!j(r))return!1;const i=V(r),s=i.length;if(0===s&&r.isCollapsed())return t===e.INDENT_CONTENT_COMMAND&&r.insertNodes([e.$createTabNode()]),!0;if(0===s&&t===e.INDENT_CONTENT_COMMAND&&"\n"===r.getTextContent()){const t=e.$createTabNode(),n=e.$createLineBreakNode(),i=r.isBackward()?"previous":"next";return r.insertNodes([t,n]),e.$setSelectionFromCaretRange(e.$getCaretRangeInDirection(e.$getCaretRange(e.$getTextPointCaret(t,"next",0),e.$normalizeCaret(e.$getSiblingCaret(n,"next"))),i)),!0}for(let l=0;l<s;l++){const s=i[l];if(s.length>0){let i=s[0];if(0===l&&(i=o(i)),t===e.INDENT_CONTENT_COMMAND){const t=e.$createTabNode();if(i.insertBefore(t),0===l){const n=r.isBackward()?"focus":"anchor",o=e.$createPoint(i.getKey(),0,"text");r[n].is(o)&&r[n].set(t.getKey(),0,"text")}}else e.$isTabNode(i)?i.remove():void 0!==n&&A(i)&&u(i,n,r)}}return!0}function G(t,n){const r=e.$getSelection();if(!e.$isRangeSelection(r))return!1;const{anchor:i,focus:l}=r,a=i.offset,c=l.offset,u=i.getNode(),g=l.getNode(),d=t===e.KEY_ARROW_UP_COMMAND;if(!j(r)||!A(u)&&!e.$isTabNode(u)||!A(g)&&!e.$isTabNode(g))return!1;if(!n.altKey){if(r.isCollapsed()){const e=u.getParentOrThrow();if(d&&0===a&&null===u.getPreviousSibling()){if(null===e.getPreviousSibling())return e.selectPrevious(),n.preventDefault(),!0}else if(!d&&a===u.getTextContentSize()&&null===u.getNextSibling()){if(null===e.getNextSibling())return e.selectNext(),n.preventDefault(),!0}}return!1}let f,h;if(u.isBefore(g)?(f=o(u),h=s(g)):(f=o(g),h=s(u)),null==f||null==h)return!1;const p=f.getNodesBetween(h);for(let t=0;t<p.length;t++){const n=p[t];if(!A(n)&&!e.$isTabNode(n)&&!e.$isLineBreakNode(n))return!1}n.preventDefault(),n.stopPropagation();const N=d?f.getPreviousSibling():h.getNextSibling();if(!e.$isLineBreakNode(N))return!0;const m=d?N.getPreviousSibling():N.getNextSibling();if(null==m)return!0;const _=A(m)||e.$isTabNode(m)||e.$isLineBreakNode(m)?d?o(m):s(m):null;let T=null!=_?_:m;return N.remove(),p.forEach(e=>e.remove()),t===e.KEY_ARROW_UP_COMMAND?(p.forEach(e=>T.insertBefore(e)),T.insertBefore(N)):(T.insertAfter(N),T=N,p.forEach(e=>{T.insertAfter(e),T=e})),r.setTextNodeRange(u,a,g,c),!0}function Q(t,n){const r=e.$getSelection();if(!e.$isRangeSelection(r))return!1;const{anchor:i,focus:o}=r,s=i.getNode(),u=o.getNode(),g=t===e.MOVE_TO_START;if(!j(r)||!A(s)&&!e.$isTabNode(s)||!A(u)&&!e.$isTabNode(u))return!1;const d=u,f="rtl"===l(d)?!g:g,h=i.key,p=i.offset,N=i.type;if(f){const t=a(d,o.offset);if(null!==t){const{node:n,offset:i}=t;e.$isLineBreakNode(n)?n.selectNext(0,0):r.setTextNodeRange(n,i,n,i)}else d.getParentOrThrow().selectStart()}else{c(d).select()}return n.shiftKey&&r.anchor.set(h,p,N),n.preventDefault(),n.stopPropagation(),!0}function X(t,n){return e.mergeRegister(t.registerCommand(e.KEY_TAB_COMMAND,n=>{const i=function(t){const n=e.$getSelection();if(!e.$isRangeSelection(n)||!j(n))return null;const i=t?e.OUTDENT_CONTENT_COMMAND:e.INDENT_CONTENT_COMMAND,l=t?e.OUTDENT_CONTENT_COMMAND:e.INSERT_TAB_COMMAND,a=n.anchor,c=n.focus;if(a.is(c))return l;const u=V(n);if(1!==u.length)return i;const g=u[0];let d,f;0===g.length&&r(285),n.isBackward()?(d=c,f=a):(d=a,f=c);const h=o(g[0]),p=s(g[0]),N=e.$createPoint(h.getKey(),0,"text"),m=e.$createPoint(p.getKey(),p.getTextContentSize(),"text");return d.isBefore(N)||m.isBefore(f)?i:N.isBefore(d)||f.isBefore(m)?l:i}(n.shiftKey);return null!==i&&(n.preventDefault(),t.dispatchCommand(i,void 0),!0)},e.COMMAND_PRIORITY_LOW),t.registerCommand(e.INSERT_TAB_COMMAND,()=>!!j(e.$getSelection())&&(e.$insertNodes([e.$createTabNode()]),!0),e.COMMAND_PRIORITY_LOW),t.registerCommand(e.INDENT_CONTENT_COMMAND,()=>q(e.INDENT_CONTENT_COMMAND),e.COMMAND_PRIORITY_LOW),t.registerCommand(e.OUTDENT_CONTENT_COMMAND,()=>q(e.OUTDENT_CONTENT_COMMAND,n),e.COMMAND_PRIORITY_LOW),t.registerCommand(e.KEY_ARROW_UP_COMMAND,t=>{const n=e.$getSelection();if(!e.$isRangeSelection(n))return!1;const{anchor:r}=n,i=r.getNode();return!!j(n)&&(n.isCollapsed()&&0===r.offset&&null===i.getPreviousSibling()&&T(i.getParentOrThrow())?(t.preventDefault(),!0):G(e.KEY_ARROW_UP_COMMAND,t))},e.COMMAND_PRIORITY_LOW),t.registerCommand(e.KEY_ARROW_DOWN_COMMAND,t=>{const n=e.$getSelection();if(!e.$isRangeSelection(n))return!1;const{anchor:r}=n,i=r.getNode();return!!j(n)&&(n.isCollapsed()&&r.offset===i.getTextContentSize()&&null===i.getNextSibling()&&T(i.getParentOrThrow())?(t.preventDefault(),!0):G(e.KEY_ARROW_DOWN_COMMAND,t))},e.COMMAND_PRIORITY_LOW),t.registerCommand(e.MOVE_TO_START,t=>Q(e.MOVE_TO_START,t),e.COMMAND_PRIORITY_LOW),t.registerCommand(e.MOVE_TO_END,t=>Q(e.MOVE_TO_END,t),e.COMMAND_PRIORITY_LOW))}const Z=e.defineExtension({build:(e,n)=>t.namedSignals(n),config:e.safeCast({disabled:!1,tabSize:void 0}),dependencies:[R],name:"@lexical/code-indent",register:(e,n,r)=>{const i=r.getOutput();return t.effect(()=>{if(!i.disabled.value)return X(e,i.tabSize.value)})}});exports.$createCodeHighlightNode=D,exports.$createCodeNode=_,exports.$getCodeLineDirection=l,exports.$getEndOfCodeInLine=c,exports.$getFirstCodeNodeOfLine=o,exports.$getLastCodeNodeOfLine=s,exports.$getStartOfCodeInLine=a,exports.$isCodeHighlightNode=A,exports.$isCodeNode=T,exports.$outdentLeadingSpaces=u,exports.$plainifyCodeContent=function(t){const n=[];return t.split("\n").forEach((t,r)=>{r>0&&n.push(e.$createLineBreakNode());t.split("\t").forEach((t,r)=>{r>0&&n.push(e.$createTabNode()),t.length>0&&n.push(D(t))})}),n},exports.CodeExtension=R,exports.CodeHighlightNode=y,exports.CodeImportExtension=U,exports.CodeImportRules=J,exports.CodeIndentExtension=Z,exports.CodeNode=m,exports.DEFAULT_CODE_LANGUAGE=g,exports.getDefaultCodeLanguage=()=>g,exports.registerCodeIndentation=X;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import{getTextDirection as t,$isElementNode as e,$isTabNode as n,$isLineBreakNode as r,$createLineBreakNode as i,$createTabNode as o,$getSiblingCaret as s,$create as l,ElementNode as u,addClassNamesToElement as c,setDOMStyleFromCSS as a,$getEditor as g,$isTextNode as h,$createParagraphNode as f,isHTMLElement as p,$applyNodeReplacement as d,TextNode as m,removeClassNamesFromElement as x,defineExtension as _,KEY_ENTER_COMMAND as S,$getSelection as y,$isRangeSelection as b,COMMAND_PRIORITY_LOW as v,configExtension as C,isDOMDocumentNode as T,isDOMTextNode as N,$generateNodesFromRawText as A,safeCast as O,mergeRegister as P,KEY_TAB_COMMAND as w,INSERT_TAB_COMMAND as H,$insertNodes as D,INDENT_CONTENT_COMMAND as B,OUTDENT_CONTENT_COMMAND as E,KEY_ARROW_UP_COMMAND as L,KEY_ARROW_DOWN_COMMAND as $,MOVE_TO_START as k,MOVE_TO_END as F,$createPoint as M,$setSelectionFromCaretRange as J,$getCaretRangeInDirection as z,$getCaretRange as I,$getTextPointCaret as K,$normalizeCaret as j}from"lexical";import{getPeerDependencyFromEditor as R,effect as W,namedSignals as q}from"@lexical/extension";import{CoreImportExtension as U,DOMImportExtension as V,defineImportRule as G,sel as Q,ImportOverlays as X,defineOverlayRules as Y}from"@lexical/html";function Z(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);throw n.search=r.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function tt(t,e){let r=t;for(let i=s(t,e);i&&(Pt(i.origin)||n(i.origin));i=i.getAdjacentCaret())r=i.origin;return r}function et(t){return tt(t,"previous")}function nt(t){return tt(t,"next")}function rt(n){const r=et(n),i=nt(n);let o=r;for(;null!==o;){if(Pt(o)){const e=t(o.getTextContent());if(null!==e)return e}if(o===i)break;o=o.getNextSibling()}const s=r.getParent();if(e(s)){const t=s.getDirection();if("ltr"===t||"rtl"===t)return t}return null}function it(t,e){let i=null,o=null,s=t,l=e,u=t.getTextContent();for(;;){if(0===l){if(s=s.getPreviousSibling(),null===s)break;if(Pt(s)||n(s)||r(s)||Z(167),r(s)){i={node:s,offset:1};break}l=Math.max(0,s.getTextContentSize()-1),u=s.getTextContent()}else l--;const t=u[l];Pt(s)&&" "!==t&&(o={node:s,offset:l})}if(null!==o)return o;let c=null;if(e<t.getTextContentSize())Pt(t)&&(c=t.getTextContent()[e]);else{const e=t.getNextSibling();Pt(e)&&(c=e.getTextContent()[0])}if(null!==c&&" "!==c)return i;{const n=function(t,e){let n=t,i=e,o=t.getTextContent(),s=t.getTextContentSize();for(;;){if(!Pt(n)||i===s){if(n=n.getNextSibling(),null===n||r(n))return null;Pt(n)&&(i=0,o=n.getTextContent(),s=n.getTextContentSize())}if(Pt(n)){if(" "!==o[i])return{node:n,offset:i};i++}}}(t,e);return null!==n?n:i}}function ot(t){const e=nt(t);return r(e)&&Z(168),e}function st(t){const e=[];return t.split("\n").forEach((t,n)=>{n>0&&e.push(i());t.split("\t").forEach((t,n)=>{n>0&&e.push(o()),t.length>0&&e.push(Ot(t))})}),e}function lt(t,e,n){if(!Number.isInteger(e)||e<=0)return!1;const r=t.getTextContent(),i=/^ +/.exec(r);if(!i)return!1;const o=Math.min(e,i[0].length),s=t.getKey(),l=n.anchor.key===s&&"text"===n.anchor.type?n.anchor.offset:null,u=n.focus.key===s&&"text"===n.focus.type?n.focus.offset:null;return t.spliceText(0,o,""),null!==l&&n.anchor.set(s,Math.max(0,l-o),"text"),null!==u&&n.focus.set(s,Math.max(0,u-o),"text"),!0}const ut="javascript",ct=()=>ut;function at(t,e){for(const n of t.childNodes){if(p(n)&&n.tagName===e)return!0;if(at(n,e))return!0}return!1}const gt="data-language",ht="data-highlight-language",ft="data-theme",pt=()=>{};class dt extends u{__language;__theme;__isSyntaxHighlightSupported;static getType(){return"code"}static clone(t){return new dt(t.__language,t.__key)}constructor(t,e){super(e),this.__language=t||void 0,this.__isSyntaxHighlightSupported=!1,this.__theme=void 0}afterCloneFrom(t){super.afterCloneFrom(t),this.__language=t.__language,this.__theme=t.__theme,this.__isSyntaxHighlightSupported=t.__isSyntaxHighlightSupported}createDOM(t){const e=document.createElement("code");c(e,t.theme.code),e.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(e.setAttribute(gt,n),this.getIsSyntaxHighlightSupported()&&e.setAttribute(ht,n));const r=this.getTheme();r&&e.setAttribute(ft,r);const i=this.getStyle();return i&&a(e.style,i),e}updateDOM(t,e,n){const r=this.__language,i=t.__language;r?r!==i&&e.setAttribute(gt,r):i&&e.removeAttribute(gt);const o=this.__isSyntaxHighlightSupported;t.__isSyntaxHighlightSupported&&i?o&&r?r!==i&&e.setAttribute(ht,r):e.removeAttribute(ht):o&&r&&e.setAttribute(ht,r);const s=this.__theme,l=t.__theme;s?s!==l&&e.setAttribute(ft,s):l&&e.removeAttribute(ft);const u=this.__style,c=t.__style;return u!==c&&a(e.style,u,c),!1}exportDOM(t){const e=document.createElement("pre");c(e,t._config.theme.code),e.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(e.setAttribute(gt,n),this.getIsSyntaxHighlightSupported()&&e.setAttribute(ht,n));const r=this.getTheme();r&&e.setAttribute(ft,r);const i=this.getStyle();return i&&a(e.style,i),{element:e}}static importDOM(){return{code:t=>null!=t.textContent&&(/\r?\n/.test(t.textContent)||at(t,"BR"))?{conversion:_t,priority:1}:null,div:()=>({conversion:St,priority:1}),pre:()=>({conversion:_t,priority:0}),table:t=>Ct(t)?{conversion:yt,priority:3}:null,td:t=>{const e=t,n=e.closest("table");return e.classList.contains("js-file-line")||n&&Ct(n)?{conversion:bt,priority:3}:null},tr:t=>{const e=t.closest("table");return e&&Ct(e)?{conversion:bt,priority:3}:null}}}static importJSON(t){return mt().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setLanguage(t.language).setTheme(t.theme)}exportJSON(){return{...super.exportJSON(),language:this.getLanguage(),theme:this.getTheme()}}insertNewAfter(t,e=!0){if(!R(g(),"@lexical/code")){pt();const e=Tt(t);if(e)return e}const{anchor:r,focus:s}=t,l=(r.isBefore(s)?r:s).getNode();if(h(l)){let t=et(l);const e=[];for(;;)if(n(t))e.push(o()),t=t.getNextSibling();else{if(!Pt(t))break;{let n=0;const r=t.getTextContent(),i=t.getTextContentSize();for(;n<i&&" "===r[n];)n++;if(0!==n&&e.push(Ot(" ".repeat(n))),n!==i)break;t=t.getNextSibling()}}const s=l.splitText(r.offset)[0],u=0===r.offset?0:1,c=s.getIndexWithinParent()+u,a=l.getParentOrThrow(),g=[i(),...e];a.splice(c,0,g);const h=e[e.length-1];h?h.select():0===r.offset?s.selectPrevious():s.getNextSibling().selectNext(0,0)}if(xt(l)){const{offset:e}=t.anchor;l.splice(e,0,[i()]),l.select(e+1,e+1)}return null}canIndent(){return!1}collapseAtStart(){const t=f();return this.getChildren().forEach(e=>t.append(e)),this.replace(t),!0}setLanguage(t){const e=this.getWritable();return e.__language=t||void 0,e}getLanguage(){return this.getLatest().__language}setIsSyntaxHighlightSupported(t){const e=this.getWritable();return e.__isSyntaxHighlightSupported=t,e}getIsSyntaxHighlightSupported(){return this.getLatest().__isSyntaxHighlightSupported}setTheme(t){const e=this.getWritable();return e.__theme=t||void 0,e}getTheme(){return this.getLatest().__theme}}function mt(t,e){return l(dt).setLanguage(t).setTheme(e)}function xt(t){return t instanceof dt}function _t(t){return{node:mt(t.getAttribute(gt))}}function St(t){const e=t,n=vt(e);return n||function(t){let e=t.parentElement;for(;null!==e;){if(vt(e))return!0;e=e.parentElement}return!1}(e)?{node:n?mt():null}:{node:null}}function yt(){return{node:mt()}}function bt(){return{node:null}}function vt(t){return null!==t.style.fontFamily.match("monospace")}function Ct(t){return t.classList.contains("js-file-line-container")}function Tt(t){const{anchor:e}=t;if(t.isCollapsed()&&"element"===e.type){const t=e.getNode();if(xt(t)){const n=t.getChildrenSize();if(n>=2&&e.offset===n){const e=t.getLastChild();if(r(e)&&r(e.getPreviousSibling())){const e=f();return t.splice(n-2,2,[]).insertAfter(e,!1),e.select(),e}}}}return null}class Nt extends m{__highlightType;constructor(t="",e,n){super(t,n),this.__highlightType=e}static getType(){return"code-highlight"}static clone(t){return new Nt(t.__text,t.__highlightType||void 0,t.__key)}afterCloneFrom(t){super.afterCloneFrom(t),this.__highlightType=t.__highlightType}getHighlightType(){return this.getLatest().__highlightType}setHighlightType(t){const e=this.getWritable();return e.__highlightType=t||void 0,e}canHaveFormat(){return!1}createDOM(t){const e=super.createDOM(t),n=At(t.theme,this.__highlightType);return c(e,n),e}updateDOM(t,e,n){const r=super.updateDOM(t,e,n),i=At(n.theme,t.__highlightType),o=At(n.theme,this.__highlightType);return i!==o&&(i&&x(e,i),o&&c(e,o)),r}static importJSON(t){return Ot().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setHighlightType(t.highlightType)}exportJSON(){return{...super.exportJSON(),highlightType:this.getHighlightType()}}setFormat(t){return this}isParentRequired(){return!0}createParentElementNode(){return mt()}}function At(t,e){return e&&t&&t.codeHighlight&&t.codeHighlight[e]}function Ot(t="",e){return d(new Nt(t,e))}function Pt(t){return t instanceof Nt}const wt=_({name:"@lexical/code",nodes:()=>[dt,Nt],register:t=>t.registerCommand(S,t=>{const e=y();return!(!b(e)||!Tt(e))&&(t.preventDefault(),!0)},v)}),Ht="data-language";function Dt(t){return null!==t.style.fontFamily.match("monospace")}function Bt(t){let e=t.parentElement;for(;null!==e;){if(Dt(e))return!0;e=e.parentElement}return!1}const Et=Y([G({$import:(t,e)=>t.$importChildren(e),match:Q.tag("tr","td"),name:"@lexical/code/github-code-table/unwrap"})]),Lt=G({$import:(t,e)=>[mt(e.getAttribute(Ht)).splice(0,0,t.$importChildren(e))],match:Q.tag("pre"),name:"@lexical/code/pre"}),$t=G({$import:(t,e,n)=>{const r=e.textContent||"";return/\r?\n/.test(r)||null!==e.querySelector("br")?[mt(e.getAttribute(Ht)).splice(0,0,t.$importChildren(e))]:n()},match:Q.tag("code"),name:"@lexical/code/code-multiline"});function kt(t){if(!p(t))return!1;const e=t.style.fontFamily,n=t.style.whiteSpace;return"string"==typeof e&&/monospace/i.test(e)&&"string"==typeof n&&n.startsWith("pre")}function Ft(t){let e=!1;const n=[];let r="",i=!1;const o=()=>{i&&(n.push(r),r="",i=!1)};for(const s of Array.from(t.childNodes))if(p(s))"DIV"===s.tagName?(o(),n.push(s.textContent||""),e=!0):"BR"===s.tagName?(o(),n.push(""),e=!0):(r+=s.textContent||"",i=!0);else if(N(s)){const t=s.textContent||"";t.length>0&&(r+=t,i=!0)}return o(),e?n:null}function Mt(t){for(const e of Array.from(t.children)){if(p(e)&&kt(e)){if(null!==Ft(e))return!0;const t=e.nextElementSibling;if(t&&kt(t))return!0;continue}if(Mt(e))return!0}return!1}const Jt=Y([G({$import:(t,e,n)=>{if(!kt(e)||Bt(e))return n();const r=Ft(e);return null===r||0===r.length?n():[mt().splice(0,0,A(r.join("\n")))]},match:Q.tag("div"),name:"@lexical/code/vscode-wrapper"}),G({$import:(t,e,n)=>{if(!kt(e)||Bt(e))return n();const r=e.previousElementSibling;if(r&&kt(r))return[];const i=[];let o=e;for(;o&&kt(o);)i.push("BR"===o.tagName?"":o.textContent||""),o=o.nextElementSibling;return i.length<2?n():[mt().splice(0,0,A(i.join("\n")))]},match:Q.tag("div","br"),name:"@lexical/code/vscode-line-run"})]),zt=G({$import:(t,e,n)=>Dt(e)?[mt().splice(0,0,t.$importChildren(e))]:Bt(e)?t.$importChildren(e):n(),match:Q.tag("div"),name:"@lexical/code/div"}),It=[G({$import:(t,e)=>[mt().splice(0,0,t.$importChildren(e,{rules:Et}))],match:Q.tag("table").classAll("js-file-line-container"),name:"@lexical/code/github-code-table"}),G({$import:(t,e)=>t.$importChildren(e),match:Q.tag("td").classAll("js-file-line"),name:"@lexical/code/github-code-cell-by-class"}),$t,Lt,zt],Kt=_({dependencies:[U,wt,C(V,{preprocess:[(t,e,n)=>{Mt(T(t)?t.body:t)&&e.session.update(X,t=>[...t,Jt]),n()}],rules:It})],name:"@lexical/code/Import"});function jt(t){if(!b(t))return!1;const e=t.anchor.getNode(),n=xt(e)?e:e.getParent(),r=t.focus.getNode(),i=xt(r)?r:r.getParent();return xt(n)&&n.is(i)}function Rt(t){const e=t.getNodes(),i=[];if(1===e.length&&xt(e[0]))return i;let o=[];for(let t=0;t<e.length;t++){const s=e[t];Pt(s)||n(s)||r(s)||Z(169),r(s)?o.length>0&&(i.push(o),o=[]):o.push(s)}if(o.length>0){const e=t.isBackward()?t.anchor:t.focus,n=M(o[0].getKey(),0,"text");e.is(n)||i.push(o)}return i}function Wt(t,e){const r=y();if(!b(r)||!jt(r))return!1;const l=Rt(r),u=l.length;if(0===u&&r.isCollapsed())return t===B&&r.insertNodes([o()]),!0;if(0===u&&t===B&&"\n"===r.getTextContent()){const t=o(),e=i(),n=r.isBackward()?"previous":"next";return r.insertNodes([t,e]),J(z(I(K(t,"next",0),j(s(e,"next"))),n)),!0}for(let i=0;i<u;i++){const s=l[i];if(s.length>0){let l=s[0];if(0===i&&(l=et(l)),t===B){const t=o();if(l.insertBefore(t),0===i){const e=r.isBackward()?"focus":"anchor",n=M(l.getKey(),0,"text");r[e].is(n)&&r[e].set(t.getKey(),0,"text")}}else n(l)?l.remove():void 0!==e&&Pt(l)&&lt(l,e,r)}}return!0}function qt(t,e){const i=y();if(!b(i))return!1;const{anchor:o,focus:s}=i,l=o.offset,u=s.offset,c=o.getNode(),a=s.getNode(),g=t===L;if(!jt(i)||!Pt(c)&&!n(c)||!Pt(a)&&!n(a))return!1;if(!e.altKey){if(i.isCollapsed()){const t=c.getParentOrThrow();if(g&&0===l&&null===c.getPreviousSibling()){if(null===t.getPreviousSibling())return t.selectPrevious(),e.preventDefault(),!0}else if(!g&&l===c.getTextContentSize()&&null===c.getNextSibling()){if(null===t.getNextSibling())return t.selectNext(),e.preventDefault(),!0}}return!1}let h,f;if(c.isBefore(a)?(h=et(c),f=nt(a)):(h=et(a),f=nt(c)),null==h||null==f)return!1;const p=h.getNodesBetween(f);for(let t=0;t<p.length;t++){const e=p[t];if(!Pt(e)&&!n(e)&&!r(e))return!1}e.preventDefault(),e.stopPropagation();const d=g?h.getPreviousSibling():f.getNextSibling();if(!r(d))return!0;const m=g?d.getPreviousSibling():d.getNextSibling();if(null==m)return!0;const x=Pt(m)||n(m)||r(m)?g?et(m):nt(m):null;let _=null!=x?x:m;return d.remove(),p.forEach(t=>t.remove()),t===L?(p.forEach(t=>_.insertBefore(t)),_.insertBefore(d)):(_.insertAfter(d),_=d,p.forEach(t=>{_.insertAfter(t),_=t})),i.setTextNodeRange(c,l,a,u),!0}function Ut(t,e){const i=y();if(!b(i))return!1;const{anchor:o,focus:s}=i,l=o.getNode(),u=s.getNode(),c=t===k;if(!jt(i)||!Pt(l)&&!n(l)||!Pt(u)&&!n(u))return!1;const a=u,g="rtl"===rt(a)?!c:c,h=o.key,f=o.offset,p=o.type;if(g){const t=it(a,s.offset);if(null!==t){const{node:e,offset:n}=t;r(e)?e.selectNext(0,0):i.setTextNodeRange(e,n,e,n)}else a.getParentOrThrow().selectStart()}else{ot(a).select()}return e.shiftKey&&i.anchor.set(h,f,p),e.preventDefault(),e.stopPropagation(),!0}function Vt(t,e){return P(t.registerCommand(w,e=>{const n=function(t){const e=y();if(!b(e)||!jt(e))return null;const n=t?E:B,r=t?E:H,i=e.anchor,o=e.focus;if(i.is(o))return r;const s=Rt(e);if(1!==s.length)return n;const l=s[0];let u,c;0===l.length&&Z(285),e.isBackward()?(u=o,c=i):(u=i,c=o);const a=et(l[0]),g=nt(l[0]),h=M(a.getKey(),0,"text"),f=M(g.getKey(),g.getTextContentSize(),"text");return u.isBefore(h)||f.isBefore(c)?n:h.isBefore(u)||c.isBefore(f)?r:n}(e.shiftKey);return null!==n&&(e.preventDefault(),t.dispatchCommand(n,void 0),!0)},v),t.registerCommand(H,()=>!!jt(y())&&(D([o()]),!0),v),t.registerCommand(B,()=>Wt(B),v),t.registerCommand(E,()=>Wt(E,e),v),t.registerCommand(L,t=>{const e=y();if(!b(e))return!1;const{anchor:n}=e,r=n.getNode();return!!jt(e)&&(e.isCollapsed()&&0===n.offset&&null===r.getPreviousSibling()&&xt(r.getParentOrThrow())?(t.preventDefault(),!0):qt(L,t))},v),t.registerCommand($,t=>{const e=y();if(!b(e))return!1;const{anchor:n}=e,r=n.getNode();return!!jt(e)&&(e.isCollapsed()&&n.offset===r.getTextContentSize()&&null===r.getNextSibling()&&xt(r.getParentOrThrow())?(t.preventDefault(),!0):qt($,t))},v),t.registerCommand(k,t=>Ut(k,t),v),t.registerCommand(F,t=>Ut(F,t),v))}const Gt=_({build:(t,e)=>q(e),config:O({disabled:!1,tabSize:void 0}),dependencies:[wt],name:"@lexical/code-indent",register:(t,e,n)=>{const r=n.getOutput();return W(()=>{if(!r.disabled.value)return Vt(t,r.tabSize.value)})}});export{Ot as $createCodeHighlightNode,mt as $createCodeNode,rt as $getCodeLineDirection,ot as $getEndOfCodeInLine,et as $getFirstCodeNodeOfLine,nt as $getLastCodeNodeOfLine,it as $getStartOfCodeInLine,Pt as $isCodeHighlightNode,xt as $isCodeNode,lt as $outdentLeadingSpaces,st as $plainifyCodeContent,wt as CodeExtension,Nt as CodeHighlightNode,Kt as CodeImportExtension,It as CodeImportRules,Gt as CodeIndentExtension,dt as CodeNode,ut as DEFAULT_CODE_LANGUAGE,ct as getDefaultCodeLanguage,Vt as registerCodeIndentation};
@@ -7,7 +7,8 @@
7
7
  */
8
8
  export { CodeExtension } from './CodeExtension';
9
9
  export { $createCodeHighlightNode, $isCodeHighlightNode, CodeHighlightNode, } from './CodeHighlightNode';
10
+ export { CodeImportExtension, CodeImportRules } from './CodeImportExtension';
10
11
  export { type CodeIndentConfig, CodeIndentExtension, registerCodeIndentation, } from './CodeIndentation';
11
12
  export type { SerializedCodeNode } from './CodeNode';
12
13
  export { $createCodeNode, $isCodeNode, CodeNode, DEFAULT_CODE_LANGUAGE, getDefaultCodeLanguage, } from './CodeNode';
13
- export { $getCodeLineDirection, $getEndOfCodeInLine, $getFirstCodeNodeOfLine, $getLastCodeNodeOfLine, $getStartOfCodeInLine, $outdentLeadingSpaces, } from './FlatStructureUtils';
14
+ export { $getCodeLineDirection, $getEndOfCodeInLine, $getFirstCodeNodeOfLine, $getLastCodeNodeOfLine, $getStartOfCodeInLine, $outdentLeadingSpaces, $plainifyCodeContent, } from './FlatStructureUtils';