@lexical/code-core 0.50.1-nightly.20260916.0 → 0.51.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # `@lexical/code-core`
2
2
 
3
- [![See API Documentation](https://lexical.dev/img/see-api-documentation.svg)](https://lexical.dev/docs/api/modules/lexical_code_core)
3
+ [![See API Documentation](https://lexical.dev/img/see-api-documentation.svg)](https://lexical.dev/docs/api/modules/lexical_code-core)
4
4
 
5
5
  This package contains the base functionality for the code blocks and code highlighting for Lexical. This package
6
6
  is considered an implementation detail and is being used transitionally while the deprecated highlighting
@@ -5,10 +5,15 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import { type EditorConfig, type ElementNode, type LexicalNode, type LexicalUpdateJSON, type NodeKey, type SerializedTextNode, type Spread, TextNode } from 'lexical';
8
+ import { type EditorConfig, type ElementNode, type LexicalNode, type LexicalParseJSON, type NodeKey, type SerializedPartial, type SerializedTextNode, type Spread, TextNode } from 'lexical';
9
9
  type SerializedCodeHighlightNode = Spread<{
10
10
  highlightType: string | null | undefined;
11
11
  }, SerializedTextNode>;
12
+ export interface CodeHighlightNode {
13
+ exportJSON(compact?: false): SerializedCodeHighlightNode;
14
+ exportJSON(compact: boolean): SerializedPartial<SerializedCodeHighlightNode>;
15
+ updateFromJSON(serializedNode: LexicalParseJSON<SerializedCodeHighlightNode>): this;
16
+ }
12
17
  /** @noInheritDoc */
13
18
  export declare class CodeHighlightNode extends TextNode {
14
19
  /** @internal */
@@ -16,6 +21,8 @@ export declare class CodeHighlightNode extends TextNode {
16
21
  constructor(text?: string, highlightType?: string | null | undefined, key?: NodeKey);
17
22
  $config(): import("lexical").BaseStaticNodeConfig & {
18
23
  readonly text?: {
24
+ readonly extends: typeof LexicalNode;
25
+ readonly generated: import("lexical").GeneratedJSONFactory;
19
26
  readonly importDOM: {
20
27
  readonly '#text': () => {
21
28
  conversion: (domNode: Node) => import("lexical").DOMConversionOutput;
@@ -66,22 +73,94 @@ export declare class CodeHighlightNode extends TextNode {
66
73
  priority: 0;
67
74
  };
68
75
  };
76
+ readonly json: import("lexical").NodeSerializationSchema<TextNode, {
77
+ readonly detail?: string | number | undefined;
78
+ readonly format?: string | number | undefined;
79
+ readonly mode?: "normal" | "token" | "segmented" | undefined;
80
+ readonly style?: string | undefined;
81
+ readonly text?: string | undefined;
82
+ }>;
69
83
  } | undefined;
70
- } & {
84
+ } & import("lexical").StaticNodeTypeAccessor<"text"> & import("lexical").StaticNodeConfigAccessor<{
85
+ readonly extends: typeof LexicalNode;
86
+ readonly generated: import("lexical").GeneratedJSONFactory;
87
+ readonly importDOM: {
88
+ readonly '#text': () => {
89
+ conversion: (domNode: Node) => import("lexical").DOMConversionOutput;
90
+ priority: 0;
91
+ };
92
+ readonly b: () => {
93
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
94
+ priority: 0;
95
+ };
96
+ readonly code: () => {
97
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
98
+ priority: 0;
99
+ };
100
+ readonly em: () => {
101
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
102
+ priority: 0;
103
+ };
104
+ readonly i: () => {
105
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
106
+ priority: 0;
107
+ };
108
+ readonly mark: () => {
109
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
110
+ priority: 0;
111
+ };
112
+ readonly s: () => {
113
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
114
+ priority: 0;
115
+ };
116
+ readonly span: () => {
117
+ conversion: (domNode: HTMLSpanElement) => import("lexical").DOMConversionOutput;
118
+ priority: 0;
119
+ };
120
+ readonly strong: () => {
121
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
122
+ priority: 0;
123
+ };
124
+ readonly sub: () => {
125
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
126
+ priority: 0;
127
+ };
128
+ readonly sup: () => {
129
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
130
+ priority: 0;
131
+ };
132
+ readonly u: () => {
133
+ conversion: (domNode: HTMLElement) => import("lexical").DOMConversionOutput;
134
+ priority: 0;
135
+ };
136
+ };
137
+ readonly json: import("lexical").NodeSerializationSchema<TextNode, {
138
+ readonly detail?: string | number | undefined;
139
+ readonly format?: string | number | undefined;
140
+ readonly mode?: "normal" | "token" | "segmented" | undefined;
141
+ readonly style?: string | undefined;
142
+ readonly text?: string | undefined;
143
+ }>;
144
+ }> & {
71
145
  readonly "code-highlight"?: {
72
146
  readonly extends: typeof TextNode;
147
+ readonly generated: import("lexical").GeneratedJSONFactory;
148
+ readonly json: import("lexical").NodeSerializationSchema<CodeHighlightNode, {
149
+ readonly highlightType?: string | null | undefined;
150
+ }>;
73
151
  } | undefined;
74
152
  } & import("lexical").StaticNodeTypeAccessor<"code-highlight"> & import("lexical").StaticNodeConfigAccessor<{
75
153
  readonly extends: typeof TextNode;
154
+ readonly generated: import("lexical").GeneratedJSONFactory;
155
+ readonly json: import("lexical").NodeSerializationSchema<CodeHighlightNode, {
156
+ readonly highlightType?: string | null | undefined;
157
+ }>;
76
158
  }>;
77
- afterCloneFrom(prevNode: this): void;
78
159
  getHighlightType(): string | null | undefined;
79
160
  setHighlightType(highlightType?: string | null | undefined): this;
80
161
  canHaveFormat(): boolean;
81
162
  createDOM(config: EditorConfig): HTMLElement;
82
163
  updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean;
83
- updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedCodeHighlightNode>): this;
84
- exportJSON(): SerializedCodeHighlightNode;
85
164
  setFormat(format: number): this;
86
165
  isParentRequired(): true;
87
166
  createParentElementNode(): ElementNode;
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import { type DOMConversionOutput, type DOMExportOutput, type EditorConfig, ElementNode, type LexicalEditor, type LexicalNode, type LexicalUpdateJSON, type NodeKey, type ParagraphNode, type RangeSelection, type SerializedElementNode, type Spread, type TabNode } from 'lexical';
8
+ import { type DOMConversionOutput, type DOMExportOutput, type EditorConfig, ElementNode, type LexicalEditor, type LexicalNode, type LexicalParseJSON, type NodeKey, type ParagraphNode, type RangeSelection, type SerializedElementNode, type SerializedPartial, type Spread, type TabNode } from 'lexical';
9
9
  import { type CodeHighlightNode } from './CodeHighlightNode.js';
10
10
  export type SerializedCodeNode = Spread<{
11
11
  language: string | null | undefined;
@@ -14,6 +14,11 @@ export type SerializedCodeNode = Spread<{
14
14
  export declare const DEFAULT_CODE_LANGUAGE = "javascript";
15
15
  /** @internal Configurable through the extensions. */
16
16
  export declare const getDefaultCodeLanguage: () => string;
17
+ export interface CodeNode {
18
+ exportJSON(compact?: false): SerializedCodeNode;
19
+ exportJSON(compact: boolean): SerializedPartial<SerializedCodeNode>;
20
+ updateFromJSON(serializedNode: LexicalParseJSON<SerializedCodeNode>): this;
21
+ }
17
22
  /** @noInheritDoc */
18
23
  export declare class CodeNode extends ElementNode {
19
24
  /** @internal */
@@ -22,9 +27,21 @@ export declare class CodeNode extends ElementNode {
22
27
  __theme: string | undefined;
23
28
  /** @internal */
24
29
  __isSyntaxHighlightSupported: boolean;
25
- $config(): import("lexical").BaseStaticNodeConfig & {
30
+ $config(): import("lexical").BaseStaticNodeConfig & import("lexical").StaticNodeConfigAccessor<{
31
+ readonly $transform: (node: ElementNode) => void;
32
+ readonly extends: typeof LexicalNode;
33
+ readonly generated: import("lexical").GeneratedJSONFactory;
34
+ readonly json: import("lexical").NodeSerializationSchema<ElementNode, {
35
+ readonly direction?: "ltr" | "rtl" | null | undefined;
36
+ readonly format?: "" | "left" | "start" | "center" | "right" | "end" | "justify" | undefined;
37
+ readonly indent?: string | number | undefined;
38
+ readonly textFormat?: string | number | undefined;
39
+ readonly textStyle?: string | undefined;
40
+ }>;
41
+ }> & {
26
42
  readonly code?: {
27
43
  readonly extends: typeof ElementNode;
44
+ readonly generated: import("lexical").GeneratedJSONFactory;
28
45
  readonly importDOM: {
29
46
  readonly code: (node: Node) => {
30
47
  conversion: typeof $convertPreElement;
@@ -51,9 +68,14 @@ export declare class CodeNode extends ElementNode {
51
68
  priority: 3;
52
69
  } | null;
53
70
  };
71
+ readonly json: import("lexical").NodeSerializationSchema<CodeNode, {
72
+ readonly language?: string | null | undefined;
73
+ readonly theme?: string | undefined;
74
+ }>;
54
75
  } | undefined;
55
76
  } & import("lexical").StaticNodeTypeAccessor<"code"> & import("lexical").StaticNodeConfigAccessor<{
56
77
  readonly extends: typeof ElementNode;
78
+ readonly generated: import("lexical").GeneratedJSONFactory;
57
79
  readonly importDOM: {
58
80
  readonly code: (node: Node) => {
59
81
  conversion: typeof $convertPreElement;
@@ -80,14 +102,16 @@ export declare class CodeNode extends ElementNode {
80
102
  priority: 3;
81
103
  } | null;
82
104
  };
105
+ readonly json: import("lexical").NodeSerializationSchema<CodeNode, {
106
+ readonly language?: string | null | undefined;
107
+ readonly theme?: string | undefined;
108
+ }>;
83
109
  }>;
84
110
  constructor(language?: string | null | undefined, key?: NodeKey);
85
111
  afterCloneFrom(prevNode: this): void;
86
112
  createDOM(config: EditorConfig): HTMLElement;
87
113
  updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean;
88
114
  exportDOM(editor: LexicalEditor): DOMExportOutput;
89
- updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedCodeNode>): this;
90
- exportJSON(): SerializedCodeNode;
91
115
  insertNewAfter(selection: RangeSelection, restoreSelection?: boolean): null | ParagraphNode | CodeHighlightNode | TabNode;
92
116
  canIndent(): false;
93
117
  collapseAtStart(): boolean;
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { sel, ImportOverlays, defineOverlayRules, CoreImportExtension, DOMImportExtension } from '@lexical/html';
10
- import { getTextDirection, $isElementNode, $isTabNode, $isLineBreakNode, tokenizeRawText, $createTabNode, $createLineBreakNode, $getSiblingCaret, $create, ElementNode, $getDocument, addClassNamesToElement, setDOMStyleFromCSS, $getEditor, $isTextNode, $createParagraphNode, isHTMLElement, $applyNodeReplacement, TextNode, removeClassNamesFromElement, isDOMDocumentNode, isDOMTextNode, $generateNodesFromRawText, mergeRegister, KEY_ENTER_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_LOW, TabNode, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ARROW_LEFT_COMMAND, KEY_TAB_COMMAND, INSERT_TAB_COMMAND, $insertNodes, INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND, MOVE_TO_START, MOVE_TO_END, $createPoint, $setSelectionFromCaretRange, $getCaretRangeInDirection, $getCaretRange, $getTextPointCaret, $normalizeCaret } from 'lexical';
10
+ import { getTextDirection, $isElementNode, $isTabNode, $isLineBreakNode, tokenizeRawText, $createTabNode, $createLineBreakNode, $getSiblingCaret, getterTableOf, setterTableOf, setterDefaultOf, aliasTableOf, $create, ElementNode, $getDocument, addClassNamesToElement, setDOMStyleFromCSS, $getEditor, $isTextNode, $createParagraphNode, nodeSchema, withAccessors, optional, stringValue, nullable, isHTMLElement, $applyNodeReplacement, TextNode, removeClassNamesFromElement, isDOMDocumentNode, isDOMTextNode, $generateNodesFromRawText, mergeRegister, KEY_ENTER_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_LOW, TabNode, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ARROW_LEFT_COMMAND, KEY_TAB_COMMAND, INSERT_TAB_COMMAND, $insertNodes, INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND, MOVE_TO_START, MOVE_TO_END, $createPoint, $setSelectionFromCaretRange, $getCaretRangeInDirection, $getCaretRange, $getTextPointCaret, $normalizeCaret } from 'lexical';
11
11
  import { getPeerDependencyFromEditor } from '@lexical/extension/getPeerDependencyFromEditor';
12
12
  import { effect } from '@lexical/extension/signals';
13
13
  import { namedSignals } from '@lexical/extension/namedSignals';
@@ -273,6 +273,236 @@ function $outdentLeadingSpaces(node, tabSize, selection) {
273
273
  *
274
274
  */
275
275
 
276
+
277
+ // The JSON number grammar, anchored, matching numberValue: `Number()` alone
278
+ // reads '0x10' as 16 and '' as 0, and neither is a shape a JSON encoder
279
+ // produces. Emitted from the same source the codegen verified against, so the
280
+ // two cannot be different functions.
281
+ const JSON_NUMBER = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
282
+ function num(v, d) {
283
+ if (typeof v === 'number') {
284
+ return Number.isFinite(v) ? v : d;
285
+ }
286
+ if (typeof v !== 'string' || !JSON_NUMBER.test(v)) {
287
+ return d;
288
+ }
289
+ const n = Number(v);
290
+ return Number.isFinite(n) ? n : d;
291
+ }
292
+ function numC(v, d, min, max, integer) {
293
+ const n = num(v, d);
294
+ return n >= min && n <= max && (false || Number.isInteger(n)) ? n : d;
295
+ }
296
+
297
+ /**
298
+ * CodeNode's schema-declared fields, for a clone. Generated from that
299
+ * schema; do not edit by hand.
300
+ *
301
+ * @internal
302
+ */
303
+ function afterCloneCodeNode(node, prevNode) {
304
+ node.__language = prevNode.__language;
305
+ node.__theme = prevNode.__theme;
306
+ }
307
+
308
+ /** CodeNode's generated implementations, for its `$config`. @internal */
309
+ const GENERATED_CODE = fields => {
310
+ const CODE_FORMAT_GETTER = getterTableOf(fields, 'format');
311
+ const CODE_FORMAT_SETTER = setterTableOf(fields, 'format');
312
+ const CODE_FORMAT_SETTER_DEFAULT = setterDefaultOf(fields, 'format');
313
+
314
+ /** Generated from CodeNode's serialization schema. Do not edit by hand. */
315
+ function exportCodeNode(node) {
316
+ const textFormat = node.__textFormat;
317
+ const textStyle = node.__textStyle;
318
+ const shouldSerializeTextStyles = (textFormat !== 0 || textStyle !== '') && node.shouldSerializeTextStyles();
319
+ return {
320
+ children: [],
321
+ language: node.__language,
322
+ theme: node.__theme,
323
+ direction: node.__dir,
324
+ format: CODE_FORMAT_GETTER[node.__format],
325
+ indent: node.__indent,
326
+ textFormat: textFormat !== 0 && shouldSerializeTextStyles ? textFormat : undefined,
327
+ textStyle: textStyle !== '' && shouldSerializeTextStyles ? textStyle : undefined,
328
+ type: node.__type,
329
+ version: 1
330
+ };
331
+ }
332
+
333
+ /** Generated from CodeNode's serialization schema. Do not edit by hand. */
334
+ function exportCompactCodeNode(node) {
335
+ const textFormat = node.__textFormat;
336
+ const textStyle = node.__textStyle;
337
+ const shouldSerializeTextStyles = (textFormat !== 0 || textStyle !== '') && node.shouldSerializeTextStyles();
338
+ const json = {
339
+ type: node.__type,
340
+ children: []
341
+ };
342
+ const language = node.__language;
343
+ if (language !== undefined) {
344
+ json.language = language;
345
+ }
346
+ const theme = node.__theme;
347
+ if (theme !== undefined) {
348
+ json.theme = theme;
349
+ }
350
+ const direction = node.__dir;
351
+ if (direction != null) {
352
+ json.direction = direction;
353
+ }
354
+ const format = CODE_FORMAT_GETTER[node.__format];
355
+ if (format !== undefined && format !== '') {
356
+ json.format = format;
357
+ }
358
+ const indent = node.__indent;
359
+ if (indent !== undefined && indent !== 0) {
360
+ json.indent = indent;
361
+ }
362
+ if (textFormat !== undefined && textFormat !== 0 && shouldSerializeTextStyles) {
363
+ json.textFormat = textFormat;
364
+ }
365
+ if (textStyle !== undefined && textStyle !== '' && shouldSerializeTextStyles) {
366
+ json.textStyle = textStyle;
367
+ }
368
+ return json;
369
+ }
370
+
371
+ /** Generated from CodeNode's serialization schema. Do not edit by hand. */
372
+ function updateCodeNode(node, json) {
373
+ const direction = json.direction;
374
+ node.__dir = direction === null || direction === 'ltr' || direction === 'rtl' ? direction : null;
375
+ const format = json.format;
376
+ node.__format = typeof format === 'string' && format in CODE_FORMAT_SETTER ? CODE_FORMAT_SETTER[format] : CODE_FORMAT_SETTER_DEFAULT;
377
+ node.__indent = numC(json.indent, 0, 0, Infinity);
378
+ node.__textFormat = num(json.textFormat, 0);
379
+ const textStyle = json.textStyle;
380
+ node.__textStyle = typeof textStyle === 'string' ? textStyle : '';
381
+ const language = json.language;
382
+ node.setLanguage(language == null ? language : typeof language === 'string' ? language : '');
383
+ const theme = json.theme;
384
+ node.setTheme(theme === undefined ? undefined : typeof theme === 'string' ? theme : '');
385
+ return node;
386
+ }
387
+ return {
388
+ exportJSON: exportCodeNode,
389
+ exportCompactJSON: exportCompactCodeNode,
390
+ updateFromJSON: updateCodeNode
391
+ };
392
+ };
393
+
394
+ /**
395
+ * CodeHighlightNode's schema-declared fields, for a clone. Generated from that
396
+ * schema; do not edit by hand.
397
+ *
398
+ * @internal
399
+ */
400
+ function afterCloneCodeHighlightNode(node, prevNode) {
401
+ node.__highlightType = prevNode.__highlightType;
402
+ }
403
+
404
+ /** CodeHighlightNode's generated implementations, for its `$config`. @internal */
405
+ const GENERATED_CODEHIGHLIGHT = fields => {
406
+ const CODEHIGHLIGHT_MODE_GETTER = getterTableOf(fields, 'mode');
407
+ const CODEHIGHLIGHT_DETAIL_ALIAS = aliasTableOf(fields, 'detail', 0);
408
+ const CODEHIGHLIGHT_FORMAT_ALIAS = aliasTableOf(fields, 'format', 0);
409
+ const CODEHIGHLIGHT_MODE_SETTER = setterTableOf(fields, 'mode');
410
+ const CODEHIGHLIGHT_MODE_SETTER_DEFAULT = setterDefaultOf(fields, 'mode');
411
+
412
+ /** Generated from CodeHighlightNode's serialization schema. Do not edit by hand. */
413
+ function exportCodeHighlightNode(node) {
414
+ return {
415
+ highlightType: node.__highlightType,
416
+ detail: node.__detail,
417
+ format: node.__format,
418
+ mode: CODEHIGHLIGHT_MODE_GETTER[node.__mode],
419
+ style: node.__style,
420
+ text: node.__text,
421
+ type: node.__type,
422
+ version: 1
423
+ };
424
+ }
425
+
426
+ /** Generated from CodeHighlightNode's serialization schema. Do not edit by hand. */
427
+ function exportCompactCodeHighlightNode(node) {
428
+ const json = {
429
+ type: node.__type
430
+ };
431
+ const highlightType = node.__highlightType;
432
+ if (highlightType !== undefined) {
433
+ json.highlightType = highlightType;
434
+ }
435
+ const detail = node.__detail;
436
+ if (detail !== undefined && detail !== 0) {
437
+ json.detail = detail;
438
+ }
439
+ const format = node.__format;
440
+ if (format !== undefined && format !== 0) {
441
+ json.format = format;
442
+ }
443
+ const mode = CODEHIGHLIGHT_MODE_GETTER[node.__mode];
444
+ if (mode !== undefined && mode !== 'normal') {
445
+ json.mode = mode;
446
+ }
447
+ const style = node.__style;
448
+ if (style !== undefined && style !== '') {
449
+ json.style = style;
450
+ }
451
+ const text = node.__text;
452
+ if (text !== undefined && text !== '') {
453
+ json.text = text;
454
+ }
455
+ return json;
456
+ }
457
+
458
+ /** Generated from CodeHighlightNode's serialization schema. Do not edit by hand. */
459
+ function updateCodeHighlightNode(node, json) {
460
+ const detail = json.detail;
461
+ node.__detail = typeof detail === 'string' && detail in CODEHIGHLIGHT_DETAIL_ALIAS ? CODEHIGHLIGHT_DETAIL_ALIAS[detail] : num(detail, 0);
462
+ const format = json.format;
463
+ node.setFormat(typeof format === 'string' && format in CODEHIGHLIGHT_FORMAT_ALIAS ? CODEHIGHLIGHT_FORMAT_ALIAS[format] : num(format, 0));
464
+ const mode = json.mode;
465
+ node.__mode = typeof mode === 'string' && mode in CODEHIGHLIGHT_MODE_SETTER ? CODEHIGHLIGHT_MODE_SETTER[mode] : CODEHIGHLIGHT_MODE_SETTER_DEFAULT;
466
+ const style = json.style;
467
+ node.__style = typeof style === 'string' ? style : '';
468
+ const text = json.text;
469
+ node.__text = typeof text === 'string' ? text : '';
470
+ const highlightType = json.highlightType;
471
+ node.setHighlightType(highlightType == null ? highlightType : typeof highlightType === 'string' ? highlightType : '');
472
+ return node;
473
+ }
474
+ return {
475
+ exportJSON: exportCodeHighlightNode,
476
+ exportCompactJSON: exportCompactCodeHighlightNode,
477
+ updateFromJSON: updateCodeHighlightNode,
478
+ afterCloneFrom: afterCloneCodeHighlightNode
479
+ };
480
+ };
481
+
482
+ /**
483
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
484
+ *
485
+ * This source code is licensed under the MIT license found in the
486
+ * LICENSE file in the root directory of this source tree.
487
+ *
488
+ */
489
+
490
+ // Single source of truth for parsing the node-specific properties of a
491
+ // SerializedCodeNode (those it adds over a SerializedElementNode).
492
+ const codeNodeSchema = /* @__PURE__ */nodeSchema()({
493
+ // Read straight off the fields; applied through the setters, which
494
+ // normalize a falsy value to undefined.
495
+ language: /* @__PURE__ */withAccessors(/* @__PURE__ */optional(/* @__PURE__ */nullable(/* @__PURE__ */stringValue())), {
496
+ getter: {
497
+ field: '__language'
498
+ }
499
+ }),
500
+ theme: /* @__PURE__ */withAccessors(/* @__PURE__ */optional(/* @__PURE__ */stringValue()), {
501
+ getter: {
502
+ field: '__theme'
503
+ }
504
+ })
505
+ });
276
506
  const DEFAULT_CODE_LANGUAGE = 'javascript';
277
507
  /** @internal Configurable through the extensions. */
278
508
  const getDefaultCodeLanguage = () => DEFAULT_CODE_LANGUAGE;
@@ -292,7 +522,10 @@ const HIGHLIGHT_LANGUAGE_DATA_ATTRIBUTE = 'data-highlight-language';
292
522
  const THEME_DATA_ATTRIBUTE$1 = 'data-theme';
293
523
  const noExtensionDeprecation = /* @__PURE__ */warnOnlyOnce('Using CodeNode without CodeExtension is deprecated');
294
524
 
525
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
526
+
295
527
  /** @noInheritDoc */
528
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
296
529
  class CodeNode extends ElementNode {
297
530
  /** @internal */
298
531
  __language;
@@ -303,6 +536,7 @@ class CodeNode extends ElementNode {
303
536
  $config() {
304
537
  return this.config('code', {
305
538
  extends: ElementNode,
539
+ generated: GENERATED_CODE,
306
540
  importDOM: {
307
541
  // Typically <pre> is used for code blocks, and <code> for inline code styles
308
542
  // but if it's a multi line <code> we'll create a block. Pass through to
@@ -359,7 +593,8 @@ class CodeNode extends ElementNode {
359
593
  }
360
594
  return null;
361
595
  }
362
- }
596
+ },
597
+ json: codeNodeSchema
363
598
  });
364
599
  }
365
600
 
@@ -372,10 +607,20 @@ class CodeNode extends ElementNode {
372
607
  this.__isSyntaxHighlightSupported = false;
373
608
  this.__theme = undefined;
374
609
  }
610
+
611
+ // Written rather than synthesized from the schema, because
612
+ // `__isSyntaxHighlightSupported` is not a serialized property and no schema
613
+ // describes it: the highlighter extensions set it as they run, and a clone
614
+ // that dropped it would render unhighlighted until the next pass.
615
+ //
616
+ // Declaring one of these takes the class out of the synthesized
617
+ // `afterCloneFrom` entirely, so the schema's own fields are this method's
618
+ // responsibility too — but not its boilerplate: `afterCloneCodeNode` is
619
+ // generated from the same declaration, so adding a property to the schema
620
+ // needs no line here.
375
621
  afterCloneFrom(prevNode) {
376
622
  super.afterCloneFrom(prevNode);
377
- this.__language = prevNode.__language;
378
- this.__theme = prevNode.__theme;
623
+ afterCloneCodeNode(this, prevNode);
379
624
  this.__isSyntaxHighlightSupported = prevNode.__isSyntaxHighlightSupported;
380
625
  }
381
626
 
@@ -463,16 +708,6 @@ class CodeNode extends ElementNode {
463
708
  element
464
709
  };
465
710
  }
466
- updateFromJSON(serializedNode) {
467
- return super.updateFromJSON(serializedNode).setLanguage(serializedNode.language).setTheme(serializedNode.theme);
468
- }
469
- exportJSON() {
470
- return {
471
- ...super.exportJSON(),
472
- language: this.getLanguage(),
473
- theme: this.getTheme()
474
- };
475
- }
476
711
 
477
712
  // Mutation
478
713
  insertNewAfter(selection, restoreSelection = true) {
@@ -663,7 +898,24 @@ function $exitCodeNodeOnEnter(selection) {
663
898
  *
664
899
  */
665
900
 
901
+ // Single source of truth for parsing the node-specific properties of a
902
+ // SerializedCodeHighlightNode (those it adds over a SerializedTextNode).
903
+ const codeHighlightNodeSchema = /* @__PURE__ */nodeSchema()({
904
+ // Read straight off the field; applied through setHighlightType, which
905
+ // normalizes a falsy value to undefined. Naming the field is also what
906
+ // tells the clone where this property lives, so the class needs no
907
+ // `afterCloneFrom` of its own. The same shape CodeNode's `language` uses.
908
+ highlightType: /* @__PURE__ */withAccessors(/* @__PURE__ */optional(/* @__PURE__ */nullable(/* @__PURE__ */stringValue())), {
909
+ getter: {
910
+ field: '__highlightType'
911
+ }
912
+ })
913
+ });
914
+
915
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
916
+
666
917
  /** @noInheritDoc */
918
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
667
919
  class CodeHighlightNode extends TextNode {
668
920
  /** @internal */
669
921
  __highlightType;
@@ -673,13 +925,11 @@ class CodeHighlightNode extends TextNode {
673
925
  }
674
926
  $config() {
675
927
  return this.config('code-highlight', {
676
- extends: TextNode
928
+ extends: TextNode,
929
+ generated: GENERATED_CODEHIGHLIGHT,
930
+ json: codeHighlightNodeSchema
677
931
  });
678
932
  }
679
- afterCloneFrom(prevNode) {
680
- super.afterCloneFrom(prevNode);
681
- this.__highlightType = prevNode.__highlightType;
682
- }
683
933
  getHighlightType() {
684
934
  const self = this.getLatest();
685
935
  return self.__highlightType;
@@ -712,15 +962,6 @@ class CodeHighlightNode extends TextNode {
712
962
  }
713
963
  return update;
714
964
  }
715
- updateFromJSON(serializedNode) {
716
- return super.updateFromJSON(serializedNode).setHighlightType(serializedNode.highlightType);
717
- }
718
- exportJSON() {
719
- return {
720
- ...super.exportJSON(),
721
- highlightType: this.getHighlightType()
722
- };
723
- }
724
965
 
725
966
  // Prevent formatting (bold, underline, etc)
726
967
  setFormat(format) {
@@ -6,5 +6,5 @@
6
6
  *
7
7
  */
8
8
 
9
- import{sel as e,ImportOverlays as t,defineOverlayRules as n,CoreImportExtension as r,DOMImportExtension as i}from"@lexical/html";import{getTextDirection as o,$isElementNode as s,$isTabNode as l,$isLineBreakNode as u,tokenizeRawText as c,$createTabNode as a,$createLineBreakNode as g,$getSiblingCaret as f,$create as h,ElementNode as p,$getDocument as d,addClassNamesToElement as m,setDOMStyleFromCSS as x,$getEditor as S,$isTextNode as b,$createParagraphNode as y,isHTMLElement as _,$applyNodeReplacement as v,TextNode as C,removeClassNamesFromElement as N,isDOMDocumentNode as T,isDOMTextNode as A,$generateNodesFromRawText as P,mergeRegister as O,KEY_ENTER_COMMAND as w,$getSelection as D,$isRangeSelection as H,COMMAND_PRIORITY_LOW as $,TabNode as B,KEY_ARROW_DOWN_COMMAND as E,KEY_ARROW_RIGHT_COMMAND as L,KEY_ARROW_UP_COMMAND as F,KEY_ARROW_LEFT_COMMAND as k,KEY_TAB_COMMAND as M,INSERT_TAB_COMMAND as z,$insertNodes as K,INDENT_CONTENT_COMMAND as I,OUTDENT_CONTENT_COMMAND as j,MOVE_TO_START as J,MOVE_TO_END as R,$createPoint as W,$setSelectionFromCaretRange as q,$getCaretRangeInDirection as U,$getCaretRange as V,$getTextPointCaret as G,$normalizeCaret as Q}from"lexical";import{getPeerDependencyFromEditor as X}from"@lexical/extension/getPeerDependencyFromEditor";import{effect as Y}from"@lexical/extension/signals";import{namedSignals as Z}from"@lexical/extension/namedSignals";import{$onEscapeDown as ee,$onEscapeUp as te}from"@lexical/utils";
10
- /*@__INLINE__*/function ne(e){return()=>{}}function re(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 ie(e,t){let n=e;for(let r=f(e,t);r&&($e(r.origin)||l(r.origin));r=r.getAdjacentCaret())n=r.origin;return n}function oe(e){return ie(e,"previous")}function se(e){return ie(e,"next")}function le(e){const t=oe(e),n=se(e);let r=t;for(;null!==r;){if($e(r)){const e=o(r.getTextContent());if(null!==e)return e}if(r===n)break;r=r.getNextSibling()}const i=t.getParent();if(s(i)){const e=i.getDirection();if("ltr"===e||"rtl"===e)return e}return null}function ue(e,t){let n=null,r=null,i=e,o=t,s=e.getTextContent();for(;;){if(0===o){const e=i.getPreviousSibling();if(null===e){i=null;break}if($e(e)||l(e)||u(e)||re(167),i=e,u(i)){n={node:i,offset:1};break}o=Math.max(0,i.getTextContentSize()-1),s=i.getTextContent()}else o--;const e=s[o];$e(i)&&" "!==e&&(r={node:i,offset:o})}if(null!==r)return r;let c=null;if(t<e.getTextContentSize())$e(e)&&(c=e.getTextContent()[t]);else{const t=e.getNextSibling();$e(t)&&(c=t.getTextContent()[0])}if(null!==c&&" "!==c)return n;{const r=function(e,t){let n=e,r=t,i=e.getTextContent(),o=e.getTextContentSize();for(;;){if(!$e(n)||r===o){if(n=n.getNextSibling(),null===n||u(n))return null;$e(n)&&(r=0,i=n.getTextContent(),o=n.getTextContentSize())}if($e(n)){if(" "!==i[r])return{node:n,offset:r};r++}}}(e,t);return null!==r?r:n}}function ce(e){const t=se(e);return u(t)&&re(168),t}function ae(e){const t=[];return c(e,{linebreak:()=>t.push(g()),tab:()=>t.push(a()),text:e=>t.push(He(e))}),t}function ge(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,u=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!==u&&n.focus.set(s,Math.max(0,u-o),"text"),!0}const fe="javascript",he=()=>fe;function pe(e,t){for(const n of e.childNodes){if(_(n)&&n.tagName===t)return!0;if(pe(n,t))return!0}return!1}const de="data-language",me="data-highlight-language",xe="data-theme",Se=/* @__PURE__ */ne();class be extends p{__language;__theme;__isSyntaxHighlightSupported;$config(){return this.config("code",{extends:p,importDOM:{code:e=>null!=e.textContent&&(/\r?\n/.test(e.textContent)||pe(e,"BR"))?{conversion:ve,priority:1}:null,div:()=>({conversion:Ce,priority:1}),pre:()=>({conversion:ve,priority:0}),table:e=>Pe(e)?{conversion:Ne,priority:3}:null,td:e=>{const t=e,n=t.closest("table");return t.classList.contains("js-file-line")||n&&Pe(n)?{conversion:Te,priority:3}:null},tr:e=>{const t=e.closest("table");return t&&Pe(t)?{conversion:Te,priority:3}:null}}})}constructor(e=void 0,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(e){const t=d().createElement("code");m(t,e.theme.code),t.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(t.setAttribute(de,n),this.getIsSyntaxHighlightSupported()&&t.setAttribute(me,n));const r=this.getTheme();r&&t.setAttribute(xe,r);const i=this.getStyle();return i&&x(t.style,i),t}updateDOM(e,t,n){const r=this.__language,i=e.__language;r?r!==i&&t.setAttribute(de,r):i&&t.removeAttribute(de);const o=this.__isSyntaxHighlightSupported;e.__isSyntaxHighlightSupported&&i?o&&r?r!==i&&t.setAttribute(me,r):t.removeAttribute(me):o&&r&&t.setAttribute(me,r);const s=this.__theme,l=e.__theme;s?s!==l&&t.setAttribute(xe,s):l&&t.removeAttribute(xe);const u=this.__style,c=e.__style;return u!==c&&x(t.style,u,c),!1}exportDOM(e){const t=d().createElement("pre");m(t,e._config.theme.code),t.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(t.setAttribute(de,n),this.getIsSyntaxHighlightSupported()&&t.setAttribute(me,n));const r=this.getTheme();r&&t.setAttribute(xe,r);const i=this.getStyle();return i&&x(t.style,i),{element:t}}updateFromJSON(e){return super.updateFromJSON(e).setLanguage(e.language).setTheme(e.theme)}exportJSON(){return{...super.exportJSON(),language:this.getLanguage(),theme:this.getTheme()}}insertNewAfter(e,t=!0){if(!X(S(),"@lexical/code")){Se();const t=Oe(e);if(t)return t}const{anchor:n,focus:r}=e,i=(n.isBefore(r)?n:r).getNode();if(b(i)){let e=oe(i);const t=[];for(;;)if(l(e))t.push(a()),e=e.getNextSibling();else{if(!$e(e))break;{let n=0;const r=e.getTextContent(),i=e.getTextContentSize();for(;n<i&&" "===r[n];)n++;if(0!==n&&t.push(He(" ".repeat(n))),n!==i)break;e=e.getNextSibling()}}const r=i.splitText(n.offset)[0],o=0===n.offset?0:1,s=r.getIndexWithinParent()+o,u=i.getParentOrThrow(),c=[g(),...t];u.splice(s,0,c);const f=t[t.length-1];f?f.select():0===n.offset?r.selectPrevious():r.getNextSibling().selectNext(0,0)}if(_e(i)){const{offset:t}=e.anchor;i.splice(t,0,[g()]),i.select(t+1,t+1)}return null}canIndent(){return!1}collapseAtStart(){const e=y();return this.getChildren().forEach(t=>e.append(t)),this.replace(e),!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 ye(e,t){return h(be).setLanguage(e).setTheme(t)}function _e(e){return e instanceof be}function ve(e){return{node:ye(e.getAttribute(de),e.getAttribute(xe))}}function Ce(e){const t=e,n=Ae(t);return n||function(e){let t=e.parentElement;for(;null!==t;){if(Ae(t))return!0;t=t.parentElement}return!1}(t)?{node:n?ye():null}:{node:null}}function Ne(){return{node:ye()}}function Te(){return{node:null}}function Ae(e){return null!==e.style.fontFamily.match("monospace")}function Pe(e){return e.classList.contains("js-file-line-container")}function Oe(e){const{anchor:t}=e;if(e.isCollapsed()&&"element"===t.type){const e=t.getNode();if(_e(e)){const n=e.getChildrenSize();if(n>=2&&t.offset===n){const t=e.getLastChild();if(u(t)&&u(t.getPreviousSibling())){const t=y();return e.splice(n-2,2,[]).insertAfter(t,!1),t.select(),t}}}}return null}class we extends C{__highlightType;constructor(e="",t,n){super(e,n),this.__highlightType=t}$config(){return this.config("code-highlight",{extends:C})}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(e){const t=super.createDOM(e),n=De(e.theme,this.__highlightType);return m(t,n),t}updateDOM(e,t,n){const r=super.updateDOM(e,t,n),i=De(n.theme,e.__highlightType),o=De(n.theme,this.__highlightType);return i!==o&&(i&&N(t,i),o&&m(t,o)),r}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 ye()}}function De(e,t){return t&&e&&e.codeHighlight&&e.codeHighlight[t]}function He(e="",t){return v(new we(e,t))}function $e(e){return e instanceof we}const Be="data-language",Ee="data-theme";function Le(e){return null!==e.style.fontFamily.match("monospace")}function Fe(e){let t=e.parentElement;for(;null!==t;){if(Le(t))return!0;t=t.parentElement}return!1}const ke=/* @__PURE__ */n([{$import:(e,t)=>e.$importChildren(t),match:/* @__PURE__ */e.tag("tr","td"),name:"@lexical/code/github-code-table/unwrap"}]),Me={$import:(e,t)=>[ye(t.getAttribute(Be),t.getAttribute(Ee)).splice(0,0,e.$importChildren(t))],match:/* @__PURE__ */e.tag("pre"),name:"@lexical/code/pre"},ze={$import:(e,t,n)=>{const r=t.textContent||"";return/\r?\n/.test(r)||null!==t.querySelector("br")?[ye(t.getAttribute(Be),t.getAttribute(Ee)).splice(0,0,e.$importChildren(t))]:n()},match:/* @__PURE__ */e.tag("code"),name:"@lexical/code/code-multiline"};function Ke(e){if(!_(e))return!1;const t=e.style.fontFamily,n=e.style.whiteSpace;return"string"==typeof t&&/monospace/i.test(t)&&"string"==typeof n&&n.startsWith("pre")}function Ie(e){let t=!1;const n=[];let r="",i=!1;const o=()=>{i&&(n.push(r),r="",i=!1)};for(const s of Array.from(e.childNodes))if(_(s))"DIV"===s.tagName?(o(),n.push(s.textContent||""),t=!0):"BR"===s.tagName?(o(),n.push(""),t=!0):(r+=s.textContent||"",i=!0);else if(A(s)){const e=s.textContent||"";e.length>0&&(r+=e,i=!0)}return o(),t?n:null}function je(e){for(const t of Array.from(e.children)){if(_(t)&&Ke(t)){if(null!==Ie(t))return!0;const e=t.nextElementSibling;if(e&&Ke(e))return!0;continue}if(je(t))return!0}return!1}const Je=/* @__PURE__ */n([{$import:(e,t,n)=>{if(!Ke(t)||Fe(t))return n();const r=Ie(t);return null===r||0===r.length?n():[ye().splice(0,0,P(r.join("\n")))]},match:/* @__PURE__ */e.tag("div"),name:"@lexical/code/vscode-wrapper"},{$import:(e,t,n)=>{if(!Ke(t)||Fe(t))return n();const r=t.previousElementSibling;if(r&&Ke(r))return[];const i=[];let o=t;for(;o&&Ke(o);)i.push("BR"===o.tagName?"":o.textContent||""),o=o.nextElementSibling;return i.length<2?n():[ye().splice(0,0,P(i.join("\n")))]},match:/* @__PURE__ */e.tag("div","br"),name:"@lexical/code/vscode-line-run"}]),Re={$import:(e,t,n)=>Le(t)?[ye().splice(0,0,e.$importChildren(t))]:Fe(t)?e.$importChildren(t):n(),match:/* @__PURE__ */e.tag("div"),name:"@lexical/code/div"},We=[{$import:(e,t)=>[ye().splice(0,0,e.$importChildren(t,{rules:ke}))],match:/* @__PURE__ */e.tag("table").classAll("js-file-line-container"),name:"@lexical/code/github-code-table"},{$import:(e,t)=>e.$importChildren(t),match:/* @__PURE__ */e.tag("td").classAll("js-file-line"),name:"@lexical/code/github-code-cell-by-class"},ze,Me,Re],qe={dependencies:[r,[i,{preprocess:[(e,n,r)=>{je(T(e)?e.body:e)&&n.session.update(t,e=>[...e,Je]),r()}],rules:We}]],name:"@lexical/code",nodes:()=>[be,we],register:e=>O(e.registerCommand(w,e=>{const t=D();return!(!H(t)||!Oe(t))&&(null!==e&&e.preventDefault(),!0)},$),e.registerNodeTransform(B,e=>{0!==e.getFormat()&&_e(e.getParent())&&e.setFormat(0)}))},Ue={dependencies:[qe],name:"@lexical/code/Import"};function Ve(e){if(!H(e))return!1;const t=e.anchor.getNode(),n=_e(t)?t:t.getParent(),r=e.focus.getNode(),i=_e(r)?r:r.getParent();return _e(n)&&n.is(i)}function Ge(e){const t=e.getNodes(),n=[];if(1===t.length&&_e(t[0]))return n;let r=[];for(let e=0;e<t.length;e++){const i=t[e];$e(i)||l(i)||u(i)||re(169),u(i)?r.length>0&&(n.push(r),r=[]):r.push(i)}if(r.length>0){const t=e.isBackward()?e.anchor:e.focus,i=W(r[0].getKey(),0,"text");t.is(i)||n.push(r)}return n}function Qe(e,t){const n=D();if(!H(n)||!Ve(n))return!1;const r=Ge(n),i=r.length;if(0===i&&n.isCollapsed())return e===I?n.insertNodes([a()]):function(e,t){const n=e.anchor.getNode();if(!$e(n)&&!l(n))return;const r=oe(n);l(r)?r.remove():void 0!==t&&$e(r)&&ge(r,t,e)}(n,t),!0;if(0===i&&e===I&&"\n"===n.getTextContent()){const e=a(),t=g(),r=n.isBackward()?"previous":"next";return n.insertNodes([e,t]),q(U(V(G(e,"next",0),Q(f(t,"next"))),r)),!0}for(let o=0;o<i;o++){const i=r[o];if(i.length>0){let r=i[0];if(0===o&&(r=oe(r)),e===I){const e=a();if(r.insertBefore(e),0===o){const t=n.isBackward()?"focus":"anchor",i=W(r.getKey(),0,"text");n[t].is(i)&&n[t].set(e.getKey(),0,"text")}}else l(r)?r.remove():void 0!==t&&$e(r)&&ge(r,t,n)}}return!0}function Xe(e,t){const n=D();if(!H(n))return!1;const{anchor:r,focus:i}=n,o=r.offset,s=i.offset,c=r.getNode(),a=i.getNode(),g=e===F;if(!Ve(n)||!$e(c)&&!l(c)||!$e(a)&&!l(a))return!1;if(!t.altKey){if(n.isCollapsed()){const e=c.getParentOrThrow();if(g&&0===o&&null===c.getPreviousSibling()){if(null===e.getPreviousSibling())return e.selectPrevious(),t.preventDefault(),!1}else if(!g&&o===c.getTextContentSize()&&null===c.getNextSibling()){if(null===e.getNextSibling())return e.selectNext(),t.preventDefault(),!1}}return!1}let f,h;if(c.isBefore(a)?(f=oe(c),h=se(a)):(f=oe(a),h=se(c)),null==f||null==h)return!1;const p=f.getNodesBetween(h);for(let e=0;e<p.length;e++){const t=p[e];if(!$e(t)&&!l(t)&&!u(t))return!1}t.preventDefault(),t.stopPropagation();const d=g?f.getPreviousSibling():h.getNextSibling();if(!u(d))return!0;const m=g?d.getPreviousSibling():d.getNextSibling();if(null==m)return!0;const x=u(m),S=x||!$e(m)&&!l(m)?null:g?oe(m):se(m);let b=null!=S?S:m;return d.remove(),p.forEach(e=>e.remove()),x?(p.forEach(e=>{b.insertAfter(e),b=e}),b.insertAfter(d)):e===F?(p.forEach(e=>b.insertBefore(e)),b.insertBefore(d)):(b.insertAfter(d),b=d,p.forEach(e=>{b.insertAfter(e),b=e})),n.setTextNodeRange(c,o,a,s),!0}function Ye(e,t){const n=D();if(!H(n))return!1;const{anchor:r,focus:i}=n,o=r.getNode(),s=i.getNode(),c=e===J;if(!Ve(n)||!$e(o)&&!l(o)||!$e(s)&&!l(s))return!1;const a=s,g="rtl"===le(a)?!c:c,f=r.key,h=r.offset,p=r.type;if(g){const e=ue(a,i.offset);if(null!==e){const{node:t,offset:r}=e;u(t)?t.selectNext(0,0):n.setTextNodeRange(t,r,t,r)}else a.getParentOrThrow().selectStart()}else{ce(a).select()}return t.shiftKey&&n.anchor.set(f,h,p),t.preventDefault(),t.stopPropagation(),!0}function Ze(e,t,n){return O(...n?[e.registerCommand(E,e=>!e.altKey&&ee(_e,e),$),e.registerCommand(L,e=>ee(_e,e),$),e.registerCommand(F,e=>!e.altKey&&te(_e,e),$),e.registerCommand(k,e=>te(_e,e),$)]:[],e.registerCommand(M,t=>{const n=function(e){const t=D();if(!H(t)||!Ve(t))return null;const n=e?j:I,r=e?j:z,i=t.anchor,o=t.focus;if(i.is(o))return r;const s=Ge(t);if(1!==s.length)return n;const l=s[0];let u,c;0===l.length&&re(285),t.isBackward()?(u=o,c=i):(u=i,c=o);const a=oe(l[0]),g=se(l[0]),f=W(a.getKey(),0,"text"),h=W(g.getKey(),g.getTextContentSize(),"text");return u.isBefore(f)||h.isBefore(c)?n:f.isBefore(u)||c.isBefore(h)?r:n}(t.shiftKey);return null!==n&&(t.preventDefault(),e.dispatchCommand(n),!0)},$),e.registerCommand(z,()=>!!Ve(D())&&(K([a()]),!0),$),e.registerCommand(I,()=>Qe(I),$),e.registerCommand(j,()=>Qe(j,t),$),e.registerCommand(F,e=>{const t=D();if(!H(t))return!1;const{anchor:n}=t,r=n.getNode();if(!Ve(t))return!1;const i=r.getParent();return t.isCollapsed()&&0===n.offset&&null===r.getPreviousSibling()&&_e(i)&&null===i.getPreviousSibling()?(e.preventDefault(),!0):Xe(F,e)},$),e.registerCommand(E,e=>{const t=D();if(!H(t))return!1;const{anchor:n}=t,r=n.getNode();return!!Ve(t)&&(t.isCollapsed()&&n.offset===r.getTextContentSize()&&null===r.getNextSibling()&&_e(r.getParentOrThrow())&&null===r.getParentOrThrow().getNextSibling()?(e.preventDefault(),!0):Xe(E,e))},$),e.registerCommand(J,e=>Ye(J,e),$),e.registerCommand(R,e=>Ye(R,e),$))}const et={build:(e,t)=>Z(t),config:{disabled:!1,escapeWithArrows:!1,tabSize:void 0},dependencies:[qe],name:"@lexical/code-indent",register:(e,t,n)=>{const r=n.getOutput();return Y(()=>{if(!r.disabled.value)return Ze(e,r.tabSize.value,r.escapeWithArrows.value)})}};export{He as $createCodeHighlightNode,ye as $createCodeNode,le as $getCodeLineDirection,ce as $getEndOfCodeInLine,oe as $getFirstCodeNodeOfLine,se as $getLastCodeNodeOfLine,ue as $getStartOfCodeInLine,$e as $isCodeHighlightNode,_e as $isCodeNode,ge as $outdentLeadingSpaces,ae as $plainifyCodeContent,qe as CodeExtension,we as CodeHighlightNode,Ue as CodeImportExtension,We as CodeImportRules,et as CodeIndentExtension,be as CodeNode,fe as DEFAULT_CODE_LANGUAGE,he as getDefaultCodeLanguage,Ze as registerCodeIndentation};
9
+ import{sel as t,ImportOverlays as e,defineOverlayRules as n,CoreImportExtension as r,DOMImportExtension as i}from"@lexical/html";import{getTextDirection as o,$isElementNode as s,$isTabNode as l,$isLineBreakNode as c,tokenizeRawText as u,$createTabNode as a,$createLineBreakNode as g,$getSiblingCaret as f,getterTableOf as h,setterTableOf as d,setterDefaultOf as p,aliasTableOf as m,$create as _,ElementNode as x,$getDocument as y,addClassNamesToElement as S,setDOMStyleFromCSS as b,$getEditor as v,$isTextNode as C,$createParagraphNode as T,nodeSchema as N,withAccessors as A,optional as P,stringValue as F,nullable as w,isHTMLElement as O,$applyNodeReplacement as $,TextNode as D,removeClassNamesFromElement as E,isDOMDocumentNode as H,isDOMTextNode as B,$generateNodesFromRawText as L,mergeRegister as k,KEY_ENTER_COMMAND as z,$getSelection as M,$isRangeSelection as I,COMMAND_PRIORITY_LOW as K,TabNode as j,KEY_ARROW_DOWN_COMMAND as R,KEY_ARROW_RIGHT_COMMAND as W,KEY_ARROW_UP_COMMAND as J,KEY_ARROW_LEFT_COMMAND as q,KEY_TAB_COMMAND as U,INSERT_TAB_COMMAND as V,$insertNodes as G,INDENT_CONTENT_COMMAND as Q,OUTDENT_CONTENT_COMMAND as X,MOVE_TO_START as Y,MOVE_TO_END as Z,$createPoint as tt,$setSelectionFromCaretRange as et,$getCaretRangeInDirection as nt,$getCaretRange as rt,$getTextPointCaret as it,$normalizeCaret as ot}from"lexical";import{getPeerDependencyFromEditor as st}from"@lexical/extension/getPeerDependencyFromEditor";import{effect as lt}from"@lexical/extension/signals";import{namedSignals as ct}from"@lexical/extension/namedSignals";import{$onEscapeDown as ut,$onEscapeUp as at}from"@lexical/utils";
10
+ /*@__INLINE__*/function gt(t){return()=>{}}function ft(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 ht(t,e){let n=t;for(let r=f(t,e);r&&(Vt(r.origin)||l(r.origin));r=r.getAdjacentCaret())n=r.origin;return n}function dt(t){return ht(t,"previous")}function pt(t){return ht(t,"next")}function mt(t){const e=dt(t),n=pt(t);let r=e;for(;null!==r;){if(Vt(r)){const t=o(r.getTextContent());if(null!==t)return t}if(r===n)break;r=r.getNextSibling()}const i=e.getParent();if(s(i)){const t=i.getDirection();if("ltr"===t||"rtl"===t)return t}return null}function _t(t,e){let n=null,r=null,i=t,o=e,s=t.getTextContent();for(;;){if(0===o){const t=i.getPreviousSibling();if(null===t){i=null;break}if(Vt(t)||l(t)||c(t)||ft(167),i=t,c(i)){n={node:i,offset:1};break}o=Math.max(0,i.getTextContentSize()-1),s=i.getTextContent()}else o--;const t=s[o];Vt(i)&&" "!==t&&(r={node:i,offset:o})}if(null!==r)return r;let u=null;if(e<t.getTextContentSize())Vt(t)&&(u=t.getTextContent()[e]);else{const e=t.getNextSibling();Vt(e)&&(u=e.getTextContent()[0])}if(null!==u&&" "!==u)return n;{const r=function(t,e){let n=t,r=e,i=t.getTextContent(),o=t.getTextContentSize();for(;;){if(!Vt(n)||r===o){if(n=n.getNextSibling(),null===n||c(n))return null;Vt(n)&&(r=0,i=n.getTextContent(),o=n.getTextContentSize())}if(Vt(n)){if(" "!==i[r])return{node:n,offset:r};r++}}}(t,e);return null!==r?r:n}}function xt(t){const e=pt(t);return c(e)&&ft(168),e}function yt(t){const e=[];return u(t,{linebreak:()=>e.push(g()),tab:()=>e.push(a()),text:t=>e.push(Ut(t))}),e}function St(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,c=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!==c&&n.focus.set(s,Math.max(0,c-o),"text"),!0}const bt=/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;function vt(t,e){if("number"==typeof t)return Number.isFinite(t)?t:e;if("string"!=typeof t||!bt.test(t))return e;const n=Number(t);return Number.isFinite(n)?n:e}const Ct=t=>{const e=h(t,"format"),n=d(t,"format"),r=p(t,"format");return{exportJSON:function(t){const n=t.__textFormat,r=t.__textStyle,i=(0!==n||""!==r)&&t.shouldSerializeTextStyles();return{children:[],language:t.__language,theme:t.__theme,direction:t.__dir,format:e[t.__format],indent:t.__indent,textFormat:0!==n&&i?n:void 0,textStyle:""!==r&&i?r:void 0,type:t.__type,version:1}},exportCompactJSON:function(t){const n=t.__textFormat,r=t.__textStyle,i=(0!==n||""!==r)&&t.shouldSerializeTextStyles(),o={type:t.__type,children:[]},s=t.__language;void 0!==s&&(o.language=s);const l=t.__theme;void 0!==l&&(o.theme=l);const c=t.__dir;null!=c&&(o.direction=c);const u=e[t.__format];void 0!==u&&""!==u&&(o.format=u);const a=t.__indent;return void 0!==a&&0!==a&&(o.indent=a),void 0!==n&&0!==n&&i&&(o.textFormat=n),void 0!==r&&""!==r&&i&&(o.textStyle=r),o},updateFromJSON:function(t,e){const i=e.direction;t.__dir=null===i||"ltr"===i||"rtl"===i?i:null;const o=e.format;t.__format="string"==typeof o&&o in n?n[o]:r,t.__indent=function(t,e,n,r){const i=vt(t,e);return i>=n&&i<=r&&Number.isInteger(i)?i:e}(e.indent,0,0,Infinity),t.__textFormat=vt(e.textFormat,0);const s=e.textStyle;t.__textStyle="string"==typeof s?s:"";const l=e.language;t.setLanguage(null==l||"string"==typeof l?l:"");const c=e.theme;return t.setTheme(void 0===c?void 0:"string"==typeof c?c:""),t}}};function Tt(t,e){t.__highlightType=e.__highlightType}const Nt=t=>{const e=h(t,"mode"),n=m(t,"detail",0),r=m(t,"format",0),i=d(t,"mode"),o=p(t,"mode");return{exportJSON:function(t){return{highlightType:t.__highlightType,detail:t.__detail,format:t.__format,mode:e[t.__mode],style:t.__style,text:t.__text,type:t.__type,version:1}},exportCompactJSON:function(t){const n={type:t.__type},r=t.__highlightType;void 0!==r&&(n.highlightType=r);const i=t.__detail;void 0!==i&&0!==i&&(n.detail=i);const o=t.__format;void 0!==o&&0!==o&&(n.format=o);const s=e[t.__mode];void 0!==s&&"normal"!==s&&(n.mode=s);const l=t.__style;void 0!==l&&""!==l&&(n.style=l);const c=t.__text;return void 0!==c&&""!==c&&(n.text=c),n},updateFromJSON:function(t,e){const s=e.detail;t.__detail="string"==typeof s&&s in n?n[s]:vt(s,0);const l=e.format;t.setFormat("string"==typeof l&&l in r?r[l]:vt(l,0));const c=e.mode;t.__mode="string"==typeof c&&c in i?i[c]:o;const u=e.style;t.__style="string"==typeof u?u:"";const a=e.text;t.__text="string"==typeof a?a:"";const g=e.highlightType;return t.setHighlightType(null==g||"string"==typeof g?g:""),t},afterCloneFrom:Tt}},At=/* @__PURE__ */N()({language:/* @__PURE__ */A(/* @__PURE__ */P(/* @__PURE__ */w(/* @__PURE__ */F())),{getter:{field:"__language"}}),theme:/* @__PURE__ */A(/* @__PURE__ */P(/* @__PURE__ */F()),{getter:{field:"__theme"}})}),Pt="javascript",Ft=()=>Pt;function wt(t,e){for(const n of t.childNodes){if(O(n)&&n.tagName===e)return!0;if(wt(n,e))return!0}return!1}const Ot="data-language",$t="data-highlight-language",Dt="data-theme",Et=/* @__PURE__ */gt();class Ht extends x{__language;__theme;__isSyntaxHighlightSupported;$config(){return this.config("code",{extends:x,generated:Ct,importDOM:{code:t=>null!=t.textContent&&(/\r?\n/.test(t.textContent)||wt(t,"BR"))?{conversion:kt,priority:1}:null,div:()=>({conversion:zt,priority:1}),pre:()=>({conversion:kt,priority:0}),table:t=>jt(t)?{conversion:Mt,priority:3}:null,td:t=>{const e=t,n=e.closest("table");return e.classList.contains("js-file-line")||n&&jt(n)?{conversion:It,priority:3}:null},tr:t=>{const e=t.closest("table");return e&&jt(e)?{conversion:It,priority:3}:null}},json:At})}constructor(t=void 0,e){super(e),this.__language=t||void 0,this.__isSyntaxHighlightSupported=!1,this.__theme=void 0}afterCloneFrom(t){super.afterCloneFrom(t),function(t,e){t.__language=e.__language,t.__theme=e.__theme}(this,t),this.__isSyntaxHighlightSupported=t.__isSyntaxHighlightSupported}createDOM(t){const e=y().createElement("code");S(e,t.theme.code),e.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(e.setAttribute(Ot,n),this.getIsSyntaxHighlightSupported()&&e.setAttribute($t,n));const r=this.getTheme();r&&e.setAttribute(Dt,r);const i=this.getStyle();return i&&b(e.style,i),e}updateDOM(t,e,n){const r=this.__language,i=t.__language;r?r!==i&&e.setAttribute(Ot,r):i&&e.removeAttribute(Ot);const o=this.__isSyntaxHighlightSupported;t.__isSyntaxHighlightSupported&&i?o&&r?r!==i&&e.setAttribute($t,r):e.removeAttribute($t):o&&r&&e.setAttribute($t,r);const s=this.__theme,l=t.__theme;s?s!==l&&e.setAttribute(Dt,s):l&&e.removeAttribute(Dt);const c=this.__style,u=t.__style;return c!==u&&b(e.style,c,u),!1}exportDOM(t){const e=y().createElement("pre");S(e,t._config.theme.code),e.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(e.setAttribute(Ot,n),this.getIsSyntaxHighlightSupported()&&e.setAttribute($t,n));const r=this.getTheme();r&&e.setAttribute(Dt,r);const i=this.getStyle();return i&&b(e.style,i),{element:e}}insertNewAfter(t,e=!0){if(!st(v(),"@lexical/code")){Et();const e=Rt(t);if(e)return e}const{anchor:n,focus:r}=t,i=(n.isBefore(r)?n:r).getNode();if(C(i)){let t=dt(i);const e=[];for(;;)if(l(t))e.push(a()),t=t.getNextSibling();else{if(!Vt(t))break;{let n=0;const r=t.getTextContent(),i=t.getTextContentSize();for(;n<i&&" "===r[n];)n++;if(0!==n&&e.push(Ut(" ".repeat(n))),n!==i)break;t=t.getNextSibling()}}const r=i.splitText(n.offset)[0],o=0===n.offset?0:1,s=r.getIndexWithinParent()+o,c=i.getParentOrThrow(),u=[g(),...e];c.splice(s,0,u);const f=e[e.length-1];f?f.select():0===n.offset?r.selectPrevious():r.getNextSibling().selectNext(0,0)}if(Lt(i)){const{offset:e}=t.anchor;i.splice(e,0,[g()]),i.select(e+1,e+1)}return null}canIndent(){return!1}collapseAtStart(){const t=T();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 Bt(t,e){return _(Ht).setLanguage(t).setTheme(e)}function Lt(t){return t instanceof Ht}function kt(t){return{node:Bt(t.getAttribute(Ot),t.getAttribute(Dt))}}function zt(t){const e=t,n=Kt(e);return n||function(t){let e=t.parentElement;for(;null!==e;){if(Kt(e))return!0;e=e.parentElement}return!1}(e)?{node:n?Bt():null}:{node:null}}function Mt(){return{node:Bt()}}function It(){return{node:null}}function Kt(t){return null!==t.style.fontFamily.match("monospace")}function jt(t){return t.classList.contains("js-file-line-container")}function Rt(t){const{anchor:e}=t;if(t.isCollapsed()&&"element"===e.type){const t=e.getNode();if(Lt(t)){const n=t.getChildrenSize();if(n>=2&&e.offset===n){const e=t.getLastChild();if(c(e)&&c(e.getPreviousSibling())){const e=T();return t.splice(n-2,2,[]).insertAfter(e,!1),e.select(),e}}}}return null}const Wt=/* @__PURE__ */N()({highlightType:/* @__PURE__ */A(/* @__PURE__ */P(/* @__PURE__ */w(/* @__PURE__ */F())),{getter:{field:"__highlightType"}})});class Jt extends D{__highlightType;constructor(t="",e,n){super(t,n),this.__highlightType=e}$config(){return this.config("code-highlight",{extends:D,generated:Nt,json:Wt})}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=qt(t.theme,this.__highlightType);return S(e,n),e}updateDOM(t,e,n){const r=super.updateDOM(t,e,n),i=qt(n.theme,t.__highlightType),o=qt(n.theme,this.__highlightType);return i!==o&&(i&&E(e,i),o&&S(e,o)),r}setFormat(t){return this}isParentRequired(){return!0}createParentElementNode(){return Bt()}}function qt(t,e){return e&&t&&t.codeHighlight&&t.codeHighlight[e]}function Ut(t="",e){return $(new Jt(t,e))}function Vt(t){return t instanceof Jt}const Gt="data-language",Qt="data-theme";function Xt(t){return null!==t.style.fontFamily.match("monospace")}function Yt(t){let e=t.parentElement;for(;null!==e;){if(Xt(e))return!0;e=e.parentElement}return!1}const Zt=/* @__PURE__ */n([{$import:(t,e)=>t.$importChildren(e),match:/* @__PURE__ */t.tag("tr","td"),name:"@lexical/code/github-code-table/unwrap"}]),te={$import:(t,e)=>[Bt(e.getAttribute(Gt),e.getAttribute(Qt)).splice(0,0,t.$importChildren(e))],match:/* @__PURE__ */t.tag("pre"),name:"@lexical/code/pre"},ee={$import:(t,e,n)=>{const r=e.textContent||"";return/\r?\n/.test(r)||null!==e.querySelector("br")?[Bt(e.getAttribute(Gt),e.getAttribute(Qt)).splice(0,0,t.$importChildren(e))]:n()},match:/* @__PURE__ */t.tag("code"),name:"@lexical/code/code-multiline"};function ne(t){if(!O(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 re(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(O(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(B(s)){const t=s.textContent||"";t.length>0&&(r+=t,i=!0)}return o(),e?n:null}function ie(t){for(const e of Array.from(t.children)){if(O(e)&&ne(e)){if(null!==re(e))return!0;const t=e.nextElementSibling;if(t&&ne(t))return!0;continue}if(ie(e))return!0}return!1}const oe=/* @__PURE__ */n([{$import:(t,e,n)=>{if(!ne(e)||Yt(e))return n();const r=re(e);return null===r||0===r.length?n():[Bt().splice(0,0,L(r.join("\n")))]},match:/* @__PURE__ */t.tag("div"),name:"@lexical/code/vscode-wrapper"},{$import:(t,e,n)=>{if(!ne(e)||Yt(e))return n();const r=e.previousElementSibling;if(r&&ne(r))return[];const i=[];let o=e;for(;o&&ne(o);)i.push("BR"===o.tagName?"":o.textContent||""),o=o.nextElementSibling;return i.length<2?n():[Bt().splice(0,0,L(i.join("\n")))]},match:/* @__PURE__ */t.tag("div","br"),name:"@lexical/code/vscode-line-run"}]),se={$import:(t,e,n)=>Xt(e)?[Bt().splice(0,0,t.$importChildren(e))]:Yt(e)?t.$importChildren(e):n(),match:/* @__PURE__ */t.tag("div"),name:"@lexical/code/div"},le=[{$import:(t,e)=>[Bt().splice(0,0,t.$importChildren(e,{rules:Zt}))],match:/* @__PURE__ */t.tag("table").classAll("js-file-line-container"),name:"@lexical/code/github-code-table"},{$import:(t,e)=>t.$importChildren(e),match:/* @__PURE__ */t.tag("td").classAll("js-file-line"),name:"@lexical/code/github-code-cell-by-class"},ee,te,se],ce={dependencies:[r,[i,{preprocess:[(t,n,r)=>{ie(H(t)?t.body:t)&&n.session.update(e,t=>[...t,oe]),r()}],rules:le}]],name:"@lexical/code",nodes:()=>[Ht,Jt],register:t=>k(t.registerCommand(z,t=>{const e=M();return!(!I(e)||!Rt(e))&&(null!==t&&t.preventDefault(),!0)},K),t.registerNodeTransform(j,t=>{0!==t.getFormat()&&Lt(t.getParent())&&t.setFormat(0)}))},ue={dependencies:[ce],name:"@lexical/code/Import"};function ae(t){if(!I(t))return!1;const e=t.anchor.getNode(),n=Lt(e)?e:e.getParent(),r=t.focus.getNode(),i=Lt(r)?r:r.getParent();return Lt(n)&&n.is(i)}function ge(t){const e=t.getNodes(),n=[];if(1===e.length&&Lt(e[0]))return n;let r=[];for(let t=0;t<e.length;t++){const i=e[t];Vt(i)||l(i)||c(i)||ft(169),c(i)?r.length>0&&(n.push(r),r=[]):r.push(i)}if(r.length>0){const e=t.isBackward()?t.anchor:t.focus,i=tt(r[0].getKey(),0,"text");e.is(i)||n.push(r)}return n}function fe(t,e){const n=M();if(!I(n)||!ae(n))return!1;const r=ge(n),i=r.length;if(0===i&&n.isCollapsed())return t===Q?n.insertNodes([a()]):function(t,e){const n=t.anchor.getNode();if(!Vt(n)&&!l(n))return;const r=dt(n);l(r)?r.remove():void 0!==e&&Vt(r)&&St(r,e,t)}(n,e),!0;if(0===i&&t===Q&&"\n"===n.getTextContent()){const t=a(),e=g(),r=n.isBackward()?"previous":"next";return n.insertNodes([t,e]),et(nt(rt(it(t,"next",0),ot(f(e,"next"))),r)),!0}for(let o=0;o<i;o++){const i=r[o];if(i.length>0){let r=i[0];if(0===o&&(r=dt(r)),t===Q){const t=a();if(r.insertBefore(t),0===o){const e=n.isBackward()?"focus":"anchor",i=tt(r.getKey(),0,"text");n[e].is(i)&&n[e].set(t.getKey(),0,"text")}}else l(r)?r.remove():void 0!==e&&Vt(r)&&St(r,e,n)}}return!0}function he(t,e){const n=M();if(!I(n))return!1;const{anchor:r,focus:i}=n,o=r.offset,s=i.offset,u=r.getNode(),a=i.getNode(),g=t===J;if(!ae(n)||!Vt(u)&&!l(u)||!Vt(a)&&!l(a))return!1;if(!e.altKey){if(n.isCollapsed()){const t=u.getParentOrThrow();if(g&&0===o&&null===u.getPreviousSibling()){if(null===t.getPreviousSibling())return t.selectPrevious(),e.preventDefault(),!1}else if(!g&&o===u.getTextContentSize()&&null===u.getNextSibling()){if(null===t.getNextSibling())return t.selectNext(),e.preventDefault(),!1}}return!1}let f,h;if(u.isBefore(a)?(f=dt(u),h=pt(a)):(f=dt(a),h=pt(u)),null==f||null==h)return!1;const d=f.getNodesBetween(h);for(let t=0;t<d.length;t++){const e=d[t];if(!Vt(e)&&!l(e)&&!c(e))return!1}e.preventDefault(),e.stopPropagation();const p=g?f.getPreviousSibling():h.getNextSibling();if(!c(p))return!0;const m=g?p.getPreviousSibling():p.getNextSibling();if(null==m)return!0;const _=c(m),x=_||!Vt(m)&&!l(m)?null:g?dt(m):pt(m);let y=null!=x?x:m;return p.remove(),d.forEach(t=>t.remove()),_?(d.forEach(t=>{y.insertAfter(t),y=t}),y.insertAfter(p)):t===J?(d.forEach(t=>y.insertBefore(t)),y.insertBefore(p)):(y.insertAfter(p),y=p,d.forEach(t=>{y.insertAfter(t),y=t})),n.setTextNodeRange(u,o,a,s),!0}function de(t,e){const n=M();if(!I(n))return!1;const{anchor:r,focus:i}=n,o=r.getNode(),s=i.getNode(),u=t===Y;if(!ae(n)||!Vt(o)&&!l(o)||!Vt(s)&&!l(s))return!1;const a=s,g="rtl"===mt(a)?!u:u,f=r.key,h=r.offset,d=r.type;if(g){const t=_t(a,i.offset);if(null!==t){const{node:e,offset:r}=t;c(e)?e.selectNext(0,0):n.setTextNodeRange(e,r,e,r)}else a.getParentOrThrow().selectStart()}else{xt(a).select()}return e.shiftKey&&n.anchor.set(f,h,d),e.preventDefault(),e.stopPropagation(),!0}function pe(t,e,n){return k(...n?[t.registerCommand(R,t=>!t.altKey&&ut(Lt,t),K),t.registerCommand(W,t=>ut(Lt,t),K),t.registerCommand(J,t=>!t.altKey&&at(Lt,t),K),t.registerCommand(q,t=>at(Lt,t),K)]:[],t.registerCommand(U,e=>{const n=function(t){const e=M();if(!I(e)||!ae(e))return null;const n=t?X:Q,r=t?X:V,i=e.anchor,o=e.focus;if(i.is(o))return r;const s=ge(e);if(1!==s.length)return n;const l=s[0];let c,u;0===l.length&&ft(285),e.isBackward()?(c=o,u=i):(c=i,u=o);const a=dt(l[0]),g=pt(l[0]),f=tt(a.getKey(),0,"text"),h=tt(g.getKey(),g.getTextContentSize(),"text");return c.isBefore(f)||h.isBefore(u)?n:f.isBefore(c)||u.isBefore(h)?r:n}(e.shiftKey);return null!==n&&(e.preventDefault(),t.dispatchCommand(n),!0)},K),t.registerCommand(V,()=>!!ae(M())&&(G([a()]),!0),K),t.registerCommand(Q,()=>fe(Q),K),t.registerCommand(X,()=>fe(X,e),K),t.registerCommand(J,t=>{const e=M();if(!I(e))return!1;const{anchor:n}=e,r=n.getNode();if(!ae(e))return!1;const i=r.getParent();return e.isCollapsed()&&0===n.offset&&null===r.getPreviousSibling()&&Lt(i)&&null===i.getPreviousSibling()?(t.preventDefault(),!0):he(J,t)},K),t.registerCommand(R,t=>{const e=M();if(!I(e))return!1;const{anchor:n}=e,r=n.getNode();return!!ae(e)&&(e.isCollapsed()&&n.offset===r.getTextContentSize()&&null===r.getNextSibling()&&Lt(r.getParentOrThrow())&&null===r.getParentOrThrow().getNextSibling()?(t.preventDefault(),!0):he(R,t))},K),t.registerCommand(Y,t=>de(Y,t),K),t.registerCommand(Z,t=>de(Z,t),K))}const me={build:(t,e)=>ct(e),config:{disabled:!1,escapeWithArrows:!1,tabSize:void 0},dependencies:[ce],name:"@lexical/code-indent",register:(t,e,n)=>{const r=n.getOutput();return lt(()=>{if(!r.disabled.value)return pe(t,r.tabSize.value,r.escapeWithArrows.value)})}};export{Ut as $createCodeHighlightNode,Bt as $createCodeNode,mt as $getCodeLineDirection,xt as $getEndOfCodeInLine,dt as $getFirstCodeNodeOfLine,pt as $getLastCodeNodeOfLine,_t as $getStartOfCodeInLine,Vt as $isCodeHighlightNode,Lt as $isCodeNode,St as $outdentLeadingSpaces,yt as $plainifyCodeContent,ce as CodeExtension,Jt as CodeHighlightNode,ue as CodeImportExtension,le as CodeImportRules,me as CodeIndentExtension,Ht as CodeNode,Pt as DEFAULT_CODE_LANGUAGE,Ft as getDefaultCodeLanguage,pe as registerCodeIndentation};
@@ -0,0 +1,28 @@
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
+ import type { CodeHighlightNode } from './CodeHighlightNode.js';
9
+ import type { CodeNode } from './CodeNode.js';
10
+ import { type GeneratedJSONFactory } from 'lexical';
11
+ /**
12
+ * CodeNode's schema-declared fields, for a clone. Generated from that
13
+ * schema; do not edit by hand.
14
+ *
15
+ * @internal
16
+ */
17
+ export declare function afterCloneCodeNode(node: CodeNode, prevNode: CodeNode): void;
18
+ /** CodeNode's generated implementations, for its `$config`. @internal */
19
+ export declare const GENERATED_CODE: GeneratedJSONFactory;
20
+ /**
21
+ * CodeHighlightNode's schema-declared fields, for a clone. Generated from that
22
+ * schema; do not edit by hand.
23
+ *
24
+ * @internal
25
+ */
26
+ export declare function afterCloneCodeHighlightNode(node: CodeHighlightNode, prevNode: CodeHighlightNode): void;
27
+ /** CodeHighlightNode's generated implementations, for its `$config`. @internal */
28
+ export declare const GENERATED_CODEHIGHLIGHT: GeneratedJSONFactory;
package/package.json CHANGED
@@ -8,15 +8,15 @@
8
8
  "code"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.50.1-nightly.20260916.0",
11
+ "version": "0.51.0",
12
12
  "main": "./dist/LexicalCodeCore.js",
13
13
  "types": "./dist/typescript-too-old.d.ts",
14
14
  "dependencies": {
15
- "@lexical/extension": "0.50.1-nightly.20260916.0",
16
- "@lexical/html": "0.50.1-nightly.20260916.0",
17
- "@lexical/internal": "0.50.1-nightly.20260916.0",
18
- "@lexical/utils": "0.50.1-nightly.20260916.0",
19
- "lexical": "0.50.1-nightly.20260916.0"
15
+ "@lexical/extension": "0.51.0",
16
+ "@lexical/html": "0.51.0",
17
+ "@lexical/internal": "0.51.0",
18
+ "@lexical/utils": "0.51.0",
19
+ "lexical": "0.51.0"
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
@@ -13,15 +13,22 @@ import {
13
13
  type EditorThemeClasses,
14
14
  type ElementNode,
15
15
  type LexicalNode,
16
- type LexicalUpdateJSON,
16
+ type LexicalParseJSON,
17
17
  type NodeKey,
18
+ nodeSchema,
19
+ nullable,
20
+ optional,
18
21
  removeClassNamesFromElement,
22
+ type SerializedPartial,
19
23
  type SerializedTextNode,
20
24
  type Spread,
25
+ stringValue,
21
26
  TextNode,
27
+ withAccessors,
22
28
  } from 'lexical';
23
29
 
24
30
  import {$createCodeNode} from './CodeNode';
31
+ import {GENERATED_CODEHIGHLIGHT} from './LexicalCodeCoreGeneratedJSON';
25
32
 
26
33
  type SerializedCodeHighlightNode = Spread<
27
34
  {
@@ -30,7 +37,29 @@ type SerializedCodeHighlightNode = Spread<
30
37
  SerializedTextNode
31
38
  >;
32
39
 
40
+ // Single source of truth for parsing the node-specific properties of a
41
+ // SerializedCodeHighlightNode (those it adds over a SerializedTextNode).
42
+ const codeHighlightNodeSchema = nodeSchema<CodeHighlightNode>()({
43
+ // Read straight off the field; applied through setHighlightType, which
44
+ // normalizes a falsy value to undefined. Naming the field is also what
45
+ // tells the clone where this property lives, so the class needs no
46
+ // `afterCloneFrom` of its own. The same shape CodeNode's `language` uses.
47
+ highlightType: withAccessors(optional(nullable(stringValue())), {
48
+ getter: {field: '__highlightType'},
49
+ }),
50
+ });
51
+
52
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
53
+ export interface CodeHighlightNode {
54
+ exportJSON(compact?: false): SerializedCodeHighlightNode;
55
+ exportJSON(compact: boolean): SerializedPartial<SerializedCodeHighlightNode>;
56
+ updateFromJSON(
57
+ serializedNode: LexicalParseJSON<SerializedCodeHighlightNode>,
58
+ ): this;
59
+ }
60
+
33
61
  /** @noInheritDoc */
62
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
34
63
  export class CodeHighlightNode extends TextNode {
35
64
  /** @internal */
36
65
  __highlightType: string | null | undefined;
@@ -45,12 +74,11 @@ export class CodeHighlightNode extends TextNode {
45
74
  }
46
75
 
47
76
  $config() {
48
- return this.config('code-highlight', {extends: TextNode});
49
- }
50
-
51
- afterCloneFrom(prevNode: this): void {
52
- super.afterCloneFrom(prevNode);
53
- this.__highlightType = prevNode.__highlightType;
77
+ return this.config('code-highlight', {
78
+ extends: TextNode,
79
+ generated: GENERATED_CODEHIGHLIGHT,
80
+ json: codeHighlightNodeSchema,
81
+ });
54
82
  }
55
83
 
56
84
  getHighlightType(): string | null | undefined {
@@ -99,21 +127,6 @@ export class CodeHighlightNode extends TextNode {
99
127
  return update;
100
128
  }
101
129
 
102
- updateFromJSON(
103
- serializedNode: LexicalUpdateJSON<SerializedCodeHighlightNode>,
104
- ): this {
105
- return super
106
- .updateFromJSON(serializedNode)
107
- .setHighlightType(serializedNode.highlightType);
108
- }
109
-
110
- exportJSON(): SerializedCodeHighlightNode {
111
- return {
112
- ...super.exportJSON(),
113
- highlightType: this.getHighlightType(),
114
- };
115
- }
116
-
117
130
  // Prevent formatting (bold, underline, etc)
118
131
  setFormat(format: number): this {
119
132
  return this;
package/src/CodeNode.ts CHANGED
@@ -28,14 +28,20 @@ import {
28
28
  isHTMLElement,
29
29
  type LexicalEditor,
30
30
  type LexicalNode,
31
- type LexicalUpdateJSON,
31
+ type LexicalParseJSON,
32
32
  type NodeKey,
33
+ nodeSchema,
34
+ nullable,
35
+ optional,
33
36
  type ParagraphNode,
34
37
  type RangeSelection,
35
38
  type SerializedElementNode,
39
+ type SerializedPartial,
36
40
  setDOMStyleFromCSS,
37
41
  type Spread,
42
+ stringValue,
38
43
  type TabNode,
44
+ withAccessors,
39
45
  } from 'lexical';
40
46
 
41
47
  import {
@@ -44,6 +50,10 @@ import {
44
50
  type CodeHighlightNode,
45
51
  } from './CodeHighlightNode';
46
52
  import {$getFirstCodeNodeOfLine} from './FlatStructureUtils';
53
+ import {
54
+ afterCloneCodeNode,
55
+ GENERATED_CODE,
56
+ } from './LexicalCodeCoreGeneratedJSON';
47
57
 
48
58
  export type SerializedCodeNode = Spread<
49
59
  {
@@ -53,6 +63,19 @@ export type SerializedCodeNode = Spread<
53
63
  SerializedElementNode
54
64
  >;
55
65
 
66
+ // Single source of truth for parsing the node-specific properties of a
67
+ // SerializedCodeNode (those it adds over a SerializedElementNode).
68
+ const codeNodeSchema = nodeSchema<CodeNode>()({
69
+ // Read straight off the fields; applied through the setters, which
70
+ // normalize a falsy value to undefined.
71
+ language: withAccessors(optional(nullable(stringValue())), {
72
+ getter: {field: '__language'},
73
+ }),
74
+ theme: withAccessors(optional(stringValue()), {
75
+ getter: {field: '__theme'},
76
+ }),
77
+ });
78
+
56
79
  export const DEFAULT_CODE_LANGUAGE = 'javascript';
57
80
  /** @internal Configurable through the extensions. */
58
81
  export const getDefaultCodeLanguage = (): string => DEFAULT_CODE_LANGUAGE;
@@ -77,7 +100,15 @@ const noExtensionDeprecation = warnOnlyOnce(
77
100
  'Using CodeNode without CodeExtension is deprecated',
78
101
  );
79
102
 
103
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
104
+ export interface CodeNode {
105
+ exportJSON(compact?: false): SerializedCodeNode;
106
+ exportJSON(compact: boolean): SerializedPartial<SerializedCodeNode>;
107
+ updateFromJSON(serializedNode: LexicalParseJSON<SerializedCodeNode>): this;
108
+ }
109
+
80
110
  /** @noInheritDoc */
111
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
81
112
  export class CodeNode extends ElementNode {
82
113
  /** @internal */
83
114
  __language: string | null | undefined;
@@ -89,6 +120,7 @@ export class CodeNode extends ElementNode {
89
120
  $config() {
90
121
  return this.config('code', {
91
122
  extends: ElementNode,
123
+ generated: GENERATED_CODE,
92
124
  importDOM: {
93
125
  // Typically <pre> is used for code blocks, and <code> for inline code styles
94
126
  // but if it's a multi line <code> we'll create a block. Pass through to
@@ -153,6 +185,7 @@ export class CodeNode extends ElementNode {
153
185
  return null;
154
186
  },
155
187
  },
188
+ json: codeNodeSchema,
156
189
  });
157
190
  }
158
191
 
@@ -166,10 +199,19 @@ export class CodeNode extends ElementNode {
166
199
  this.__theme = undefined;
167
200
  }
168
201
 
202
+ // Written rather than synthesized from the schema, because
203
+ // `__isSyntaxHighlightSupported` is not a serialized property and no schema
204
+ // describes it: the highlighter extensions set it as they run, and a clone
205
+ // that dropped it would render unhighlighted until the next pass.
206
+ //
207
+ // Declaring one of these takes the class out of the synthesized
208
+ // `afterCloneFrom` entirely, so the schema's own fields are this method's
209
+ // responsibility too — but not its boilerplate: `afterCloneCodeNode` is
210
+ // generated from the same declaration, so adding a property to the schema
211
+ // needs no line here.
169
212
  afterCloneFrom(prevNode: this): void {
170
213
  super.afterCloneFrom(prevNode);
171
- this.__language = prevNode.__language;
172
- this.__theme = prevNode.__theme;
214
+ afterCloneCodeNode(this, prevNode);
173
215
  this.__isSyntaxHighlightSupported = prevNode.__isSyntaxHighlightSupported;
174
216
  }
175
217
 
@@ -270,21 +312,6 @@ export class CodeNode extends ElementNode {
270
312
  return {element};
271
313
  }
272
314
 
273
- updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedCodeNode>): this {
274
- return super
275
- .updateFromJSON(serializedNode)
276
- .setLanguage(serializedNode.language)
277
- .setTheme(serializedNode.theme);
278
- }
279
-
280
- exportJSON(): SerializedCodeNode {
281
- return {
282
- ...super.exportJSON(),
283
- language: this.getLanguage(),
284
- theme: this.getTheme(),
285
- };
286
- }
287
-
288
315
  // Mutation
289
316
  insertNewAfter(
290
317
  selection: RangeSelection,
@@ -0,0 +1,338 @@
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
+ // @generated by scripts/generate-node-json.mjs from each class's `json`
10
+ // schema. Run `pnpm run generate-node-json` to regenerate; do not edit.
11
+
12
+ // Keys are emitted in the order the schema-driven walk writes them, so the two
13
+ // produce byte-identical JSON. That order is the schema's, not alphabetical.
14
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
15
+
16
+ import type {CodeHighlightNode} from './CodeHighlightNode';
17
+ import type {CodeNode} from './CodeNode';
18
+
19
+ import {
20
+ aliasTableOf,
21
+ type GeneratedJSONFactory,
22
+ getterTableOf,
23
+ setterDefaultOf,
24
+ setterTableOf,
25
+ } from 'lexical';
26
+
27
+ // The JSON number grammar, anchored, matching numberValue: `Number()` alone
28
+ // reads '0x10' as 16 and '' as 0, and neither is a shape a JSON encoder
29
+ // produces. Emitted from the same source the codegen verified against, so the
30
+ // two cannot be different functions.
31
+ const JSON_NUMBER = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
32
+
33
+ function num(v: unknown, d: number): number {
34
+ if (typeof v === 'number') {
35
+ return Number.isFinite(v) ? v : d;
36
+ }
37
+ if (typeof v !== 'string' || !JSON_NUMBER.test(v)) {
38
+ return d;
39
+ }
40
+ const n = Number(v);
41
+ return Number.isFinite(n) ? n : d;
42
+ }
43
+
44
+ function numC(
45
+ v: unknown,
46
+ d: number,
47
+ min: number,
48
+ max: number,
49
+ integer: boolean,
50
+ ): number {
51
+ const n = num(v, d);
52
+ return n >= min && n <= max && (!integer || Number.isInteger(n)) ? n : d;
53
+ }
54
+
55
+ /**
56
+ * CodeNode's schema-declared fields, for a clone. Generated from that
57
+ * schema; do not edit by hand.
58
+ *
59
+ * @internal
60
+ */
61
+ export function afterCloneCodeNode(node: CodeNode, prevNode: CodeNode): void {
62
+ node.__language = prevNode.__language;
63
+ node.__theme = prevNode.__theme;
64
+ }
65
+
66
+ /** CodeNode's generated implementations, for its `$config`. @internal */
67
+ export const GENERATED_CODE: GeneratedJSONFactory = fields => {
68
+ const CODE_FORMAT_GETTER = getterTableOf(fields, 'format') as {
69
+ readonly [key: string]:
70
+ | ''
71
+ | 'center'
72
+ | 'end'
73
+ | 'justify'
74
+ | 'left'
75
+ | 'right'
76
+ | 'start';
77
+ };
78
+
79
+ const CODE_FORMAT_SETTER = setterTableOf(fields, 'format') as {
80
+ readonly [key: string]: 0 | 1 | 2 | 3 | 4 | 5 | 6;
81
+ };
82
+
83
+ const CODE_FORMAT_SETTER_DEFAULT = setterDefaultOf(fields, 'format') as
84
+ | 0
85
+ | 1
86
+ | 2
87
+ | 3
88
+ | 4
89
+ | 5
90
+ | 6;
91
+
92
+ /** Generated from CodeNode's serialization schema. Do not edit by hand. */
93
+ function exportCodeNode(node: CodeNode): {[key: string]: unknown} {
94
+ const textFormat = node.__textFormat;
95
+ const textStyle = node.__textStyle;
96
+ const shouldSerializeTextStyles =
97
+ (textFormat !== 0 || textStyle !== '') &&
98
+ node.shouldSerializeTextStyles();
99
+ return {
100
+ children: [],
101
+ language: node.__language,
102
+ theme: node.__theme,
103
+ direction: node.__dir,
104
+ format: CODE_FORMAT_GETTER[node.__format],
105
+ indent: node.__indent,
106
+ textFormat:
107
+ textFormat !== 0 && shouldSerializeTextStyles ? textFormat : undefined,
108
+ textStyle:
109
+ textStyle !== '' && shouldSerializeTextStyles ? textStyle : undefined,
110
+ type: node.__type,
111
+ version: 1,
112
+ };
113
+ }
114
+
115
+ /** Generated from CodeNode's serialization schema. Do not edit by hand. */
116
+ function exportCompactCodeNode(node: CodeNode): {[key: string]: unknown} {
117
+ const textFormat = node.__textFormat;
118
+ const textStyle = node.__textStyle;
119
+ const shouldSerializeTextStyles =
120
+ (textFormat !== 0 || textStyle !== '') &&
121
+ node.shouldSerializeTextStyles();
122
+ const json: {[key: string]: unknown} = {type: node.__type, children: []};
123
+ const language = node.__language;
124
+ if (language !== undefined) {
125
+ json.language = language;
126
+ }
127
+ const theme = node.__theme;
128
+ if (theme !== undefined) {
129
+ json.theme = theme;
130
+ }
131
+ const direction = node.__dir;
132
+ if (direction != null) {
133
+ json.direction = direction;
134
+ }
135
+ const format = CODE_FORMAT_GETTER[node.__format];
136
+ if (format !== undefined && format !== '') {
137
+ json.format = format;
138
+ }
139
+ const indent = node.__indent;
140
+ if (indent !== undefined && indent !== 0) {
141
+ json.indent = indent;
142
+ }
143
+ if (
144
+ textFormat !== undefined &&
145
+ textFormat !== 0 &&
146
+ shouldSerializeTextStyles
147
+ ) {
148
+ json.textFormat = textFormat;
149
+ }
150
+ if (
151
+ textStyle !== undefined &&
152
+ textStyle !== '' &&
153
+ shouldSerializeTextStyles
154
+ ) {
155
+ json.textStyle = textStyle;
156
+ }
157
+ return json;
158
+ }
159
+
160
+ /** Generated from CodeNode's serialization schema. Do not edit by hand. */
161
+ function updateCodeNode(
162
+ node: CodeNode,
163
+ json: {readonly [key: string]: unknown},
164
+ ): CodeNode {
165
+ const direction = json.direction;
166
+ node.__dir =
167
+ direction === null || direction === 'ltr' || direction === 'rtl'
168
+ ? direction
169
+ : null;
170
+ const format = json.format;
171
+ node.__format =
172
+ typeof format === 'string' && format in CODE_FORMAT_SETTER
173
+ ? CODE_FORMAT_SETTER[format]
174
+ : CODE_FORMAT_SETTER_DEFAULT;
175
+ node.__indent = numC(json.indent, 0, 0, Infinity, true);
176
+ node.__textFormat = num(json.textFormat, 0);
177
+ const textStyle = json.textStyle;
178
+ node.__textStyle = typeof textStyle === 'string' ? textStyle : '';
179
+ const language = json.language;
180
+ node.setLanguage(
181
+ language == null
182
+ ? language
183
+ : typeof language === 'string'
184
+ ? language
185
+ : '',
186
+ );
187
+ const theme = json.theme;
188
+ node.setTheme(
189
+ theme === undefined ? undefined : typeof theme === 'string' ? theme : '',
190
+ );
191
+ return node;
192
+ }
193
+
194
+ return {
195
+ exportJSON: exportCodeNode,
196
+ exportCompactJSON: exportCompactCodeNode,
197
+ updateFromJSON: updateCodeNode,
198
+ };
199
+ };
200
+
201
+ /**
202
+ * CodeHighlightNode's schema-declared fields, for a clone. Generated from that
203
+ * schema; do not edit by hand.
204
+ *
205
+ * @internal
206
+ */
207
+ export function afterCloneCodeHighlightNode(
208
+ node: CodeHighlightNode,
209
+ prevNode: CodeHighlightNode,
210
+ ): void {
211
+ node.__highlightType = prevNode.__highlightType;
212
+ }
213
+
214
+ /** CodeHighlightNode's generated implementations, for its `$config`. @internal */
215
+ export const GENERATED_CODEHIGHLIGHT: GeneratedJSONFactory = fields => {
216
+ const CODEHIGHLIGHT_MODE_GETTER = getterTableOf(fields, 'mode') as {
217
+ readonly [key: string]: 'normal' | 'segmented' | 'token';
218
+ };
219
+
220
+ const CODEHIGHLIGHT_DETAIL_ALIAS = aliasTableOf(fields, 'detail', 0) as {
221
+ readonly [key: string]: 1 | 2;
222
+ };
223
+
224
+ const CODEHIGHLIGHT_FORMAT_ALIAS = aliasTableOf(fields, 'format', 0) as {
225
+ readonly [key: string]:
226
+ | 1
227
+ | 2
228
+ | 4
229
+ | 8
230
+ | 16
231
+ | 32
232
+ | 64
233
+ | 128
234
+ | 256
235
+ | 512
236
+ | 1024;
237
+ };
238
+
239
+ const CODEHIGHLIGHT_MODE_SETTER = setterTableOf(fields, 'mode') as {
240
+ readonly [key: string]: 0 | 1 | 2;
241
+ };
242
+
243
+ const CODEHIGHLIGHT_MODE_SETTER_DEFAULT = setterDefaultOf(fields, 'mode') as
244
+ | 0
245
+ | 1
246
+ | 2;
247
+
248
+ /** Generated from CodeHighlightNode's serialization schema. Do not edit by hand. */
249
+ function exportCodeHighlightNode(node: CodeHighlightNode): {
250
+ [key: string]: unknown;
251
+ } {
252
+ return {
253
+ highlightType: node.__highlightType,
254
+ detail: node.__detail,
255
+ format: node.__format,
256
+ mode: CODEHIGHLIGHT_MODE_GETTER[node.__mode],
257
+ style: node.__style,
258
+ text: node.__text,
259
+ type: node.__type,
260
+ version: 1,
261
+ };
262
+ }
263
+
264
+ /** Generated from CodeHighlightNode's serialization schema. Do not edit by hand. */
265
+ function exportCompactCodeHighlightNode(node: CodeHighlightNode): {
266
+ [key: string]: unknown;
267
+ } {
268
+ const json: {[key: string]: unknown} = {type: node.__type};
269
+ const highlightType = node.__highlightType;
270
+ if (highlightType !== undefined) {
271
+ json.highlightType = highlightType;
272
+ }
273
+ const detail = node.__detail;
274
+ if (detail !== undefined && detail !== 0) {
275
+ json.detail = detail;
276
+ }
277
+ const format = node.__format;
278
+ if (format !== undefined && format !== 0) {
279
+ json.format = format;
280
+ }
281
+ const mode = CODEHIGHLIGHT_MODE_GETTER[node.__mode];
282
+ if (mode !== undefined && mode !== 'normal') {
283
+ json.mode = mode;
284
+ }
285
+ const style = node.__style;
286
+ if (style !== undefined && style !== '') {
287
+ json.style = style;
288
+ }
289
+ const text = node.__text;
290
+ if (text !== undefined && text !== '') {
291
+ json.text = text;
292
+ }
293
+ return json;
294
+ }
295
+
296
+ /** Generated from CodeHighlightNode's serialization schema. Do not edit by hand. */
297
+ function updateCodeHighlightNode(
298
+ node: CodeHighlightNode,
299
+ json: {readonly [key: string]: unknown},
300
+ ): CodeHighlightNode {
301
+ const detail = json.detail;
302
+ node.__detail =
303
+ typeof detail === 'string' && detail in CODEHIGHLIGHT_DETAIL_ALIAS
304
+ ? CODEHIGHLIGHT_DETAIL_ALIAS[detail]
305
+ : num(detail, 0);
306
+ const format = json.format;
307
+ node.setFormat(
308
+ typeof format === 'string' && format in CODEHIGHLIGHT_FORMAT_ALIAS
309
+ ? CODEHIGHLIGHT_FORMAT_ALIAS[format]
310
+ : num(format, 0),
311
+ );
312
+ const mode = json.mode;
313
+ node.__mode =
314
+ typeof mode === 'string' && mode in CODEHIGHLIGHT_MODE_SETTER
315
+ ? CODEHIGHLIGHT_MODE_SETTER[mode]
316
+ : CODEHIGHLIGHT_MODE_SETTER_DEFAULT;
317
+ const style = json.style;
318
+ node.__style = typeof style === 'string' ? style : '';
319
+ const text = json.text;
320
+ node.__text = typeof text === 'string' ? text : '';
321
+ const highlightType = json.highlightType;
322
+ node.setHighlightType(
323
+ highlightType == null
324
+ ? highlightType
325
+ : typeof highlightType === 'string'
326
+ ? highlightType
327
+ : '',
328
+ );
329
+ return node;
330
+ }
331
+
332
+ return {
333
+ exportJSON: exportCodeHighlightNode,
334
+ exportCompactJSON: exportCompactCodeHighlightNode,
335
+ updateFromJSON: updateCodeHighlightNode,
336
+ afterCloneFrom: afterCloneCodeHighlightNode,
337
+ };
338
+ };