@vscode/markdown-editor 0.0.2-12 → 0.0.2-13
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 +501 -21
- package/dist/index.js +3271 -1963
- package/dist/index.js.map +1 -1
- package/dist/markdown-editor.css +1 -0
- package/package.json +12 -3
- package/src/contrib/comments/commentInput.css +131 -0
- package/src/contrib/comments/comments.css +129 -0
- package/src/contrib/commentsVscode/vscodeCommentWidgetV2.css +166 -0
- package/src/view/editor.css +85 -3
- package/src/view/themes/vscode-default.css +337 -0
- package/src/view/themes/{vscode.css → vscode-github.css} +54 -46
package/dist/index.d.ts
CHANGED
|
@@ -6,10 +6,27 @@ import { ISettableObservable } from './_observables/index';
|
|
|
6
6
|
import { ITransaction } from './_observables/index';
|
|
7
7
|
import { MonarchTokenizer } from 'monaco-editor/esm/vs/editor/standalone/common/monarch/monarchLexer.js';
|
|
8
8
|
|
|
9
|
+
declare interface AddedItem {
|
|
10
|
+
readonly kind: 'added';
|
|
11
|
+
readonly node: AstNode;
|
|
12
|
+
readonly modifiedStart: number;
|
|
13
|
+
readonly insertedLocal: readonly AnnotatedRange[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A word/character-level highlight inside a single block, in that block's
|
|
18
|
+
* *local* coordinate space (`0` = block start). `inserted` ranges live on a
|
|
19
|
+
* modified/added block, `deleted` ranges on an original/removed block.
|
|
20
|
+
*/
|
|
21
|
+
declare interface AnnotatedRange {
|
|
22
|
+
readonly range: OffsetRange;
|
|
23
|
+
readonly kind: 'inserted' | 'deleted';
|
|
24
|
+
}
|
|
25
|
+
|
|
9
26
|
/** Every concrete node kind, for exhaustive consumer-side dispatch. */
|
|
10
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;
|
|
11
28
|
|
|
12
|
-
declare type AnyViewData = DocumentViewData | BlockViewData | InlineViewData | ListItemViewData | TableRowViewData | TableCellViewData | MarkerViewData | GlueViewData;
|
|
29
|
+
declare type AnyViewData = DocumentViewData | BlockViewData | InlineViewData | ListItemViewData | TableRowViewData | TableCellViewData | MarkerViewData | GlueViewData | DiffHunkViewData | DiffDecorationViewData;
|
|
13
30
|
|
|
14
31
|
export declare abstract class AstNode {
|
|
15
32
|
abstract readonly kind: string;
|
|
@@ -275,6 +292,228 @@ export declare class CodeBlockViewNode extends BlockViewNode<CodeBlockViewData>
|
|
|
275
292
|
dispose(): void;
|
|
276
293
|
}
|
|
277
294
|
|
|
295
|
+
/** A persistent comment anchored to a source range. */
|
|
296
|
+
declare interface Comment_2 {
|
|
297
|
+
readonly id: string;
|
|
298
|
+
/** Source range the comment refers to (its highlighted region). */
|
|
299
|
+
readonly range: OffsetRange;
|
|
300
|
+
/** The comment text. */
|
|
301
|
+
readonly body: string;
|
|
302
|
+
/** Display name of the author, if any. */
|
|
303
|
+
readonly author?: string;
|
|
304
|
+
/** Creation time (epoch ms), used to render a relative timestamp. */
|
|
305
|
+
readonly createdAt?: number;
|
|
306
|
+
}
|
|
307
|
+
export { Comment_2 as Comment }
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* A self-contained comment input box — a rounded panel with an auto-growing
|
|
311
|
+
* textarea and a send button, styled after the gdocs/Word "add a comment"
|
|
312
|
+
* affordance.
|
|
313
|
+
*
|
|
314
|
+
* This widget is *positioning-agnostic*: it only owns its own DOM and state.
|
|
315
|
+
* A host (the comment-mode controller, or a fixture) mounts {@link element}
|
|
316
|
+
* wherever it likes and is responsible for placing it relative to a selection.
|
|
317
|
+
*
|
|
318
|
+
* State is observable-driven (no framework): {@link value} reflects the live
|
|
319
|
+
* textarea content; submit/cancel are reported through the option callbacks.
|
|
320
|
+
*/
|
|
321
|
+
export declare class CommentInputWidget extends Disposable {
|
|
322
|
+
private readonly _options?;
|
|
323
|
+
readonly element: HTMLElement;
|
|
324
|
+
private readonly _textarea;
|
|
325
|
+
private readonly _measure;
|
|
326
|
+
private readonly _submitButton;
|
|
327
|
+
private readonly _value;
|
|
328
|
+
/** Live, untrimmed textarea content. */
|
|
329
|
+
get value(): IObservable<string>;
|
|
330
|
+
/** The raw textarea, exposed so a host can move focus into it (e.g. on Tab). */
|
|
331
|
+
get inputElement(): HTMLTextAreaElement;
|
|
332
|
+
constructor(_options?: CommentInputWidgetOptions | undefined);
|
|
333
|
+
/** Move focus into the textarea (caret at the end). */
|
|
334
|
+
focus(): void;
|
|
335
|
+
/** Replace the textarea content. */
|
|
336
|
+
setText(text: string): void;
|
|
337
|
+
/** Clear the textarea. */
|
|
338
|
+
clear(): void;
|
|
339
|
+
private _submit;
|
|
340
|
+
private _autoSize;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export declare interface CommentInputWidgetOptions {
|
|
344
|
+
/** Placeholder shown while the textarea is empty. Defaults to "Add Comment". */
|
|
345
|
+
readonly placeholder?: string;
|
|
346
|
+
/**
|
|
347
|
+
* Called when the user submits a non-empty comment (Enter or the send
|
|
348
|
+
* button). The text is trimmed; never called with an empty string.
|
|
349
|
+
*/
|
|
350
|
+
readonly onSubmit?: (text: string) => void;
|
|
351
|
+
/** Called when the user dismisses the input (Escape). */
|
|
352
|
+
readonly onCancel?: () => void;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Comment mode — a gdocs/Word-style "add a comment" affordance layered on top of
|
|
357
|
+
* the editor *without modifying it*. It reads the editor's public observables
|
|
358
|
+
* ({@link EditorModel.readonlyMode}, {@link EditorModel.selection}) and the
|
|
359
|
+
* exposed {@link EditorView.caretRect} geometry, and mounts a
|
|
360
|
+
* {@link CommentInputWidget} into {@link EditorView.overlayContainer}.
|
|
361
|
+
*
|
|
362
|
+
* Behaviour:
|
|
363
|
+
* - Only active in read-only mode (the "review" view).
|
|
364
|
+
* - When the selection is non-empty, the input box appears next to the caret
|
|
365
|
+
* (the selection's active end) but does NOT take focus, so keyboard selection
|
|
366
|
+
* keeps working. Press Tab to move focus into the box, then type.
|
|
367
|
+
* - The box appears on mouse-up, not mid-drag, so it doesn't flicker/jump
|
|
368
|
+
* while a selection is being dragged out (keyboard selection shows at once).
|
|
369
|
+
* - While the box has focus or holds a draft it is frozen in place (selection
|
|
370
|
+
* changes, drags and clicks no longer move it). It is dismissed by Escape,
|
|
371
|
+
* by submitting, or by blurring an empty box.
|
|
372
|
+
* - The editor's painted caret is hidden only while the box has focus (the
|
|
373
|
+
* blinking caret then belongs to the comment input); it stays visible while
|
|
374
|
+
* the box is merely shown, so keyboard selection remains visible.
|
|
375
|
+
*/
|
|
376
|
+
export declare class CommentModeController extends Disposable {
|
|
377
|
+
private readonly _model;
|
|
378
|
+
private readonly _view;
|
|
379
|
+
private readonly _options?;
|
|
380
|
+
private readonly _widget;
|
|
381
|
+
private readonly _gap;
|
|
382
|
+
private _visible;
|
|
383
|
+
private _pinnedRange;
|
|
384
|
+
/**
|
|
385
|
+
* The range a comment was just submitted for. The box stays hidden for it
|
|
386
|
+
* until the selection changes, so submitting doesn't immediately re-summon an
|
|
387
|
+
* empty box on the still-selected text.
|
|
388
|
+
*/
|
|
389
|
+
private _submittedRange;
|
|
390
|
+
/** True while a mouse button is held over the editor (a selection drag in progress). */
|
|
391
|
+
private readonly _mouseDown;
|
|
392
|
+
constructor(_model: EditorModel, _view: EditorView, _options?: CommentModeControllerOptions | undefined);
|
|
393
|
+
private _update;
|
|
394
|
+
private _show;
|
|
395
|
+
/** Force-hide and clear the box (used by Escape and submit). */
|
|
396
|
+
private _hide;
|
|
397
|
+
/**
|
|
398
|
+
* Hide unless the user is engaged with the box: it has focus or holds a
|
|
399
|
+
* non-empty draft. This preserves in-progress text and keeps a focused box
|
|
400
|
+
* open (it is dismissed explicitly via Escape/submit, or by blurring it).
|
|
401
|
+
*/
|
|
402
|
+
private _autoHide;
|
|
403
|
+
private _widgetHasFocus;
|
|
404
|
+
/**
|
|
405
|
+
* The visible viewport (client coords) used for the flip-above decision: the
|
|
406
|
+
* nearest scrollable ancestor of the editor. `.md-editor` itself spans the
|
|
407
|
+
* full document height and never clips, so measuring against it would always
|
|
408
|
+
* report room below. Falls back to the window when nothing scrolls.
|
|
409
|
+
*/
|
|
410
|
+
private _getViewportRect;
|
|
411
|
+
private _hideAndRefocus;
|
|
412
|
+
private _submit;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export declare interface CommentModeControllerOptions {
|
|
416
|
+
/** Called when the user submits a comment for the current selection. */
|
|
417
|
+
readonly onSubmit?: (submission: CommentSubmission) => void;
|
|
418
|
+
/** Gap (px) between the bottom of the selection and the top of the input box. */
|
|
419
|
+
readonly gap?: number;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/** Human-readable labels (for pickers / dropdowns). */
|
|
423
|
+
export declare const COMMENTS_DESIGN_LABELS: Record<CommentsDesign, string>;
|
|
424
|
+
|
|
425
|
+
/** design id → presenter factory over a shared CommentsModel + EditorView. */
|
|
426
|
+
export declare const COMMENTS_DESIGNS: Record<CommentsDesign, CommentsPresenterFactory>;
|
|
427
|
+
|
|
428
|
+
/** The available comment rendering designs. */
|
|
429
|
+
export declare type CommentsDesign = 'connected' | 'vscode' | 'vscode-v2';
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Seedable store of {@link Comment}s for the comment-mode contribution. Owns the
|
|
433
|
+
* comment list and the shared hover state; it has no opinion on rendering or
|
|
434
|
+
* persistence — a host seeds it via {@link set}/{@link add} and observes
|
|
435
|
+
* {@link comments}.
|
|
436
|
+
*/
|
|
437
|
+
export declare class CommentsModel {
|
|
438
|
+
private readonly _comments;
|
|
439
|
+
/** Monotonic counter for ids of comments created via {@link create}. */
|
|
440
|
+
private _sequence;
|
|
441
|
+
/** The current comments, in insertion order. */
|
|
442
|
+
get comments(): IObservable<readonly Comment_2[]>;
|
|
443
|
+
/**
|
|
444
|
+
* The comment currently hovered (by its card or its highlight), or
|
|
445
|
+
* `undefined`. Shared so the card and the highlight can react together.
|
|
446
|
+
*/
|
|
447
|
+
readonly hoveredId: ISettableObservable<string | undefined>;
|
|
448
|
+
/** Replace the whole comment set. */
|
|
449
|
+
set(comments: readonly Comment_2[]): void;
|
|
450
|
+
/**
|
|
451
|
+
* Create a comment from a user submission and append it, generating its `id`
|
|
452
|
+
* and `createdAt` here so id/time allocation stays the store's concern (the
|
|
453
|
+
* UI only supplies the range and text). Returns the created comment.
|
|
454
|
+
*/
|
|
455
|
+
create(input: {
|
|
456
|
+
range: OffsetRange;
|
|
457
|
+
body: string;
|
|
458
|
+
author?: string;
|
|
459
|
+
}): Comment_2;
|
|
460
|
+
/** Append a comment. */
|
|
461
|
+
add(comment: Comment_2): void;
|
|
462
|
+
/** Remove a comment by id. */
|
|
463
|
+
remove(id: string): void;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/** Optional, design-specific context a presenter may use (ignored by others). */
|
|
467
|
+
export declare interface CommentsPresenterContext {
|
|
468
|
+
/** Light/dark hint for the token-wrapped VS Code widget designs. */
|
|
469
|
+
readonly theme?: 'light' | 'dark';
|
|
470
|
+
/**
|
|
471
|
+
* Resolves a source offset to a 1-based line number, for designs that show
|
|
472
|
+
* line info (the VS Code V1 card). Optional because the model itself carries
|
|
473
|
+
* no text; the host (which owns the source) supplies it.
|
|
474
|
+
*/
|
|
475
|
+
readonly resolveLine?: (offset: number) => number;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** Builds a presenter for a given model + editor view. */
|
|
479
|
+
export declare type CommentsPresenterFactory = (model: CommentsModel, view: EditorView, context?: CommentsPresenterContext) => ICommentsPresenter;
|
|
480
|
+
|
|
481
|
+
/** A comment the user submitted, with the source range it was anchored to. */
|
|
482
|
+
export declare interface CommentSubmission {
|
|
483
|
+
readonly text: string;
|
|
484
|
+
readonly range: OffsetRange;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Renders persistent comments as a gdocs-style side rail: each comment's range
|
|
489
|
+
* is highlighted (reusing the editor's selection geometry via
|
|
490
|
+
* {@link EditorView.rangeRects}), a leader line curves from the bottom of that
|
|
491
|
+
* highlight to a card stacked in the right rail, and cards never overlap.
|
|
492
|
+
*
|
|
493
|
+
* Everything is mounted into {@link EditorView.overlayContainer} so it shares
|
|
494
|
+
* the selection/caret coordinate space and scrolls with the document. When the
|
|
495
|
+
* editor's natural right margin is too narrow for the rail, the view reserves
|
|
496
|
+
* proportional space by padding the editor on the right — but only while there
|
|
497
|
+
* are comments.
|
|
498
|
+
*/
|
|
499
|
+
export declare class CommentsView extends Disposable {
|
|
500
|
+
private readonly _model;
|
|
501
|
+
private readonly _view;
|
|
502
|
+
private readonly _layer;
|
|
503
|
+
private readonly _entries;
|
|
504
|
+
constructor(_model: CommentsModel, _view: EditorView);
|
|
505
|
+
private _createLayer;
|
|
506
|
+
private _update;
|
|
507
|
+
/** Create/update/remove per-comment DOM to match `comments`. */
|
|
508
|
+
private _reconcile;
|
|
509
|
+
private _createEntry;
|
|
510
|
+
private _fillCard;
|
|
511
|
+
private _disposeEntry;
|
|
512
|
+
/** Position highlights, cards (stacked) and leader lines. */
|
|
513
|
+
private _layout;
|
|
514
|
+
private _applyHover;
|
|
515
|
+
}
|
|
516
|
+
|
|
278
517
|
/**
|
|
279
518
|
* A {@link MonacoSyntaxHighlighter} preloaded with a handful of common Monarch
|
|
280
519
|
* grammars (plus the usual short aliases). Unknown languages fall back to an
|
|
@@ -366,6 +605,74 @@ export declare const deleteWordLeft: EditCommand;
|
|
|
366
605
|
|
|
367
606
|
export declare const deleteWordRight: EditCommand;
|
|
368
607
|
|
|
608
|
+
/**
|
|
609
|
+
* A read-only "removed" decoration: an original block rendered (red) above its
|
|
610
|
+
* place in the modified document, occupying vertical space like a view-zone but
|
|
611
|
+
* contributing **zero** source length, so the editor's source mapping stays the
|
|
612
|
+
* modified document and editing is unaffected. Used for `removed` and the
|
|
613
|
+
* original side of a `replaced` block in editor diff mode.
|
|
614
|
+
*/
|
|
615
|
+
declare class DiffDecorationViewData {
|
|
616
|
+
readonly ast: AstNode;
|
|
617
|
+
readonly side: BlockViewData;
|
|
618
|
+
readonly deletedRanges: readonly DiffHighlightRange[];
|
|
619
|
+
/** True when the whole block was removed: solid red band, no word rects. */
|
|
620
|
+
readonly whole: boolean;
|
|
621
|
+
/** Absolute offset of this block in the *original* document. */
|
|
622
|
+
readonly originalStart: number;
|
|
623
|
+
readonly kind = "diffDecoration";
|
|
624
|
+
constructor(ast: AstNode, side: BlockViewData, deletedRanges: readonly DiffHighlightRange[],
|
|
625
|
+
/** True when the whole block was removed: solid red band, no word rects. */
|
|
626
|
+
whole: boolean,
|
|
627
|
+
/** Absolute offset of this block in the *original* document. */
|
|
628
|
+
originalStart: number);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/** A word/character highlight inside one diff side, in block-local coords. */
|
|
632
|
+
declare interface DiffHighlightRange {
|
|
633
|
+
readonly range: OffsetRange;
|
|
634
|
+
readonly kind: 'inserted' | 'deleted';
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* A changed block rendered as its original form stacked over its modified form
|
|
639
|
+
* (either side may be absent for a pure deletion/insertion). It is itself a
|
|
640
|
+
* document child the renderer mounts like a block; its {@link ast} is the
|
|
641
|
+
* surviving side's ast, used only for view-node identity/reuse.
|
|
642
|
+
*/
|
|
643
|
+
declare class DiffHunkViewData {
|
|
644
|
+
readonly ast: AstNode;
|
|
645
|
+
readonly original: DiffSideViewData | undefined;
|
|
646
|
+
readonly modified: DiffSideViewData | undefined;
|
|
647
|
+
readonly kind = "diffHunk";
|
|
648
|
+
constructor(ast: AstNode, original: DiffSideViewData | undefined, modified: DiffSideViewData | undefined);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* The recursive classification of a diff. Each item describes one aligned
|
|
653
|
+
* position in the merged document:
|
|
654
|
+
*
|
|
655
|
+
* - `unchanged` — render the (modified) node once, neutral.
|
|
656
|
+
* - `added` — exists only in the modified document (green).
|
|
657
|
+
* - `removed` — exists only in the original document (red).
|
|
658
|
+
* - `replaced` — a *leaf* block changed in place → render original over
|
|
659
|
+
* modified, with word-level {@link AnnotatedRange}s on each.
|
|
660
|
+
* - `nested` — a *container* changed → render it once and diff its
|
|
661
|
+
* {@link NestedItem.children} recursively.
|
|
662
|
+
*
|
|
663
|
+
* Offsets ({@link UnchangedItem.modifiedStart} etc.) are absolute in their
|
|
664
|
+
* respective documents, so a renderer/visualizer can slice the source text.
|
|
665
|
+
*/
|
|
666
|
+
declare type DiffItem = UnchangedItem | AddedItem | RemovedItem | ReplacedItem | NestedItem;
|
|
667
|
+
|
|
668
|
+
/** One side (original or modified) of a {@link DiffHunkViewData}. */
|
|
669
|
+
declare interface DiffSideViewData {
|
|
670
|
+
readonly view: BlockViewData;
|
|
671
|
+
/** Render in active form (markers/whitespace visible). */
|
|
672
|
+
readonly active: boolean;
|
|
673
|
+
readonly ranges: readonly DiffHighlightRange[];
|
|
674
|
+
}
|
|
675
|
+
|
|
369
676
|
export declare class DocumentAstNode extends AstNode {
|
|
370
677
|
readonly content: readonly (BlockAstNode | GlueAstNode)[];
|
|
371
678
|
readonly kind = "document";
|
|
@@ -390,14 +697,21 @@ declare interface DocumentBlockViewData {
|
|
|
390
697
|
readonly view: BlockViewData;
|
|
391
698
|
}
|
|
392
699
|
|
|
393
|
-
/** A mounted document child: a block, a run of inter-block glue,
|
|
394
|
-
* transient empty paragraph (see {@link PendingParagraphViewData})
|
|
700
|
+
/** A mounted document child: a block, a run of inter-block glue, the
|
|
701
|
+
* transient empty paragraph (see {@link PendingParagraphViewData}), or a
|
|
702
|
+
* {@link DiffHunkViewData diff hunk} (stacked original/modified blocks). */
|
|
395
703
|
declare interface DocumentChildViewData {
|
|
396
704
|
readonly absoluteStart: number;
|
|
397
705
|
/** For a block: selection reaches it. For glue: always false (unowned, hidden). */
|
|
398
706
|
readonly isActive: boolean;
|
|
399
|
-
readonly view: BlockViewData | GlueViewData | PendingParagraphViewData;
|
|
400
|
-
readonly kind: 'block' | 'glue' | 'pendingParagraph';
|
|
707
|
+
readonly view: BlockViewData | GlueViewData | PendingParagraphViewData | DiffHunkViewData | DiffDecorationViewData;
|
|
708
|
+
readonly kind: 'block' | 'glue' | 'pendingParagraph' | 'diffHunk' | 'diffDecoration';
|
|
709
|
+
/**
|
|
710
|
+
* Diff mode: how this (modified) block changed. `added` = a whole new block
|
|
711
|
+
* (strong green band, no inline rects); `modified` = a partial change (light
|
|
712
|
+
* band + inline rects on the changed words).
|
|
713
|
+
*/
|
|
714
|
+
readonly diffKind?: 'added' | 'modified';
|
|
401
715
|
}
|
|
402
716
|
|
|
403
717
|
/**
|
|
@@ -532,6 +846,16 @@ export declare class EditorModel {
|
|
|
532
846
|
*/
|
|
533
847
|
private _pendingEdit;
|
|
534
848
|
readonly sourceText: ISettableObservable<StringValue, void>;
|
|
849
|
+
/**
|
|
850
|
+
* Read-only mode. When `true`, the editor never reveals a block's source
|
|
851
|
+
* markers (markdown special characters like `**`, `#`, list bullets, code
|
|
852
|
+
* fences, `$…$`) — every block stays in its clean rendered form regardless
|
|
853
|
+
* of where the caret/selection is — and source-mutating edits are ignored.
|
|
854
|
+
* Plain text selection still works everywhere (so the user can copy). The
|
|
855
|
+
* default (`false`) is the normal editing mode where the active block
|
|
856
|
+
* reveals its markers.
|
|
857
|
+
*/
|
|
858
|
+
readonly readonlyMode: ISettableObservable<boolean, void>;
|
|
535
859
|
/**
|
|
536
860
|
* The current selection, or `undefined` when the editor has no caret
|
|
537
861
|
* (e.g. an inactive/unfocused rendering).
|
|
@@ -589,6 +913,25 @@ export declare class EditorModel {
|
|
|
589
913
|
* collapsed this is a one-element set holding {@link activeBlock}.
|
|
590
914
|
*/
|
|
591
915
|
readonly activeBlocks: IObservableWithChange<Set<BlockAstNode>, void>;
|
|
916
|
+
/**
|
|
917
|
+
* The baseline document to diff against. When set, the editor renders in
|
|
918
|
+
* diff mode: the modified document ({@link document}) stays editable, while
|
|
919
|
+
* the baseline's removed/changed blocks are shown as read-only decorations.
|
|
920
|
+
* `undefined` (the default) renders normally.
|
|
921
|
+
*/
|
|
922
|
+
readonly baseline: ISettableObservable<StringValue | undefined, void>;
|
|
923
|
+
private readonly _baselineDocument;
|
|
924
|
+
/**
|
|
925
|
+
* The diff of {@link baseline} → {@link document}, or `undefined` when no
|
|
926
|
+
* baseline is set. The view renders the {@link DiffItem}s as stacked
|
|
927
|
+
* decorations; `insertedRanges` (modified-side change spans) drive the green
|
|
928
|
+
* word-level highlight.
|
|
929
|
+
*/
|
|
930
|
+
readonly diff: IObservableWithChange< {
|
|
931
|
+
items: DiffItem[];
|
|
932
|
+
insertedRanges: OffsetRange[];
|
|
933
|
+
changedBlocks: Set<BlockAstNode>;
|
|
934
|
+
} | undefined, void>;
|
|
592
935
|
/**
|
|
593
936
|
* Arm a {@link PendingParagraph} at the given gap, minting a fresh synthetic
|
|
594
937
|
* AST node for it, and park the caret at the gap start. No source edit is
|
|
@@ -650,6 +993,7 @@ export declare class EditorView extends Disposable {
|
|
|
650
993
|
private readonly _cursorView;
|
|
651
994
|
private readonly _selectionView;
|
|
652
995
|
private readonly _gutterMarkersView;
|
|
996
|
+
private readonly _diffHighlightsView;
|
|
653
997
|
/**
|
|
654
998
|
* The mounted block sequence, in source order. Rebuilt (not mutated) each
|
|
655
999
|
* frame by {@link DocumentViewNode.create}; the view just swaps one
|
|
@@ -682,6 +1026,29 @@ export declare class EditorView extends Disposable {
|
|
|
682
1026
|
* lock-step without any manual bookkeeping.
|
|
683
1027
|
*/
|
|
684
1028
|
private readonly _selectionBlocksObs;
|
|
1029
|
+
/**
|
|
1030
|
+
* The caret rect (zero width) at the selection's active end, in
|
|
1031
|
+
* {@link overlayContainer}-local coordinates, or `undefined` when there is no
|
|
1032
|
+
* caret. This is the same geometry the editor paints its cursor from, so
|
|
1033
|
+
* contributions (e.g. comment mode) can anchor an overlay to the active end of
|
|
1034
|
+
* the selection — where the user's cursor is — without re-deriving geometry.
|
|
1035
|
+
*/
|
|
1036
|
+
private readonly _caretRect;
|
|
1037
|
+
get caretRect(): IObservable<Rect2D | undefined>;
|
|
1038
|
+
/**
|
|
1039
|
+
* The container that establishes the positioning context for the editor's
|
|
1040
|
+
* overlays (cursor, selection, gutter). Contributions mount their own
|
|
1041
|
+
* absolutely-positioned overlays here so they share the coordinate space of
|
|
1042
|
+
* {@link caretRect}.
|
|
1043
|
+
*/
|
|
1044
|
+
get overlayContainer(): HTMLElement;
|
|
1045
|
+
/**
|
|
1046
|
+
* Selection-style rectangles covering `range`, in {@link overlayContainer}-
|
|
1047
|
+
* local coordinates — the same geometry the live selection paints. Exposed so
|
|
1048
|
+
* contributions (e.g. persistent comments) can highlight arbitrary ranges and
|
|
1049
|
+
* anchor overlays to them. Recomputes when the measured layout changes.
|
|
1050
|
+
*/
|
|
1051
|
+
rangeRects(range: OffsetRange): IObservable<readonly SelectionRect[]>;
|
|
685
1052
|
constructor(_model: EditorModel, _options?: EditorViewOptions | undefined);
|
|
686
1053
|
/**
|
|
687
1054
|
* Mirrors the model's live Ctrl/Cmd state onto the editor root as
|
|
@@ -690,11 +1057,33 @@ export declare class EditorView extends Disposable {
|
|
|
690
1057
|
* a plain click, but an active link only opens with the modifier held.
|
|
691
1058
|
*/
|
|
692
1059
|
private _setupModifierTracking;
|
|
1060
|
+
/**
|
|
1061
|
+
* Renders the edit/read-only lock toggle. It flips the model's
|
|
1062
|
+
* {@link EditorModel.readonlyMode}: when locked (read-only) every block stays
|
|
1063
|
+
* in its clean rendered form (no markdown markers revealed) and edits are
|
|
1064
|
+
* ignored, while text selection still works. The control lives in a
|
|
1065
|
+
* zero-height *sticky* host so the lock stays pinned to the top-right corner
|
|
1066
|
+
* of the scroll container as the document scrolls. The current mode is also
|
|
1067
|
+
* mirrored onto the root as `.md-readonly` for any CSS hooks.
|
|
1068
|
+
*/
|
|
1069
|
+
private _setupReadonlyToggle;
|
|
693
1070
|
focus(): void;
|
|
1071
|
+
/**
|
|
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.
|
|
1081
|
+
*/
|
|
1082
|
+
readonly geometricHitTest: ISettableObservable<boolean, void>;
|
|
694
1083
|
/**
|
|
695
1084
|
* Client coordinates → absolute source offset (any block). Used during
|
|
696
1085
|
* drag to keep extending the selection even when the pointer leaves the
|
|
697
|
-
* original block.
|
|
1086
|
+
* original block. Honours {@link geometricHitTest}.
|
|
698
1087
|
*/
|
|
699
1088
|
resolveOffsetFromPoint(point: Point2D): SourceOffset | undefined;
|
|
700
1089
|
/**
|
|
@@ -715,6 +1104,15 @@ export declare class EditorView extends Disposable {
|
|
|
715
1104
|
* is not read here, so there is no feedback loop into the render autorun.
|
|
716
1105
|
*/
|
|
717
1106
|
private _publishMeasurements;
|
|
1107
|
+
/**
|
|
1108
|
+
* Paint the diff highlights via the CSS Custom Highlight API: green over the
|
|
1109
|
+
* inserted/changed modified ranges (mapped on the document's own DOM), and
|
|
1110
|
+
* red over each {@link DiffDecorationViewNode}'s deleted ranges (mapped on
|
|
1111
|
+
* the decoration's own subtree). No DOM is mutated, so reconciliation and
|
|
1112
|
+
* editing are unaffected.
|
|
1113
|
+
*/
|
|
1114
|
+
private _paintDiff;
|
|
1115
|
+
private _clearDiff;
|
|
718
1116
|
}
|
|
719
1117
|
|
|
720
1118
|
export declare interface EditorViewOptions extends BlockViewOptions {
|
|
@@ -735,6 +1133,14 @@ export declare interface EditorViewOptions extends BlockViewOptions {
|
|
|
735
1133
|
* root ({@link element}) always spans the full available width.
|
|
736
1134
|
*/
|
|
737
1135
|
readonly limitedWidth?: IObservable<number | undefined>;
|
|
1136
|
+
/**
|
|
1137
|
+
* Diff mode only: render every read-only original decoration in active
|
|
1138
|
+
* (source) form, so even whole-block removals expose their markdown markers
|
|
1139
|
+
* as real text. Used by the diff-coverage fixture to verify that every
|
|
1140
|
+
* changed original character is rendered somewhere; off in normal use, where
|
|
1141
|
+
* whole removals show a clean solid band.
|
|
1142
|
+
*/
|
|
1143
|
+
readonly diffDecorationsActive?: boolean;
|
|
738
1144
|
}
|
|
739
1145
|
|
|
740
1146
|
export declare class EmphasisAstNode extends AstNode {
|
|
@@ -881,6 +1287,9 @@ export declare interface IClipboardStrategy {
|
|
|
881
1287
|
connect(context: IClipboardContext): IDisposable;
|
|
882
1288
|
}
|
|
883
1289
|
|
|
1290
|
+
/** A live rendering of a {@link CommentsModel}. Dispose to unmount it. */
|
|
1291
|
+
export declare type ICommentsPresenter = IDisposable;
|
|
1292
|
+
|
|
884
1293
|
/** The Monarch language definitions the default highlighter wires up. */
|
|
885
1294
|
export declare interface IDefaultMonarchGrammars {
|
|
886
1295
|
typescript: unknown;
|
|
@@ -1353,6 +1762,15 @@ export declare class NativeClipboardStrategy implements IClipboardStrategy {
|
|
|
1353
1762
|
connect(context: IClipboardContext): IDisposable;
|
|
1354
1763
|
}
|
|
1355
1764
|
|
|
1765
|
+
declare interface NestedItem {
|
|
1766
|
+
readonly kind: 'nested';
|
|
1767
|
+
readonly original: AstNode;
|
|
1768
|
+
readonly originalStart: number;
|
|
1769
|
+
readonly modified: AstNode;
|
|
1770
|
+
readonly modifiedStart: number;
|
|
1771
|
+
readonly children: readonly DiffItem[];
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1356
1774
|
/**
|
|
1357
1775
|
* Move the cursor one position left or right, skipping over hidden marker
|
|
1358
1776
|
* ranges in inactive blocks (and inactive items of an active list).
|
|
@@ -1483,6 +1901,23 @@ export declare class Rect2D {
|
|
|
1483
1901
|
translate(dx: number, dy: number): Rect2D;
|
|
1484
1902
|
}
|
|
1485
1903
|
|
|
1904
|
+
declare interface RemovedItem {
|
|
1905
|
+
readonly kind: 'removed';
|
|
1906
|
+
readonly node: AstNode;
|
|
1907
|
+
readonly originalStart: number;
|
|
1908
|
+
readonly deletedLocal: readonly AnnotatedRange[];
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
declare interface ReplacedItem {
|
|
1912
|
+
readonly kind: 'replaced';
|
|
1913
|
+
readonly original: AstNode;
|
|
1914
|
+
readonly originalStart: number;
|
|
1915
|
+
readonly modified: AstNode;
|
|
1916
|
+
readonly modifiedStart: number;
|
|
1917
|
+
readonly insertedLocal: readonly AnnotatedRange[];
|
|
1918
|
+
readonly deletedLocal: readonly AnnotatedRange[];
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1486
1921
|
export declare const selectAll: SelectionCommand;
|
|
1487
1922
|
|
|
1488
1923
|
export declare function selectBlock(ctx: CursorCommandContext, blockRange: OffsetRange): Selection_2;
|
|
@@ -1595,6 +2030,26 @@ export declare interface SnapshotTokens {
|
|
|
1595
2030
|
|
|
1596
2031
|
export declare type SourceOffset = number;
|
|
1597
2032
|
|
|
2033
|
+
export declare abstract class StackedCommentsPresenter extends Disposable implements ICommentsPresenter {
|
|
2034
|
+
protected readonly model: CommentsModel;
|
|
2035
|
+
protected readonly view: EditorView;
|
|
2036
|
+
protected readonly context?: CommentsPresenterContext | undefined;
|
|
2037
|
+
private readonly _layer;
|
|
2038
|
+
private readonly _entries;
|
|
2039
|
+
private _order;
|
|
2040
|
+
constructor(model: CommentsModel, view: EditorView, context?: CommentsPresenterContext | undefined);
|
|
2041
|
+
/** Build the card DOM for a comment. Called once per new comment. */
|
|
2042
|
+
protected abstract createWidget(comment: Comment_2): StackWidget;
|
|
2043
|
+
private _reconcile;
|
|
2044
|
+
private _relayout;
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
/** The minimal widget contract a subclass must produce. */
|
|
2048
|
+
export declare interface StackWidget {
|
|
2049
|
+
readonly element: HTMLElement;
|
|
2050
|
+
dispose(): void;
|
|
2051
|
+
}
|
|
2052
|
+
|
|
1598
2053
|
export declare class StrikethroughAstNode extends AstNode {
|
|
1599
2054
|
readonly openMarker: MarkerAstNode;
|
|
1600
2055
|
readonly content: readonly (InlineAstNode | GlueAstNode)[];
|
|
@@ -1799,6 +2254,13 @@ export declare class Token {
|
|
|
1799
2254
|
className: string | undefined);
|
|
1800
2255
|
}
|
|
1801
2256
|
|
|
2257
|
+
declare interface UnchangedItem {
|
|
2258
|
+
readonly kind: 'unchanged';
|
|
2259
|
+
/** The modified-side node (identical in content to the original). */
|
|
2260
|
+
readonly node: AstNode;
|
|
2261
|
+
readonly modifiedStart: number;
|
|
2262
|
+
}
|
|
2263
|
+
|
|
1802
2264
|
/**
|
|
1803
2265
|
* Immutable view of an AST node. Pairs `ast` with its rendered `dom` and a
|
|
1804
2266
|
* mirror of `ast.children` as ViewNode children. Source offsets are NEVER
|
|
@@ -1863,10 +2325,12 @@ export declare class ViewNode extends Disposable {
|
|
|
1863
2325
|
/**
|
|
1864
2326
|
* Map a DOM hit that lands on THIS node's own representation into a source
|
|
1865
2327
|
* range in this node's local space `[0, ast.length)`. Polymorphic: a text
|
|
1866
|
-
* leaf maps the caret offset 1:1
|
|
1867
|
-
* an image, a hidden marker)
|
|
1868
|
-
*
|
|
1869
|
-
*
|
|
2328
|
+
* leaf maps the caret offset 1:1. For an element hit — an element-only node
|
|
2329
|
+
* (KaTeX math, `<hr>`, an image, a hidden marker) or a wrapper/container
|
|
2330
|
+
* element — the platform reports a child-index offset, not a text caret, so
|
|
2331
|
+
* there is no internal mapping to honour: it snaps to the node's nearer
|
|
2332
|
+
* edge, `offset 0` (the "before" side) → start, any `offset >= 1` (the
|
|
2333
|
+
* "after" side) → end. Subclasses may override for finer control.
|
|
1870
2334
|
*/
|
|
1871
2335
|
getLocalSourceRange(pos: DomPosition): OffsetRange;
|
|
1872
2336
|
/**
|
|
@@ -1931,8 +2395,9 @@ export declare class VisualLine {
|
|
|
1931
2395
|
xAtOffset(offset: SourceOffset): number;
|
|
1932
2396
|
/**
|
|
1933
2397
|
* Snap `x` to the nearest offset on this line. If `x` falls inside a
|
|
1934
|
-
* run, the offset
|
|
1935
|
-
*
|
|
2398
|
+
* run, the run resolves the offset (exact glyph boundary for text runs,
|
|
2399
|
+
* nearer edge for source-less runs); otherwise it snaps to the closer
|
|
2400
|
+
* edge of the nearest run.
|
|
1936
2401
|
*/
|
|
1937
2402
|
offsetAtX(x: number): SourceOffset;
|
|
1938
2403
|
}
|
|
@@ -2020,8 +2485,14 @@ export declare class VisualLineMap {
|
|
|
2020
2485
|
* When constructed with a {@link VisualRunSource}, `xAtOffset` returns the
|
|
2021
2486
|
* pixel-exact x of the caret before character `offset` by measuring the
|
|
2022
2487
|
* prefix `[textNodeStart, textNodeStart + (offset - sourceStart))` with a
|
|
2023
|
-
* DOM `Range`.
|
|
2024
|
-
*
|
|
2488
|
+
* DOM `Range`.
|
|
2489
|
+
*
|
|
2490
|
+
* A source-less run has no per-offset geometry: it either represents an
|
|
2491
|
+
* element-only block (KaTeX math, a mermaid/custom diagram, an image, an
|
|
2492
|
+
* inactive `<hr>`) whose box does not correspond to source offsets, or a
|
|
2493
|
+
* hand-built run in a test. Either way it maps between offsets and x by
|
|
2494
|
+
* snapping to the nearer edge of {@link rect} rather than fabricating
|
|
2495
|
+
* interior positions.
|
|
2025
2496
|
*/
|
|
2026
2497
|
export declare class VisualRun {
|
|
2027
2498
|
readonly sourceRange: OffsetRange;
|
|
@@ -2039,14 +2510,15 @@ export declare class VisualRun {
|
|
|
2039
2510
|
|
|
2040
2511
|
/**
|
|
2041
2512
|
* The DOM source of a {@link VisualRun}. When set, `xAtOffset` and
|
|
2042
|
-
* `offsetAtX` measure exact glyph positions via `Range.getBoundingClientRect
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
*
|
|
2046
|
-
* wrong character.
|
|
2513
|
+
* `offsetAtX` measure exact glyph positions via `Range.getBoundingClientRect`.
|
|
2514
|
+
* This matters for proportional fonts where character widths differ a lot
|
|
2515
|
+
* (e.g. `m` vs `i`): a caret placed by anything coarser than real glyph
|
|
2516
|
+
* measurement lands several pixels inside the wrong character.
|
|
2047
2517
|
*
|
|
2048
|
-
*
|
|
2049
|
-
*
|
|
2518
|
+
* A run without a source has no per-offset geometry, so it maps between
|
|
2519
|
+
* offsets and x by snapping to the nearer run edge. Real text runs always
|
|
2520
|
+
* carry a source; source-less runs are element-only blocks (see
|
|
2521
|
+
* {@link _appendElementBlockRun}) and hand-built runs in tests.
|
|
2050
2522
|
*/
|
|
2051
2523
|
declare interface VisualRunSource {
|
|
2052
2524
|
readonly textNode: Text;
|
|
@@ -2054,4 +2526,12 @@ declare interface VisualRunSource {
|
|
|
2054
2526
|
readonly textNodeStart: number;
|
|
2055
2527
|
}
|
|
2056
2528
|
|
|
2529
|
+
export declare class VscodeStackedCommentsView extends StackedCommentsPresenter {
|
|
2530
|
+
protected createWidget(comment: Comment_2): StackWidget;
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2533
|
+
export declare class VsCodeV2CommentsView extends StackedCommentsPresenter {
|
|
2534
|
+
protected createWidget(comment: Comment_2): StackWidget;
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2057
2537
|
export { }
|