@vscode/markdown-editor 0.0.2-1 → 0.0.2-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -31,7 +31,7 @@ export declare abstract class AstNode {
31
31
  * instances — keeping this O(children), not O(subtree). Leaves have no
32
32
  * children, so {@link _localEquals} is their whole comparison.
33
33
  */
34
- structurallyEqual(other: AstNode): boolean;
34
+ equalsShallow(other: AstNode): boolean;
35
35
  /** Compares only this node's own scalar fields (kind/length already match). */
36
36
  protected _localEquals(_other: this): boolean;
37
37
  /**
@@ -54,8 +54,41 @@ declare interface AstVisualizationNode {
54
54
  children?: AstVisualizationNode[];
55
55
  }
56
56
 
57
+ /**
58
+ * Strategy for hosts that never deliver native clipboard events to the editor
59
+ * — most importantly VS Code webviews, whose preload calls `preventDefault()`
60
+ * on the Ctrl/Cmd+C/X/V keydowns, so no `copy`/`cut`/`paste` event is ever
61
+ * dispatched. Here the keystrokes are the only signal, so this strategy
62
+ * listens for them directly and drives the async {@link Clipboard} API
63
+ * (`navigator.clipboard`), which webviews are granted.
64
+ *
65
+ * Cut deletes synchronously once the text is captured; the clipboard write is
66
+ * fire-and-forget. Paste must wait for the async read before inserting.
67
+ */
68
+ export declare class AsyncClipboardStrategy implements IClipboardStrategy {
69
+ private readonly _clipboard;
70
+ constructor(_clipboard?: Clipboard);
71
+ connect(context: IClipboardContext): IDisposable;
72
+ }
73
+
57
74
  export declare type BlockAstNode = HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | ThematicBreakAstNode | BlockQuoteAstNode | ListAstNode | TableAstNode;
58
75
 
76
+ /**
77
+ * A block-level node. Every block may carry a {@link leadingTrivia} glue — the
78
+ * whitespace that precedes it on its own line (a nested list's indentation, the
79
+ * leading space of a continued paragraph). It is owned by the block it precedes
80
+ * (not the one it trails), so the view reveals it exactly when *this* block is
81
+ * active, and it tiles at the block's front: {@link children} prepends it to the
82
+ * block's own content while `content` stays the block's real payload.
83
+ */
84
+ declare abstract class BlockAstNodeBase extends AstNode {
85
+ abstract readonly leadingTrivia?: GlueAstNode;
86
+ /** This block with its leading trivia replaced — re-homes a leading glue onto it. */
87
+ abstract withLeadingTrivia(trivia: GlueAstNode | undefined): BlockAstNode;
88
+ /** Prepends {@link leadingTrivia}, if any, ahead of the block's own children. */
89
+ protected _withLeading(own: readonly AstNode[]): readonly AstNode[];
90
+ }
91
+
59
92
  /**
60
93
  * One block's place in the rendered document.
61
94
  *
@@ -79,13 +112,15 @@ export declare interface BlockMeasurement {
79
112
  readonly viewNode: ViewNode | undefined;
80
113
  }
81
114
 
82
- export declare class BlockQuoteAstNode extends AstNode {
115
+ export declare class BlockQuoteAstNode extends BlockAstNodeBase {
83
116
  readonly content: readonly (MarkerAstNode | BlockAstNode | GlueAstNode)[];
117
+ readonly leadingTrivia?: GlueAstNode | undefined;
84
118
  readonly kind = "blockQuote";
85
- constructor(content: readonly (MarkerAstNode | BlockAstNode | GlueAstNode)[]);
119
+ constructor(content: readonly (MarkerAstNode | BlockAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
86
120
  get children(): readonly AstNode[];
87
121
  get blocks(): readonly BlockAstNode[];
88
122
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
123
+ withLeadingTrivia(trivia: GlueAstNode | undefined): BlockQuoteAstNode;
89
124
  }
90
125
 
91
126
  declare class BlockQuoteViewData {
@@ -163,13 +198,14 @@ export declare interface BlockViewOptions {
163
198
  readonly renderMath?: (request: MathRenderRequest) => MathRendering | undefined;
164
199
  }
165
200
 
166
- export declare class CodeBlockAstNode extends AstNode {
201
+ export declare class CodeBlockAstNode extends BlockAstNodeBase {
167
202
  readonly language: string;
168
203
  readonly content: readonly (MarkerAstNode | GlueAstNode)[];
204
+ readonly leadingTrivia?: GlueAstNode | undefined;
169
205
  readonly kind = "codeBlock";
170
206
  private _previous?;
171
207
  private _contentEdit?;
172
- constructor(language: string, content: readonly (MarkerAstNode | GlueAstNode)[]);
208
+ constructor(language: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
173
209
  get children(): readonly AstNode[];
174
210
  get openFence(): MarkerAstNode | undefined;
175
211
  get closeFence(): MarkerAstNode | undefined;
@@ -177,6 +213,7 @@ export declare class CodeBlockAstNode extends AstNode {
177
213
  /** Relative start offset of the {@link code} marker within this block. */
178
214
  get codeOffset(): number;
179
215
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
216
+ withLeadingTrivia(trivia: GlueAstNode | undefined): CodeBlockAstNode;
180
217
  protected _localEquals(o: this): boolean;
181
218
  /**
182
219
  * A copy of this block carrying an incremental link to `previous`:
@@ -349,7 +386,7 @@ declare interface DocumentBlockViewData {
349
386
  /** A mounted document child: a block or a run of inter-block glue. */
350
387
  declare interface DocumentChildViewData {
351
388
  readonly absoluteStart: number;
352
- /** For a block: selection reaches it. For glue: a neighbouring block is active. */
389
+ /** For a block: selection reaches it. For glue: always false (unowned, hidden). */
353
390
  readonly isActive: boolean;
354
391
  readonly view: BlockViewData | GlueViewData;
355
392
  readonly kind: 'block' | 'glue';
@@ -442,7 +479,7 @@ export declare class EditorController extends Disposable {
442
479
  private readonly _model;
443
480
  private readonly _view;
444
481
  private _desiredColumn;
445
- constructor(_model: EditorModel, _view: EditorView);
482
+ constructor(_model: EditorModel, _view: EditorView, options?: EditorControllerOptions);
446
483
  private readonly _handleTextUpdate;
447
484
  private readonly _handleMouseDown;
448
485
  private _makeCursorContext;
@@ -454,13 +491,20 @@ export declare class EditorController extends Disposable {
454
491
  cursorDown(extend?: boolean): void;
455
492
  /** Move the cursor up one visual line (Arrow Up). */
456
493
  cursorUp(extend?: boolean): void;
457
- private readonly _handleCopy;
458
- private readonly _handleCut;
459
- private readonly _handlePaste;
460
494
  private _selectedText;
461
495
  private readonly _handleKeyDown;
462
496
  }
463
497
 
498
+ /** Options for an {@link EditorController}. */
499
+ export declare interface EditorControllerOptions {
500
+ /**
501
+ * How copy/cut/paste is handled. Defaults to {@link NativeClipboardStrategy},
502
+ * which reads the browser's native clipboard events — pass a different
503
+ * strategy (e.g. `AsyncClipboardStrategy`) in hosts that swallow them.
504
+ */
505
+ readonly clipboardStrategy?: IClipboardStrategy;
506
+ }
507
+
464
508
  export declare class EditorModel {
465
509
  private readonly _parser;
466
510
  /**
@@ -540,6 +584,13 @@ export declare class EditorView extends Disposable {
540
584
  readonly element: HTMLElement;
541
585
  readonly editContext: EditContext;
542
586
  readonly measuredLayout: MeasuredLayoutModel;
587
+ /**
588
+ * Inner container that holds the rendered document and the cursor/selection
589
+ * overlays. The outer {@link element} spans the full width; this container
590
+ * is what limited-width mode caps and centers, so the overlays (which anchor
591
+ * to their parent's box) stay aligned with the content.
592
+ */
593
+ private readonly _contentContainer;
543
594
  private readonly _cursorView;
544
595
  private readonly _selectionView;
545
596
  /**
@@ -603,6 +654,16 @@ export declare interface EditorViewOptions extends BlockViewOptions {
603
654
  * only) unless a theme class is supplied.
604
655
  */
605
656
  readonly classNames?: readonly string[];
657
+ /**
658
+ * Controls "limited width mode". The observable yields the maximum content
659
+ * width in pixels, or `undefined` to let the content fill the available
660
+ * width. When the option is omitted, the width is capped at
661
+ * {@link DEFAULT_LIMITED_WIDTH}px (limited mode is on by default).
662
+ *
663
+ * The cap and centering apply to an inner content container; the editor
664
+ * root ({@link element}) always spans the full available width.
665
+ */
666
+ readonly limitedWidth?: IObservable<number | undefined>;
606
667
  }
607
668
 
608
669
  export declare class EmphasisAstNode extends AstNode {
@@ -670,14 +731,16 @@ declare class GlueViewData {
670
731
  decorateNewline: boolean);
671
732
  }
672
733
 
673
- export declare class HeadingAstNode extends AstNode {
734
+ export declare class HeadingAstNode extends BlockAstNodeBase {
674
735
  readonly level: 1 | 2 | 3 | 4 | 5 | 6;
675
736
  readonly marker: MarkerAstNode;
676
737
  readonly content: readonly (InlineAstNode | GlueAstNode)[];
738
+ readonly leadingTrivia?: GlueAstNode | undefined;
677
739
  readonly kind = "heading";
678
- constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[]);
740
+ constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
679
741
  get children(): readonly AstNode[];
680
742
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
743
+ withLeadingTrivia(trivia: GlueAstNode | undefined): HeadingAstNode;
681
744
  protected _localEquals(o: this): boolean;
682
745
  }
683
746
 
@@ -688,6 +751,42 @@ declare class HeadingViewData {
688
751
  constructor(ast: HeadingAstNode, content: readonly AnyViewData[]);
689
752
  }
690
753
 
754
+ /**
755
+ * The editor operations a clipboard strategy drives. The strategy never
756
+ * touches the model or the DOM directly — it asks through this seam, so the
757
+ * same strategy works regardless of how the editor is wired up.
758
+ */
759
+ export declare interface IClipboardContext {
760
+ /** The element that owns focus and receives clipboard/keyboard events. */
761
+ readonly element: HTMLElement;
762
+ /** The selected source text, or `undefined` when the selection is empty. */
763
+ getSelectedText(): string | undefined;
764
+ /** Delete the current selection (the cut half of cut). */
765
+ deleteSelection(): void;
766
+ /** Insert text at the caret, replacing any selection (the paste action). */
767
+ insertText(text: string): void;
768
+ }
769
+
770
+ /**
771
+ * How copy/cut/paste intent reaches the editor. Host environments deliver it
772
+ * differently, so the controller owns no clipboard logic itself — it
773
+ * {@link connect}s a strategy and lets it install whatever listeners it needs.
774
+ *
775
+ * Two implementations ship:
776
+ * - {@link NativeClipboardStrategy} (default) reads the browser's native
777
+ * `copy`/`cut`/`paste` events and their synchronous `clipboardData`.
778
+ * - {@link AsyncClipboardStrategy} drives the async `navigator.clipboard` API
779
+ * from Ctrl/Cmd+C/X/V keystrokes, for hosts (e.g. VS Code webviews) that
780
+ * swallow the native clipboard events before they reach the editor.
781
+ */
782
+ export declare interface IClipboardStrategy {
783
+ /**
784
+ * Wire up clipboard handling against `context`. The returned disposable
785
+ * tears down every listener the strategy installed.
786
+ */
787
+ connect(context: IClipboardContext): IDisposable;
788
+ }
789
+
691
790
  /** The Monarch language definitions the default highlighter wires up. */
692
791
  export declare interface IDefaultMonarchGrammars {
693
792
  typescript: unknown;
@@ -886,14 +985,16 @@ declare class LinkViewData {
886
985
  constructor(ast: LinkAstNode, content: readonly AnyViewData[]);
887
986
  }
888
987
 
889
- export declare class ListAstNode extends AstNode {
988
+ export declare class ListAstNode extends BlockAstNodeBase {
890
989
  readonly ordered: boolean;
891
990
  readonly content: readonly (ListItemAstNode | GlueAstNode)[];
991
+ readonly leadingTrivia?: GlueAstNode | undefined;
892
992
  readonly kind = "list";
893
- constructor(ordered: boolean, content: readonly (ListItemAstNode | GlueAstNode)[]);
993
+ constructor(ordered: boolean, content: readonly (ListItemAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
894
994
  get children(): readonly AstNode[];
895
995
  get items(): readonly ListItemAstNode[];
896
996
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
997
+ withLeadingTrivia(trivia: GlueAstNode | undefined): ListAstNode;
897
998
  protected _localEquals(o: this): boolean;
898
999
  }
899
1000
 
@@ -907,6 +1008,7 @@ export declare class ListItemAstNode extends AstNode {
907
1008
  get children(): readonly AstNode[];
908
1009
  get blocks(): readonly BlockAstNode[];
909
1010
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1011
+ withLeadingTrivia(trivia: GlueAstNode | undefined): ListItemAstNode;
910
1012
  protected _localEquals(o: this): boolean;
911
1013
  }
912
1014
 
@@ -960,13 +1062,15 @@ declare class MarkerViewData {
960
1062
  constructor(ast: MarkerAstNode, visible: boolean);
961
1063
  }
962
1064
 
963
- export declare class MathBlockAstNode extends AstNode {
1065
+ export declare class MathBlockAstNode extends BlockAstNodeBase {
964
1066
  readonly content: readonly (MarkerAstNode | GlueAstNode)[];
1067
+ readonly leadingTrivia?: GlueAstNode | undefined;
965
1068
  readonly kind = "mathBlock";
966
- constructor(content: readonly (MarkerAstNode | GlueAstNode)[]);
1069
+ constructor(content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
967
1070
  get children(): readonly AstNode[];
968
1071
  get code(): MarkerAstNode | undefined;
969
1072
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1073
+ withLeadingTrivia(trivia: GlueAstNode | undefined): MathBlockAstNode;
970
1074
  }
971
1075
 
972
1076
  declare class MathBlockViewData {
@@ -1129,6 +1233,17 @@ export declare class MonacoSyntaxHighlighter implements ISyntaxHighlighter {
1129
1233
  private _tokenizerFor;
1130
1234
  }
1131
1235
 
1236
+ /**
1237
+ * Default strategy: handle the browser's native `copy`/`cut`/`paste` events,
1238
+ * reading and writing the synchronous {@link ClipboardEvent.clipboardData}.
1239
+ * This is the standard rich-editor approach and works wherever the browser
1240
+ * actually dispatches those events to the focused element (e.g. a standalone
1241
+ * web page).
1242
+ */
1243
+ export declare class NativeClipboardStrategy implements IClipboardStrategy {
1244
+ connect(context: IClipboardContext): IDisposable;
1245
+ }
1246
+
1132
1247
  /**
1133
1248
  * Move the cursor one position left or right, skipping over hidden marker
1134
1249
  * ranges in inactive blocks (and inactive items of an active list).
@@ -1164,12 +1279,14 @@ export declare class OffsetRange {
1164
1279
  toString(): string;
1165
1280
  }
1166
1281
 
1167
- export declare class ParagraphAstNode extends AstNode {
1282
+ export declare class ParagraphAstNode extends BlockAstNodeBase {
1168
1283
  readonly content: readonly (InlineAstNode | GlueAstNode)[];
1284
+ readonly leadingTrivia?: GlueAstNode | undefined;
1169
1285
  readonly kind = "paragraph";
1170
- constructor(content: readonly (InlineAstNode | GlueAstNode)[]);
1286
+ constructor(content: readonly (InlineAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1171
1287
  get children(): readonly AstNode[];
1172
1288
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1289
+ withLeadingTrivia(trivia: GlueAstNode | undefined): ParagraphAstNode;
1173
1290
  }
1174
1291
 
1175
1292
  declare class ParagraphViewData {
@@ -1381,16 +1498,18 @@ declare class StrongViewData {
1381
1498
  constructor(ast: StrongAstNode, content: readonly AnyViewData[]);
1382
1499
  }
1383
1500
 
1384
- export declare class TableAstNode extends AstNode {
1501
+ export declare class TableAstNode extends BlockAstNodeBase {
1385
1502
  readonly content: readonly (TableRowAstNode | GlueAstNode)[];
1503
+ readonly leadingTrivia?: GlueAstNode | undefined;
1386
1504
  readonly kind = "table";
1387
- constructor(content: readonly (TableRowAstNode | GlueAstNode)[]);
1505
+ constructor(content: readonly (TableRowAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1388
1506
  get children(): readonly AstNode[];
1389
1507
  private get _rows();
1390
1508
  get headerRow(): TableRowAstNode | undefined;
1391
1509
  get delimiterRow(): TableRowAstNode | undefined;
1392
1510
  get bodyRows(): readonly TableRowAstNode[];
1393
1511
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1512
+ withLeadingTrivia(trivia: GlueAstNode | undefined): TableAstNode;
1394
1513
  }
1395
1514
 
1396
1515
  export declare class TableCellAstNode extends AstNode {
@@ -1472,13 +1591,15 @@ declare class TextViewData {
1472
1591
  constructor(ast: TextAstNode, showWhitespace: boolean, leftWordBoundary?: boolean, rightWordBoundary?: boolean);
1473
1592
  }
1474
1593
 
1475
- export declare class ThematicBreakAstNode extends AstNode {
1594
+ export declare class ThematicBreakAstNode extends BlockAstNodeBase {
1476
1595
  readonly content: readonly (MarkerAstNode | GlueAstNode)[];
1596
+ readonly leadingTrivia?: GlueAstNode | undefined;
1477
1597
  readonly kind = "thematicBreak";
1478
- constructor(content: readonly (MarkerAstNode | GlueAstNode)[]);
1598
+ constructor(content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1479
1599
  get children(): readonly AstNode[];
1480
1600
  get marker(): MarkerAstNode | undefined;
1481
1601
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1602
+ withLeadingTrivia(trivia: GlueAstNode | undefined): ThematicBreakAstNode;
1482
1603
  }
1483
1604
 
1484
1605
  declare class ThematicBreakViewData {