@lexical/code-core 0.44.1-nightly.20260519.0 → 0.45.1-dev.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} +367 -6
- package/{LexicalCodeCore.dev.mjs → dist/LexicalCodeCore.dev.mjs} +366 -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 +302 -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, tokenizeRawText, $createTabNode, $createLineBreakNode, $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,24 @@ 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
|
+
tokenizeRawText(text, {
|
|
206
|
+
linebreak: () => out.push($createLineBreakNode()),
|
|
207
|
+
tab: () => out.push($createTabNode()),
|
|
208
|
+
text: part => out.push($createCodeHighlightNode(part))
|
|
209
|
+
});
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
|
|
193
213
|
/**
|
|
194
214
|
* Strip up to `tabSize` leading spaces from a {@link CodeHighlightNode} that
|
|
195
215
|
* starts a code line, to support outdenting space-indented code lines (e.g.
|
|
@@ -236,6 +256,7 @@ function $outdentLeadingSpaces(node, tabSize, selection) {
|
|
|
236
256
|
*/
|
|
237
257
|
|
|
238
258
|
const DEFAULT_CODE_LANGUAGE = 'javascript';
|
|
259
|
+
/** @internal Configurable through the extensions. */
|
|
239
260
|
const getDefaultCodeLanguage = () => DEFAULT_CODE_LANGUAGE;
|
|
240
261
|
function hasChildDOMNodeTag(node, tagName) {
|
|
241
262
|
for (const child of node.childNodes) {
|
|
@@ -248,7 +269,7 @@ function hasChildDOMNodeTag(node, tagName) {
|
|
|
248
269
|
}
|
|
249
270
|
return false;
|
|
250
271
|
}
|
|
251
|
-
const LANGUAGE_DATA_ATTRIBUTE = 'data-language';
|
|
272
|
+
const LANGUAGE_DATA_ATTRIBUTE$1 = 'data-language';
|
|
252
273
|
const HIGHLIGHT_LANGUAGE_DATA_ATTRIBUTE = 'data-highlight-language';
|
|
253
274
|
const THEME_DATA_ATTRIBUTE = 'data-theme';
|
|
254
275
|
const noExtensionDeprecation = warnOnlyOnce('Using CodeNode without CodeExtension is deprecated');
|
|
@@ -287,7 +308,7 @@ class CodeNode extends ElementNode {
|
|
|
287
308
|
element.setAttribute('spellcheck', 'false');
|
|
288
309
|
const language = this.getLanguage();
|
|
289
310
|
if (language) {
|
|
290
|
-
element.setAttribute(LANGUAGE_DATA_ATTRIBUTE, language);
|
|
311
|
+
element.setAttribute(LANGUAGE_DATA_ATTRIBUTE$1, language);
|
|
291
312
|
if (this.getIsSyntaxHighlightSupported()) {
|
|
292
313
|
element.setAttribute(HIGHLIGHT_LANGUAGE_DATA_ATTRIBUTE, language);
|
|
293
314
|
}
|
|
@@ -307,10 +328,10 @@ class CodeNode extends ElementNode {
|
|
|
307
328
|
const prevLanguage = prevNode.__language;
|
|
308
329
|
if (language) {
|
|
309
330
|
if (language !== prevLanguage) {
|
|
310
|
-
dom.setAttribute(LANGUAGE_DATA_ATTRIBUTE, language);
|
|
331
|
+
dom.setAttribute(LANGUAGE_DATA_ATTRIBUTE$1, language);
|
|
311
332
|
}
|
|
312
333
|
} else if (prevLanguage) {
|
|
313
|
-
dom.removeAttribute(LANGUAGE_DATA_ATTRIBUTE);
|
|
334
|
+
dom.removeAttribute(LANGUAGE_DATA_ATTRIBUTE$1);
|
|
314
335
|
}
|
|
315
336
|
const isSyntaxHighlightSupported = this.__isSyntaxHighlightSupported;
|
|
316
337
|
const prevIsSyntaxHighlightSupported = prevNode.__isSyntaxHighlightSupported;
|
|
@@ -347,7 +368,7 @@ class CodeNode extends ElementNode {
|
|
|
347
368
|
element.setAttribute('spellcheck', 'false');
|
|
348
369
|
const language = this.getLanguage();
|
|
349
370
|
if (language) {
|
|
350
|
-
element.setAttribute(LANGUAGE_DATA_ATTRIBUTE, language);
|
|
371
|
+
element.setAttribute(LANGUAGE_DATA_ATTRIBUTE$1, language);
|
|
351
372
|
if (this.getIsSyntaxHighlightSupported()) {
|
|
352
373
|
element.setAttribute(HIGHLIGHT_LANGUAGE_DATA_ATTRIBUTE, language);
|
|
353
374
|
}
|
|
@@ -546,7 +567,7 @@ function $isCodeNode(node) {
|
|
|
546
567
|
return node instanceof CodeNode;
|
|
547
568
|
}
|
|
548
569
|
function $convertPreElement(domNode) {
|
|
549
|
-
const language = domNode.getAttribute(LANGUAGE_DATA_ATTRIBUTE);
|
|
570
|
+
const language = domNode.getAttribute(LANGUAGE_DATA_ATTRIBUTE$1);
|
|
550
571
|
return {
|
|
551
572
|
node: $createCodeNode(language)
|
|
552
573
|
};
|
|
@@ -734,6 +755,331 @@ const CodeExtension = defineExtension({
|
|
|
734
755
|
}
|
|
735
756
|
});
|
|
736
757
|
|
|
758
|
+
/**
|
|
759
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
760
|
+
*
|
|
761
|
+
* This source code is licensed under the MIT license found in the
|
|
762
|
+
* LICENSE file in the root directory of this source tree.
|
|
763
|
+
*
|
|
764
|
+
*/
|
|
765
|
+
|
|
766
|
+
const LANGUAGE_DATA_ATTRIBUTE = 'data-language';
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* True for elements whose `font-family` mentions `monospace` — the
|
|
770
|
+
* heuristic the legacy `<div>` rule uses to spot copy-pasted code blocks
|
|
771
|
+
* (e.g. Google Docs serializes a code block as a styled `<div>`).
|
|
772
|
+
*/
|
|
773
|
+
function isMonospaceElement(el) {
|
|
774
|
+
return el.style.fontFamily.match('monospace') !== null;
|
|
775
|
+
}
|
|
776
|
+
function isMonospaceDescendant(node) {
|
|
777
|
+
let parent = node.parentElement;
|
|
778
|
+
while (parent !== null) {
|
|
779
|
+
if (isMonospaceElement(parent)) {
|
|
780
|
+
return true;
|
|
781
|
+
}
|
|
782
|
+
parent = parent.parentElement;
|
|
783
|
+
}
|
|
784
|
+
return false;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Overlay rules active only while {@link GitHubCodeTableRule} is
|
|
789
|
+
* processing its children. Inside the code-table subtree, every `<tr>`
|
|
790
|
+
* and `<td>` unwraps unconditionally — they never become table-row /
|
|
791
|
+
* table-cell nodes (even when `@lexical/table` registers its rules for
|
|
792
|
+
* those tags). Outside the subtree, this overlay isn't installed, so
|
|
793
|
+
* the cost of these rules is never paid against unrelated `<tr>` /
|
|
794
|
+
* `<td>` pastes.
|
|
795
|
+
*/
|
|
796
|
+
const GitHubCodeTableOverlayRules = defineOverlayRules([defineImportRule({
|
|
797
|
+
$import: (ctx, el) => ctx.$importChildren(el),
|
|
798
|
+
match: sel.tag('tr', 'td'),
|
|
799
|
+
name: '@lexical/code/github-code-table/unwrap'
|
|
800
|
+
})]);
|
|
801
|
+
const PreRule = defineImportRule({
|
|
802
|
+
$import: (ctx, el) => [$createCodeNode(el.getAttribute(LANGUAGE_DATA_ATTRIBUTE)).splice(0, 0, ctx.$importChildren(el))],
|
|
803
|
+
match: sel.tag('pre'),
|
|
804
|
+
name: '@lexical/code/pre'
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Multi-line `<code>` (containing newlines or `<br>`) is treated as a
|
|
809
|
+
* block code element — mirrors the legacy behavior. Single-line `<code>`
|
|
810
|
+
* defers to the inline-format rule from `CoreImportExtension` so it
|
|
811
|
+
* becomes a TextNode with IS_CODE.
|
|
812
|
+
*/
|
|
813
|
+
const MultilineCodeRule = defineImportRule({
|
|
814
|
+
$import: (ctx, el, $next) => {
|
|
815
|
+
const text = el.textContent || '';
|
|
816
|
+
const isMultiLine = /\r?\n/.test(text) || el.querySelector('br') !== null;
|
|
817
|
+
if (!isMultiLine) {
|
|
818
|
+
return $next();
|
|
819
|
+
}
|
|
820
|
+
return [$createCodeNode(el.getAttribute(LANGUAGE_DATA_ATTRIBUTE)).splice(0, 0, ctx.$importChildren(el))];
|
|
821
|
+
},
|
|
822
|
+
match: sel.tag('code'),
|
|
823
|
+
name: '@lexical/code/code-multiline'
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* True for elements carrying BOTH `font-family: …monospace…` and
|
|
828
|
+
* `white-space: pre*` inline — the shape VS Code uses for every line
|
|
829
|
+
* of a copied code block (on every per-line `<div>` on Safari, on
|
|
830
|
+
* the single outer wrapper on Chrome).
|
|
831
|
+
*/
|
|
832
|
+
function isMonospacePreElement(el) {
|
|
833
|
+
if (!isHTMLElement(el)) {
|
|
834
|
+
return false;
|
|
835
|
+
}
|
|
836
|
+
const ff = el.style.fontFamily;
|
|
837
|
+
const ws = el.style.whiteSpace;
|
|
838
|
+
return typeof ff === 'string' && /monospace/i.test(ff) && typeof ws === 'string' && ws.startsWith('pre');
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* Split a monospace-pre wrapper element into logical code lines:
|
|
843
|
+
* `<div>` children contribute their text content as one line,
|
|
844
|
+
* `<br>` children contribute an empty line, inline children (spans
|
|
845
|
+
* and bare text) accumulate into the current line until the next
|
|
846
|
+
* block child.
|
|
847
|
+
*
|
|
848
|
+
* Returns `null` if `el` has no block children (i.e. it's a leaf
|
|
849
|
+
* line, not a wrapper) so the caller can leave it to the
|
|
850
|
+
* sibling-run pass.
|
|
851
|
+
*/
|
|
852
|
+
function splitMonospaceWrapperLines(el) {
|
|
853
|
+
let hasBlockChild = false;
|
|
854
|
+
const lines = [];
|
|
855
|
+
let acc = '';
|
|
856
|
+
let hasAcc = false;
|
|
857
|
+
const flush = () => {
|
|
858
|
+
if (hasAcc) {
|
|
859
|
+
lines.push(acc);
|
|
860
|
+
acc = '';
|
|
861
|
+
hasAcc = false;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
for (const child of Array.from(el.childNodes)) {
|
|
865
|
+
if (isHTMLElement(child)) {
|
|
866
|
+
if (child.tagName === 'DIV') {
|
|
867
|
+
flush();
|
|
868
|
+
lines.push(child.textContent || '');
|
|
869
|
+
hasBlockChild = true;
|
|
870
|
+
} else if (child.tagName === 'BR') {
|
|
871
|
+
flush();
|
|
872
|
+
lines.push('');
|
|
873
|
+
hasBlockChild = true;
|
|
874
|
+
} else {
|
|
875
|
+
acc += child.textContent || '';
|
|
876
|
+
hasAcc = true;
|
|
877
|
+
}
|
|
878
|
+
} else if (isDOMTextNode(child)) {
|
|
879
|
+
const t = child.textContent || '';
|
|
880
|
+
if (t.length > 0) {
|
|
881
|
+
acc += t;
|
|
882
|
+
hasAcc = true;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
flush();
|
|
887
|
+
return hasBlockChild ? lines : null;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Returns `true` if `root` contains the structural signature of a
|
|
892
|
+
* VS Code code-block paste:
|
|
893
|
+
*
|
|
894
|
+
* - a monospace+pre `<div>` wrapper with at least one block (`<div>` /
|
|
895
|
+
* `<br>`) child — the Chrome shape, or
|
|
896
|
+
* - two or more consecutive monospace+pre siblings — the Safari shape.
|
|
897
|
+
*
|
|
898
|
+
* Walked once in preprocess; the matching overlay is only installed
|
|
899
|
+
* when this returns `true` so an unrelated paste doesn't pay for the
|
|
900
|
+
* detection or rule cost.
|
|
901
|
+
*/
|
|
902
|
+
function looksLikeVscodePaste(root) {
|
|
903
|
+
for (const child of Array.from(root.children)) {
|
|
904
|
+
if (isHTMLElement(child) && isMonospacePreElement(child)) {
|
|
905
|
+
const lines = splitMonospaceWrapperLines(child);
|
|
906
|
+
if (lines !== null) {
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
909
|
+
const next = child.nextElementSibling;
|
|
910
|
+
if (next && isMonospacePreElement(next)) {
|
|
911
|
+
return true;
|
|
912
|
+
}
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
if (looksLikeVscodePaste(child)) {
|
|
916
|
+
return true;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return false;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* Match a monospace+pre `<div>` whose direct children include block
|
|
924
|
+
* (`<div>` / `<br>`) elements — the Chrome shape, one outer wrapper
|
|
925
|
+
* around per-line `<div>`s and `<br>`s. Emits a single CodeNode whose
|
|
926
|
+
* text is the wrapper's lines joined by `\n`.
|
|
927
|
+
*/
|
|
928
|
+
const VscodeWrapperRule = defineImportRule({
|
|
929
|
+
$import: (_ctx, el, $next) => {
|
|
930
|
+
if (!isMonospacePreElement(el) || isMonospaceDescendant(el)) {
|
|
931
|
+
return $next();
|
|
932
|
+
}
|
|
933
|
+
const lines = splitMonospaceWrapperLines(el);
|
|
934
|
+
if (lines === null || lines.length === 0) {
|
|
935
|
+
return $next();
|
|
936
|
+
}
|
|
937
|
+
return [$createCodeNode().splice(0, 0, $generateNodesFromRawText(lines.join('\n')))];
|
|
938
|
+
},
|
|
939
|
+
match: sel.tag('div'),
|
|
940
|
+
name: '@lexical/code/vscode-wrapper'
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* Match the first of a run of consecutive monospace+pre `<div>` /
|
|
945
|
+
* `<br>` siblings (the Safari shape) and emit one CodeNode for the
|
|
946
|
+
* whole run. When the framework's per-child dispatch lands on a
|
|
947
|
+
* subsequent sibling in the same run, the prev-sibling check below
|
|
948
|
+
* returns `[]` so the run is only emitted once.
|
|
949
|
+
*/
|
|
950
|
+
const VscodeLineRunRule = defineImportRule({
|
|
951
|
+
$import: (_ctx, el, $next) => {
|
|
952
|
+
if (!isMonospacePreElement(el) || isMonospaceDescendant(el)) {
|
|
953
|
+
return $next();
|
|
954
|
+
}
|
|
955
|
+
const prev = el.previousElementSibling;
|
|
956
|
+
if (prev && isMonospacePreElement(prev)) {
|
|
957
|
+
// An earlier sibling's walk already absorbed `el` into its run.
|
|
958
|
+
return [];
|
|
959
|
+
}
|
|
960
|
+
const lines = [];
|
|
961
|
+
let cur = el;
|
|
962
|
+
while (cur && isMonospacePreElement(cur)) {
|
|
963
|
+
lines.push(cur.tagName === 'BR' ? '' : cur.textContent || '');
|
|
964
|
+
cur = cur.nextElementSibling;
|
|
965
|
+
}
|
|
966
|
+
if (lines.length < 2) {
|
|
967
|
+
return $next();
|
|
968
|
+
}
|
|
969
|
+
return [$createCodeNode().splice(0, 0, $generateNodesFromRawText(lines.join('\n')))];
|
|
970
|
+
},
|
|
971
|
+
match: sel.tag('div', 'br'),
|
|
972
|
+
name: '@lexical/code/vscode-line-run'
|
|
973
|
+
});
|
|
974
|
+
const VscodeCodePasteOverlay = defineOverlayRules([VscodeWrapperRule, VscodeLineRunRule]);
|
|
975
|
+
|
|
976
|
+
/**
|
|
977
|
+
* VS Code → browser code-block pastes ship the block as either:
|
|
978
|
+
*
|
|
979
|
+
* - **Chrome**: one outer
|
|
980
|
+
* `<div style="font-family: …monospace…; white-space: pre">…</div>`
|
|
981
|
+
* wrapping per-line `<div>`s and `<br>`s.
|
|
982
|
+
* - **Safari**: a flat run of sibling
|
|
983
|
+
* `<div style="…monospace…; white-space: pre">…</div>` and
|
|
984
|
+
* `<br style="…monospace…; …">` elements with no wrapping
|
|
985
|
+
* monospace ancestor (the styles are duplicated onto every
|
|
986
|
+
* element).
|
|
987
|
+
*
|
|
988
|
+
* The legacy `<div>` rule (and {@link DivRule}) produces one CodeNode
|
|
989
|
+
* per `<div>` on Safari and concatenates inner divs without
|
|
990
|
+
* separating `\n`s on Chrome. This preprocess scans once for the
|
|
991
|
+
* structural signature and, only when it matches, pushes
|
|
992
|
+
* {@link VscodeCodePasteOverlay} onto {@link ImportOverlays} so the
|
|
993
|
+
* VS Code-specific rules participate in the walk. Pastes from other
|
|
994
|
+
* sources pay only the detection cost.
|
|
995
|
+
*
|
|
996
|
+
* @experimental
|
|
997
|
+
*/
|
|
998
|
+
const $installVscodeCodePasteOverlay = (dom, ctx, $next) => {
|
|
999
|
+
const root = isDOMDocumentNode(dom) ? dom.body : dom;
|
|
1000
|
+
if (looksLikeVscodePaste(root)) {
|
|
1001
|
+
ctx.session.update(ImportOverlays, prev => [...prev, VscodeCodePasteOverlay]);
|
|
1002
|
+
}
|
|
1003
|
+
$next();
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* A `<div style="font-family: …monospace…">` (Google-Docs-style code
|
|
1008
|
+
* block) creates a CodeNode. Descendant elements inside a monospace
|
|
1009
|
+
* wrapper just unwrap so their text content flows into the surrounding
|
|
1010
|
+
* CodeNode.
|
|
1011
|
+
*/
|
|
1012
|
+
const DivRule = defineImportRule({
|
|
1013
|
+
$import: (ctx, el, $next) => {
|
|
1014
|
+
if (isMonospaceElement(el)) {
|
|
1015
|
+
return [$createCodeNode().splice(0, 0, ctx.$importChildren(el))];
|
|
1016
|
+
}
|
|
1017
|
+
if (isMonospaceDescendant(el)) {
|
|
1018
|
+
// Unwrap so children flow into the enclosing CodeNode.
|
|
1019
|
+
return ctx.$importChildren(el);
|
|
1020
|
+
}
|
|
1021
|
+
return $next();
|
|
1022
|
+
},
|
|
1023
|
+
match: sel.tag('div'),
|
|
1024
|
+
name: '@lexical/code/div'
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* GitHub raw-file-view `<table class="js-file-line-container">` becomes
|
|
1029
|
+
* a CodeNode. Walking the table's children pushes an overlay (see
|
|
1030
|
+
* {@link GitHubCodeTableOverlayRules}) so `<tr>` / `<td>` inside this
|
|
1031
|
+
* subtree unwrap unconditionally — without paying the predicate cost
|
|
1032
|
+
* on every other `<tr>` / `<td>` paste elsewhere.
|
|
1033
|
+
*/
|
|
1034
|
+
const GitHubCodeTableRule = defineImportRule({
|
|
1035
|
+
$import: (ctx, el) => [$createCodeNode().splice(0, 0, ctx.$importChildren(el, {
|
|
1036
|
+
rules: GitHubCodeTableOverlayRules
|
|
1037
|
+
}))],
|
|
1038
|
+
match: sel.tag('table').classAll('js-file-line-container'),
|
|
1039
|
+
name: '@lexical/code/github-code-table'
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Stray `<td class="js-file-line">` (cell with the explicit GitHub code-
|
|
1044
|
+
* line class but no surrounding code-table wrapper) — unwrap so the
|
|
1045
|
+
* descendant text flows up into whatever context the cell is in. The
|
|
1046
|
+
* class is part of the selector itself, so no runtime guard.
|
|
1047
|
+
*/
|
|
1048
|
+
const GitHubCodeCellByClassRule = defineImportRule({
|
|
1049
|
+
$import: (ctx, el) => ctx.$importChildren(el),
|
|
1050
|
+
match: sel.tag('td').classAll('js-file-line'),
|
|
1051
|
+
name: '@lexical/code/github-code-cell-by-class'
|
|
1052
|
+
});
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Import rules for {@link CodeNode}.
|
|
1056
|
+
*
|
|
1057
|
+
* Specific class-restricted rules (GitHub raw-file-view detectors) are
|
|
1058
|
+
* registered before the generic `<table>` / `<tr>` / `<td>` rules so
|
|
1059
|
+
* they win dispatch.
|
|
1060
|
+
*
|
|
1061
|
+
* @experimental
|
|
1062
|
+
*/
|
|
1063
|
+
const CodeImportRules = [
|
|
1064
|
+
// Higher-priority (more-specific) rules first:
|
|
1065
|
+
GitHubCodeTableRule, GitHubCodeCellByClassRule, MultilineCodeRule, PreRule, DivRule];
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* Bundles {@link CodeImportRules} (plus {@link CoreImportExtension}) into
|
|
1069
|
+
* a single dependency. The legacy {@link CodeNode.importDOM} continues to
|
|
1070
|
+
* work in parallel; depend on this extension to opt into the new
|
|
1071
|
+
* pipeline.
|
|
1072
|
+
*
|
|
1073
|
+
* @experimental
|
|
1074
|
+
*/
|
|
1075
|
+
const CodeImportExtension = defineExtension({
|
|
1076
|
+
dependencies: [CoreImportExtension, CodeExtension, configExtension(DOMImportExtension, {
|
|
1077
|
+
preprocess: [$installVscodeCodePasteOverlay],
|
|
1078
|
+
rules: CodeImportRules
|
|
1079
|
+
})],
|
|
1080
|
+
name: '@lexical/code/Import'
|
|
1081
|
+
});
|
|
1082
|
+
|
|
737
1083
|
function $isSelectionInCode(selection) {
|
|
738
1084
|
if (!$isRangeSelection(selection)) {
|
|
739
1085
|
return false;
|
|
@@ -1027,6 +1373,15 @@ function $handleMoveTo(type, event) {
|
|
|
1027
1373
|
const focusLineNode = focusNode;
|
|
1028
1374
|
const direction = $getCodeLineDirection(focusLineNode);
|
|
1029
1375
|
const moveToStart = direction === 'rtl' ? !isMoveToStart : isMoveToStart;
|
|
1376
|
+
|
|
1377
|
+
// Shift variant: let the non-shift branches resolve the target via
|
|
1378
|
+
// framework helpers (`selectNext` / `selectStart` / `setTextNodeRange` /
|
|
1379
|
+
// `node.select`), then restore the original anchor so we end up with an
|
|
1380
|
+
// extended selection rather than a collapsed caret. This keeps point
|
|
1381
|
+
// shapes (text vs. element) consistent between shift and non-shift.
|
|
1382
|
+
const originalAnchorKey = anchor.key;
|
|
1383
|
+
const originalAnchorOffset = anchor.offset;
|
|
1384
|
+
const originalAnchorType = anchor.type;
|
|
1030
1385
|
if (moveToStart) {
|
|
1031
1386
|
const start = $getStartOfCodeInLine(focusLineNode, focus.offset);
|
|
1032
1387
|
if (start !== null) {
|
|
@@ -1046,6 +1401,9 @@ function $handleMoveTo(type, event) {
|
|
|
1046
1401
|
const node = $getEndOfCodeInLine(focusLineNode);
|
|
1047
1402
|
node.select();
|
|
1048
1403
|
}
|
|
1404
|
+
if (event.shiftKey) {
|
|
1405
|
+
selection.anchor.set(originalAnchorKey, originalAnchorOffset, originalAnchorType);
|
|
1406
|
+
}
|
|
1049
1407
|
event.preventDefault();
|
|
1050
1408
|
event.stopPropagation();
|
|
1051
1409
|
return true;
|
|
@@ -1150,4 +1508,4 @@ const CodeIndentExtension = defineExtension({
|
|
|
1150
1508
|
}
|
|
1151
1509
|
});
|
|
1152
1510
|
|
|
1153
|
-
export { $createCodeHighlightNode, $createCodeNode, $getCodeLineDirection, $getEndOfCodeInLine, $getFirstCodeNodeOfLine, $getLastCodeNodeOfLine, $getStartOfCodeInLine, $isCodeHighlightNode, $isCodeNode, $outdentLeadingSpaces, CodeExtension, CodeHighlightNode, CodeIndentExtension, CodeNode, DEFAULT_CODE_LANGUAGE, getDefaultCodeLanguage, registerCodeIndentation };
|
|
1511
|
+
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 e.tokenizeRawText(t,{linebreak:()=>n.push(e.$createLineBreakNode()),tab:()=>n.push(e.$createTabNode()),text:e=>n.push(D(e))}),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,tokenizeRawText as i,$createTabNode as o,$createLineBreakNode as s,$getSiblingCaret as l,$create as u,ElementNode as c,addClassNamesToElement as a,setDOMStyleFromCSS as g,$getEditor as h,$isTextNode as f,$createParagraphNode as p,isHTMLElement as d,$applyNodeReplacement as m,TextNode as x,removeClassNamesFromElement as _,defineExtension as S,KEY_ENTER_COMMAND as y,$getSelection as b,$isRangeSelection as v,COMMAND_PRIORITY_LOW as C,configExtension as T,isDOMDocumentNode as N,isDOMTextNode as A,$generateNodesFromRawText as O,safeCast as P,mergeRegister as w,KEY_TAB_COMMAND as H,INSERT_TAB_COMMAND as D,$insertNodes as k,INDENT_CONTENT_COMMAND as B,OUTDENT_CONTENT_COMMAND as L,KEY_ARROW_UP_COMMAND as $,KEY_ARROW_DOWN_COMMAND as E,MOVE_TO_START as F,MOVE_TO_END as M,$createPoint as J,$setSelectionFromCaretRange as z,$getCaretRangeInDirection as I,$getCaretRange as K,$getTextPointCaret as j,$normalizeCaret as R}from"lexical";import{getPeerDependencyFromEditor as W,effect as q,namedSignals as U}from"@lexical/extension";import{CoreImportExtension as V,DOMImportExtension as G,defineImportRule as Q,sel as X,ImportOverlays as Y,defineOverlayRules as Z}from"@lexical/html";function tt(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 et(t,e){let r=t;for(let i=l(t,e);i&&(wt(i.origin)||n(i.origin));i=i.getAdjacentCaret())r=i.origin;return r}function nt(t){return et(t,"previous")}function rt(t){return et(t,"next")}function it(n){const r=nt(n),i=rt(n);let o=r;for(;null!==o;){if(wt(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 ot(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(wt(s)||n(s)||r(s)||tt(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];wt(s)&&" "!==t&&(o={node:s,offset:l})}if(null!==o)return o;let c=null;if(e<t.getTextContentSize())wt(t)&&(c=t.getTextContent()[e]);else{const e=t.getNextSibling();wt(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(!wt(n)||i===s){if(n=n.getNextSibling(),null===n||r(n))return null;wt(n)&&(i=0,o=n.getTextContent(),s=n.getTextContentSize())}if(wt(n)){if(" "!==o[i])return{node:n,offset:i};i++}}}(t,e);return null!==n?n:i}}function st(t){const e=rt(t);return r(e)&&tt(168),e}function lt(t){const e=[];return i(t,{linebreak:()=>e.push(s()),tab:()=>e.push(o()),text:t=>e.push(Pt(t))}),e}function ut(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 ct="javascript",at=()=>ct;function gt(t,e){for(const n of t.childNodes){if(d(n)&&n.tagName===e)return!0;if(gt(n,e))return!0}return!1}const ht="data-language",ft="data-highlight-language",pt="data-theme",dt=()=>{};class mt extends c{__language;__theme;__isSyntaxHighlightSupported;static getType(){return"code"}static clone(t){return new mt(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");a(e,t.theme.code),e.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(e.setAttribute(ht,n),this.getIsSyntaxHighlightSupported()&&e.setAttribute(ft,n));const r=this.getTheme();r&&e.setAttribute(pt,r);const i=this.getStyle();return i&&g(e.style,i),e}updateDOM(t,e,n){const r=this.__language,i=t.__language;r?r!==i&&e.setAttribute(ht,r):i&&e.removeAttribute(ht);const o=this.__isSyntaxHighlightSupported;t.__isSyntaxHighlightSupported&&i?o&&r?r!==i&&e.setAttribute(ft,r):e.removeAttribute(ft):o&&r&&e.setAttribute(ft,r);const s=this.__theme,l=t.__theme;s?s!==l&&e.setAttribute(pt,s):l&&e.removeAttribute(pt);const u=this.__style,c=t.__style;return u!==c&&g(e.style,u,c),!1}exportDOM(t){const e=document.createElement("pre");a(e,t._config.theme.code),e.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(e.setAttribute(ht,n),this.getIsSyntaxHighlightSupported()&&e.setAttribute(ft,n));const r=this.getTheme();r&&e.setAttribute(pt,r);const i=this.getStyle();return i&&g(e.style,i),{element:e}}static importDOM(){return{code:t=>null!=t.textContent&&(/\r?\n/.test(t.textContent)||gt(t,"BR"))?{conversion:St,priority:1}:null,div:()=>({conversion:yt,priority:1}),pre:()=>({conversion:St,priority:0}),table:t=>Tt(t)?{conversion:bt,priority:3}:null,td:t=>{const e=t,n=e.closest("table");return e.classList.contains("js-file-line")||n&&Tt(n)?{conversion:vt,priority:3}:null},tr:t=>{const e=t.closest("table");return e&&Tt(e)?{conversion:vt,priority:3}:null}}}static importJSON(t){return xt().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(!W(h(),"@lexical/code")){dt();const e=Nt(t);if(e)return e}const{anchor:r,focus:i}=t,l=(r.isBefore(i)?r:i).getNode();if(f(l)){let t=nt(l);const e=[];for(;;)if(n(t))e.push(o()),t=t.getNextSibling();else{if(!wt(t))break;{let n=0;const r=t.getTextContent(),i=t.getTextContentSize();for(;n<i&&" "===r[n];)n++;if(0!==n&&e.push(Pt(" ".repeat(n))),n!==i)break;t=t.getNextSibling()}}const i=l.splitText(r.offset)[0],u=0===r.offset?0:1,c=i.getIndexWithinParent()+u,a=l.getParentOrThrow(),g=[s(),...e];a.splice(c,0,g);const h=e[e.length-1];h?h.select():0===r.offset?i.selectPrevious():i.getNextSibling().selectNext(0,0)}if(_t(l)){const{offset:e}=t.anchor;l.splice(e,0,[s()]),l.select(e+1,e+1)}return null}canIndent(){return!1}collapseAtStart(){const t=p();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 xt(t,e){return u(mt).setLanguage(t).setTheme(e)}function _t(t){return t instanceof mt}function St(t){return{node:xt(t.getAttribute(ht))}}function yt(t){const e=t,n=Ct(e);return n||function(t){let e=t.parentElement;for(;null!==e;){if(Ct(e))return!0;e=e.parentElement}return!1}(e)?{node:n?xt():null}:{node:null}}function bt(){return{node:xt()}}function vt(){return{node:null}}function Ct(t){return null!==t.style.fontFamily.match("monospace")}function Tt(t){return t.classList.contains("js-file-line-container")}function Nt(t){const{anchor:e}=t;if(t.isCollapsed()&&"element"===e.type){const t=e.getNode();if(_t(t)){const n=t.getChildrenSize();if(n>=2&&e.offset===n){const e=t.getLastChild();if(r(e)&&r(e.getPreviousSibling())){const e=p();return t.splice(n-2,2,[]).insertAfter(e,!1),e.select(),e}}}}return null}class At extends x{__highlightType;constructor(t="",e,n){super(t,n),this.__highlightType=e}static getType(){return"code-highlight"}static clone(t){return new At(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=Ot(t.theme,this.__highlightType);return a(e,n),e}updateDOM(t,e,n){const r=super.updateDOM(t,e,n),i=Ot(n.theme,t.__highlightType),o=Ot(n.theme,this.__highlightType);return i!==o&&(i&&_(e,i),o&&a(e,o)),r}static importJSON(t){return Pt().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 xt()}}function Ot(t,e){return e&&t&&t.codeHighlight&&t.codeHighlight[e]}function Pt(t="",e){return m(new At(t,e))}function wt(t){return t instanceof At}const Ht=S({name:"@lexical/code",nodes:()=>[mt,At],register:t=>t.registerCommand(y,t=>{const e=b();return!(!v(e)||!Nt(e))&&(t.preventDefault(),!0)},C)}),Dt="data-language";function kt(t){return null!==t.style.fontFamily.match("monospace")}function Bt(t){let e=t.parentElement;for(;null!==e;){if(kt(e))return!0;e=e.parentElement}return!1}const Lt=Z([Q({$import:(t,e)=>t.$importChildren(e),match:X.tag("tr","td"),name:"@lexical/code/github-code-table/unwrap"})]),$t=Q({$import:(t,e)=>[xt(e.getAttribute(Dt)).splice(0,0,t.$importChildren(e))],match:X.tag("pre"),name:"@lexical/code/pre"}),Et=Q({$import:(t,e,n)=>{const r=e.textContent||"";return/\r?\n/.test(r)||null!==e.querySelector("br")?[xt(e.getAttribute(Dt)).splice(0,0,t.$importChildren(e))]:n()},match:X.tag("code"),name:"@lexical/code/code-multiline"});function Ft(t){if(!d(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 Mt(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(d(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(A(s)){const t=s.textContent||"";t.length>0&&(r+=t,i=!0)}return o(),e?n:null}function Jt(t){for(const e of Array.from(t.children)){if(d(e)&&Ft(e)){if(null!==Mt(e))return!0;const t=e.nextElementSibling;if(t&&Ft(t))return!0;continue}if(Jt(e))return!0}return!1}const zt=Z([Q({$import:(t,e,n)=>{if(!Ft(e)||Bt(e))return n();const r=Mt(e);return null===r||0===r.length?n():[xt().splice(0,0,O(r.join("\n")))]},match:X.tag("div"),name:"@lexical/code/vscode-wrapper"}),Q({$import:(t,e,n)=>{if(!Ft(e)||Bt(e))return n();const r=e.previousElementSibling;if(r&&Ft(r))return[];const i=[];let o=e;for(;o&&Ft(o);)i.push("BR"===o.tagName?"":o.textContent||""),o=o.nextElementSibling;return i.length<2?n():[xt().splice(0,0,O(i.join("\n")))]},match:X.tag("div","br"),name:"@lexical/code/vscode-line-run"})]),It=Q({$import:(t,e,n)=>kt(e)?[xt().splice(0,0,t.$importChildren(e))]:Bt(e)?t.$importChildren(e):n(),match:X.tag("div"),name:"@lexical/code/div"}),Kt=[Q({$import:(t,e)=>[xt().splice(0,0,t.$importChildren(e,{rules:Lt}))],match:X.tag("table").classAll("js-file-line-container"),name:"@lexical/code/github-code-table"}),Q({$import:(t,e)=>t.$importChildren(e),match:X.tag("td").classAll("js-file-line"),name:"@lexical/code/github-code-cell-by-class"}),Et,$t,It],jt=S({dependencies:[V,Ht,T(G,{preprocess:[(t,e,n)=>{Jt(N(t)?t.body:t)&&e.session.update(Y,t=>[...t,zt]),n()}],rules:Kt})],name:"@lexical/code/Import"});function Rt(t){if(!v(t))return!1;const e=t.anchor.getNode(),n=_t(e)?e:e.getParent(),r=t.focus.getNode(),i=_t(r)?r:r.getParent();return _t(n)&&n.is(i)}function Wt(t){const e=t.getNodes(),i=[];if(1===e.length&&_t(e[0]))return i;let o=[];for(let t=0;t<e.length;t++){const s=e[t];wt(s)||n(s)||r(s)||tt(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=J(o[0].getKey(),0,"text");e.is(n)||i.push(o)}return i}function qt(t,e){const r=b();if(!v(r)||!Rt(r))return!1;const i=Wt(r),u=i.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=s(),n=r.isBackward()?"previous":"next";return r.insertNodes([t,e]),z(I(K(j(t,"next",0),R(l(e,"next"))),n)),!0}for(let s=0;s<u;s++){const l=i[s];if(l.length>0){let i=l[0];if(0===s&&(i=nt(i)),t===B){const t=o();if(i.insertBefore(t),0===s){const e=r.isBackward()?"focus":"anchor",n=J(i.getKey(),0,"text");r[e].is(n)&&r[e].set(t.getKey(),0,"text")}}else n(i)?i.remove():void 0!==e&&wt(i)&&ut(i,e,r)}}return!0}function Ut(t,e){const i=b();if(!v(i))return!1;const{anchor:o,focus:s}=i,l=o.offset,u=s.offset,c=o.getNode(),a=s.getNode(),g=t===$;if(!Rt(i)||!wt(c)&&!n(c)||!wt(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=nt(c),f=rt(a)):(h=nt(a),f=rt(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(!wt(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=wt(m)||n(m)||r(m)?g?nt(m):rt(m):null;let _=null!=x?x:m;return d.remove(),p.forEach(t=>t.remove()),t===$?(p.forEach(t=>_.insertBefore(t)),_.insertBefore(d)):(_.insertAfter(d),_=d,p.forEach(t=>{_.insertAfter(t),_=t})),i.setTextNodeRange(c,l,a,u),!0}function Vt(t,e){const i=b();if(!v(i))return!1;const{anchor:o,focus:s}=i,l=o.getNode(),u=s.getNode(),c=t===F;if(!Rt(i)||!wt(l)&&!n(l)||!wt(u)&&!n(u))return!1;const a=u,g="rtl"===it(a)?!c:c,h=o.key,f=o.offset,p=o.type;if(g){const t=ot(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{st(a).select()}return e.shiftKey&&i.anchor.set(h,f,p),e.preventDefault(),e.stopPropagation(),!0}function Gt(t,e){return w(t.registerCommand(H,e=>{const n=function(t){const e=b();if(!v(e)||!Rt(e))return null;const n=t?L:B,r=t?L:D,i=e.anchor,o=e.focus;if(i.is(o))return r;const s=Wt(e);if(1!==s.length)return n;const l=s[0];let u,c;0===l.length&&tt(285),e.isBackward()?(u=o,c=i):(u=i,c=o);const a=nt(l[0]),g=rt(l[0]),h=J(a.getKey(),0,"text"),f=J(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)},C),t.registerCommand(D,()=>!!Rt(b())&&(k([o()]),!0),C),t.registerCommand(B,()=>qt(B),C),t.registerCommand(L,()=>qt(L,e),C),t.registerCommand($,t=>{const e=b();if(!v(e))return!1;const{anchor:n}=e,r=n.getNode();return!!Rt(e)&&(e.isCollapsed()&&0===n.offset&&null===r.getPreviousSibling()&&_t(r.getParentOrThrow())?(t.preventDefault(),!0):Ut($,t))},C),t.registerCommand(E,t=>{const e=b();if(!v(e))return!1;const{anchor:n}=e,r=n.getNode();return!!Rt(e)&&(e.isCollapsed()&&n.offset===r.getTextContentSize()&&null===r.getNextSibling()&&_t(r.getParentOrThrow())?(t.preventDefault(),!0):Ut(E,t))},C),t.registerCommand(F,t=>Vt(F,t),C),t.registerCommand(M,t=>Vt(M,t),C))}const Qt=S({build:(t,e)=>U(e),config:P({disabled:!1,tabSize:void 0}),dependencies:[Ht],name:"@lexical/code-indent",register:(t,e,n)=>{const r=n.getOutput();return q(()=>{if(!r.disabled.value)return Gt(t,r.tabSize.value)})}});export{Pt as $createCodeHighlightNode,xt as $createCodeNode,it as $getCodeLineDirection,st as $getEndOfCodeInLine,nt as $getFirstCodeNodeOfLine,rt as $getLastCodeNodeOfLine,ot as $getStartOfCodeInLine,wt as $isCodeHighlightNode,_t as $isCodeNode,ut as $outdentLeadingSpaces,lt as $plainifyCodeContent,Ht as CodeExtension,At as CodeHighlightNode,jt as CodeImportExtension,Kt as CodeImportRules,Qt as CodeIndentExtension,mt as CodeNode,ct as DEFAULT_CODE_LANGUAGE,at as getDefaultCodeLanguage,Gt 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';
|