@vscode/markdown-editor 0.0.2-14 → 0.0.2-16

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
@@ -24,7 +24,7 @@ declare interface AnnotatedRange {
24
24
  }
25
25
 
26
26
  /** Every concrete node kind, for exhaustive consumer-side dispatch. */
27
- export declare type AnyAstNode = TextAstNode | MarkerAstNode | GlueAstNode | ThematicBreakAstNode | StrongAstNode | EmphasisAstNode | StrikethroughAstNode | InlineCodeAstNode | InlineMathAstNode | LinkAstNode | ImageAstNode | HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | BlockQuoteAstNode | ListAstNode | ListItemAstNode | TableAstNode | TableRowAstNode | TableCellAstNode | DocumentAstNode;
27
+ export declare type AnyAstNode = TextAstNode | MarkerAstNode | GlueAstNode | ThematicBreakAstNode | StrongAstNode | EmphasisAstNode | StrikethroughAstNode | InlineCodeAstNode | InlineMathAstNode | LinkAstNode | ImageAstNode | HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | BlockQuoteAstNode | ListAstNode | ListItemAstNode | TableAstNode | TableRowAstNode | TableCellAstNode | DocumentAstNode | UnhandledBlockAstNode;
28
28
 
29
29
  declare type AnyViewData = DocumentViewData | BlockViewData | InlineViewData | ListItemViewData | TableRowViewData | TableCellViewData | MarkerViewData | GlueViewData | DiffHunkViewData | DiffDecorationViewData;
30
30
 
@@ -88,7 +88,7 @@ export declare class AsyncClipboardStrategy implements IClipboardStrategy {
88
88
  connect(context: IClipboardContext): IDisposable;
89
89
  }
90
90
 
91
- export declare type BlockAstNode = HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | ThematicBreakAstNode | BlockQuoteAstNode | ListAstNode | TableAstNode;
91
+ export declare type BlockAstNode = HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | ThematicBreakAstNode | BlockQuoteAstNode | ListAstNode | TableAstNode | UnhandledBlockAstNode;
92
92
 
93
93
  /**
94
94
  * A block-level node. Every block may carry a {@link leadingTrivia} glue — the
@@ -147,7 +147,7 @@ declare class BlockQuoteViewData {
147
147
  constructor(ast: BlockQuoteAstNode, content: readonly AnyViewData[]);
148
148
  }
149
149
 
150
- declare type BlockViewData = HeadingViewData | ParagraphViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | BlockQuoteViewData | ListViewData | TableViewData;
150
+ declare type BlockViewData = HeadingViewData | ParagraphViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | BlockQuoteViewData | ListViewData | TableViewData | UnhandledBlockViewData;
151
151
 
152
152
  /**
153
153
  * Base view node for everything the editor renders, generic over the
@@ -191,9 +191,10 @@ export declare interface BlockViewOptions {
191
191
  /**
192
192
  * Opens a link's URL. Called when the user activates a link: a plain click
193
193
  * while the link's block is inactive (rendered), or a Ctrl/Cmd+click while it
194
- * is active (source shown). Defaults to `window.open(url, '_blank')`.
194
+ * is active (source shown). Return `false` to use the anchor's native
195
+ * navigation behavior.
195
196
  */
196
- readonly onOpenLink?: (url: string, event: MouseEvent) => void;
197
+ readonly onOpenLink?: (url: string, event: MouseEvent) => false | void;
197
198
  /**
198
199
  * Colours fenced code blocks. When set, a code block's content is rendered
199
200
  * as a sequence of token spans instead of one plain text node. This is the
@@ -213,6 +214,22 @@ export declare interface BlockViewOptions {
213
214
  * `katexEditableIdentifiers.ts`).
214
215
  */
215
216
  readonly renderMath?: (request: MathRenderRequest) => MathRendering | undefined;
217
+ /**
218
+ * Pluggable factory for an in-place, interactive editor that replaces the
219
+ * *rendered* (inactive) form of a fenced code block — see
220
+ * {@link IEmbeddedCodeEditor}. When it returns an editor for the block's
221
+ * language, that editor's element is mounted instead of the highlighted
222
+ * code, and content flows both ways as string edits. Returning `undefined`
223
+ * falls back to the default rendering. EXPERIMENTAL.
224
+ */
225
+ readonly embeddedCodeEditorFactory?: IEmbeddedCodeEditorFactory;
226
+ /**
227
+ * Called when an {@link IEmbeddedCodeEditor} edits its content. `contentEdit`
228
+ * is in the block's *content* coordinates; the host translates it to a
229
+ * document edit (via {@link CodeBlockAstNode.codeOffset} and the block's
230
+ * offset) and applies it to the model.
231
+ */
232
+ readonly onEmbeddedCodeEditorEdit?: (block: CodeBlockAstNode, contentEdit: StringEdit) => void;
216
233
  }
217
234
 
218
235
  export declare class CodeBlockAstNode extends BlockAstNodeBase {
@@ -288,6 +305,13 @@ export declare class CodeBlockViewNode extends BlockViewNode<CodeBlockViewData>
288
305
  * its predecessor's subscription explicitly.
289
306
  */
290
307
  private _snapshotSub;
308
+ /**
309
+ * An in-place interactive editor (e.g. an iframe) mounted instead of the
310
+ * rendered code. Like {@link _session} it is adopted from `previous` across
311
+ * rebuilds so the underlying editor keeps its state, and must be disposed
312
+ * manually (a node reused as `previous` is never {@link dispose}d).
313
+ */
314
+ private _embeddedEditor;
291
315
  constructor(data: CodeBlockViewData, options: BlockViewOptions | undefined, previous: ViewNode | undefined);
292
316
  dispose(): void;
293
317
  }
@@ -343,6 +367,8 @@ export declare class CommentInputWidget extends Disposable {
343
367
  export declare interface CommentInputWidgetOptions {
344
368
  /** Placeholder shown while the textarea is empty. Defaults to "Add Comment". */
345
369
  readonly placeholder?: string;
370
+ /** Called after the textarea changes size. */
371
+ readonly onDidChangeSize?: () => void;
346
372
  /**
347
373
  * Called when the user submits a non-empty comment (Enter or the send
348
374
  * button). The text is trimmed; never called with an empty string.
@@ -380,6 +406,7 @@ export declare class CommentModeController extends Disposable {
380
406
  private readonly _widget;
381
407
  private readonly _gap;
382
408
  private _visible;
409
+ private _anchorX;
383
410
  private _pinnedRange;
384
411
  /**
385
412
  * The range a comment was just submitted for. The box stays hidden for it
@@ -387,11 +414,10 @@ export declare class CommentModeController extends Disposable {
387
414
  * empty box on the still-selected text.
388
415
  */
389
416
  private _submittedRange;
390
- /** True while a mouse button is held over the editor (a selection drag in progress). */
391
- private readonly _mouseDown;
392
417
  constructor(_model: EditorModel, _view: EditorView, _options?: CommentModeControllerOptions | undefined);
393
418
  private _update;
394
419
  private _show;
420
+ private _layoutHorizontally;
395
421
  /** Force-hide and clear the box (used by Escape and submit). */
396
422
  private _hide;
397
423
  /**
@@ -577,6 +603,12 @@ export declare class CursorView extends Disposable {
577
603
  export declare interface CursorViewOptions {
578
604
  readonly offset: IObservable<SourceOffset | undefined>;
579
605
  readonly visualLineMap: IObservable<VisualLineMap>;
606
+ /**
607
+ * The mounted blocks, used to hide the caret when it sits at an offset that
608
+ * has been scrolled out of its (horizontally scrolling) block's viewport —
609
+ * matching how the selection is clipped there.
610
+ */
611
+ readonly blocks?: IObservable<readonly SelectionBlock[]>;
580
612
  /**
581
613
  * When set, the caret is drawn over the transient empty paragraph instead
582
614
  * of at {@link offset} — its rect (in client coordinates) comes straight
@@ -798,14 +830,21 @@ export declare type EditCommand = (ctx: CursorCommandContext) => {
798
830
  *
799
831
  * Owns the only non-derivable controller state:
800
832
  * - `_desiredColumn` — sticky column for up/down navigation
833
+ * - `_clickCount` / `_lastPointerDown` — multi-click detection for pointer
834
+ * input, since `pointerdown` events (unlike `mousedown`) don't populate
835
+ * `detail` with a click count.
801
836
  */
802
837
  export declare class EditorController extends Disposable {
803
838
  private readonly _model;
804
839
  private readonly _view;
805
840
  private _desiredColumn;
841
+ /** Running click count for the current multi-click sequence (1, 2, 3, …). */
842
+ private _clickCount;
843
+ /** Timestamp and position of the previous pointer-down, for multi-click detection. */
844
+ private _lastPointerDown;
806
845
  constructor(_model: EditorModel, _view: EditorView, options?: EditorControllerOptions);
807
846
  private readonly _handleTextUpdate;
808
- private readonly _handleMouseDown;
847
+ private readonly _handlePointerDown;
809
848
  private _makeCursorContext;
810
849
  private _makeVisualCursorContext;
811
850
  private _executeCursorCommand;
@@ -868,6 +907,14 @@ export declare class EditorModel {
868
907
  * whose block is active.
869
908
  */
870
909
  readonly ctrlOrMetaDown: ISettableObservable<boolean, void>;
910
+ /**
911
+ * Whether a pointer-driven selection drag is currently in progress. Set by
912
+ * the controller between the pointer-down that starts the drag and the
913
+ * pointer-up/cancel that ends it. Contributions read it to defer UI that
914
+ * would otherwise flicker mid-drag (e.g. the comment input box appears only
915
+ * once the drag ends).
916
+ */
917
+ readonly isSelecting: ISettableObservable<boolean, void>;
871
918
  /**
872
919
  * Gutter markers (source-control style change indicators) painted in the
873
920
  * left gutter. Each entry maps a source {@link OffsetRange} to a change kind
@@ -1069,15 +1116,16 @@ export declare class EditorView extends Disposable {
1069
1116
  private _setupReadonlyToggle;
1070
1117
  focus(): void;
1071
1118
  /**
1072
- * Opt-in "own" point→offset resolution (a debug/experimental flag). When
1073
- * `false` (default), {@link resolveOffsetFromPoint} uses the platform DOM
1074
- * hit-test (`caretPositionFromPoint`). When `true`, it ignores the DOM
1075
- * hit-test and snaps the point to the nearest offset purely from the
1076
- * rendered {@link VisualLineMap} geometry picking the nearest visual line
1077
- * by `y`, then the nearest offset on it by `x`. Because a table row's cells
1078
- * share one horizontal line band, this makes the whole width of a row
1079
- * resolve into that row (rather than only the cell boxes), with no visible
1080
- * layout change.
1119
+ * Own point→offset resolution. When `true` (the default),
1120
+ * {@link resolveOffsetFromPoint} ignores the platform DOM hit-test
1121
+ * (`caretPositionFromPoint`) and snaps the point to the nearest offset purely
1122
+ * from the rendered {@link VisualLineMap} geometry picking the nearest
1123
+ * visual line by `y`, then the nearest offset on it by `x`. Because a table
1124
+ * row's cells share one horizontal line band, this makes the whole width of a
1125
+ * row resolve into that row (rather than only the cell boxes), with no visible
1126
+ * layout change. It also lets a drag keep extending toward off-viewport points
1127
+ * (e.g. the pointer leaving the window), which the platform hit-test cannot
1128
+ * resolve. Set to `false` to fall back to the platform DOM hit-test.
1081
1129
  */
1082
1130
  readonly geometricHitTest: ISettableObservable<boolean, void>;
1083
1131
  /**
@@ -1123,6 +1171,12 @@ export declare interface EditorViewOptions extends BlockViewOptions {
1123
1171
  * only) unless a theme class is supplied.
1124
1172
  */
1125
1173
  readonly classNames?: readonly string[];
1174
+ /**
1175
+ * Whether to render the sticky "Editing / Locked" readonly toggle in the
1176
+ * top-right corner. Defaults to `true`; set to `false` to omit it (e.g. in
1177
+ * fixtures that focus on selection rendering).
1178
+ */
1179
+ readonly showReadonlyToggle?: boolean;
1126
1180
  /**
1127
1181
  * Controls "limited width mode". The observable yields the maximum content
1128
1182
  * width in pixels, or `undefined` to let the content fill the available
@@ -1301,6 +1355,55 @@ export declare interface IDefaultMonarchGrammars {
1301
1355
  shell: unknown;
1302
1356
  }
1303
1357
 
1358
+ /**
1359
+ * A live editor embedded in place of a fenced code block's *rendered* form.
1360
+ *
1361
+ * This is the internal seam between the block view and a concrete embedded
1362
+ * editor (e.g. an `<iframe>` speaking the web-editor protocol). The block view
1363
+ * only speaks string edits: it pushes the block's content down via
1364
+ * {@link setContent} and receives the editor's own changes back through
1365
+ * {@link onEdit} (set by the block view on each (re)construction, so it always
1366
+ * routes to the current AST node). The concrete implementation owns its DOM,
1367
+ * transport, and lifecycle.
1368
+ *
1369
+ * A single instance is adopted across re-renders (like the highlighter session)
1370
+ * so the underlying editor keeps its state across edits — see
1371
+ * {@link CodeBlockViewNode}.
1372
+ */
1373
+ declare interface IEmbeddedCodeEditor {
1374
+ /** The element mounted as the block's rendered form. */
1375
+ readonly element: HTMLElement;
1376
+ /**
1377
+ * Document → editor. The block's content changed (from any source). Must be
1378
+ * idempotent: pushing the content the editor already holds is a no-op, which
1379
+ * is how edits the editor itself originated are prevented from echoing back.
1380
+ */
1381
+ setContent(content: string): void;
1382
+ /**
1383
+ * Optional synchronous height (px) to reserve for `content` *before* the
1384
+ * editor has laid out. Return `undefined` to let the editor size itself
1385
+ * (the implementation may report its real height later). Lets a registration
1386
+ * avoid a layout jump when it can cheaply estimate the size from content.
1387
+ */
1388
+ estimateHeight?(content: string): number | undefined;
1389
+ /**
1390
+ * Editor → document. Set by the block view on every (re)construction to
1391
+ * route the editor's own edits, expressed in the block's *content*
1392
+ * coordinates, to the current AST node.
1393
+ */
1394
+ onEdit?: (edit: StringEdit) => void;
1395
+ dispose(): void;
1396
+ }
1397
+
1398
+ /** Creates an {@link IEmbeddedCodeEditor} for a fenced block, or opts out. */
1399
+ declare interface IEmbeddedCodeEditorFactory {
1400
+ /**
1401
+ * Return an editor for a fenced block of `language`, or `undefined` to fall
1402
+ * back to the default (highlighting / {@link BlockViewOptions.renderCustomCodeBlock}).
1403
+ */
1404
+ create(language: string, initialContent: string): IEmbeddedCodeEditor | undefined;
1405
+ }
1406
+
1304
1407
  export declare class ImageAstNode extends AstNode {
1305
1408
  readonly alt: string;
1306
1409
  readonly url: string;
@@ -2261,6 +2364,40 @@ declare interface UnchangedItem {
2261
2364
  readonly modifiedStart: number;
2262
2365
  }
2263
2366
 
2367
+ /**
2368
+ * A block whose token type the parser does not understand (a setext heading, a
2369
+ * frontmatter fence, any future/extension construct). Rather than dropping the
2370
+ * span — which would demote its text to invisible glue — the parser captures the
2371
+ * whole source range verbatim as a single {@link MarkerAstNode} of kind
2372
+ * `content` and records the originating micromark {@link tokenType}, so the view
2373
+ * can render it as raw, editable text with an "unhandled" affordance. Offsets
2374
+ * stay sound: `content` tiles the block's full source span exactly.
2375
+ */
2376
+ declare class UnhandledBlockAstNode extends BlockAstNodeBase {
2377
+ readonly tokenType: string;
2378
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
2379
+ readonly leadingTrivia?: GlueAstNode | undefined;
2380
+ readonly kind = "unhandledBlock";
2381
+ constructor(tokenType: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
2382
+ get children(): readonly AstNode[];
2383
+ get code(): MarkerAstNode | undefined;
2384
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
2385
+ withLeadingTrivia(trivia: GlueAstNode | undefined): UnhandledBlockAstNode;
2386
+ protected _localEquals(o: this): boolean;
2387
+ }
2388
+
2389
+ /**
2390
+ * View-data for an {@link UnhandledBlockAstNode}. It has no active/inactive
2391
+ * split — the raw source *is* both the source and the rendered form — so it
2392
+ * carries no `showMarkup` flag; the renderer always shows the verbatim text.
2393
+ */
2394
+ declare class UnhandledBlockViewData {
2395
+ readonly ast: UnhandledBlockAstNode;
2396
+ readonly content: readonly AnyViewData[];
2397
+ readonly kind = "unhandledBlock";
2398
+ constructor(ast: UnhandledBlockAstNode, content: readonly AnyViewData[]);
2399
+ }
2400
+
2264
2401
  /**
2265
2402
  * Immutable view of an AST node. Pairs `ast` with its rendered `dom` and a
2266
2403
  * mirror of `ast.children` as ViewNode children. Source offsets are NEVER
@@ -2387,10 +2524,22 @@ export declare class VisualLine {
2387
2524
  */
2388
2525
  sourceDistanceTo(offset: SourceOffset): number;
2389
2526
  /**
2390
- * x of the caret position before `offset` on this line. When `offset`
2391
- * is past all runs (trailing whitespace / blank line), returns the
2392
- * right edge of the last run; when before all runs, returns the left
2393
- * edge of the first run.
2527
+ * x of the caret position before `offset` on this line.
2528
+ *
2529
+ * The runs tile the source but are stored in paint order, not sorted by
2530
+ * source offset (hidden-marker runs are appended last). So this scans all
2531
+ * runs rather than assuming any ordering:
2532
+ *
2533
+ * - If some run *covers* `offset`, its own geometry places the caret
2534
+ * (exact glyph boundary for text runs). In the active, markers-visible
2535
+ * form every offset is covered, so this branch keeps distinct offsets
2536
+ * distinct.
2537
+ * - Otherwise `offset` sits in a gap — a hidden inline marker such as the
2538
+ * `**` of `**bold**`, or before/after the painted text. It snaps to the
2539
+ * seam between the source-nearest runs on either side: the right edge of
2540
+ * the closest run ending at/before `offset`, else the left edge of the
2541
+ * closest run starting at/after it. A hidden marker collapses to zero
2542
+ * width, so both edges coincide at the seam.
2394
2543
  */
2395
2544
  xAtOffset(offset: SourceOffset): number;
2396
2545
  /**