@lexical/code-core 0.44.1-nightly.20260518.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.
- package/dist/CodeImportExtension.d.ts +50 -0
- package/{CodeNode.d.ts → dist/CodeNode.d.ts} +1 -0
- package/{FlatStructureUtils.d.ts → dist/FlatStructureUtils.d.ts} +10 -1
- package/{LexicalCodeCore.dev.js → dist/LexicalCodeCore.dev.js} +377 -6
- package/{LexicalCodeCore.dev.mjs → dist/LexicalCodeCore.dev.mjs} +376 -8
- package/{LexicalCodeCore.js.flow → dist/LexicalCodeCore.js.flow} +2 -0
- package/{LexicalCodeCore.mjs → dist/LexicalCodeCore.mjs} +3 -0
- package/{LexicalCodeCore.node.mjs → dist/LexicalCodeCore.node.mjs} +3 -0
- package/dist/LexicalCodeCore.prod.js +9 -0
- package/dist/LexicalCodeCore.prod.mjs +9 -0
- package/{index.d.ts → dist/index.d.ts} +2 -1
- package/package.json +32 -16
- package/src/CodeExtension.ts +40 -0
- package/src/CodeHighlightNode.ts +171 -0
- package/src/CodeImportExtension.ts +403 -0
- package/src/CodeIndentation.ts +654 -0
- package/src/CodeNode.ts +503 -0
- package/src/FlatStructureUtils.ts +311 -0
- package/src/index.ts +37 -0
- package/LexicalCodeCore.prod.js +0 -9
- package/LexicalCodeCore.prod.mjs +0 -9
- /package/{CodeExtension.d.ts → dist/CodeExtension.d.ts} +0 -0
- /package/{CodeHighlightNode.d.ts → dist/CodeHighlightNode.d.ts} +0 -0
- /package/{CodeIndentation.d.ts → dist/CodeIndentation.d.ts} +0 -0
- /package/{LexicalCodeCore.js → dist/LexicalCodeCore.js} +0 -0
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { getTextDirection, $isElementNode, $isTabNode, $isLineBreakNode, $getSiblingCaret, $create, ElementNode, addClassNamesToElement, setDOMStyleFromCSS, $getEditor, $isTextNode, $
|
|
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 };
|
|
@@ -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)&<(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';
|