@lexical/code 0.10.0 → 0.11.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.
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import type { EditorConfig, LexicalNode, NodeKey, SerializedTextNode, Spread } from 'lexical';
8
+ import type { EditorConfig, LexicalNode, LineBreakNode, NodeKey, SerializedTextNode, Spread, TabNode } from 'lexical';
9
9
  import 'prismjs/components/prism-clike';
10
10
  import 'prismjs/components/prism-javascript';
11
11
  import 'prismjs/components/prism-markup';
@@ -49,6 +49,6 @@ export declare class CodeHighlightNode extends TextNode {
49
49
  }
50
50
  export declare function $createCodeHighlightNode(text: string, highlightType?: string | null | undefined): CodeHighlightNode;
51
51
  export declare function $isCodeHighlightNode(node: LexicalNode | CodeHighlightNode | null | undefined): node is CodeHighlightNode;
52
- export declare function getFirstCodeHighlightNodeOfLine(anchor: LexicalNode): CodeHighlightNode | null | undefined;
53
- export declare function getLastCodeHighlightNodeOfLine(anchor: LexicalNode): CodeHighlightNode | null | undefined;
52
+ export declare function getFirstCodeNodeOfLine(anchor: CodeHighlightNode | TabNode | LineBreakNode): null | CodeHighlightNode | TabNode | LineBreakNode;
53
+ export declare function getLastCodeNodeOfLine(anchor: CodeHighlightNode | TabNode | LineBreakNode): CodeHighlightNode | TabNode | LineBreakNode;
54
54
  export {};
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import type { LexicalEditor, LexicalNode } from 'lexical';
8
+ import type { LexicalEditor, LineBreakNode } from 'lexical';
9
9
  import 'prismjs/components/prism-clike';
10
10
  import 'prismjs/components/prism-javascript';
11
11
  import 'prismjs/components/prism-markup';
@@ -20,7 +20,8 @@ import 'prismjs/components/prism-swift';
20
20
  import 'prismjs/components/prism-typescript';
21
21
  import 'prismjs/components/prism-java';
22
22
  import 'prismjs/components/prism-cpp';
23
- import { TextNode } from 'lexical';
23
+ import { TabNode } from 'lexical';
24
+ import { CodeHighlightNode } from './CodeHighlightNode';
24
25
  declare type TokenContent = string | Token | (string | Token)[];
25
26
  export interface Token {
26
27
  type: string;
@@ -31,13 +32,10 @@ export interface Tokenizer {
31
32
  tokenize(code: string, language?: string): (string | Token)[];
32
33
  }
33
34
  export declare const PrismTokenizer: Tokenizer;
34
- export declare function getStartOfCodeInLine(anchor: LexicalNode): {
35
- node: TextNode | null;
36
- offset: number;
37
- };
38
- export declare function getEndOfCodeInLine(anchor: LexicalNode): {
39
- node: TextNode | null;
35
+ export declare function getStartOfCodeInLine(anchor: CodeHighlightNode | TabNode, offset: number): null | {
36
+ node: CodeHighlightNode | TabNode | LineBreakNode;
40
37
  offset: number;
41
38
  };
39
+ export declare function getEndOfCodeInLine(anchor: CodeHighlightNode | TabNode): CodeHighlightNode | TabNode;
42
40
  export declare function registerCodeHighlighting(editor: LexicalEditor, tokenizer?: Tokenizer): () => void;
43
41
  export {};
package/CodeNode.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import type { DOMConversionMap, EditorConfig, LexicalNode, NodeKey, ParagraphNode, RangeSelection, SerializedElementNode, Spread } from 'lexical';
8
+ import type { DOMConversionMap, EditorConfig, LexicalNode, NodeKey, ParagraphNode, RangeSelection, SerializedElementNode, Spread, TabNode } from 'lexical';
9
9
  import type { CodeHighlightNode } from '@lexical/code';
10
10
  import 'prismjs/components/prism-clike';
11
11
  import 'prismjs/components/prism-javascript';
@@ -37,8 +37,7 @@ export declare class CodeNode extends ElementNode {
37
37
  static importDOM(): DOMConversionMap | null;
38
38
  static importJSON(serializedNode: SerializedCodeNode): CodeNode;
39
39
  exportJSON(): SerializedCodeNode;
40
- insertNewAfter(selection: RangeSelection, restoreSelection?: boolean): null | ParagraphNode | CodeHighlightNode;
41
- canInsertTab(): boolean;
40
+ insertNewAfter(selection: RangeSelection, restoreSelection?: boolean): null | ParagraphNode | CodeHighlightNode | TabNode;
42
41
  canIndent(): false;
43
42
  collapseAtStart(): boolean;
44
43
  setLanguage(language: string): void;
@@ -200,40 +200,49 @@ class CodeNode extends lexical.ElementNode {
200
200
  // tabs and spaces, such that leading indentation is preserved.
201
201
 
202
202
 
203
- const anchor = selection.anchor.getNode();
204
- const firstNode = getFirstCodeHighlightNodeOfLine(anchor);
203
+ const anchor = selection.anchor;
204
+ const focus = selection.focus;
205
+ const firstPoint = anchor.isBefore(focus) ? anchor : focus;
206
+ const firstSelectionNode = firstPoint.getNode();
207
+
208
+ if ($isCodeHighlightNode(firstSelectionNode) || lexical.$isTabNode(firstSelectionNode)) {
209
+ let node = getFirstCodeNodeOfLine(firstSelectionNode);
210
+ const insertNodes = []; // eslint-disable-next-line no-constant-condition
211
+
212
+ while (true) {
213
+ if (lexical.$isTabNode(node)) {
214
+ insertNodes.push(lexical.$createTabNode());
215
+ node = node.getNextSibling();
216
+ } else if ($isCodeHighlightNode(node)) {
217
+ let spaces = 0;
218
+ const text = node.getTextContent();
219
+ const textSize = node.getTextContentSize();
220
+
221
+ for (; spaces < textSize && text[spaces] === ' '; spaces++);
222
+
223
+ if (spaces !== 0) {
224
+ insertNodes.push($createCodeHighlightNode(' '.repeat(spaces)));
225
+ }
205
226
 
206
- if (firstNode != null) {
207
- let leadingWhitespace = 0;
208
- const firstNodeText = firstNode.getTextContent();
227
+ if (spaces !== textSize) {
228
+ break;
229
+ }
209
230
 
210
- while (leadingWhitespace < firstNodeText.length && /[\t ]/.test(firstNodeText[leadingWhitespace])) {
211
- leadingWhitespace += 1;
231
+ node = node.getNextSibling();
232
+ } else {
233
+ break;
234
+ }
212
235
  }
213
236
 
214
- if (leadingWhitespace > 0) {
215
- const whitespace = firstNodeText.substring(0, leadingWhitespace);
216
- const indentedChild = $createCodeHighlightNode(whitespace);
217
- anchor.insertAfter(indentedChild);
218
- selection.insertNodes([lexical.$createLineBreakNode()]);
219
- indentedChild.select();
220
- return indentedChild;
237
+ if (insertNodes.length > 0) {
238
+ selection.insertNodes([lexical.$createLineBreakNode(), ...insertNodes]);
239
+ return insertNodes[insertNodes.length - 1];
221
240
  }
222
241
  }
223
242
 
224
243
  return null;
225
244
  }
226
245
 
227
- canInsertTab() {
228
- const selection = lexical.$getSelection();
229
-
230
- if (!lexical.$isRangeSelection(selection) || !selection.isCollapsed()) {
231
- return false;
232
- }
233
-
234
- return true;
235
- }
236
-
237
246
  canIndent() {
238
247
  return false;
239
248
  }
@@ -265,8 +274,7 @@ function $isCodeNode(node) {
265
274
 
266
275
  function convertPreElement(domNode) {
267
276
  return {
268
- node: $createCodeNode(),
269
- preformatted: true
277
+ node: $createCodeNode()
270
278
  };
271
279
  }
272
280
 
@@ -291,15 +299,13 @@ function convertDivElement(domNode) {
291
299
 
292
300
  return childLexicalNodes;
293
301
  },
294
- node: isCode ? $createCodeNode() : null,
295
- preformatted: isCode
302
+ node: isCode ? $createCodeNode() : null
296
303
  };
297
304
  }
298
305
 
299
306
  function convertTableElement() {
300
307
  return {
301
- node: $createCodeNode(),
302
- preformatted: true
308
+ node: $createCodeNode()
303
309
  };
304
310
  }
305
311
 
@@ -488,43 +494,27 @@ function $createCodeHighlightNode(text, highlightType) {
488
494
  function $isCodeHighlightNode(node) {
489
495
  return node instanceof CodeHighlightNode;
490
496
  }
491
- function getFirstCodeHighlightNodeOfLine(anchor) {
492
- let currentNode = null;
493
- const previousSiblings = anchor.getPreviousSiblings();
494
- previousSiblings.push(anchor);
497
+ function getFirstCodeNodeOfLine(anchor) {
498
+ let previousNode = anchor;
499
+ let node = anchor;
495
500
 
496
- while (previousSiblings.length > 0) {
497
- const node = previousSiblings.pop();
498
-
499
- if ($isCodeHighlightNode(node)) {
500
- currentNode = node;
501
- }
502
-
503
- if (lexical.$isLineBreakNode(node)) {
504
- break;
505
- }
501
+ while ($isCodeHighlightNode(node) || lexical.$isTabNode(node)) {
502
+ previousNode = node;
503
+ node = node.getPreviousSibling();
506
504
  }
507
505
 
508
- return currentNode;
506
+ return previousNode;
509
507
  }
510
- function getLastCodeHighlightNodeOfLine(anchor) {
511
- let currentNode = null;
512
- const nextSiblings = anchor.getNextSiblings();
513
- nextSiblings.unshift(anchor);
514
-
515
- while (nextSiblings.length > 0) {
516
- const node = nextSiblings.shift();
517
-
518
- if ($isCodeHighlightNode(node)) {
519
- currentNode = node;
520
- }
508
+ function getLastCodeNodeOfLine(anchor) {
509
+ let nextNode = anchor;
510
+ let node = anchor;
521
511
 
522
- if (lexical.$isLineBreakNode(node)) {
523
- break;
524
- }
512
+ while ($isCodeHighlightNode(node) || lexical.$isTabNode(node)) {
513
+ nextNode = node;
514
+ node = node.getNextSibling();
525
515
  }
526
516
 
527
- return currentNode;
517
+ return nextNode;
528
518
  }
529
519
 
530
520
  /**
@@ -542,141 +532,125 @@ const PrismTokenizer = {
542
532
  }
543
533
 
544
534
  };
535
+ function getStartOfCodeInLine(anchor, offset) {
536
+ let last = null;
537
+ let lastNonBlank = null;
538
+ let node = anchor;
539
+ let nodeOffset = offset;
540
+ let nodeTextContent = anchor.getTextContent(); // eslint-disable-next-line no-constant-condition
541
+
542
+ while (true) {
543
+ if (nodeOffset === 0) {
544
+ node = node.getPreviousSibling();
545
+
546
+ if (node === null) {
547
+ break;
548
+ }
545
549
 
546
- function isSpaceOrTabChar(char) {
547
- return char === ' ' || char === '\t';
548
- }
549
-
550
- function findFirstNotSpaceOrTabCharAtText(text, isForward) {
551
- const length = text.length;
552
- let offset = -1;
553
-
554
- if (isForward) {
555
- for (let i = 0; i < length; i++) {
556
- const char = text[i];
550
+ if (!($isCodeHighlightNode(node) || lexical.$isTabNode(node) || lexical.$isLineBreakNode(node))) {
551
+ throw Error(`Expected a valid Code Node: CodeHighlightNode, TabNode, LineBreakNode`);
552
+ }
557
553
 
558
- if (!isSpaceOrTabChar(char)) {
559
- offset = i;
554
+ if (lexical.$isLineBreakNode(node)) {
555
+ last = {
556
+ node,
557
+ offset: 1
558
+ };
560
559
  break;
561
560
  }
561
+
562
+ nodeOffset = Math.max(0, node.getTextContentSize() - 1);
563
+ nodeTextContent = node.getTextContent();
564
+ } else {
565
+ nodeOffset--;
562
566
  }
563
- } else {
564
- for (let i = length - 1; i > -1; i--) {
565
- const char = text[i];
566
567
 
567
- if (!isSpaceOrTabChar(char)) {
568
- offset = i;
569
- break;
570
- }
568
+ const character = nodeTextContent[nodeOffset];
569
+
570
+ if ($isCodeHighlightNode(node) && character !== ' ') {
571
+ lastNonBlank = {
572
+ node,
573
+ offset: nodeOffset
574
+ };
571
575
  }
572
- }
576
+ } // lastNonBlank !== null: anchor in the middle of code; move to line beginning
573
577
 
574
- return offset;
575
- }
576
578
 
577
- function getStartOfCodeInLine(anchor) {
578
- let currentNode = null;
579
- let currentNodeOffset = -1;
580
- const previousSiblings = anchor.getPreviousSiblings();
581
- previousSiblings.push(anchor);
579
+ if (lastNonBlank !== null) {
580
+ return lastNonBlank;
581
+ } // Spaces, tabs or nothing ahead of anchor
582
582
 
583
- while (previousSiblings.length > 0) {
584
- const node = previousSiblings.pop();
585
583
 
586
- if ($isCodeHighlightNode(node)) {
587
- const text = node.getTextContent();
588
- const offset = findFirstNotSpaceOrTabCharAtText(text, true);
584
+ let codeCharacterAtAnchorOffset = null;
589
585
 
590
- if (offset !== -1) {
591
- currentNode = node;
592
- currentNodeOffset = offset;
593
- }
586
+ if (offset < anchor.getTextContentSize()) {
587
+ if ($isCodeHighlightNode(anchor)) {
588
+ codeCharacterAtAnchorOffset = anchor.getTextContent()[offset];
594
589
  }
590
+ } else {
591
+ const nextSibling = anchor.getNextSibling();
595
592
 
596
- if (lexical.$isLineBreakNode(node)) {
597
- break;
593
+ if ($isCodeHighlightNode(nextSibling)) {
594
+ codeCharacterAtAnchorOffset = nextSibling.getTextContent()[0];
598
595
  }
599
596
  }
600
597
 
601
- if (currentNode === null) {
602
- const nextSiblings = anchor.getNextSiblings();
598
+ if (codeCharacterAtAnchorOffset !== null && codeCharacterAtAnchorOffset !== ' ') {
599
+ // Borderline whitespace and code, move to line beginning
600
+ return last;
601
+ } else {
602
+ const nextNonBlank = findNextNonBlankInLine(anchor, offset);
603
603
 
604
- while (nextSiblings.length > 0) {
605
- const node = nextSiblings.shift();
604
+ if (nextNonBlank !== null) {
605
+ return nextNonBlank;
606
+ } else {
607
+ return last;
608
+ }
609
+ }
610
+ }
606
611
 
607
- if ($isCodeHighlightNode(node)) {
608
- const text = node.getTextContent();
609
- const offset = findFirstNotSpaceOrTabCharAtText(text, true);
612
+ function findNextNonBlankInLine(anchor, offset) {
613
+ let node = anchor;
614
+ let nodeOffset = offset;
615
+ let nodeTextContent = anchor.getTextContent();
616
+ let nodeTextContentSize = anchor.getTextContentSize(); // eslint-disable-next-line no-constant-condition
610
617
 
611
- if (offset !== -1) {
612
- currentNode = node;
613
- currentNodeOffset = offset;
614
- break;
615
- }
618
+ while (true) {
619
+ if (!$isCodeHighlightNode(node) || nodeOffset === nodeTextContentSize) {
620
+ node = node.getNextSibling();
621
+
622
+ if (node === null || lexical.$isLineBreakNode(node)) {
623
+ return null;
616
624
  }
617
625
 
618
- if (lexical.$isLineBreakNode(node)) {
619
- break;
626
+ if ($isCodeHighlightNode(node)) {
627
+ nodeOffset = 0;
628
+ nodeTextContent = node.getTextContent();
629
+ nodeTextContentSize = node.getTextContentSize();
620
630
  }
621
631
  }
622
- }
623
-
624
- return {
625
- node: currentNode,
626
- offset: currentNodeOffset
627
- };
628
- }
629
- function getEndOfCodeInLine(anchor) {
630
- let currentNode = null;
631
- let currentNodeOffset = -1;
632
- const nextSiblings = anchor.getNextSiblings();
633
- nextSiblings.unshift(anchor);
634
-
635
- while (nextSiblings.length > 0) {
636
- const node = nextSiblings.shift();
637
632
 
638
633
  if ($isCodeHighlightNode(node)) {
639
- const text = node.getTextContent();
640
- const offset = findFirstNotSpaceOrTabCharAtText(text, false);
641
-
642
- if (offset !== -1) {
643
- currentNode = node;
644
- currentNodeOffset = offset + 1;
634
+ if (nodeTextContent[nodeOffset] !== ' ') {
635
+ return {
636
+ node,
637
+ offset: nodeOffset
638
+ };
645
639
  }
646
- }
647
640
 
648
- if (lexical.$isLineBreakNode(node)) {
649
- break;
641
+ nodeOffset++;
650
642
  }
651
643
  }
644
+ }
652
645
 
653
- if (currentNode === null) {
654
- const previousSiblings = anchor.getPreviousSiblings();
655
-
656
- while (previousSiblings.length > 0) {
657
- const node = previousSiblings.pop();
658
-
659
- if ($isCodeHighlightNode(node)) {
660
- const text = node.getTextContent();
661
- const offset = findFirstNotSpaceOrTabCharAtText(text, false);
662
-
663
- if (offset !== -1) {
664
- currentNode = node;
665
- currentNodeOffset = offset + 1;
666
- break;
667
- }
668
- }
646
+ function getEndOfCodeInLine(anchor) {
647
+ const lastNode = getLastCodeNodeOfLine(anchor);
669
648
 
670
- if (lexical.$isLineBreakNode(node)) {
671
- break;
672
- }
673
- }
649
+ if (!!lexical.$isLineBreakNode(lastNode)) {
650
+ throw Error(`Unexpected lineBreakNode in getEndOfCodeInLine`);
674
651
  }
675
652
 
676
- return {
677
- node: currentNode,
678
- offset: currentNodeOffset
679
- };
653
+ return lastNode;
680
654
  }
681
655
 
682
656
  function textNodeTransform(node, editor, tokenizer) {
@@ -784,17 +758,18 @@ function getHighlightNodes(tokens) {
784
758
  const nodes = [];
785
759
  tokens.forEach(token => {
786
760
  if (typeof token === 'string') {
787
- const partials = token.split('\n');
761
+ const partials = token.split(/(\n|\t)/);
762
+ const partialsLength = partials.length;
788
763
 
789
- for (let i = 0; i < partials.length; i++) {
790
- const text = partials[i];
764
+ for (let i = 0; i < partialsLength; i++) {
765
+ const part = partials[i];
791
766
 
792
- if (text.length) {
793
- nodes.push($createCodeHighlightNode(text));
794
- }
795
-
796
- if (i < partials.length - 1) {
767
+ if (part === '\n' || part === '\r\n') {
797
768
  nodes.push(lexical.$createLineBreakNode());
769
+ } else if (part === '\t') {
770
+ nodes.push(lexical.$createTabNode());
771
+ } else if (part.length > 0) {
772
+ nodes.push($createCodeHighlightNode(part));
798
773
  }
799
774
  }
800
775
  } else {
@@ -915,80 +890,176 @@ function getDiffRange(prevNodes, nextNodes) {
915
890
  }
916
891
 
917
892
  function isEqual(nodeA, nodeB) {
918
- // Only checking for code higlight nodes and linebreaks. If it's regular text node
893
+ // Only checking for code higlight nodes, tabs and linebreaks. If it's regular text node
919
894
  // returning false so that it's transformed into code highlight node
920
- if ($isCodeHighlightNode(nodeA) && $isCodeHighlightNode(nodeB)) {
921
- return nodeA.__text === nodeB.__text && nodeA.__highlightType === nodeB.__highlightType;
895
+ return $isCodeHighlightNode(nodeA) && $isCodeHighlightNode(nodeB) && nodeA.__text === nodeB.__text && nodeA.__highlightType === nodeB.__highlightType || lexical.$isTabNode(nodeA) && lexical.$isTabNode(nodeB) || lexical.$isLineBreakNode(nodeA) && lexical.$isLineBreakNode(nodeB);
896
+ }
897
+
898
+ function $isSelectionInCode(selection) {
899
+ if (!lexical.$isRangeSelection(selection)) {
900
+ return false;
922
901
  }
923
902
 
924
- if (lexical.$isLineBreakNode(nodeA) && lexical.$isLineBreakNode(nodeB)) {
903
+ const anchorNode = selection.anchor.getNode();
904
+ const focusNode = selection.focus.getNode();
905
+
906
+ if (anchorNode.is(focusNode) && $isCodeNode(anchorNode)) {
925
907
  return true;
926
908
  }
927
909
 
928
- return false;
910
+ const anchorParent = anchorNode.getParent();
911
+ return $isCodeNode(anchorParent) && anchorParent.is(focusNode.getParent());
929
912
  }
930
913
 
931
- function handleMultilineIndent(type) {
932
- const selection = lexical.$getSelection();
933
-
934
- if (!lexical.$isRangeSelection(selection) || selection.isCollapsed()) {
935
- return false;
936
- } // Only run multiline indent logic on selections exclusively composed of code highlights and linebreaks
914
+ function $getCodeLines(selection) {
915
+ const nodes = selection.getNodes();
916
+ const lines = [[]];
937
917
 
918
+ if (nodes.length === 1 && $isCodeNode(nodes[0])) {
919
+ return lines;
920
+ }
938
921
 
939
- const nodes = selection.getNodes();
922
+ let lastLine = lines[0];
940
923
 
941
924
  for (let i = 0; i < nodes.length; i++) {
942
925
  const node = nodes[i];
943
926
 
944
- if (!$isCodeHighlightNode(node) && !lexical.$isLineBreakNode(node)) {
945
- return false;
927
+ if (!($isCodeHighlightNode(node) || lexical.$isTabNode(node) || lexical.$isLineBreakNode(node))) {
928
+ throw Error(`Expected selection to be inside CodeBlock and consisting of CodeHighlightNode, TabNode and LineBreakNode`);
929
+ }
930
+
931
+ if (lexical.$isLineBreakNode(node)) {
932
+ if (i !== 0 && lastLine.length > 0) {
933
+ lastLine = [];
934
+ lines.push(lastLine);
935
+ }
936
+ } else {
937
+ lastLine.push(node);
946
938
  }
947
939
  }
948
940
 
949
- const startOfLine = getFirstCodeHighlightNodeOfLine(nodes[0]);
941
+ return lines;
942
+ }
943
+
944
+ function handleTab(shiftKey) {
945
+ const selection = lexical.$getSelection();
950
946
 
951
- if (startOfLine != null) {
952
- doIndent(startOfLine, type);
947
+ if (!lexical.$isRangeSelection(selection) || !$isSelectionInCode(selection)) {
948
+ return null;
953
949
  }
954
950
 
955
- for (let i = 1; i < nodes.length; i++) {
956
- const node = nodes[i];
951
+ const indentOrOutdent = !shiftKey ? lexical.INDENT_CONTENT_COMMAND : lexical.OUTDENT_CONTENT_COMMAND;
952
+ const tabOrOutdent = !shiftKey ? lexical.INSERT_TAB_COMMAND : lexical.OUTDENT_CONTENT_COMMAND; // 1. If multiple lines selected: indent/outdent
957
953
 
958
- if (lexical.$isLineBreakNode(nodes[i - 1]) && $isCodeHighlightNode(node)) {
959
- doIndent(node, type);
960
- }
954
+ const codeLines = $getCodeLines(selection);
955
+
956
+ if (codeLines.length > 1) {
957
+ return indentOrOutdent;
958
+ } // 2. If entire line selected: indent/outdent
959
+
960
+
961
+ const selectionNodes = selection.getNodes();
962
+ const firstNode = selectionNodes[0];
963
+
964
+ if (!($isCodeNode(firstNode) || $isCodeHighlightNode(firstNode) || lexical.$isTabNode(firstNode) || lexical.$isLineBreakNode(firstNode))) {
965
+ throw Error(`Expected selection firstNode to be CodeHighlightNode or TabNode`);
961
966
  }
962
967
 
963
- return true;
968
+ if ($isCodeNode(firstNode)) {
969
+ return indentOrOutdent;
970
+ }
971
+
972
+ const firstOfLine = getFirstCodeNodeOfLine(firstNode);
973
+ const lastOfLine = getLastCodeNodeOfLine(firstNode);
974
+ const anchor = selection.anchor;
975
+ const focus = selection.focus;
976
+ let selectionFirst;
977
+ let selectionLast;
978
+
979
+ if (focus.isBefore(anchor)) {
980
+ selectionFirst = focus;
981
+ selectionLast = anchor;
982
+ } else {
983
+ selectionFirst = anchor;
984
+ selectionLast = focus;
985
+ }
986
+
987
+ if (firstOfLine !== null && lastOfLine !== null && selectionFirst.key === firstOfLine.getKey() && selectionFirst.offset === 0 && selectionLast.key === lastOfLine.getKey() && selectionLast.offset === lastOfLine.getTextContentSize()) {
988
+ return indentOrOutdent;
989
+ } // 3. Else: tab/outdent
990
+
991
+
992
+ return tabOrOutdent;
964
993
  }
965
994
 
966
- function doIndent(node, type) {
967
- const text = node.getTextContent();
995
+ function handleMultilineIndent(type) {
996
+ const selection = lexical.$getSelection();
997
+
998
+ if (!lexical.$isRangeSelection(selection) || !$isSelectionInCode(selection)) {
999
+ return false;
1000
+ }
1001
+
1002
+ const codeLines = $getCodeLines(selection);
1003
+ const codeLinesLength = codeLines.length; // Multiple lines selection
1004
+
1005
+ if (codeLines.length > 1) {
1006
+ for (let i = 0; i < codeLinesLength; i++) {
1007
+ const line = codeLines[i];
1008
+
1009
+ if (line.length > 0) {
1010
+ let firstOfLine = line[0]; // First and last lines might not be complete
1011
+
1012
+ if (i === 0) {
1013
+ firstOfLine = getFirstCodeNodeOfLine(firstOfLine);
1014
+ }
1015
+
1016
+ if (firstOfLine !== null) {
1017
+ if (type === lexical.INDENT_CONTENT_COMMAND) {
1018
+ firstOfLine.insertBefore(lexical.$createTabNode());
1019
+ } else if (lexical.$isTabNode(firstOfLine)) {
1020
+ firstOfLine.remove();
1021
+ }
1022
+ }
1023
+ }
1024
+ }
1025
+
1026
+ return true;
1027
+ } // Just one line
1028
+
1029
+
1030
+ const selectionNodes = selection.getNodes();
1031
+ const firstNode = selectionNodes[0];
1032
+
1033
+ if (!($isCodeNode(firstNode) || $isCodeHighlightNode(firstNode) || lexical.$isTabNode(firstNode) || lexical.$isLineBreakNode(firstNode))) {
1034
+ throw Error(`Expected selection firstNode to be CodeHighlightNode or CodeTabNode`);
1035
+ }
1036
+
1037
+ if ($isCodeNode(firstNode)) {
1038
+ // CodeNode is empty
1039
+ if (type === lexical.INDENT_CONTENT_COMMAND) {
1040
+ selection.insertNodes([lexical.$createTabNode()]);
1041
+ }
1042
+
1043
+ return true;
1044
+ }
1045
+
1046
+ const firstOfLine = getFirstCodeNodeOfLine(firstNode);
1047
+
1048
+ if (!(firstOfLine !== null)) {
1049
+ throw Error(`Expected getFirstCodeNodeOfLine to return a valid Code Node`);
1050
+ }
968
1051
 
969
1052
  if (type === lexical.INDENT_CONTENT_COMMAND) {
970
- // If the codeblock node doesn't start with whitespace, we don't want to
971
- // naively prepend a '\t'; Prism will then mangle all of our nodes when
972
- // it separates the whitespace from the first non-whitespace node. This
973
- // will lead to selection bugs when indenting lines that previously
974
- // didn't start with a whitespace character
975
- if (text.length > 0 && /\s/.test(text[0])) {
976
- node.setTextContent('\t' + text);
1053
+ if (lexical.$isLineBreakNode(firstOfLine)) {
1054
+ firstOfLine.insertAfter(lexical.$createTabNode());
977
1055
  } else {
978
- const indentNode = $createCodeHighlightNode('\t');
979
- node.insertBefore(indentNode);
980
- }
981
- } else {
982
- if (text.indexOf('\t') === 0) {
983
- // Same as above - if we leave empty text nodes lying around, the resulting
984
- // selection will be mangled
985
- if (text.length === 1) {
986
- node.remove();
987
- } else {
988
- node.setTextContent(text.substring(1));
989
- }
1056
+ firstOfLine.insertBefore(lexical.$createTabNode());
990
1057
  }
1058
+ } else if (lexical.$isTabNode(firstOfLine)) {
1059
+ firstOfLine.remove();
991
1060
  }
1061
+
1062
+ return true;
992
1063
  }
993
1064
 
994
1065
  function handleShiftLines(type, event) {
@@ -1011,7 +1082,7 @@ function handleShiftLines(type, event) {
1011
1082
  const focusNode = focus.getNode();
1012
1083
  const arrowIsUp = type === lexical.KEY_ARROW_UP_COMMAND; // Ensure the selection is within the codeblock
1013
1084
 
1014
- if (!$isCodeHighlightNode(anchorNode) || !$isCodeHighlightNode(focusNode)) {
1085
+ if (!$isSelectionInCode(selection) || !($isCodeHighlightNode(anchorNode) || lexical.$isTabNode(anchorNode)) || !($isCodeHighlightNode(focusNode) || lexical.$isTabNode(focusNode))) {
1015
1086
  return false;
1016
1087
  }
1017
1088
 
@@ -1043,8 +1114,16 @@ function handleShiftLines(type, event) {
1043
1114
  return false;
1044
1115
  }
1045
1116
 
1046
- const start = getFirstCodeHighlightNodeOfLine(anchorNode);
1047
- const end = getLastCodeHighlightNodeOfLine(focusNode);
1117
+ let start;
1118
+ let end;
1119
+
1120
+ if (anchorNode.isBefore(focusNode)) {
1121
+ start = getFirstCodeNodeOfLine(anchorNode);
1122
+ end = getLastCodeNodeOfLine(focusNode);
1123
+ } else {
1124
+ start = getFirstCodeNodeOfLine(focusNode);
1125
+ end = getLastCodeNodeOfLine(anchorNode);
1126
+ }
1048
1127
 
1049
1128
  if (start == null || end == null) {
1050
1129
  return false;
@@ -1055,7 +1134,7 @@ function handleShiftLines(type, event) {
1055
1134
  for (let i = 0; i < range.length; i++) {
1056
1135
  const node = range[i];
1057
1136
 
1058
- if (!$isCodeHighlightNode(node) && !lexical.$isLineBreakNode(node)) {
1137
+ if (!$isCodeHighlightNode(node) && !lexical.$isTabNode(node) && !lexical.$isLineBreakNode(node)) {
1059
1138
  return false;
1060
1139
  }
1061
1140
  } // After this point, we know the selection is within the codeblock. We may not be able to
@@ -1078,7 +1157,7 @@ function handleShiftLines(type, event) {
1078
1157
  return true;
1079
1158
  }
1080
1159
 
1081
- const maybeInsertionPoint = arrowIsUp ? getFirstCodeHighlightNodeOfLine(sibling) : getLastCodeHighlightNodeOfLine(sibling);
1160
+ const maybeInsertionPoint = $isCodeHighlightNode(sibling) || lexical.$isTabNode(sibling) || lexical.$isLineBreakNode(sibling) ? arrowIsUp ? getFirstCodeNodeOfLine(sibling) : getLastCodeNodeOfLine(sibling) : null;
1082
1161
  let insertionPoint = maybeInsertionPoint != null ? maybeInsertionPoint : sibling;
1083
1162
  linebreak.remove();
1084
1163
  range.forEach(node => node.remove());
@@ -1114,27 +1193,30 @@ function handleMoveTo(type, event) {
1114
1193
  const focusNode = focus.getNode();
1115
1194
  const isMoveToStart = type === lexical.MOVE_TO_START;
1116
1195
 
1117
- if (!$isCodeHighlightNode(anchorNode) || !$isCodeHighlightNode(focusNode)) {
1196
+ if (!($isCodeHighlightNode(anchorNode) || lexical.$isTabNode(anchorNode)) || !($isCodeHighlightNode(focusNode) || lexical.$isTabNode(focusNode))) {
1118
1197
  return false;
1119
1198
  }
1120
1199
 
1121
- let node;
1122
- let offset;
1123
-
1124
1200
  if (isMoveToStart) {
1125
- ({
1126
- node,
1127
- offset
1128
- } = getStartOfCodeInLine(focusNode));
1129
- } else {
1130
- ({
1131
- node,
1132
- offset
1133
- } = getEndOfCodeInLine(focusNode));
1134
- }
1201
+ const start = getStartOfCodeInLine(focusNode, focus.offset);
1202
+
1203
+ if (start !== null) {
1204
+ const {
1205
+ node,
1206
+ offset
1207
+ } = start;
1135
1208
 
1136
- if (node !== null && offset !== -1) {
1137
- selection.setTextNodeRange(node, offset, node, offset);
1209
+ if (lexical.$isLineBreakNode(node)) {
1210
+ node.selectNext(0, 0);
1211
+ } else {
1212
+ selection.setTextNodeRange(node, offset, node, offset);
1213
+ }
1214
+ } else {
1215
+ focusNode.getParentOrThrow().selectStart();
1216
+ }
1217
+ } else {
1218
+ const node = getEndOfCodeInLine(focusNode);
1219
+ node.select();
1138
1220
  }
1139
1221
 
1140
1222
  event.preventDefault();
@@ -1163,7 +1245,26 @@ function registerCodeHighlighting(editor, tokenizer) {
1163
1245
  }
1164
1246
  }
1165
1247
  });
1166
- }), editor.registerNodeTransform(CodeNode, node => codeNodeTransform(node, editor, tokenizer)), editor.registerNodeTransform(lexical.TextNode, node => textNodeTransform(node, editor, tokenizer)), editor.registerNodeTransform(CodeHighlightNode, node => textNodeTransform(node, editor, tokenizer)), editor.registerCommand(lexical.INDENT_CONTENT_COMMAND, payload => handleMultilineIndent(lexical.INDENT_CONTENT_COMMAND), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.OUTDENT_CONTENT_COMMAND, payload => handleMultilineIndent(lexical.OUTDENT_CONTENT_COMMAND), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ARROW_UP_COMMAND, payload => handleShiftLines(lexical.KEY_ARROW_UP_COMMAND, payload), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ARROW_DOWN_COMMAND, payload => handleShiftLines(lexical.KEY_ARROW_DOWN_COMMAND, payload), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.MOVE_TO_END, payload => handleMoveTo(lexical.MOVE_TO_END, payload), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.MOVE_TO_START, payload => handleMoveTo(lexical.MOVE_TO_START, payload), lexical.COMMAND_PRIORITY_LOW));
1248
+ }), editor.registerNodeTransform(CodeNode, node => codeNodeTransform(node, editor, tokenizer)), editor.registerNodeTransform(lexical.TextNode, node => textNodeTransform(node, editor, tokenizer)), editor.registerNodeTransform(CodeHighlightNode, node => textNodeTransform(node, editor, tokenizer)), editor.registerCommand(lexical.KEY_TAB_COMMAND, event => {
1249
+ const command = handleTab(event.shiftKey);
1250
+
1251
+ if (command === null) {
1252
+ return false;
1253
+ }
1254
+
1255
+ event.preventDefault();
1256
+ editor.dispatchCommand(command, undefined);
1257
+ return true;
1258
+ }, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.INSERT_TAB_COMMAND, () => {
1259
+ const selection = lexical.$getSelection();
1260
+
1261
+ if (!$isSelectionInCode(selection)) {
1262
+ return false;
1263
+ }
1264
+
1265
+ lexical.$insertNodes([lexical.$createTabNode()]);
1266
+ return true;
1267
+ }, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.INDENT_CONTENT_COMMAND, payload => handleMultilineIndent(lexical.INDENT_CONTENT_COMMAND), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.OUTDENT_CONTENT_COMMAND, payload => handleMultilineIndent(lexical.OUTDENT_CONTENT_COMMAND), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ARROW_UP_COMMAND, payload => handleShiftLines(lexical.KEY_ARROW_UP_COMMAND, payload), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ARROW_DOWN_COMMAND, payload => handleShiftLines(lexical.KEY_ARROW_DOWN_COMMAND, payload), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.MOVE_TO_END, payload => handleMoveTo(lexical.MOVE_TO_END, payload), lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.MOVE_TO_START, payload => handleMoveTo(lexical.MOVE_TO_START, payload), lexical.COMMAND_PRIORITY_LOW));
1167
1268
  }
1168
1269
 
1169
1270
  exports.$createCodeHighlightNode = $createCodeHighlightNode;
@@ -1179,9 +1280,9 @@ exports.PrismTokenizer = PrismTokenizer;
1179
1280
  exports.getCodeLanguages = getCodeLanguages;
1180
1281
  exports.getDefaultCodeLanguage = getDefaultCodeLanguage;
1181
1282
  exports.getEndOfCodeInLine = getEndOfCodeInLine;
1182
- exports.getFirstCodeHighlightNodeOfLine = getFirstCodeHighlightNodeOfLine;
1283
+ exports.getFirstCodeNodeOfLine = getFirstCodeNodeOfLine;
1183
1284
  exports.getLanguageFriendlyName = getLanguageFriendlyName;
1184
- exports.getLastCodeHighlightNodeOfLine = getLastCodeHighlightNodeOfLine;
1285
+ exports.getLastCodeNodeOfLine = getLastCodeNodeOfLine;
1185
1286
  exports.getStartOfCodeInLine = getStartOfCodeInLine;
1186
1287
  exports.normalizeCodeLang = normalizeCodeLang;
1187
1288
  exports.registerCodeHighlighting = registerCodeHighlighting;
@@ -15,40 +15,60 @@ import type {
15
15
  RangeSelection,
16
16
  EditorThemeClasses,
17
17
  LexicalEditor,
18
+ LineBreakNode,
19
+ SerializedElementNode,
20
+ SerializedTabNode,
21
+ TabNode,
18
22
  } from 'lexical';
19
23
 
20
24
  import {ElementNode, TextNode} from 'lexical';
21
25
 
22
- declare export class CodeNode extends ElementNode {
23
- static getType(): string;
24
- static clone(node: CodeNode): CodeNode;
25
- constructor(language: ?string, key?: NodeKey): void;
26
- createDOM(config: EditorConfig): HTMLElement;
27
- updateDOM(prevNode: CodeNode, dom: HTMLElement): boolean;
28
- insertNewAfter(
29
- selection: RangeSelection,
30
- restoreSelection?: boolean,
31
- ): null | ParagraphNode | CodeHighlightNode;
32
- canInsertTab(): boolean;
33
- collapseAtStart(): true;
34
- setLanguage(language: string): void;
35
- getLanguage(): string | void;
26
+ /**
27
+ * CodeHighlighter
28
+ */
29
+ declare export function getEndOfCodeInLine(
30
+ anchor: CodeHighlightNode | TabNode,
31
+ ): CodeHighlightNode | TabNode;
32
+
33
+ declare export function getStartOfCodeInLine(
34
+ anchor: CodeHighlightNode | TabNode,
35
+ offset: number,
36
+ ): null | {
37
+ node: CodeHighlightNode | TabNode | LineBreakNode,
38
+ offset: number,
39
+ };
40
+
41
+ type TokenContent = string | Token | (string | Token)[];
42
+ export interface Token {
43
+ type: string;
44
+ content: TokenContent;
36
45
  }
37
- declare export function $createCodeNode(language: ?string): CodeNode;
38
- declare export function $isCodeNode(
39
- node: ?LexicalNode,
40
- ): boolean %checks(node instanceof CodeNode);
46
+ export interface Tokenizer {
47
+ defaultLanguage: string;
48
+ tokenize(code: string, language?: string): (string | Token)[];
49
+ }
50
+ declare export var PrismTokenizer: Tokenizer;
51
+
52
+ declare export function registerCodeHighlighting(
53
+ editor: LexicalEditor,
54
+ tokenizer?: Tokenizer,
55
+ ): () => void;
41
56
 
42
- declare export function getFirstCodeHighlightNodeOfLine(
43
- anchor: LexicalNode,
44
- ): ?CodeHighlightNode;
57
+ /**
58
+ * CodeHighlightNode
59
+ */
45
60
 
46
- declare export function getLastCodeHighlightNodeOfLine(
47
- anchor: LexicalNode,
48
- ): ?CodeHighlightNode;
61
+ declare export function $createCodeHighlightNode(
62
+ text: string,
63
+ highlightType?: string,
64
+ ): CodeHighlightNode;
49
65
 
50
- declare export function getDefaultCodeLanguage(): string;
51
- declare export function getCodeLanguages(): Array<string>;
66
+ declare export function $isCodeHighlightNode(
67
+ node: ?LexicalNode,
68
+ ): boolean %checks(node instanceof CodeHighlightNode);
69
+
70
+ declare export var CODE_LANGUAGE_FRIENDLY_NAME_MAP: {[string]: string};
71
+ declare export var CODE_LANGUAGE_MAP: {[string]: string};
52
72
 
53
73
  declare export class CodeHighlightNode extends TextNode {
54
74
  __highlightType: ?string;
@@ -66,29 +86,50 @@ declare export class CodeHighlightNode extends TextNode {
66
86
  setFormat(format: number): this;
67
87
  }
68
88
 
69
- type TokenContent = string | Token | (string | Token)[];
70
- export interface Token {
71
- type: string;
72
- content: TokenContent;
73
- }
74
- export interface Tokenizer {
75
- defaultLanguage: string;
76
- tokenize(code: string, language?: string): (string | Token)[];
77
- }
89
+ declare export var DEFAULT_CODE_LANGUAGE: string;
78
90
 
79
- declare function getHighlightThemeClass(
80
- theme: EditorThemeClasses,
81
- highlightType: ?string,
82
- ): ?string;
83
- declare export function $createCodeHighlightNode(
84
- text: string,
85
- highlightType?: string,
86
- ): CodeHighlightNode;
87
- declare export function $isCodeHighlightNode(
91
+ declare export var getCodeLanguages: () => Array<string>;
92
+ declare export var getDefaultCodeLanguage: () => string;
93
+
94
+ declare export function getFirstCodeNodeOfLine(
95
+ anchor: CodeHighlightNode | TabNode | LineBreakNode,
96
+ ): null | CodeHighlightNode | TabNode | LineBreakNode;
97
+
98
+ declare export function getLanguageFriendlyName(lang: string): string;
99
+
100
+ declare export function getLastCodeNodeOfLine(
101
+ anchor: CodeHighlightNode | TabNode | LineBreakNode,
102
+ ): CodeHighlightNode | TabNode | LineBreakNode;
103
+
104
+ declare export function normalizeCodeLang(lang: string): string;
105
+
106
+ /**
107
+ * CodeNode
108
+ */
109
+
110
+ export type SerializedCodeNode = {
111
+ ...SerializedElementNode,
112
+ language: string | null | void,
113
+ };
114
+
115
+ declare export function $createCodeNode(language: ?string): CodeNode;
116
+
117
+ declare export function $isCodeNode(
88
118
  node: ?LexicalNode,
89
- ): boolean %checks(node instanceof CodeHighlightNode);
119
+ ): boolean %checks(node instanceof CodeNode);
90
120
 
91
- declare export function registerCodeHighlighting(
92
- editor: LexicalEditor,
93
- tokenizer?: Tokenizer,
94
- ): () => void;
121
+ declare export class CodeNode extends ElementNode {
122
+ __language: string | null | void;
123
+ static getType(): string;
124
+ static clone(node: CodeNode): CodeNode;
125
+ constructor(language: ?string, key?: NodeKey): void;
126
+ createDOM(config: EditorConfig): HTMLElement;
127
+ updateDOM(prevNode: CodeNode, dom: HTMLElement): boolean;
128
+ insertNewAfter(
129
+ selection: RangeSelection,
130
+ restoreSelection?: boolean,
131
+ ): null | ParagraphNode | CodeHighlightNode | TabNode;
132
+ collapseAtStart(): true;
133
+ setLanguage(language: string): void;
134
+ getLanguage(): string | void;
135
+ }
@@ -4,32 +4,38 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- 'use strict';var e=require("prismjs");require("prismjs/components/prism-clike");require("prismjs/components/prism-javascript");require("prismjs/components/prism-markup");require("prismjs/components/prism-markdown");require("prismjs/components/prism-c");require("prismjs/components/prism-css");require("prismjs/components/prism-objectivec");require("prismjs/components/prism-sql");require("prismjs/components/prism-python");require("prismjs/components/prism-rust");require("prismjs/components/prism-swift");
8
- require("prismjs/components/prism-typescript");require("prismjs/components/prism-java");require("prismjs/components/prism-cpp");var n=require("@lexical/utils"),u=require("lexical");let v=a=>null!=a&&e.languages.hasOwnProperty(a)?a:void 0;function x(a,b){for(let c of a.childNodes){if(n.isHTMLElement(c)&&c.tagName===b)return!0;x(c,b)}return!1}
9
- class y extends u.ElementNode{static getType(){return"code"}static clone(a){return new y(a.__language,a.__key)}constructor(a,b){super(b);this.__language=v(a)}createDOM(a){let b=document.createElement("code");n.addClassNamesToElement(b,a.theme.code);b.setAttribute("spellcheck","false");(a=this.getLanguage())&&b.setAttribute("data-highlight-language",a);return b}updateDOM(a,b){let c=this.__language;a=a.__language;c?c!==a&&b.setAttribute("data-highlight-language",c):a&&b.removeAttribute("data-highlight-language");
7
+ 'use strict';var d=require("prismjs");require("prismjs/components/prism-clike");require("prismjs/components/prism-javascript");require("prismjs/components/prism-markup");require("prismjs/components/prism-markdown");require("prismjs/components/prism-c");require("prismjs/components/prism-css");require("prismjs/components/prism-objectivec");require("prismjs/components/prism-sql");require("prismjs/components/prism-python");require("prismjs/components/prism-rust");require("prismjs/components/prism-swift");
8
+ require("prismjs/components/prism-typescript");require("prismjs/components/prism-java");require("prismjs/components/prism-cpp");var l=require("@lexical/utils"),r=require("lexical");let v=a=>null!=a&&d.languages.hasOwnProperty(a)?a:void 0;function x(a,b){for(let c of a.childNodes){if(l.isHTMLElement(c)&&c.tagName===b)return!0;x(c,b)}return!1}
9
+ class y extends r.ElementNode{static getType(){return"code"}static clone(a){return new y(a.__language,a.__key)}constructor(a,b){super(b);this.__language=v(a)}createDOM(a){let b=document.createElement("code");l.addClassNamesToElement(b,a.theme.code);b.setAttribute("spellcheck","false");(a=this.getLanguage())&&b.setAttribute("data-highlight-language",a);return b}updateDOM(a,b){let c=this.__language;a=a.__language;c?c!==a&&b.setAttribute("data-highlight-language",c):a&&b.removeAttribute("data-highlight-language");
10
10
  return!1}static importDOM(){return{code:a=>null!=a.textContent&&(/\r?\n/.test(a.textContent)||x(a,"BR"))?{conversion:z,priority:1}:null,div:()=>({conversion:aa,priority:1}),pre:()=>({conversion:z,priority:0}),table:a=>A(a)?{conversion:ba,priority:3}:null,td:a=>{let b=a.closest("table");return a.classList.contains("js-file-line")?{conversion:ca,priority:3}:b&&A(b)?{conversion:B,priority:3}:null},tr:a=>(a=a.closest("table"))&&A(a)?{conversion:B,priority:3}:null}}static importJSON(a){let b=C(a.language);
11
- b.setFormat(a.format);b.setIndent(a.indent);b.setDirection(a.direction);return b}exportJSON(){return{...super.exportJSON(),language:this.getLanguage(),type:"code",version:1}}insertNewAfter(a,b=!0){var c=this.getChildren(),d=c.length;if(2<=d&&"\n"===c[d-1].getTextContent()&&"\n"===c[d-2].getTextContent()&&a.isCollapsed()&&a.anchor.key===this.__key&&a.anchor.offset===d)return c[d-1].remove(),c[d-2].remove(),a=u.$createParagraphNode(),this.insertAfter(a,b),a;b=a.anchor.getNode();d=D(b);if(null!=d){c=
12
- 0;for(d=d.getTextContent();c<d.length&&/[\t ]/.test(d[c]);)c+=1;if(0<c)return c=d.substring(0,c),c=E(c),b.insertAfter(c),a.insertNodes([u.$createLineBreakNode()]),c.select(),c}return null}canInsertTab(){let a=u.$getSelection();return u.$isRangeSelection(a)&&a.isCollapsed()?!0:!1}canIndent(){return!1}collapseAtStart(){let a=u.$createParagraphNode();this.getChildren().forEach(b=>a.append(b));this.replace(a);return!0}setLanguage(a){this.getWritable().__language=v(a)}getLanguage(){return this.getLatest().__language}}
13
- function C(a){return u.$applyNodeReplacement(new y(a))}function F(a){return a instanceof y}function z(){return{node:C(),preformatted:!0}}function aa(a){let b=null!==a.style.fontFamily.match("monospace");return b||da(a)?{after:c=>{let d=a.parentNode;null!=d&&a!==d.lastChild&&c.push(u.$createLineBreakNode());return c},node:b?C():null,preformatted:b}:{node:null}}function ba(){return{node:C(),preformatted:!0}}function B(){return{node:null}}
14
- function ca(a){return{after:b=>{a.parentNode&&a.parentNode.nextSibling&&b.push(u.$createLineBreakNode());return b},node:null}}function da(a){for(a=a.parentElement;null!==a;){if(null!==a.style.fontFamily.match("monospace"))return!0;a=a.parentElement}return!1}function A(a){return a.classList.contains("js-file-line-container")}
15
- let G={c:"C",clike:"C-like",cpp:"C++",css:"CSS",html:"HTML",java:"Java",js:"JavaScript",markdown:"Markdown",objc:"Objective-C",plain:"Plain Text",py:"Python",rust:"Rust",sql:"SQL",swift:"Swift",typescript:"TypeScript",xml:"XML"},H={cpp:"cpp",java:"java",javascript:"js",md:"markdown",plaintext:"plain",python:"py",text:"plain",ts:"typescript"};function I(a){return H[a]||a}
16
- class J extends u.TextNode{constructor(a,b,c){super(a,c);this.__highlightType=b}static getType(){return"code-highlight"}static clone(a){return new J(a.__text,a.__highlightType||void 0,a.__key)}getHighlightType(){return this.getLatest().__highlightType}createDOM(a){let b=super.createDOM(a);a=K(a.theme,this.__highlightType);n.addClassNamesToElement(b,a);return b}updateDOM(a,b,c){let d=super.updateDOM(a,b,c);a=K(c.theme,a.__highlightType);c=K(c.theme,this.__highlightType);a!==c&&(a&&n.removeClassNamesFromElement(b,
17
- a),c&&n.addClassNamesToElement(b,c));return d}static importJSON(a){let b=E(a.text,a.highlightType);b.setFormat(a.format);b.setDetail(a.detail);b.setMode(a.mode);b.setStyle(a.style);return b}exportJSON(){return{...super.exportJSON(),highlightType:this.getHighlightType(),type:"code-highlight",version:1}}setFormat(){return this}isParentRequired(){return!0}createParentElementNode(){return C()}}function K(a,b){return b&&a&&a.codeHighlight&&a.codeHighlight[b]}
18
- function E(a,b){return u.$applyNodeReplacement(new J(a,b))}function L(a){return a instanceof J}function D(a){let b=null,c=a.getPreviousSiblings();for(c.push(a);0<c.length&&(a=c.pop(),L(a)&&(b=a),!u.$isLineBreakNode(a)););return b}function M(a){let b=null,c=a.getNextSiblings();for(c.unshift(a);0<c.length&&(a=c.shift(),L(a)&&(b=a),!u.$isLineBreakNode(a)););return b}let N={defaultLanguage:"javascript",tokenize(a,b){return e.tokenize(a,e.languages[b||""]||e.languages[this.defaultLanguage])}};
19
- function O(a,b){var c=a.length;let d=-1;if(b)for(b=0;b<c;b++){let f=a[b];if(" "!==f&&"\t"!==f){d=b;break}}else for(--c;-1<c;c--)if(b=a[c]," "!==b&&"\t"!==b){d=c;break}return d}
20
- function P(a){let b=null,c=-1;var d=a.getPreviousSiblings();for(d.push(a);0<d.length;){var f=d.pop();if(L(f)){var g=f.getTextContent();g=O(g,!0);-1!==g&&(b=f,c=g)}if(u.$isLineBreakNode(f))break}if(null===b)for(a=a.getNextSiblings();0<a.length;){d=a.shift();if(L(d)&&(f=d.getTextContent(),f=O(f,!0),-1!==f)){b=d;c=f;break}if(u.$isLineBreakNode(d))break}return{node:b,offset:c}}
21
- function Q(a){let b=null,c=-1;var d=a.getNextSiblings();for(d.unshift(a);0<d.length;){var f=d.shift();if(L(f)){var g=f.getTextContent();g=O(g,!1);-1!==g&&(b=f,c=g+1)}if(u.$isLineBreakNode(f))break}if(null===b)for(a=a.getPreviousSiblings();0<a.length;){d=a.pop();if(L(d)&&(f=d.getTextContent(),f=O(f,!1),-1!==f)){b=d;c=f+1;break}if(u.$isLineBreakNode(d))break}return{node:b,offset:c}}function R(a,b,c){let d=a.getParent();F(d)?S(d,b,c):L(a)&&a.replace(u.$createTextNode(a.__text))}let T=new Set;
22
- function S(a,b,c){let d=a.getKey();T.has(d)||(T.add(d),void 0===a.getLanguage()&&a.setLanguage(c.defaultLanguage),b.update(()=>{ea(d,()=>{var f=u.$getNodeByKey(d);if(!F(f)||!f.isAttached())return!1;var g=f.getTextContent();g=c.tokenize(g,f.getLanguage()||c.defaultLanguage);g=U(g);var k=f.getChildren();for(f=0;f<k.length&&V(k[f],g[f]);)f++;var h=k.length;let l=g.length,p=Math.min(h,l)-f,m=0;for(;m<p;)if(m++,!V(k[h-m],g[l-m])){m--;break}k=f;h-=m;g=g.slice(f,l-m);let {from:w,to:t,nodesForReplacement:r}=
23
- {from:k,nodesForReplacement:g,to:h};return w!==t||r.length?(a.splice(w,t-w,r),!0):!1})},{onUpdate:()=>{T.delete(d)},skipTransforms:!0}))}
24
- function U(a){let b=[];a.forEach(c=>{if("string"===typeof c){c=c.split("\n");for(var d=0;d<c.length;d++){let f=c[d];f.length&&b.push(E(f));d<c.length-1&&b.push(u.$createLineBreakNode())}}else({content:d}=c),"string"===typeof d?b.push(E(d,c.type)):Array.isArray(d)&&1===d.length&&"string"===typeof d[0]?b.push(E(d[0],c.type)):Array.isArray(d)&&b.push(...U(d))});return b}
25
- function ea(a,b){a=u.$getNodeByKey(a);if(F(a)&&a.isAttached()){var c=u.$getSelection();if(u.$isRangeSelection(c)){c=c.anchor;var d=c.offset,f="element"===c.type&&u.$isLineBreakNode(a.getChildAtIndex(c.offset-1)),g=0;if(!f){let k=c.getNode();g=d+k.getPreviousSiblings().reduce((h,l)=>h+l.getTextContentSize(),0)}b()&&(f?c.getNode().select(d,d):a.getChildren().some(k=>{let h=u.$isTextNode(k);if(h||u.$isLineBreakNode(k)){let l=k.getTextContentSize();if(h&&l>=g)return k.select(g,g),!0;g-=l}return!1}))}else b()}}
26
- function V(a,b){return L(a)&&L(b)?a.__text===b.__text&&a.__highlightType===b.__highlightType:u.$isLineBreakNode(a)&&u.$isLineBreakNode(b)?!0:!1}function W(a){var b=u.$getSelection();if(!u.$isRangeSelection(b)||b.isCollapsed())return!1;b=b.getNodes();for(var c=0;c<b.length;c++){var d=b[c];if(!L(d)&&!u.$isLineBreakNode(d))return!1}c=D(b[0]);null!=c&&X(c,a);for(c=1;c<b.length;c++)d=b[c],u.$isLineBreakNode(b[c-1])&&L(d)&&X(d,a);return!0}
27
- function X(a,b){let c=a.getTextContent();b===u.INDENT_CONTENT_COMMAND?0<c.length&&/\s/.test(c[0])?a.setTextContent("\t"+c):(b=E("\t"),a.insertBefore(b)):0===c.indexOf("\t")&&(1===c.length?a.remove():a.setTextContent(c.substring(1)))}
28
- function Y(a,b){let c=u.$getSelection();if(!u.$isRangeSelection(c))return!1;let {anchor:d,focus:f}=c,g=d.offset,k=f.offset,h=d.getNode(),l=f.getNode();var p=a===u.KEY_ARROW_UP_COMMAND;if(!L(h)||!L(l))return!1;if(!b.altKey){if(c.isCollapsed())if(a=h.getParentOrThrow(),p&&0===g&&null===h.getPreviousSibling()){if(null===a.getPreviousSibling())return a.selectPrevious(),b.preventDefault(),!0}else if(!p&&g===h.getTextContentSize()&&null===h.getNextSibling()&&null===a.getNextSibling())return a.selectNext(),
29
- b.preventDefault(),!0;return!1}var m=D(h);let w=M(l);if(null==m||null==w)return!1;let t=m.getNodesBetween(w);for(let q=0;q<t.length;q++){let Z=t[q];if(!L(Z)&&!u.$isLineBreakNode(Z))return!1}b.preventDefault();b.stopPropagation();b=p?m.getPreviousSibling():w.getNextSibling();if(!u.$isLineBreakNode(b))return!0;m=p?b.getPreviousSibling():b.getNextSibling();if(null==m)return!0;p=p?D(m):M(m);let r=null!=p?p:m;b.remove();t.forEach(q=>q.remove());a===u.KEY_ARROW_UP_COMMAND?(t.forEach(q=>r.insertBefore(q)),
30
- r.insertBefore(b)):(r.insertAfter(b),r=b,t.forEach(q=>{r.insertAfter(q);r=q}));c.setTextNodeRange(h,g,l,k);return!0}function fa(a,b){let c=u.$getSelection();if(!u.$isRangeSelection(c))return!1;let {anchor:d,focus:f}=c,g=d.getNode(),k=f.getNode();a=a===u.MOVE_TO_START;if(!L(g)||!L(k))return!1;let h,l;a?{node:h,offset:l}=P(k):{node:h,offset:l}=Q(k);null!==h&&-1!==l&&c.setTextNodeRange(h,l,h,l);b.preventDefault();b.stopPropagation();return!0}exports.$createCodeHighlightNode=E;
31
- exports.$createCodeNode=C;exports.$isCodeHighlightNode=L;exports.$isCodeNode=F;exports.CODE_LANGUAGE_FRIENDLY_NAME_MAP=G;exports.CODE_LANGUAGE_MAP=H;exports.CodeHighlightNode=J;exports.CodeNode=y;exports.DEFAULT_CODE_LANGUAGE="javascript";exports.PrismTokenizer=N;exports.getCodeLanguages=()=>Object.keys(e.languages).filter(a=>"function"!==typeof e.languages[a]).sort();exports.getDefaultCodeLanguage=()=>"javascript";exports.getEndOfCodeInLine=Q;exports.getFirstCodeHighlightNodeOfLine=D;
32
- exports.getLanguageFriendlyName=function(a){a=I(a);return G[a]||a};exports.getLastCodeHighlightNodeOfLine=M;exports.getStartOfCodeInLine=P;exports.normalizeCodeLang=I;
33
- exports.registerCodeHighlighting=function(a,b){if(!a.hasNodes([y,J]))throw Error("CodeHighlightPlugin: CodeNode or CodeHighlightNode not registered on editor");null==b&&(b=N);return n.mergeRegister(a.registerMutationListener(y,c=>{a.update(()=>{for(let [g,k]of c)if("destroyed"!==k){var d=u.$getNodeByKey(g);if(null!==d)a:{var f=d;d=a.getElementByKey(f.getKey());if(null===d)break a;f=f.getChildren();let h=f.length;if(h===d.__cachedChildrenLength)break a;d.__cachedChildrenLength=h;let l="1",p=1;for(let m=
34
- 0;m<h;m++)u.$isLineBreakNode(f[m])&&(l+="\n"+ ++p);d.setAttribute("data-gutter",l)}}})}),a.registerNodeTransform(y,c=>S(c,a,b)),a.registerNodeTransform(u.TextNode,c=>R(c,a,b)),a.registerNodeTransform(J,c=>R(c,a,b)),a.registerCommand(u.INDENT_CONTENT_COMMAND,()=>W(u.INDENT_CONTENT_COMMAND),u.COMMAND_PRIORITY_LOW),a.registerCommand(u.OUTDENT_CONTENT_COMMAND,()=>W(u.OUTDENT_CONTENT_COMMAND),u.COMMAND_PRIORITY_LOW),a.registerCommand(u.KEY_ARROW_UP_COMMAND,c=>Y(u.KEY_ARROW_UP_COMMAND,c),u.COMMAND_PRIORITY_LOW),
35
- a.registerCommand(u.KEY_ARROW_DOWN_COMMAND,c=>Y(u.KEY_ARROW_DOWN_COMMAND,c),u.COMMAND_PRIORITY_LOW),a.registerCommand(u.MOVE_TO_END,c=>fa(u.MOVE_TO_END,c),u.COMMAND_PRIORITY_LOW),a.registerCommand(u.MOVE_TO_START,c=>fa(u.MOVE_TO_START,c),u.COMMAND_PRIORITY_LOW))}
11
+ b.setFormat(a.format);b.setIndent(a.indent);b.setDirection(a.direction);return b}exportJSON(){return{...super.exportJSON(),language:this.getLanguage(),type:"code",version:1}}insertNewAfter(a,b=!0){var c=this.getChildren(),e=c.length;if(2<=e&&"\n"===c[e-1].getTextContent()&&"\n"===c[e-2].getTextContent()&&a.isCollapsed()&&a.anchor.key===this.__key&&a.anchor.offset===e)return c[e-1].remove(),c[e-2].remove(),a=r.$createParagraphNode(),this.insertAfter(a,b),a;b=a.anchor;c=a.focus;b=(b.isBefore(c)?b:c).getNode();
12
+ if(D(b)||r.$isTabNode(b)){b=E(b);for(c=[];;)if(r.$isTabNode(b))c.push(r.$createTabNode()),b=b.getNextSibling();else if(D(b)){e=0;let f=b.getTextContent(),g=b.getTextContentSize();for(;e<g&&" "===f[e];e++);0!==e&&c.push(F(" ".repeat(e)));if(e!==g)break;b=b.getNextSibling()}else break;if(0<c.length)return a.insertNodes([r.$createLineBreakNode(),...c]),c[c.length-1]}return null}canIndent(){return!1}collapseAtStart(){let a=r.$createParagraphNode();this.getChildren().forEach(b=>a.append(b));this.replace(a);
13
+ return!0}setLanguage(a){this.getWritable().__language=v(a)}getLanguage(){return this.getLatest().__language}}function C(a){return r.$applyNodeReplacement(new y(a))}function G(a){return a instanceof y}function z(){return{node:C()}}function aa(a){let b=null!==a.style.fontFamily.match("monospace");return b||da(a)?{after:c=>{let e=a.parentNode;null!=e&&a!==e.lastChild&&c.push(r.$createLineBreakNode());return c},node:b?C():null}:{node:null}}function ba(){return{node:C()}}
14
+ function B(){return{node:null}}function ca(a){return{after:b=>{a.parentNode&&a.parentNode.nextSibling&&b.push(r.$createLineBreakNode());return b},node:null}}function da(a){for(a=a.parentElement;null!==a;){if(null!==a.style.fontFamily.match("monospace"))return!0;a=a.parentElement}return!1}function A(a){return a.classList.contains("js-file-line-container")}
15
+ let H={c:"C",clike:"C-like",cpp:"C++",css:"CSS",html:"HTML",java:"Java",js:"JavaScript",markdown:"Markdown",objc:"Objective-C",plain:"Plain Text",py:"Python",rust:"Rust",sql:"SQL",swift:"Swift",typescript:"TypeScript",xml:"XML"},J={cpp:"cpp",java:"java",javascript:"js",md:"markdown",plaintext:"plain",python:"py",text:"plain",ts:"typescript"};function K(a){return J[a]||a}
16
+ class L extends r.TextNode{constructor(a,b,c){super(a,c);this.__highlightType=b}static getType(){return"code-highlight"}static clone(a){return new L(a.__text,a.__highlightType||void 0,a.__key)}getHighlightType(){return this.getLatest().__highlightType}createDOM(a){let b=super.createDOM(a);a=M(a.theme,this.__highlightType);l.addClassNamesToElement(b,a);return b}updateDOM(a,b,c){let e=super.updateDOM(a,b,c);a=M(c.theme,a.__highlightType);c=M(c.theme,this.__highlightType);a!==c&&(a&&l.removeClassNamesFromElement(b,
17
+ a),c&&l.addClassNamesToElement(b,c));return e}static importJSON(a){let b=F(a.text,a.highlightType);b.setFormat(a.format);b.setDetail(a.detail);b.setMode(a.mode);b.setStyle(a.style);return b}exportJSON(){return{...super.exportJSON(),highlightType:this.getHighlightType(),type:"code-highlight",version:1}}setFormat(){return this}isParentRequired(){return!0}createParentElementNode(){return C()}}function M(a,b){return b&&a&&a.codeHighlight&&a.codeHighlight[b]}
18
+ function F(a,b){return r.$applyNodeReplacement(new L(a,b))}function D(a){return a instanceof L}function E(a){let b=a;for(;D(a)||r.$isTabNode(a);)b=a,a=a.getPreviousSibling();return b}function N(a){let b=a;for(;D(a)||r.$isTabNode(a);)b=a,a=a.getNextSibling();return b}let O={defaultLanguage:"javascript",tokenize(a,b){return d.tokenize(a,d.languages[b||""]||d.languages[this.defaultLanguage])}};
19
+ function P(a,b){let c=null;var e=null,f=a;let g=b,k=a.getTextContent();for(;;){if(0===g){f=f.getPreviousSibling();if(null===f)break;if(!(D(f)||r.$isTabNode(f)||r.$isLineBreakNode(f)))throw Error("Expected a valid Code Node: CodeHighlightNode, TabNode, LineBreakNode");if(r.$isLineBreakNode(f)){c={node:f,offset:1};break}g=Math.max(0,f.getTextContentSize()-1);k=f.getTextContent()}else g--;let h=k[g];D(f)&&" "!==h&&(e={node:f,offset:g})}if(null!==e)return e;e=null;b<a.getTextContentSize()?D(a)&&(e=a.getTextContent()[b]):
20
+ (f=a.getNextSibling(),D(f)&&(e=f.getTextContent()[0]));if(null!==e&&" "!==e)return c;a:for(e=a,f=a.getTextContent(),a=a.getTextContentSize();;){if(!D(e)||b===a){e=e.getNextSibling();if(null===e||r.$isLineBreakNode(e)){a=null;break a}D(e)&&(b=0,f=e.getTextContent(),a=e.getTextContentSize())}if(D(e)){if(" "!==f[b]){a={node:e,offset:b};break a}b++}}return null!==a?a:c}function Q(a){a=N(a);if(r.$isLineBreakNode(a))throw Error("Unexpected lineBreakNode in getEndOfCodeInLine");return a}
21
+ function R(a,b,c){let e=a.getParent();G(e)?S(e,b,c):D(a)&&a.replace(r.$createTextNode(a.__text))}let T=new Set;
22
+ function S(a,b,c){let e=a.getKey();T.has(e)||(T.add(e),void 0===a.getLanguage()&&a.setLanguage(c.defaultLanguage),b.update(()=>{ea(e,()=>{var f=r.$getNodeByKey(e);if(!G(f)||!f.isAttached())return!1;var g=f.getTextContent();g=c.tokenize(g,f.getLanguage()||c.defaultLanguage);g=U(g);var k=f.getChildren();for(f=0;f<k.length&&V(k[f],g[f]);)f++;var h=k.length;let m=g.length,q=Math.min(h,m)-f,n=0;for(;n<q;)if(n++,!V(k[h-n],g[m-n])){n--;break}k=f;h-=n;g=g.slice(f,m-n);let {from:p,to:w,nodesForReplacement:u}=
23
+ {from:k,nodesForReplacement:g,to:h};return p!==w||u.length?(a.splice(p,w-p,u),!0):!1})},{onUpdate:()=>{T.delete(e)},skipTransforms:!0}))}
24
+ function U(a){let b=[];a.forEach(c=>{if("string"===typeof c){c=c.split(/(\n|\t)/);var e=c.length;for(let f=0;f<e;f++){let g=c[f];"\n"===g||"\r\n"===g?b.push(r.$createLineBreakNode()):"\t"===g?b.push(r.$createTabNode()):0<g.length&&b.push(F(g))}}else({content:e}=c),"string"===typeof e?b.push(F(e,c.type)):Array.isArray(e)&&1===e.length&&"string"===typeof e[0]?b.push(F(e[0],c.type)):Array.isArray(e)&&b.push(...U(e))});return b}
25
+ function ea(a,b){a=r.$getNodeByKey(a);if(G(a)&&a.isAttached()){var c=r.$getSelection();if(r.$isRangeSelection(c)){c=c.anchor;var e=c.offset,f="element"===c.type&&r.$isLineBreakNode(a.getChildAtIndex(c.offset-1)),g=0;if(!f){let k=c.getNode();g=e+k.getPreviousSiblings().reduce((h,m)=>h+m.getTextContentSize(),0)}b()&&(f?c.getNode().select(e,e):a.getChildren().some(k=>{let h=r.$isTextNode(k);if(h||r.$isLineBreakNode(k)){let m=k.getTextContentSize();if(h&&m>=g)return k.select(g,g),!0;g-=m}return!1}))}else b()}}
26
+ function V(a,b){return D(a)&&D(b)&&a.__text===b.__text&&a.__highlightType===b.__highlightType||r.$isTabNode(a)&&r.$isTabNode(b)||r.$isLineBreakNode(a)&&r.$isLineBreakNode(b)}function W(a){if(!r.$isRangeSelection(a))return!1;var b=a.anchor.getNode();a=a.focus.getNode();if(b.is(a)&&G(b))return!0;b=b.getParent();return G(b)&&b.is(a.getParent())}
27
+ function X(a){a=a.getNodes();let b=[[]];if(1===a.length&&G(a[0]))return b;let c=b[0];for(let e=0;e<a.length;e++){let f=a[e];if(!(D(f)||r.$isTabNode(f)||r.$isLineBreakNode(f)))throw Error("Expected selection to be inside CodeBlock and consisting of CodeHighlightNode, TabNode and LineBreakNode");r.$isLineBreakNode(f)?0!==e&&0<c.length&&(c=[],b.push(c)):c.push(f)}return b}
28
+ function fa(a){var b=r.$getSelection();if(!r.$isRangeSelection(b)||!W(b))return null;let c=a?r.OUTDENT_CONTENT_COMMAND:r.INDENT_CONTENT_COMMAND;a=a?r.OUTDENT_CONTENT_COMMAND:r.INSERT_TAB_COMMAND;if(1<X(b).length)return c;var e=b.getNodes()[0];if(!(G(e)||D(e)||r.$isTabNode(e)||r.$isLineBreakNode(e)))throw Error("Expected selection firstNode to be CodeHighlightNode or TabNode");if(G(e))return c;let f=E(e);e=N(e);var g=b.anchor;let k=b.focus;k.isBefore(g)?b=k:(b=g,g=k);return null!==f&&null!==e&&b.key===
29
+ f.getKey()&&0===b.offset&&g.key===e.getKey()&&g.offset===e.getTextContentSize()?c:a}
30
+ function Y(a){var b=r.$getSelection();if(!r.$isRangeSelection(b)||!W(b))return!1;var c=X(b);let e=c.length;if(1<c.length){for(b=0;b<e;b++){var f=c[b];0<f.length&&(f=f[0],0===b&&(f=E(f)),null!==f&&(a===r.INDENT_CONTENT_COMMAND?f.insertBefore(r.$createTabNode()):r.$isTabNode(f)&&f.remove()))}return!0}c=b.getNodes()[0];if(!(G(c)||D(c)||r.$isTabNode(c)||r.$isLineBreakNode(c)))throw Error("Expected selection firstNode to be CodeHighlightNode or CodeTabNode");if(G(c))return a===r.INDENT_CONTENT_COMMAND&&
31
+ b.insertNodes([r.$createTabNode()]),!0;c=E(c);if(null===c)throw Error("Expected getFirstCodeNodeOfLine to return a valid Code Node");a===r.INDENT_CONTENT_COMMAND?r.$isLineBreakNode(c)?c.insertAfter(r.$createTabNode()):c.insertBefore(r.$createTabNode()):r.$isTabNode(c)&&c.remove();return!0}
32
+ function Z(a,b){let c=r.$getSelection();if(!r.$isRangeSelection(c))return!1;let {anchor:e,focus:f}=c,g=e.offset,k=f.offset,h=e.getNode(),m=f.getNode();var q=a===r.KEY_ARROW_UP_COMMAND;if(!W(c)||!D(h)&&!r.$isTabNode(h)||!D(m)&&!r.$isTabNode(m))return!1;if(!b.altKey){if(c.isCollapsed())if(a=h.getParentOrThrow(),q&&0===g&&null===h.getPreviousSibling()){if(null===a.getPreviousSibling())return a.selectPrevious(),b.preventDefault(),!0}else if(!q&&g===h.getTextContentSize()&&null===h.getNextSibling()&&null===
33
+ a.getNextSibling())return a.selectNext(),b.preventDefault(),!0;return!1}let n;if(h.isBefore(m)){var p=E(h);n=N(m)}else p=E(m),n=N(h);if(null==p||null==n)return!1;let w=p.getNodesBetween(n);for(let t=0;t<w.length;t++){let I=w[t];if(!D(I)&&!r.$isTabNode(I)&&!r.$isLineBreakNode(I))return!1}b.preventDefault();b.stopPropagation();b=q?p.getPreviousSibling():n.getNextSibling();if(!r.$isLineBreakNode(b))return!0;p=q?b.getPreviousSibling():b.getNextSibling();if(null==p)return!0;q=D(p)||r.$isTabNode(p)||r.$isLineBreakNode(p)?
34
+ q?E(p):N(p):null;let u=null!=q?q:p;b.remove();w.forEach(t=>t.remove());a===r.KEY_ARROW_UP_COMMAND?(w.forEach(t=>u.insertBefore(t)),u.insertBefore(b)):(u.insertAfter(b),u=b,w.forEach(t=>{u.insertAfter(t);u=t}));c.setTextNodeRange(h,g,m,k);return!0}
35
+ function ha(a,b){let c=r.$getSelection();if(!r.$isRangeSelection(c))return!1;let {anchor:e,focus:f}=c;var g=e.getNode();let k=f.getNode();a=a===r.MOVE_TO_START;if(!D(g)&&!r.$isTabNode(g)||!D(k)&&!r.$isTabNode(k))return!1;if(a)if(g=P(k,f.offset),null!==g){let {node:h,offset:m}=g;r.$isLineBreakNode(h)?h.selectNext(0,0):c.setTextNodeRange(h,m,h,m)}else k.getParentOrThrow().selectStart();else Q(k).select();b.preventDefault();b.stopPropagation();return!0}exports.$createCodeHighlightNode=F;
36
+ exports.$createCodeNode=C;exports.$isCodeHighlightNode=D;exports.$isCodeNode=G;exports.CODE_LANGUAGE_FRIENDLY_NAME_MAP=H;exports.CODE_LANGUAGE_MAP=J;exports.CodeHighlightNode=L;exports.CodeNode=y;exports.DEFAULT_CODE_LANGUAGE="javascript";exports.PrismTokenizer=O;exports.getCodeLanguages=()=>Object.keys(d.languages).filter(a=>"function"!==typeof d.languages[a]).sort();exports.getDefaultCodeLanguage=()=>"javascript";exports.getEndOfCodeInLine=Q;exports.getFirstCodeNodeOfLine=E;
37
+ exports.getLanguageFriendlyName=function(a){a=K(a);return H[a]||a};exports.getLastCodeNodeOfLine=N;exports.getStartOfCodeInLine=P;exports.normalizeCodeLang=K;
38
+ exports.registerCodeHighlighting=function(a,b){if(!a.hasNodes([y,L]))throw Error("CodeHighlightPlugin: CodeNode or CodeHighlightNode not registered on editor");null==b&&(b=O);return l.mergeRegister(a.registerMutationListener(y,c=>{a.update(()=>{for(let [g,k]of c)if("destroyed"!==k){var e=r.$getNodeByKey(g);if(null!==e)a:{var f=e;e=a.getElementByKey(f.getKey());if(null===e)break a;f=f.getChildren();let h=f.length;if(h===e.__cachedChildrenLength)break a;e.__cachedChildrenLength=h;let m="1",q=1;for(let n=
39
+ 0;n<h;n++)r.$isLineBreakNode(f[n])&&(m+="\n"+ ++q);e.setAttribute("data-gutter",m)}}})}),a.registerNodeTransform(y,c=>S(c,a,b)),a.registerNodeTransform(r.TextNode,c=>R(c,a,b)),a.registerNodeTransform(L,c=>R(c,a,b)),a.registerCommand(r.KEY_TAB_COMMAND,c=>{let e=fa(c.shiftKey);if(null===e)return!1;c.preventDefault();a.dispatchCommand(e,void 0);return!0},r.COMMAND_PRIORITY_LOW),a.registerCommand(r.INSERT_TAB_COMMAND,()=>{let c=r.$getSelection();if(!W(c))return!1;r.$insertNodes([r.$createTabNode()]);
40
+ return!0},r.COMMAND_PRIORITY_LOW),a.registerCommand(r.INDENT_CONTENT_COMMAND,()=>Y(r.INDENT_CONTENT_COMMAND),r.COMMAND_PRIORITY_LOW),a.registerCommand(r.OUTDENT_CONTENT_COMMAND,()=>Y(r.OUTDENT_CONTENT_COMMAND),r.COMMAND_PRIORITY_LOW),a.registerCommand(r.KEY_ARROW_UP_COMMAND,c=>Z(r.KEY_ARROW_UP_COMMAND,c),r.COMMAND_PRIORITY_LOW),a.registerCommand(r.KEY_ARROW_DOWN_COMMAND,c=>Z(r.KEY_ARROW_DOWN_COMMAND,c),r.COMMAND_PRIORITY_LOW),a.registerCommand(r.MOVE_TO_END,c=>ha(r.MOVE_TO_END,c),r.COMMAND_PRIORITY_LOW),
41
+ a.registerCommand(r.MOVE_TO_START,c=>ha(r.MOVE_TO_START,c),r.COMMAND_PRIORITY_LOW))}
package/index.d.ts CHANGED
@@ -8,6 +8,6 @@
8
8
  *
9
9
  */
10
10
  export { getEndOfCodeInLine, getStartOfCodeInLine, PrismTokenizer, registerCodeHighlighting, } from './CodeHighlighter';
11
- export { $createCodeHighlightNode, $isCodeHighlightNode, CODE_LANGUAGE_FRIENDLY_NAME_MAP, CODE_LANGUAGE_MAP, CodeHighlightNode, DEFAULT_CODE_LANGUAGE, getCodeLanguages, getDefaultCodeLanguage, getFirstCodeHighlightNodeOfLine, getLanguageFriendlyName, getLastCodeHighlightNodeOfLine, normalizeCodeLang, } from './CodeHighlightNode';
11
+ export { $createCodeHighlightNode, $isCodeHighlightNode, CODE_LANGUAGE_FRIENDLY_NAME_MAP, CODE_LANGUAGE_MAP, CodeHighlightNode, DEFAULT_CODE_LANGUAGE, getCodeLanguages, getDefaultCodeLanguage, getFirstCodeNodeOfLine, getLanguageFriendlyName, getLastCodeNodeOfLine, normalizeCodeLang, } from './CodeHighlightNode';
12
12
  export type { SerializedCodeNode } from './CodeNode';
13
13
  export { $createCodeNode, $isCodeNode, CodeNode } from './CodeNode';
package/package.json CHANGED
@@ -8,13 +8,13 @@
8
8
  "code"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.10.0",
11
+ "version": "0.11.0",
12
12
  "main": "LexicalCode.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.10.0"
14
+ "lexical": "0.11.0"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/utils": "0.10.0",
17
+ "@lexical/utils": "0.11.0",
18
18
  "prismjs": "^1.27.0"
19
19
  },
20
20
  "repository": {